◎やりたいこと
Awake()でprefabをロードし、その後に別のクラスからこのクラスのCreateCube()を呼び出します。
Resourcesフォルダ内のCubesフォルダにprefabが七つ入っています。
七つのprefabの内の一つをランダムで選びクローンを作ります。
◎問題点
Awake()で配列の中にGameObjectが格納されるところまではできているのですが、別のメソッドで呼び出すと
「配列の中には何も入ってない」
とでも言うようなエラーが吐かれます...(画像)
どこが間違っているのか、自分の力では見つけられず、お力添えいただきたく思います。
よろしくお願いします。
GameSystem
1public class GameSystem : MonoBehaviour 2{ 3 //すべてのprefabを格納する配列変数 4 public GameObject[] cubes; 5 //取り出したprefabを格納する変数 6 // public GameObject cube; 7 8 void Awake() 9 { 10 Debug.Log("ロード開始"); 11 //prefabをロード 12 cubes = Resources.LoadAll<GameObject>("Cubes"); 13 Debug.Log("ロード 完了。"); 14 Debug.Log(cubes.Length); 15 } 16 17 //Cube(prefab)の生成 18 public GameObject CreateCube() 19 { 20 Debug.Log("呼びだされました。"); 21 Debug.Log(cubes.Length); 22 //乱数生成し変数cubeの中にそのprefabを入れる 23 GameObject cubePrefab = cubes[Random.Range(0, cubes.Length)]; 24 Debug.Log("乱数生成完了。"); 25 //Cube生成 26 GameObject cube = Instantiate( cubePrefab, new Vector3(500f, 101.5f, 495f),Quaternion.identity ); 27 Debug.Log("Cube生成完了。"); 28 return cube; 29 } 30 31 // 32 33}
CreateCube()を呼び出すCubeクラスです(一部)。コライダーで検知し、Invokeで呼び出します。
Cube
1 2 private void OnCollisionEnter(Collision collision) 3 { 4 //着地したか判定 5 if (collision.gameObject.tag == "Table" || 6 collision.gameObject.tag == "Cube" || 7 collision.gameObject.tag == "Terrain") 8 { 9 10 //Cube生成メソッド呼び出す 11 if (!onTable) 12 { 13 onTable = true; 14 Invoke("Create",3f ); 15 //子オブジェクト①のCameraMouseスクリプトを無効化 16 transform.GetChild(0).gameObject.GetComponent<CameraMouse>().enabled = false; 17 } 18 Debug.Log("着地しやした"); 19 } 20 21//Cube生成 22 public void Create() 23 { 24 //Cube生成メソッド呼び出し 25 gameSystem.CreateCube(); 26 //このスプリクトを無効化 27 this.GetComponent<Cube>().enabled = false; 28 } 29
1つ目のwarningが気になりますが、GameSystemをnewしてはいませんよね?
また、質問とは関係ないですが、このままだとコピー元がcubeに代入されることになりますが、意図した動作でしょうか?
質問ありがとうございます。
GameSystemをnew、してないですね。
コピー元に代入...CreateCubeメソッドが呼ばれる度、ランダムなプレハブをcubeに代入して生成しているつもりです。
理解力が無く、すみません。ご質問の回答になっていますでしょうか...
> GameSystemをnew、してないですね。
了解です。
ただ、どこかでアタッチすべき(=MonoBehaviourを継承した)スクリプトをnewしているので、そこは直したほうがよろしいかと思います。
> コピー元に代入...CreateCubeメソッドが呼ばれる度、ランダムなプレハブをcubeに代入して生成しているつもりです。
プレハブ=コピー元ということになるので、外部でInstantiate()するなら別ですが、そうでなければInstantiate()の返り値(=コピー先)を取得するのが自然だと思うのですが、どうでしょう。
ご指摘ありがとうございます。見つけ出してnew、直しておきます。
> プレハブ=コピー元ということになるので、外部でInstantiate()するなら別ですが、そうでなければInstantiate()の返り値(=コピー先)を取得するのが自然だと思うのですが
すみません。言葉ではどうも理解が難しくて....、よろしければお手数ですがソースコードを提示していただけないでしょうか?
GameObject cubePrefab = cubes[Random.Range(0, cubes.Length)];
cube = Instantiate( cubePrefab, new Vector3(500f, 101.5f, 495f),Quaternion.identity );
ということです。
まあ、そうする場合、以下のようにcubeは関数の内部で定義しておき、cubeをreturnするほうがいいとは思いますが。
//public GameObject cube; // 削除
public GameObject CreateCube()
{
GameObject cubePrefab = cubes[Random.Range(0, cubes.Length)];
GameObject cube = Instantiate( cubePrefab, new Vector3(500f, 101.5f, 495f),Quaternion.identity );
return cube;
}
なるほど!たしかにそちらの方が自然ですね。
勉強になります。ありがとうございます。
念のためStartButton.csも
質問文に追記してもらえますか?
返信が遅くなり申し訳ないです。
試行錯誤するうちにStartButton.csは消され、CubeクラスからCreateCubeメソッドを呼ぶようになっており、エラー文も短くなったので質問文を更新致します。
回答1件
あなたの回答
tips
プレビュー