質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1035閲覧

Unityでの乱数を重複なく複数回表示

Hayato555

総合スコア17

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2017/10/03 12:24

Unityでtetrisを作っています。
unity初心者なのでいろんなサイトを見て頑張っているのですが、
一つだけどこを探してもわからないことがあります。
それは 乱数を重複なく複数回表示することです。
0~7をランダムに重複なく配列し、それを繰り返したいです。
またそれを表示して、それに対応したものを出現させることです。

https://teratail.com/questions/94741
こちらのページを見たのですが、どのようにスクリプトに入力するのかがわかりません。

どなたか初心者でもわかりやすく説明してくれる方はいませんか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

コードを大幅に修正しました。

[処理内容]

    1. objctsに指定したGameObjectをランダムで出力
    1. すべて出力完了後、配列をランダムにリセット
  • 1、2の順で永遠にループ
  • 止めたい場合はstopLandObjLoop()を実行する

コードは未検証です。コメントを入れているので挙動がおかしかったらご自分で修正してください。

C#

1using UnityEngine; 2using System.Linq; 3using System; 4using System.Collections; 5 6public class createRandObjs : MonoBehaviour 7{ 8 //とりあえずインスペクタからオブジェクトを追加 9 [SerializeField] 10 GameObject[] objcts; 11 12 //何秒おきに出力するかを指定 13 static readonly float LOOP_INTERVAL = 3f; 14 15 //Coroutineをキャッシュする変数 16 Coroutine landObjLoopCorutine; 17 18 void Start() 19 { 20 // 実行 21 startLandObjLoop(); 22 } 23 24 25 /// <summary> 26 /// ループのスタート 27 /// </summary> 28 void startLandObjLoop() 29 { 30 //このGameObjectが非表示の時にlandObjLoopを実行されるとエラーになるのでその場合実行させない 31 if (!gameObject.activeInHierarchy) 32 { 33 #if UNITY_EDITOR 34 Debug.Log("このオブジェクト非表示中だから実行できないよ"); 35 #endif 36 37 return; 38 } 39 40 //実行中なら重複するので一旦停止 41 stopLandObjLoop(); 42 43 //オブジェクトの出力をスタート 44 StartCoroutine( landObjLoop() ); 45 } 46 47 48 /// <summary> 49 /// ループのストップ 50 /// </summary> 51 void stopLandObjLoop() 52 { 53 if (landObjLoopCorutine != null) StopCoroutine(landObjLoopCorutine); 54 } 55 56 57 /// <summary> 58 /// オブジェクトを出力する 59 /// </summary> 60 void instantiateObj(int idx) 61 { 62 //とりあえずVector3.zero地点にオブジェクトを生成 63 Instantiate(objcts[idx], Vector3.zero, Quaternion.identity); 64 } 65 66 67 /// <summary> 68 /// objctsをランダムに出力し続ける 69 /// </summary> 70 IEnumerator landObjLoop() 71 { 72 //オブジェクトが無ければ何もせず終了 73 if (objcts.Length == 0) yield break; 74 75 var waitTime = new WaitForSeconds( LOOP_INTERVAL ); 76 77 //順番にカウントするための変数 78 var idx = 0; 79 //ランダムなインデックスを格納する配列 80 var objIdxAry = new int[objcts.Length]; 81 82 while(true) 83 { 84 //idxが0またはobjctsの数に達したらリセット 85 if(idx == 0 || idx == objcts.Length) 86 { 87 idx = 0; 88 objIdxAry = Enumerable.Range(0, objcts.Length).OrderBy(n => Guid.NewGuid()).ToArray(); 89 } 90 91 instantiateObj(objIdxAry[idx]); 92 idx++; 93 94 yield return waitTime; 95 } 96 } 97}

遅延処理 Coroutine(コルーチン)の使い方について過去に回答したので見てみてください。
https://teratail.com/questions/93115

投稿2017/10/03 12:47

編集2017/10/05 19:56
IShix

総合スコア1724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hayato555

2017/10/03 13:17

お手数ですがすいません このコードを試してみると最初に 7個オブジェクト(テトリスのミノ)があるので 70個生成されるのですが、その時にZミノだけ出現しません、また70個生成された後に降ってくるミノも何度も重複しています。 私が行ったことは、このコードをコピペして、オブジェクトを追加しただけです。何か操作が足りていないんでしょうか?
IShix

2017/10/03 13:33

すみません。何度か修正したのですが、最終コードになってますか?お手数ですがコピペしてもう一度試してみてください。 あと、「0~7をランダムに重複なく配列し」とありますが、これが配列のインデックスになると思っていたのですがあってますか?要はオブジェクトは8個あって配列にすると0から始まるので0-7の数字が配列に入ります。7個オブジェクトがある場合は0-6の数値が配列に入ります。 このコードは設定したオブジェクトの数で配列のインデックスを生成してオブジェクトをすべて出力を10回繰り返すプログラムです。 「70個生成された後に降ってくるミノも何度も重複しています。」とありますが、7個オブジェクトがあって1度出力した場合、2回目も7個のオブジェクトからランダムに配列化して表示しているので1回目と2回目はもちろん同じ配列なので重複しますが、1回目のみ、2回目のみだと重複しないのですが、認識が間違ってますか?
Hayato555

2017/10/03 22:20

7個のオブジェクトの場合は0~7ではなく0~6でした。 最終コードを入れてみると Assets/Script/createRandObjs.cs(7,14): error CS0101: The namespace `global::' already contains a definition for `createRandObjs' というエラーが出ました。 またオブジェクトの出現なのですが、 最終コードでないので試したときは、最初に一気に大量のオブジェクト(数えてないのですが大体70個ほどでした)が出現し、それらは動かずに、別のミノが出現して、そのミノの出現はおそらくランダム(重複のある)でした。  念のためもう一度書かせていただきますが 私が望んでいるオブジェクトの出現の順は 7つのミノがまずランダムで重複なしででてきて、また7つ重複のないランダム、、、といった順です。 言葉足らずで申し訳ありませんが、ご協力お願いします。
IShix

2017/10/04 07:38 編集

▼エラーについて クラス名の重複エラーです。2つ以上同名のクラスがあるので必要ないものを削除するかリネームしてください。 ▼ 最初に一気に大量のオブジェクトが出現し〜 7(重複無し) x 10回一瞬で出力されます。 ▼ 7つのミノがまずランダムで重複なしででてきて、また7つ重複のないランダム、、、といった順です。 同じ認識です。上で説明したように、そのように出力されています。 ▼ これからの話 今の課題は一つずつ出力し、7つすべて出力されたらランダムな配列をリセットしてまた最初から一つずつ出力したいですか?それでしたら、コードを変更したので見てみてください。
Hayato555

2017/10/04 08:02

すみません、一つ大事なことを書くのを忘れていました。 私が見ていたサイトでは オブジェクトを生成するのに、spawnNext() というものになっていて、Spawnerという別のオブジェクトに、ミノが着地したらspawnNextを出力するようになっていました。(FindObjectOfType<Spawner>().spawnNext();と書いていました。)上記のコードを詳しくはわからなかったのですが、おそらく時間経過でミノを生成するようになっていますよね? どのようにしたらSpawnerからの出力でミノを出現させることが出来るでしょうか。
IShix

2017/10/04 08:50

了解です。一旦この質問を完了にして新たに質問していただけないですか?今日は忙しいので誰かが回答してくれるかもしれません。回答が無ければ今日深夜か明日回答いたします。
Hayato555

2017/10/04 09:11

本当にありがとうございます もう少しunity及びC#について勉強してから質問すればと反省しています 最初に望んでいたミノの出現はできたのでベストアンサーとさせていただきます 別の問題はまだ解決していないので 新たに別で質問します。 もし時間があればそちらも閲覧してください。 m(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問