やりたいこと
- Prefab用意して、Scriptから指定した分のGameObject(人)をばんばん作る
- 作った人をManagerクラスかなにかに保持しておく
- Cinemachineのfollowを切り替えられるようなクラスから、Managerクラスの人リストを引っ張ってきて、対象を切り替えられるようにしたい(これがやりたいこと)
よしやるぞ!
PrefabをInstantiate
よーし簡単そうだーってAssetを読み込む旅にでる。
Asset読み込みの旅
なるほど〜〜?なんかとりあえず色々種類を知る。
そしてなにか面倒ということを知る。
Addressables.InstantiateAsync
を使うぞ!
神記事に出会う
よしやろうと思う。ドキュメント・・・
読みづらい。とりあえず試してみたところ、上手く言った。わーい。
NavMeshにInstantiateしたPrefabを配置したい
Cinemachineでどうやってfollow対象を切り替える?
カメラ用のクラスもここで用意した。あとはManagerからひっぱるだけ。
インスタンス化したクラスを呼ぶ
2つのGameObjectがあるけどどっちが先に処理されるの?
なるほど。設定してみた。
しかし、うまくいかなかった。そうかコルーチンでやっているからか。というわけでawaitをができないかという旅にでた
awaitを使う旅
初心者のためのTask.Run(), async/awaitの使い方 - Qiita
色々試したがだめで、どうやらAsync設定したメソッドがあると順序守るのむずいっぽいということになっている
コルーチンとUniRXをつかったらとりあえずManagerクラス側ではawaitを利用してちゃんと順序守ることはできたので、下記の様にした。
- ManagerクラスStart()、カメラクラスStart()はほぼ同時 → Managerクラスでは生成したオブジェクトをリストに突っ込んでおく、カメラクラスでは何もしない
- カメラクラス側でManagerクラスを引っ張ってきて、Updateメソッドでリストの数が0以外で前と変化がなくなるまで監視し続ける
- 変化なくなったらカメラのfollowに突っ込むように変換して、キーボードのアクションできりかえられるようする
にした、嫌だこの設計。できれば順序よくやりたいが現時点だとよくわかっていない(特にカメラ側の監視とかいらないしバグのぬか床になりそう)
メインスレッドでしか使えない関数が多い件
Task.Run(async () => await Method())
とかやるとすぐこれにハマるのでやめた。
GameObjectをComponentに貼り付けたScript(Class)にキャストしたいんだけど・・・?
無理です。GetComponentを使おう。
なぜかPrefabにsetされているComponentのインスタンス化のタイミングが変
private async void Start() { await StartCoroutine(Load("Assets/Prefabs/Robo.prefab")); } private IEnumerator Load(string address) { Vector3 point; var range = 200.0f; for (int i = 0; i < 5; i++) { if (RandomPoint(Vector3.zero, range, out point)) { AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>(address); if (handle.Result != null) { GameObject g = Instantiate(handle.Result, point, Quaternion.identity); Human h = handle.Result.GetComponent<Human>(); this.humans.Add(h); } yield return handle; } } }
こう書くと、なぜかGetComponentで取得したHumanの位置が全部同じなので???になりました。 また、Humanクラス側でStartメソッドにログとか履くようにしてたが、コルーチンが終わった後にStartされたり、値が全然違うしさらに???となっていました。
んで、色々調べて下記の様に修正した。
GameObject g = Instantiate(handle.Result, point, Quaternion.identity) as GameObject; Human h = g.GetComponent<Human>();
修正したら、あいかわらずコルーチン後にHumanクラス側の処理が走るが、位置などの値は同じになりました。そして無事カメラも追走?するように修正できました。
雑感
とてもとても大変でした。