我如何在Unity中为多个对象使用MoveTowards方法

问题描述 投票:0回答:3

我计划在随机位置上创建GameObjects,然后每帧滑动到目标位置。

我手动创建一个对象onstart(),并且在MoveTowards中使用了update()方法,但它可以工作,但是我想同时对多个对象(大约10个对象)执行相同的操作:如果我创建多个对象它不起作用。

这是我所拥有的:

GameObject Go = Instantiate(M1, new Vector3(-5, 10, 0), Quaternion.Euler(0, 0, 0)) as GameObject;
Go.transform.position = Vector3.MoveTowards(Go.transform.position, new Vector3(10, -20, 0), 0.05f);
c# unity3d position instantiation gameobject
3个回答
1
投票

制作一个新脚本,我们称它为Mover。给它public Vector3 destinationpublic float rate字段,以及一个Update方法,用MoveTowards编辑其位置:

public class Mover: MonoBehaviour
{
    public Vector3 destination;
    public Vector3 rate;

    void Update()
    {
        transform.position = Vector3.MoveTowards(transform.position, destination, rate * Time.deltaTime);
    }
}

Mover附加到M1预制。

然后,当实例化每个M1时,设置其destination组件的rateMover

 GameObject Go = Instantiate(M1, new Vector3(-5, 10, 0), Quaternion.Euler(0, 0, 0)) as GameObject;
 Mover goMover = Go.GetComponent<Mover>();
 goMover.destination = new Vector3(10, -20, 0); 
 goMover.rate = 3f;

0
投票

您在评论中描述的内容听起来实际上是您有两个任务

  • 每秒添加一个新对象
  • 移动所有对象

注意:您可以not使用碰撞来检测对象何时到达目标!您如何知道哪个对撞机属于哪个对象?换句话说:如何确定某个对象不会偶然与其他碰撞器碰撞而发生碰撞?我宁愿直接比较职位。

public class ObjectController : MonoBehaviour
{
    // Here we will store all Transform references
    // linked to the according target position
    private Dictionary<Transform, Vector3> objects = new Dictionary<Transform, Vector3>();

    public GameObject prefab;

    // A simple timer for the spawning
    private float timer;

    // Here we will track objets that reached the Target and shall be destroyed
    List<GameObject> objectsToDestroy = new List<GameObject>();

    private void Update()
    {
        // Spawn a new object every second but only until maximum of 10 existing objects
        if(objects.Keys.Length < 10)
        {
            timer += Time.deltaTime;
            if(timer > 1f)
            {
                timer = 0;

                // However you generate your random start Position
                Vector3 startPos = GetRandomStartPosition();
                // However you generate your random target position
                Vector3 targetPos = GetRandomTargetPosition(startPos);
                var obj = Instantiate(prefab, startPos, Quaternion.Identity).transform;

                // Add this new transform and according target Position to the dictionary
                objects.Add(obj, targetPos);
            }
        }

        objectsToDestroy.Clear();
        // Now go through the items in objects and move them all
        foreach(var kvp in objects)
        {
            var obj = kvp.Key;
            var targetPos = KVP.Value;
            obj.MoveTowards(obj.position, targetPos, 0.05f * Time.deltaTime);

            // Do NOT use collisions for detecting if the object reaches but directly this
            if(obj.position == targetPos)
            // this uses a proximity of 0.00001f if you really need 0 instead use
            //if(Mathf.Approximately(Vector3.Distance(obj.position, targetPos), 0))
            {
                // mark this object for removal
                objectsToDestroy.Add(obj);
            }
        }

        // Finally remove all objects that reached from the dict and destroy them
        foreach(var obj in objectsToDestroy)
        {
            objects.Remove(obj);
            Destroy(obj);
        }
    }
}

不知道如何生成随机排名,但是您可以例如有类似的东西

private Vector3 GetRandomStartPosition ()
{
    return new Vector3(
        Random.Range(-10f, 10f),
        Random.Range(-10f, 10f),
        Random.Range(-10f, 10f)
        );
}

