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

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

ただいまの
回答率

90.47%

  • C#

    7442questions

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

  • Unity

    4205questions

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

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

解決済

回答 1

投稿

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

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

    キャンセル

関連した質問

  • 受付中

    Unityで開発するゲームのフラグ管理について

    はじめまして。最近Unityにて2Dゲームの開発をはじめました。 さっそくの質問で恐縮なのですが、 タップしたモンスターを消して(捕まえて)、得点を稼ぎ、 さらに捕まえたモンスター

  • 受付中

    unity アセットの完成プロジェクト使い方

    unity初心者です。 unityの勉強用にアセットストアの完成プロジェクトをインストール しました。スクリプトを見てみるとscore.cs..gun.cs..と色々あるのですが、

  • 解決済

    Unityによるプロジェクトの共有

    Unityによるチーム開発を行っています。 そこで進捗を共有したいと考えているのですが、 dropboxを使ってもgitを使っても相手にデータを渡すとinspectorの情報(追加

  • 解決済

    スクリプトでrigidbodyを操作する方法

    木に生えている果物をマウスカーソルでクリックすると果物が地面に落ちるというゲームを作っています。 いま、クリックして果物を消すということはスクリプトで命令を出すことができるのが、現

  • 解決済

    オブジェクトごとの効果音のつけ方

    以前も質問させていただいたのですが、各オブジェクトに1つずつAudioSourceとAudioClipを持たせ、オブジェクトがクリックされたらAudioSource.Playで音を

  • 受付中

    unity5

    unity5 でマウスのホイールの動きが止まった時に、画面に文字が表示されるようにしたいです。 方法をご存知の方返信お願いします。

  • 受付中

    UGUIでiTweenでアルファ値を変えたい

    UGUIでiTweenでアルファ値を変えたいのですが、 何か方法はないでしょうか?  ※"alpha"のハッシュがきかないので

  • 受付中

    [Unity]iTweenのコールバック関数で引数を2つ以上渡したい

    iTweenのコールバックでよぶ関数が複数引数を持っている場合に、 引数をその数だけ渡したいのですが、どうしたらよいでしょうか? 1つの場合は"oncompletepr

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

  • C#

    7442questions

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

  • Unity

    4205questions

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