2017-10-14 1 views
0
using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

public class WallsTest : MonoBehaviour 
{ 
    // using a GameObject rather than a transform 
    public GameObject prefab; 
    public Vector3 wallsStartPosition; 
    public float width = 0; 
    public float height = 1; 
    public float length = 2; 
    public Camera wallsCamera; 
    public float wallsArea; 

    void Start() 
    { 
     wallsCamera.transform.position = new Vector3(wallsStartPosition.x, wallsStartPosition.y + 100, wallsStartPosition.z - 235); 

     BuildWalls(); 
    } 

    private void Update() 
    { 

    } 

    void BuildWalls() 
    { 
     for (int i = -2; i < 2; i++) 
     { 
      GameObject go = Instantiate(prefab); 
      go.transform.parent = transform; 
      Vector3 scale = Vector3.one; 
      Vector3 adjustedPosition = wallsStartPosition; 

      float sign = Mathf.Sign(i); 
      if ((i * sign) % 2 == 0) 
      { 
       adjustedPosition.x += (length * sign)/2; 
       scale.x = width; 
       scale.y = height; 
       scale.z *= length + width; 
      } 
      else 
      { 
       adjustedPosition.z += (length * sign)/2; 
       scale.x *= length + width; 
       scale.y = height; 
       scale.z = width; 
      } 

      adjustedPosition.y += height/2; 
      go.transform.localScale = scale; 
      go.transform.localPosition = adjustedPosition; 
     } 
    } 
} 

たとえば、長さは100ですので、面積は100x100と思われます。 そして私はwallStartPositionを持っています。例:250,0,250どのように特定の特定の領域の間に重複しないランダムなオブジェクトを生成できますか?

ここでは、オブジェクトのランダムな位置番号でインスタンス化する壁領域内にしたいと思います。例えば50キューブ。しかし、彼らはお互いに重なりあってはならないし、例えば、お互いの間の最小の隙間は5でなければならず、できる限り最大の隙間がなければならない。

しかし、壁の面積と位置を計算し、内部のランダムなオブジェクトをインスタンス化する方法はまだ分かりません。

これは、指定された領域のランダムな位置にゲームオブジェクトを生成するためのスクリプトです。この場合、領域は地形です。しかし、私は最初のスクリプトで作成した壁の中にそのエリアがあることを望みます。このスクリプトは、WallsTestスクリプトと同じ空のgameobjectに添付されています。

SpawnObjectsスクリプトのもう1つの問題は、オブジェクト間にギャップが設定されていないことと、スケールのようにオブジェクトがあまりにも良好である場合です。20,20,20エッジにスポーンされたオブジェクトの一部が地形の半分。

spawn

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

public class SpawnObjects : MonoBehaviour 
{ 
    public Terrain terrain; 
    public int numberOfObjects; // number of objects to place 
    private int currentObjects; // number of placed objects 
    public GameObject objectToPlace; // GameObject to place 
    private int terrainWidth; // terrain size (x) 
    private int terrainLength; // terrain size (z) 
    private int terrainPosX; // terrain position x 
    private int terrainPosZ; // terrain position z 
    void Start() 
    { 
     // terrain size x 
     terrainWidth = (int)terrain.terrainData.size.x; 
     // terrain size z 
     terrainLength = (int)terrain.terrainData.size.z; 
     // terrain x position 
     terrainPosX = (int)terrain.transform.position.x; 
     // terrain z position 
     terrainPosZ = (int)terrain.transform.position.z; 
    } 
    // Update is called once per frame 
    void Update() 
    { 
     // generate objects 
     if (currentObjects <= numberOfObjects) 
     { 
      // generate random x position 
      int posx = Random.Range(terrainPosX, terrainPosX + terrainWidth); 
      // generate random z position 
      int posz = Random.Range(terrainPosZ, terrainPosZ + terrainLength); 
      // get the terrain height at the random position 
      float posy = Terrain.activeTerrain.SampleHeight(new Vector3(posx, 0, posz)); 
      // create new gameObject on random position 
      GameObject newObject = (GameObject)Instantiate(objectToPlace, new Vector3(posx, posy, posz), Quaternion.identity); 
      newObject.transform.localScale = new Vector3(20, 20, 20); 
      currentObjects += 1; 
     } 
     if (currentObjects == numberOfObjects) 
     { 
      Debug.Log("Generate objects complete!"); 
     } 
    } 
} 

答えて

0

私の技術的な知識が限られているが、あなたは、これらのオブジェクトに位置の量を、すべての[X]を産卵するためのスクリプトをする必要がありますいずれか取得します(「POSX + = 1.0F;」、またはそれらのオブジェクトが一様に表示されるようにするか、スクリプトがそれぞれの新しいオブジェクトの位置を記録し、その情報を使用して前記オブジェクトから離れた空間を計算して別のオブジェクトを生成させることができます。

いずれの場合でも、最終的な結果に応じて、これらのオブジェクトがどのように所定の領域で動作するかを記述する必要があります。たとえば、場面として乱雑な部屋がある場合、2つの壁の角に1つの壁、1つの壁に沿って1つのベッド、無作為に産卵するゴミ箱を見つけることができます。

0

Physics.OverlapSphereを使用すると、2つのオブジェクトが重なっているかどうかをテストできます。これは、オブジェクトに両方とも衝突があることを前提としています。

この条件をテストして真であると評価したら、シーン内の他のオブジェクトに対して重複してテストするオブジェクトを単に移動することをおすすめします。重なり合っているか重なっていると思われるオブジェクトをテストするだけで、これで巧妙になることができます。

また、すべてのオブジェクトをシーン内の他のすべてのオブジェクトと比較することもできます。多くのオブジェクトを持っていると、これは理想的ではありません。そのようにすると、複雑さはO(n^2)になるからです。

いずれにしても、この機能を使用してオーバーラップをテストできます。がんばろう。

ヒント:コライダーをオブジェクトより大きくすると、アイテムの間隔を最小限にすることができます。たとえば、キュ​​ーブがlocalSize 1,1,1の場合、コライダーのサイズは5,5,5になります。Physics.OverlapSphereは、オーバーラップが重複している場合にtrueを返し、キューブが互いに離れた特定のスペースであることを要求します。

関連する問題