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

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

ただいまの
回答率

90.61%

  • C#

    6898questions

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

  • Unity

    3837questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 663

Hayato555

score 11

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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

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

[処理内容]

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

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

using UnityEngine;
using System.Linq;
using System;
using System.Collections;

public class createRandObjs : MonoBehaviour
{
    //とりあえずインスペクタからオブジェクトを追加
    [SerializeField]
    GameObject[] objcts;

    //何秒おきに出力するかを指定
    static readonly float LOOP_INTERVAL = 3f;

    //Coroutineをキャッシュする変数
    Coroutine landObjLoopCorutine;

    void Start()
    {
        // 実行
        startLandObjLoop();
    }


    /// <summary>
    /// ループのスタート
    /// </summary>
    void startLandObjLoop()
    {
        //このGameObjectが非表示の時にlandObjLoopを実行されるとエラーになるのでその場合実行させない
        if (!gameObject.activeInHierarchy)
        {
            #if UNITY_EDITOR
            Debug.Log("このオブジェクト非表示中だから実行できないよ");
            #endif

            return;
        }

        //実行中なら重複するので一旦停止
        stopLandObjLoop();

        //オブジェクトの出力をスタート
        StartCoroutine( landObjLoop() );
    }


    /// <summary>
    /// ループのストップ
    /// </summary>
    void stopLandObjLoop()
    {
        if (landObjLoopCorutine != null) StopCoroutine(landObjLoopCorutine);
    }


    /// <summary>
    /// オブジェクトを出力する
    /// </summary>
    void instantiateObj(int idx)
    {
        //とりあえずVector3.zero地点にオブジェクトを生成
        Instantiate(objcts[idx], Vector3.zero, Quaternion.identity);
    }


    /// <summary>
    /// objctsをランダムに出力し続ける
    /// </summary>
    IEnumerator landObjLoop()
    {
        //オブジェクトが無ければ何もせず終了
        if (objcts.Length == 0) yield break;

        var waitTime = new WaitForSeconds( LOOP_INTERVAL );

        //順番にカウントするための変数
        var idx = 0;
        //ランダムなインデックスを格納する配列
        var objIdxAry = new int[objcts.Length];

        while(true)
        {
            //idxが0またはobjctsの数に達したらリセット
            if(idx == 0 || idx == objcts.Length)
            {
                idx = 0;
                objIdxAry = Enumerable.Range(0, objcts.Length).OrderBy(n => Guid.NewGuid()).ToArray();
            }

            instantiateObj(objIdxAry[idx]);
            idx++;

            yield return waitTime;
        }
    }
}

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/03 22:17

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

    キャンセル

  • 2017/10/03 22:33

    すみません。何度か修正したのですが、最終コードになってますか?お手数ですがコピペしてもう一度試してみてください。

    あと、「0~7をランダムに重複なく配列し」とありますが、これが配列のインデックスになると思っていたのですがあってますか?要はオブジェクトは8個あって配列にすると0から始まるので0-7の数字が配列に入ります。7個オブジェクトがある場合は0-6の数値が配列に入ります。

    このコードは設定したオブジェクトの数で配列のインデックスを生成してオブジェクトをすべて出力を10回繰り返すプログラムです。

    「70個生成された後に降ってくるミノも何度も重複しています。」とありますが、7個オブジェクトがあって1度出力した場合、2回目も7個のオブジェクトからランダムに配列化して表示しているので1回目と2回目はもちろん同じ配列なので重複しますが、1回目のみ、2回目のみだと重複しないのですが、認識が間違ってますか?

    キャンセル

  • 2017/10/04 07: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つ重複のないランダム、、、といった順です。
    言葉足らずで申し訳ありませんが、ご協力お願いします。

    キャンセル

  • 2017/10/04 16:26 編集

    ▼エラーについて
    クラス名の重複エラーです。2つ以上同名のクラスがあるので必要ないものを削除するかリネームしてください。

    ▼ 最初に一気に大量のオブジェクトが出現し〜
    7(重複無し) x 10回一瞬で出力されます。

    ▼ 7つのミノがまずランダムで重複なしででてきて、また7つ重複のないランダム、、、といった順です。
    同じ認識です。上で説明したように、そのように出力されています。

    ▼ これからの話
    今の課題は一つずつ出力し、7つすべて出力されたらランダムな配列をリセットしてまた最初から一つずつ出力したいですか?それでしたら、コードを変更したので見てみてください。

    キャンセル

  • 2017/10/04 17:02

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

    キャンセル

  • 2017/10/04 17:50

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

    キャンセル

  • 2017/10/04 18:11

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

    キャンセル

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

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    unity 白色のOutline

    unity5.3.5を使用しています。 キャラクター画像(PNG,2Dsprite)のimageオブジェクトにoutlineコンポーネントをアタッチして、白色のアウトラインを

  • 解決済

    UnityのTextGeneratorについて

    Unity5.3.7にて、文字列の幅を取得して、Textの枠をはみ出したら文字を…で省略するという機能を作っています。 UnityEngine.UI.Textを継承して、そこで枠

  • 解決済

    FPSでオートマチックにアングルを変更する方法。

    前提・実現したいこと 前回、こちらで質問して、FPSのアングル変更の処理をご教授いただきました。 ご回答者様、ありがとうございました。 仕様は、FPSで垂直方向に関しては

  • 受付中

    Unityのビルドについて

    Unityのビルドについて Unity初心者です。 テストとしてビルドをしてみようと試みているのですが、 windowsでのビルド方法が見つからず途方に暮れています。

  • 解決済

    Asset Storeに繋がらなくなった。

    プログラミングとは関係のない事とあったので削除申請を出しています。 タイトル通り以下のようになりました。 どうすれば繋がるのか教えてください。 調べたところ,

  • 解決済

    Unity text タブ’\t’文字

    スクリプトからtextを操作する際に、"\t"と入力することがあると思うのですが、"\t"は何をしているのでしょうか? "\t"を入力すると文字が整列するのかなと思いましたが、調

  • 解決済

    Unityのコルーチンについて

    前提・実現したいこと ソシムから出版されたUnity5 3D/2Dゲーム開発 実践入門を参照中です。 この書籍の164ページのスクリプトについて質問させてください。 持ち

  • 解決済

    UnityOSCで端末のIPアドレスを取得すると異なる値が代入されてしまいます。

    前提・実現したいこと Unityで制作したスマートフォンアプリから、同じくUnityで制作したmac用のアプリケーションに、端末のIPアドレスを送信する処理を考えています。

同じタグがついた質問を見る

  • C#

    6898questions

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

  • Unity

    3837questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。