从一个位置实例化尽可能多的游戏对象,并在另一位置结束

时间:2019-06-05 15:36:59

标签: c# unity3d

如何实例化尽可能多的从一个位置开始并在另一位置结束的gameObject。例如,在x = 0处实例化gameObject并在x = 5轴处终止。在这两个值之间,应该有尽可能多的游戏对象,最好是10-12个小比例的游戏对象。

public GameObject prefab;

void Awake()
{
    GameObject ref = (GameObject)Instantiate(prefab, Vector3.zero, Quaternion.identity);
}

4 个答案:

答案 0 :(得分:3)

您可以循环要生成的敌人数量(例如12个),并在每次循环迭代中增加其位置。

public GameObject prefab;
public Vector3 pos;

void Awake()
{
    for (int i = 0; i < 12; i++)
    {
        Instantiate(prefab, pos, Quaternion.identity);
        pos.x += 0.5f;
    }
}

答案 1 :(得分:3)

这应该在0到5之间创建10个GameObject。

void Awake() {  
     for(float x = 0; x < 5; x+=0.5f){
          Vector3 loc = new Vector3(x, 0, 0);
          GameObject gameObject = (GameObject)Instantiate(prefab, loc, Quaternion.identity);
     }
 }

答案 2 :(得分:3)

当您说as many GameObjects as possible时,我想您是说没有重叠?

此解决方案在prefab使用Collider的情况下有效。

我将始终实例化第一个对象,并简单地获取它的边界框,以便我们知道它有多大

 var first = Instantiate(prefab, Vector3.zero + Vector3.right * MinX, Quaternion.identity);

var bounds = new Bounds(Vector3.zero, Vector3.zero);
foreach (var col in first.GetComponentsInChildren<Collider>(true))
{
    bounds.Encapsulate(col.bounds);
}

// now you can get the size in X direction
var width = bounds.size.x;

我怀疑您的预制件的枢轴点可能在中心,因此请先将其向右移动其宽度的一半

first.transform.position += Vector3.right * width / 2f;

现在,您可以检查在给定范围内可以容纳多少个对象。比方说宽度为1,然后在05的范围内,总共可以容纳4个对象。计算中会有一些冗余(添加1然后减少1等),但为了更好的理解,我将其保留

var minPosition = MinX;
var maxPosition = MaxX;

var actualMinPosition = minPosition + width / 2;
var actualMaxPosition = maxPosition - width / 2;

// +1 here since before we reduced actualMinPosition and actualMaxPosition by 
// exactly 1 * width
var possibleAmount = (int)Mathf.Floor((actualMaxPosition - actualMinPosition) / width) + 1;

现在实例化丢失的对象

// since I guess you also want them evenly spread between the start and end position
var distanceBetween = (actualMaxPosition - actualMinPosition) / (possibleAmount - 1);

//,因为我们已经实例化了第一个         //我们只产生了可能的数量-另外1个         对于(var i = 0; i <可能的金额-1; i ++)         {             // +1,因为我们从i = 0开始循环,但是第一个             //这里的对象实际上是总共产生的第二个对象             //所以我们希望它已经被移动了             var x = ActualMinPosition + distanceBetween *(i +1);

        var obj = Instantiate(prefab, Vector3.zero + Vector3.right * x, Quaternion.identity);
    }

所以在一起

public void Spawn()
{
    var first = Instantiate(prefab, Vector3.zero, Quaternion.identity);

    var bounds = new Bounds(Vector3.zero, Vector3.zero);
    foreach (var col in first.GetComponentsInChildren<Collider>(true))
    {
        bounds.Encapsulate(col.bounds);
    }

    // now you can get the size in X direction
    var width = bounds.size.x;

    first.transform.position += Vector3.right * width / 2f;


    var minPosition = MinX;
    var maxPosition = MaxX;

    var actualMinPosition = minPosition + width / 2;
    var actualMaxPosition = maxPosition - width / 2;

    // +1 here since before we reduced actualMinPosition and actualMaxPosition by 
    // exactly 1 * width
    var possibleAmount = (int)Mathf.Floor((actualMaxPosition - actualMinPosition) / width) + 1;


    // since I guess you also want them evenly spread between the start and end position
    var distanceBetween = (actualMaxPosition - actualMinPosition) / (possibleAmount - 1);

    // since we already instantiated the first one
    // we spawn only possibleAmount - 1 more 
    for (var i = 0; i < possibleAmount - 1; i++)
    {
        // +1 here since we started the loop with i=0 but the first
        // object here is actually the second to be spawned in total
        // so we want it to be moved already
        var x = actualMinPosition + distanceBetween * (i + 1);

        var obj = Instantiate(prefab, Vector3.zero + Vector3.right * x, Quaternion.identity);
    }
}

enter image description here

我只是为此演示破坏并重生了Update中的所有内容

答案 3 :(得分:1)

谢谢您的回答,我做了这样的事情: (a)在场景中创建两个相隔一定距离的游戏对象 (b)在脚本中,引用这两个gameObjects (c)给出在这两点之间应该生成的线段(球)的数量

 public Transform PointA; public Transform PointB; public float NumberOfSegments = 3; public float AlongThePath = .25f;

// Update is called once per frame
void Start()
{

    Create();
}

void Create()
{
    StartCoroutine(StartSpheringOut());
}

IEnumerator StartSpheringOut()
{
    NumberOfSegments += 1;// since we are skipping 1st placement since its the same as starting point we increase the number by 1 
    AlongThePath = 1 / (NumberOfSegments);//% along the path

    for (int i = 1; i < NumberOfSegments; i++)
    {
        yield return new WaitForSeconds(0.05f);
        Vector3 CreatPosition = PointA.position + (PointB.position - PointA.position) * (AlongThePath * i);

        GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        sphere.transform.position = CreatPosition;
        sphere.transform.localScale = new Vector3(0.25f, 0.25f, 0.25f);



    }