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

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

ただいまの
回答率

87.78%

Unityで複数のPrefabを重ならないようにinstantiateしたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 5,318

score 7

 前提・実現したいこと

Unityでランゲームを制作しています。
複数の障害物Prefabをランダムに3件選択し、重ならないよう、z軸方向に並べて配置したいです。

障害物Prefab1つめ:(0, 0, 0)
2つめ:(0, 0, 3)
3つめ:(0, 0, 6)
のようなイメージです。

各prefabは

親オブジェクト
└3DモデルA
└3DモデルB

のような親子構造になっています。

現在組んでいる障害物Prefabは全てz軸が同じサイズですが、
参考までに、z軸のサイズがバラバラの場合もご教示いただければ幸いです。

 発生している問題・エラーメッセージ

複数の障害物Prefabをランダムに3件選択して生成するところまでは上手く動作していますが、
全てのオブジェクトが(0, 0, 0)の位置に生成されてしまいます。

 該当のソースコード

    int count = 0;
    int max = 3;

   [SerializeField] GameObject[] objList;

    void SetStageObjects()
    {
        if (count == max) return;
        int number = Random.Range(0, objList.Length);
        Vector3 position = new Vector3(0, 0, 0);
        Quaternion q = new Quaternion();
        q = Quaternion.identity;
        GameObject obj = Instantiate(objList[number],position,q);
        count++;
    }

 試したこと

position.z += obj.transform.localScale.z;
をcount++;の前に挿入してみましたが、想定通りに動いてくれませんでした。
エラーメッセージは表示されていません。

 補足情報

当方初心者のため、質問がわかりにくかったり、情報が不足していればご指摘ください。
どうぞよろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

Instantiateの第二引数がVector3 position = new Vector3(0, 0, 0);で固定されているので当然同じ位置に出ますね。

zを3ずつずらす(毎回固定)なら以下。
Vector3 position = new Vector3(0, 0, count*3.0f);

大きさを取得したい場合、親は子のサイズを把握していないし、3Dモデルを使っているなら更に計算が面倒臭いです。
(TransformのScale値は「大きさの"割合"」みたいなもの。「3Dモデル(fbxファイルとか)のインスペクターで設定している大きさ×TransformのScale値」なので、後者が同じでも前者が違えば見た目の大きさが変わる。もし子オブジェクト2つが離れていたりしたら更にややこしい)
なので「サイズを記載しておくクラス」を作って付与しておく方が楽かと。

//サイズを指定するクラス(プレハブの親に付ける。値はインスペクタから設定しておく)
public class PrefabSize : MonoBehaviour {
    public Vector3 size;
}

//生成するクラス
//クラス変数に以下を用意
private Vector3 stagePosition;

void SetStageObjects() {
        //中略

        //本当はpositionは何でもいい
        GameObject obj = Instantiate(objList[number],position,q);

        //指定サイズを前回までの位置に加算する
        stagePosition += obj.GetComponent<PrefabSize>().size;
        obj.transform.position = stagePosition;
}


※ちなみに子オブジェクトのローカル位置によってズレて見える可能性あります。(例えば「原点=中心」なら半分ずれる)
ローカル座標(0,0,0)に子オブジェクトの端が来るように配置するか、PrefabSizeのsize値を調整してください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/08/26 14:51

    うまく想定した挙動にできました。
    scaleに関してもわかりやすく解説していただき、大変ためになりました。他の箇所でも使えそうなテクニックなので記憶しておきます。
    ご回答本当にありがとうございました!

    キャンセル

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

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

関連した質問

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