前提・実現したいこと
初めての質問投稿になります.
私はUnityを独学で勉強している最中のため,用語の使い方など不正確な点もあると思いますが,よろしくお願いします.
環境としては,Mac BookAir(M1)で,unityのバージョンは2020.3.0f1です.
Unityで3色(色固定・重複無し)のターゲットを3つ,ランダムに等間隔で配置することを目的にスクリプトを作成しています.
スクリプトの内容としては,
0.ターゲットをprefab化しておく.(前提)
1.そのprefabをインスタンス化してオブジェクトを生成する.
2.生成したオブジェクトを等間隔に配置する.
3.prefabのマテリアルを変えることで,色を変える.
と考えています.
該当のソースコード
prefabを生成し配置するソースコードは,こちらのサイトを参考にしています.
https://ekulabo.com/prefab-block-sample
重複無しで数字を出力するソースコードは,こちらのサイトを参考にしています.
https://tech.pjin.jp/blog/2018/02/01/unity_random-number_nonoverlap/
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5/// <Summary> 6/// Prefabのオブジェクトを並べるサンプルスクリプトです。 7/// </Summary> 8public class PrefabPlaceSample : MonoBehaviour 9{ 10 // オブジェクトを生成する元となるPrefabへの参照を保持します。 11 public GameObject prefabObj; 12 13 // 生成したオブジェクトの親オブジェクトへの参照を保持します。 14 public Transform parentTran; 15 16 // マテリアルを保持します。 17 public Material redMat; 18 public Material yellowMat; 19 public Material whiteMat; 20 21void Start() 22 { 23 CreateBlockObject(); 24 } 25 26 /// <Summary> 27 /// Prefabからブロックとして使うオブジェクトを生成します。 28 /// </Summary> 29 void CreateBlockObject() 30 { 31 int row = 1; 32 int column = 3; 33 float xOffset = 2.5f; 34 float zOffset = 7.1f; 35 36 List<int> numbers = new List<int>(); 37 38 for (int j = 0; j < row; j++) 39 { 40 for (int i = 0; i < column; i++) 41 { 42 // ゲームオブジェクトを生成します。 43 GameObject obj = Instantiate(prefabObj, Vector3.zero, Quaternion.identity); 44 45 // ゲームオブジェクトの親オブジェクトを設定します。 46 obj.transform.SetParent(parentTran); 47 48 // ゲームオブジェクトの位置を設定します。 49 float xPos = xOffset * i; 50 float zPos = zOffset * j; 51 obj.transform.localPosition = new Vector3(xPos, 0.0f, zPos); 52 53 // マテリアルをランダムで設定します。 54 for (int k = row; k <= column; k++) 55 { 56 // まず,List numbers に数字を追加します. 57 numbers.Add(k); 58 } 59 while (numbers.Count > 0) 60 { 61 // ランダムに数字を取り出します. 62 int index = Random.Range(0, numbers.Count); 63 int ransu = numbers[index]; 64 Material mat = whiteMat; 65 // 乱数の結果により,マテリアルを変更します. 66 switch (ransu) 67 { 68 case 1: 69 mat = redMat; 70 break; 71 case 2: 72 mat = yellowMat; 73 break; 74 } 75 //重複を避けるため,利用した数字をnumbersから消します. 76 numbers.RemoveAt(index); 77 obj.GetComponent<MeshRenderer>().material = mat; 78 79 } 80 } 81 } 82 } 83}
試したこと
forでループする際に,数字のlistであるnumbersに要素を追加しているのではと考え,ループする前(最初のforの前)に
for (int k = row; k <= column; k++) { // まず,List numbers に数字を追加します. numbers.Add(k); }
追加してみましたが,一番最初のターゲット以外はマテリアルが変更されませんでした.
###修正1
1570pさんに,case 0 (case 3)(つまりmaterialをransuを使って変更しない)場合に何か起きているのでは?とご指摘していただいたので,defaultMatというmaterialから必ずransuを用いて,materialを変更するように,下記のように書き換えました.
実行結果としては,変わりませんでした.
修正したコード1
public class PrefabPlaceSample : MonoBehaviour { // オブジェクトを生成する元となるPrefabへの参照を保持します。 public GameObject prefabObj; // 生成したオブジェクトの親オブジェクトへの参照を保持します。 public Transform parentTran; // マテリアルを保持します。 public Material redMat; public Material yellowMat; public Material whiteMat; public Material defaultMat; 〜〜〜 while (numbers.Count > 0) { // ランダムに数字を取り出します. int index = Random.Range(0, numbers.Count); int ransu = numbers[index]; Material mat = defaultMat; // 乱数の結果により,マテリアルを変更します.(修正済み) switch (ransu) { case 1: mat = redMat; break; case 2: mat = yellowMat; break; case 3: mat = whiteMat; break; } //重複を避けるため,利用した数字をnumbersから消します. numbers.RemoveAt(index); obj.GetComponent<MeshRenderer>().material = mat; } 〜〜〜
最後に
ここまで読んでいただきありがとうございます.
回答する上で,足りない情報等ございましたら,お知らせください.
ご指導のほどよろしくお願いいたします.
解決記録
Bongoさんのご指摘の通り,書き換えたところ目的通りのスクリプトが完成しました.
完成したコード
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <Summary> /// Prefabのオブジェクトを並べるサンプルスクリプトです。 /// </Summary> public class PrefabPlaceSample : MonoBehaviour { // オブジェクトを生成する元となるPrefabへの参照を保持します。 public GameObject prefabObj; // 生成したオブジェクトの親オブジェクトへの参照を保持します。 public Transform parentTran; // マテリアルを保持します。 public Material redMat; public Material yellowMat; public Material whiteMat; public Material defaultMat; void Start() { CreateBlockObject(); } /// <Summary> /// Prefabからブロックとして使うオブジェクトを生成します。 /// </Summary> void CreateBlockObject() { int row = 6; int column = 3; float xOffset = 2.5f; float zOffset = 7.1f; List<int> numbers = new List<int>(); for (int j = 0; j < row; j++) { numbers.Clear(); for (int k = 1; k <= column; k++) { // まず,List numbers に数字を追加します. numbers.Add(k); } for (int i = 0; i < column; i++) { // ゲームオブジェクトを生成します。 GameObject obj = Instantiate(prefabObj, Vector3.zero, Quaternion.identity); // ゲームオブジェクトの親オブジェクトを設定します。 obj.transform.SetParent(parentTran); // ゲームオブジェクトの位置を設定します。 float xPos = xOffset * i; float zPos = zOffset * j; obj.transform.localPosition = new Vector3(xPos, 0.0f, zPos); // マテリアルをランダムで設定します。 if (numbers.Count > 0) { // ランダムに数字を取り出します. int index = Random.Range(0, numbers.Count); int ransu = numbers[index]; Material mat = defaultMat; // 乱数の結果により,マテリアルを変更します.(修正済み) switch (ransu) { case 1: mat = redMat; break; case 2: mat = yellowMat; break; case 3: mat = whiteMat; break; } //重複を避けるため,利用した数字をnumbersから消します. numbers.RemoveAt(index); obj.GetComponent<MeshRenderer>().material = mat; } } } } }
実行結果
回答1件
あなたの回答
tips
プレビュー