private Vector3 GetRandomTargetPosition(Vector3 startPos)
{
    return startPos + new Vector3(
            Random.Range(-1f, 1f),
            Random.Range(-1f, 1f),
            Random.Range(-1f, 1f)
        );
}

取决于您的课程需求。

实际上是,如果您希望许多对象(数百或数千个)并行移动,最好只有一个组件来控制它们,以免发生Update调用的开销。但是对于仅10个对象,我可能宁愿坚持使用Ruzihm's answer,每个对象使用一个移动分量。


注:在智能手机上键入,但我希望这个主意能清晰起来


0
投票

抱歉,我的回复很晚。我是团结的新人。让我清楚地告诉你。我想制作一个2D基本太空游戏。我将地球图像放置在场景的底部,并且有一个对撞机。我正计划在场景的随机位置上创建小行星,然后它们会掉落到地球上。如果他们来到对撞机,它们会爆炸。我能够在vector3(Random.Range(-2,2),6)上创建小行星,然后它们因具有刚体和重力而掉落到地球上。但是我不想只掉落“ y”轴,我想移动倾斜角度。例如:从Vector3(-5,12,0)到Vector3(8,-14,0)当在Vector3(-5,12,0)上生成类星体时,它将移动到Vector3(8,-14,0)如果要推动位置,如果它推动地球对撞机,我会摧毁它。

我尝试了AddForce和MoveTowards。不幸的是没有用。

如果我仅对“ y”轴进行操作,则它可以正常工作,并且每秒钟我可以有许多类星体。

如果我做倾斜运动,它仅对一个小行星有效,对其他小行星不起作用。

对于一个以上的类星体:

void Start()
{
    go1 = Instantiate(M1, new Vector3(Random.Range(-5, 5), Random.Range(6, 15), 0), Quaternion.Euler(0, 0, 0)) as GameObject;
}

void Update()
{ 
    Rigidbody2D rg = go1.GetComponent<Rigidbody2D>();
    rg.AddForce(new Vector2(10, -15));
}

对于不止一种以上的小行星:

void Start()
{
  //go1 = Instantiate(M1, new Vector3(Random.Range(-5, 5), Random.Range(6, 15), 0), Quaternion.Euler(0, 0, 0)) as GameObject;
}

void Update()
{
    //Rigidbody2D rg = go1.GetComponent<Rigidbody2D>();
    //rg.AddForce(new Vector2(10, -15));

    int i = Random.Range(0, 3);

    timer -= Time.deltaTime;
    if (timer < 0)
    {
        switch (i)
        {

            //rg's are rigidbody
            case 0:
                GameObject go0 = Instantiate(M0, new Vector3(Random.Range(-4.50f, 4.50f), Random.Range(6, 10), 0), Quaternion.Euler(0, 0, 0)) as GameObject;
                rg0 = go0.GetComponent<Rigidbody2D>();
                rg0.AddForce(new Vector2(10, -10));
                break;
            case 1:
                GameObject go1 = Instantiate(M1, new Vector3(Random.Range(-4.50f, 4.50f), Random.Range(6, 10), 0), Quaternion.Euler(0, 0, 0)) as GameObject;
                rg1 = go1.GetComponent<Rigidbody2D>();
                rg1.AddForce(new Vector2(10, -10));
                break;
            case 2:
                GameObject go2 = Instantiate(M2, new Vector3(Random.Range(-4.50f, 4.50f), Random.Range(6, 10), 0), Quaternion.Euler(0, 0, 0)) as GameObject;
                rg2 = go2.GetComponent<Rigidbody2D>();
                rg2.AddForce(new Vector2(10, -10));
                break;

        }
        timer = createTime;
    }

此代码可以每秒生成一个小行星,但它们仅落在“ y”轴上。 Rigidbody.AddForce或MoveTowards无效

感谢所有答复。

© www.soinside.com 2019 - 2024. All rights reserved.