実サイズ城のMR表示 

#環境構築 

###アプリ 

Windows 10
Unity 2019.4.16f1以上 
ARCoreサポートしたAndroidスマホ 
ARKitサポートしたiOSスマホ 

###Unity Package 

Microsoft Mixed Reality Toolkit 2.4.0 
https://github.com/microsoft/MixedRealityToolkit-Unity/releases 

AR Foundation 2.1.8 
ARCore XR Plugin 2.1.11 
ARKit XR Plugin 2.1.9 

Hanif-Castle-MR
https://github.com/fermanda/CastleInMixedReality/releases

#プロジェクト作成 

 

Hanif-Castle-MRを入れる前に、他のパッケージを入れてください。 

MRTK (Assets→Import Package→Custom Package) 
AR Foundation, ARCore XR, ARKit XR (Window→Package Manager) 
TMPro (Window→TextMeshPro→Import TMP Essential Resources)

全部入れたら、Hanif-Castle-MRを入れてください（Assets→Import Package→Custom Package) 
ProjectのAssets→Castle MR→ScenesでARシーンを開いてください。 

#プロジェクト説明 

###モデル準備 

こちらのプロジェクトで伏見桃山城のモデルを使いさせていただきます。 モデルはこちらのリンクから無料でダウンロードできます。 

[伏見桃山城3Dモデル](https://sketchfab.com/3d-models/momoyama-castle-rawscan-244171a3822f4f83bd7c65b432fa93b2 )

![Capture.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/e61b54df-4887-df08-23cf-be7e9ae6aed5.png)

普段はUnityで3Dモデルを表示するにはobjファイルをそのままHirearcyで入れたら問題ありません。けれど今回は、表示されるモデルはい実のスケールで表示される予定なので、普段の方法でモデルを表示する場合は表示されたモデルをブレになる可能性があります。なぜなら、objを入れた時、MaterialのResolutionを設定は最大8000までだけができます。別の方法はStreamingAssetsやAssetBundleのオプションがあります。 

MRTKでGLTFを表示したい場合は、まずGLTFのフォーマットを対応のため、変更してください。変更方法は、ダウンロードしたモデルをMRTKのコンバーターに入れたら完了です。 
 
MRTKのGLTFコンバーターはこちらでダウウンロードできます。exeファイルだけダウンロードは十分です。 
[MRTK GLTFコンバーター](https://github.com/Microsoft/glTF-Toolkit/releases )

###言語設定 

国際ユーザーへアプリを作る予定場合は複数な言語を用意しないといけません。複数の言語を用意するステップはLocalizationと呼ばれます。Localization方法は複数あります。小さいアプリ場合は一つのコードでDictionaryをいればは完了です。けれど、アプリをもっと大きくなる場合は、テキストを管理することは難しいになります。今回は2つのLocalizationを紹介します。 
 
* **Unity PackageのLocalization** 

現在、UnityパッケージLocalizationはUnityチームよりまだ開発中ので、今のところはpreviewパッケージだけがあります。 興味がある方はこちらのリンクへどうぞ。

[Unity Localization パッケージ](https://docs.unity3d.com/Packages/com.unity.localization@0.10/manual/index.html)
 
**インストール方法**

Window→Package Manager→(+)アイコン→ Add package from git URL 
「com.unity.localization」を入れて、完了です。 

* **JSONのLocalization**

またはJSONで複数の言語用意して、StreamingAssetから呼びされた。こちらのオプションはカスタム必要場合はもっとできます。全ての言語はStreamingAssetsフォルダーへ入れて各言語でファイルを用意します。 

まずJSONの形を準備します。今回は、鍵(Key)と内容(value)で分裂します。

```c#:LocalizationData.cs
[System.Serializable]
public class LocalizationData
{
    public LocalizationItem[] items;    
}

[System.Serializable]
public class LocalizationItem
{
    public string key;
    public string value;
}
```

鍵はGameObjectの名前にします、でないようは対応の言語です。

```c#:LocaleManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using TMPro;
using UnityEngine.Networking;

public class LocaleManager : MonoBehaviour
{
    public string CurrentLanguage = "Japanese";
    public Dictionary<string, string> localeText;
    private IEnumerator coroutine;
    
    private void Awake() {
        LoadLocalizedText();
    }

    public void ChangeLanguage(){
        if(CurrentLanguage == "English") CurrentLanguage = "Japanese";
        else CurrentLanguage = "English";
        LoadLocalizedText();
    }

    public void LoadLocalizedText(){
        localeText = new Dictionary<string, string>();
        string filePath = Path.Combine(Application.streamingAssetsPath, CurrentLanguage+".json");

#if UNITY_ANDROID && !UNITY_EDITOR
        var path = "jar:file://" + Application.dataPath + "!/assets/" + CurrentLanguage+".json";
#else
        var path = filePath;
#endif
        coroutine = GetLanguagePack(path);
        StartCoroutine(coroutine);
    }

    private IEnumerator GetLanguagePack(string path){
        var loadingRequest = UnityWebRequest.Get(path);
        loadingRequest.SendWebRequest();
        while (!loadingRequest.isDone) {
            yield return null;
        }
        
        if (loadingRequest.downloadHandler.data != null  && loadingRequest.downloadHandler.data.Length > 0){
            Debug.Log("=====>DebugLog : Data Received");
        }
        else{
            Debug.Log("=====>DebugLog : Data is Empty");
        }

        string JSONdata = loadingRequest.downloadHandler.text;
        LocalizationData loadeddata = JsonUtility.FromJson<LocalizationData>(JSONdata);
        for (int i = 0; i < loadeddata.items.Length; i++){
            localeText.Add(loadeddata.items[i].key, loadeddata.items[i].value);
        }

        UpdateLanguage();
        yield break;
    }

    public void UpdateLanguage(){
        foreach(KeyValuePair<string, string> entry in localeText){
            GameObject.Find(entry.Key).GetComponentInChildren<TextMeshProUGUI>().text = entry.Value;
        }
    }
}

```

UnityWebRequestは普段Coroutineの内で発生しますので、今回もStreamingAssetsからデータをもらうため、Coroutineで発生します。言語データを処理したら、`UpdateLanguage()`が実行された。`GameObject.Find()` を使って言語設定されるはずテキストオブジェクトを選んだ言語に対応、更新します。

#Androidのビルド設定 

File→Build Settings。Androidを選択して、Switch Platform. 
Player Settingを開いてください。Other Settingsの下に、複数のアイテムを設定します。 

* まずは、Vulkan Graphic APIを消します。 
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/6809f8f5-46bc-3810-4eb2-59d2e6f97963.png)

* 次はScripting BackendはIL2CPPに変更します。 API Compability Levelは「.NET 4.x」に変更します。Target ArchitectureはARM64を選択してください。 
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/a9baf6c6-4ace-9c5c-4cbb-47bc4085984f.png)

* 最後はStrip Engine CodeとOptimize Mesh Dataのチェックを消してください。 
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156398/361b49ec-9d6d-a3c5-c3c6-d243acdeae13.png)

* 終わりましたら、Buildボタンを押して、APKファイルを生成します。

#デモ
編集中