僕がUnityを初めてから気がついたことをメモしていきます。
Prefab
Prefabはゲームオブジェクトの雛形のようなもの。
スクリプトから動的にゲームオブジェクトを生成するときにはPrefabを使うのが便利そう。
Random.Range(x,y)
今までは
Random.Range(0,10); //0から10までの乱数を生成する
とか思ってたけど、
Random.Range(0,10); //0から9までの乱数を生成する
つまりRandom.Range()
はminからmax-1までの乱数を生成してくれる。
なぜかfloat
の場合はminからmaxまでの乱数を生成する。
事情があるんだろうけど、謎w
privateだけどUnityで初期値を設定したい
これは結構悩んだ場所。
メンバ変数をprivateにしたいけどUnityがわで初期値を設定したい・・・だけど・・・
そこで!
public class Bullet : MonoBehaviour{
[SerializeField]
float angle;
[SerializeField]
float speed;
}
いちいち宣言の前に[SerializeField]
を付けるのは面倒だけど、ないよりマシ。
Start()の順番
これも結構ハマったところ。
public class BulletManager : MonoBehaviour{
List<Bullet> bullets;
void Start(){
bullets = new List<Bullet>
}
public void Add(Vector3 pos){
/*省略(((((((((((っ・ω・)っ ブーン*/
}
}
public class GameManager{
[SerializeField]
BulletManager bulletManager;
void Start(){
bulletManager.Add(new Vector3(0,0,0));
}
}
これで実行するとReferenceException
が発生!
どうやらBulletManager
のList
で発生しているらしい。
原因
BulletManager
のStart()
でList
をnew
で生成している。
そしてGameManager
のStart()
でBulletManager
のAdd()
を呼び出している。
Add()
ではBulletManager
のList
を使っている。
原因はこれを順番にしてみると分かる。
-
GameManager
のStart()
が呼び出されてBulletManager
のAdd
が呼ばれる(ここでReferenceException) -
BulletManager
のStart()
が呼び出されList
が生成される。
つまりBulletManager
のStart()
でList
が生成される前にList
を参照するAdd()
が呼び出されてしまう。
解決策
解決策1
解決策としてGameManager
のStart()
よりBulletManager
のStart()
を初めに呼び出してList
を最初に生成させる。
解決策2
BulletManager
のList
の生成をAwake()
関数で実行すればGameManager
のStart()
よりも前にList
が生成されるので解決できます。
参考:イベント関数の実行順
ryo0kaさんありがとうございます!
解決策2のほうがUnity側で管理しなくてもいいので良さそうです。
方法
UnityでEdit->Project Settings -> Script Execution Order
で+
ボタンをクリックしてStart()
を呼び出したいクラスのtimeを短めにセットする。