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

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

新規登録して質問してみよう
ただいま回答率
85.50%
オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

Unity

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

Q&A

解決済

1回答

6279閲覧

Unityでランダム配置した箇所に重複せずオブジェクトを配置したい

manmanJ

総合スコア19

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

Unity

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

0グッド

1クリップ

投稿2019/05/23 16:24

編集2019/05/23 16:30

ランダム値から何個か取得するやり方などいろいろみましたがやり方がわからず
コライダーを使うやり方やら座標を使うやり方などあると思いますがよかったら教えてください
後forの繰り返すを3000回にしても3000繰り返してないのですがちょっと仕組みがわからないのでおしえてください

using System.Collections; using System.Collections.Generic; using UnityEngine; public class random : MonoBehaviour { public GameObject [] cube; // Start is called before the first frame update void Start() { for(int i = 0; i < 100; i++) { float x = Random.Range(0.0f, 500.0f); float y = Random.Range(1.19f, 1.19f); float z = Random.Range(0.0f, 500.0f); Instantiate(cube [0], new Vector3(x, y, z), Quaternion.identity); i+=1; } for(int i = 0; i < 3000; i++) { float x = Random.Range(0.0f, 500.0f); float y = Random.Range(2.2f, 2.2f); float z = Random.Range(0.0f, 500.0f); Instantiate(cube [1], new Vector3(x, y, z), Quaternion.identity); i+=1; } for(int i = 0; i < 50; i++) { float x = Random.Range(0.0f, 500.0f); float y = Random.Range(1.19f, 1.19f); float z = Random.Range(0.0f, 500.0f); Instantiate(cube [2], new Vector3(x, y, z), Quaternion.identity); i+=1; } for(int i = 0; i < 10; i++) { float x = Random.Range(0.0f, 500.0f); float y = Random.Range(1.19f, 1.19f); float z = Random.Range(0.0f, 500.0f); Instantiate(cube [3], new Vector3(x, y, z), Quaternion.identity); i+=1; } for(int i = 0; i < 1000; i++) { float x = Random.Range(0.0f, 500.0f); float y = Random.Range(0.5f, 0.5f); float z = Random.Range(0.0f, 500.0f); Instantiate(cube [4], new Vector3(x, y, z), Quaternion.identity); i+=1; } }

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

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

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

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

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

sakura_hana

2019/05/24 01:50

「重複しない」は「オブジェクト同士が重ならない」の意味ですか? それとも「数値が同じではない」の意味ですか?もしこちらならfloatの場合、どこまで有効かを決める必要があるかと思います(小数点以下を考えると現状でも「全く同じ値」ということは出ないと思います)。 3000回繰り返しについては、forの内部の「i+=1;」が余計です。 「for(int i = 0; i < 100; i++)」ここの「i++」が「1ループ毎にiを+1する」の意味なので、for内部で「i+=1;」が存在すると合わせて1ループ毎にiが+2されている(よって規定値の半分の回数しか回らない)ことになります。
manmanJ

2019/05/24 05:31

オブジェクト同士が重ならないようにしたいです。 floatはスクリプト同士で計算しているから、後ほどintに直す予定です。 繰り返しはできました。ありがとうございます。
guest

回答1

0

ベストアンサー

座標の場合1の差は結構大きいと思うのですが、後からintに直すなら最初からintで生成した方がいいです。その方が計算も楽ですし。
数が多いので遅いかもしれませんが、「事前に配列を作る→シャッフル→上から順番に取得」という定番の方法で出来ると思います。
以下、ざっくりコードを書きましたが未検証ですのでバグ等あったら適宜修正をお願いします。

C#

1using System.Linq; 2//↑ソースコードの上の方(using UnityEngine;とかがある所)に貼り付けてください 3 4void Start() { 5 int fieldCount = 500; //領域の最大値 6 int objectSize = 2; //オブジェクトの大きさ。とりあえず(2,2,2)と想定 7 8 // オブジェクトの大きさに合わせて領域最大値修正 9 //(切り捨てにしてますが要検証) 10 int fieldMax = (int)Mathf.Floor(fieldCount / objectSize); 11 12 // 候補が入った配列を用意 13 int[] xArray = Enumerable.Range(0, fieldMax).ToArray(); 14 int[] zArray = Enumerable.Range(0, fieldMax).ToArray(); 15 16 // Vector2のリストを作成(本当はLinqでも書けるだろうけど分かりづらいので二重forでやる) 17 Vector2[] posArray = new Vector3[fieldMax * fieldMax]; 18 for (int i=0; i < xArray.Length; i++) { 19 for (int j=0; j < zArray.Length; j++) { 20 posArray[i*zArray.Length + j] = new Vector2(xArray[i] * objectSize, zArray[j] * objectSize); 21 } 22 } 23 //(つまり「(0,0)(0,2)...(0,500)(2,0)(2,2)...(2,500)...(500,500)」という座標リストを最初に作ってしまう) 24 25 // 配列をシャッフル&オブジェクト配置 26 posArray = posArray.OrderBy(i => Guid.NewGuid()).ToArray(); 27 float y = 1.19f; 28 for(int i=0; i < 100; i++) { 29 Instantiate(cube [0], new Vector3(posArray[i].x, y, posArray[i].y), Quaternion.identity); 30 } 31 32 //(ここまでで重複無しの全リストが出来ているので、毎回シャッフルし直して上から順番に取ればよい) 33 posArray = posArray.OrderBy(i => Guid.NewGuid()).ToArray(); 34 y = 2.2f; 35 for(int i=0; i < 3000; i++) { 36 Instantiate(cube [1], new Vector3(posArray[i].x, y, posArray[i].y), Quaternion.identity); 37 } 38 39 // 以下同様 40}

投稿2019/05/24 07:48

sakura_hana

総合スコア11425

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

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

manmanJ

2019/05/24 09:30 編集

Cannot implicitly convert type 'UnityEngine.Vector3[]' to 'UnityEngine.Vector2[]' The name 'Cube' does not exist in the current context The name 'Guid' does not exist in the current context この3つのエラーがでました Vector2[] posArray = new Vector3[fieldMax * fieldMax]; は Vector3[] posArray = new Vector3[fieldMax * fieldMax]; Cubeは public GameObject [] cube; を追加することで解消できましたがあっているかわからず 他1つのGuidは何をあらわすかわかりませんよかったらおしえてください
sakura_hana

2019/05/24 10:02

すみません誤字です。 Vector2[] posArray = new Vector3[fieldMax * fieldMax]; は Vector2[] posArray = new Vector2[fieldMax * fieldMax]; Cubeは元々あったものなので public GameObject [] cube; で合ってます。 Guidは using System; を using System.Linq; の次辺りに追加してください。 参考→ https://teratail.com/questions/122041
manmanJ

2019/05/24 11:55

using System; がぬけてました! おかげさまでできました ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問