如何在两个位置之间连续移动GameObject?

时间:2019-05-24 00:09:26

标签: c# unity3d

我正在编写游戏老板的行为编码,在战斗的最后阶段,老板应该向玩家冲锋,然后回到原来的位置。等待5秒钟,然后执行相同操作。

我尝试使用协程和Vector2.MoveTowards()实现此目的,但没有获得预期的效果,首先,boss不会“移向”玩家,而是立即出现在targetPosition处,然后停留在那里,没有移回去。

下面是我的代码:

private Vector2 chargeTarget;
private Vector2 tankStartPosition;

void Start()
{
    chargeTarget = new Vector2(-5.0f, transform.position.y);
    tankStartPosition = transform.position;
}

void Update()
{
    if (Time.time > nextCharge)
    {
        StartCoroutine(TankCharge());
        nextCharge = Time.time + chargeRate;
    }
}

IEnumerator TankCharge()
{
    transform.position = Vector2.MoveTowards(tankStartPosition, chargeTarget, Time.deltaTime * chargeSpeed);

    transform.position = Vector2.MoveTowards(chargeTarget, tankStartPosition, Time.deltaTime * returnSpeed);
}

你知道我在做什么错吗?以及如何采取我想要的动作?

谢谢

1 个答案:

答案 0 :(得分:1)

一次调用MoveTowards仅在游戏循环的该迭代期间将游戏对象移动一次。一次调用MoveTowards不会将游戏对象一直移动到目标(除非maxDistanceDelta参数足够大,可以一次迭代将游戏对象移动到目标)。

如果老板立刻出现在目标上,我猜你的chargeSpeed太大了。

您要执行的操作是每MoveTowards个周期调用一次Update。但是,在执行协程的方式中,协程只会移动游戏对象一次,然后退出。通常,协程中会有一个循环(否则协程运行一次后将退出)。像这样:

IEnumerator TankCharge()
{
    while (Vector3.Distance(transform.position, chargeTarget.position) > Mathf.Epsilon)
    {
        // Adjust this so this game object doesn't move the entire
        // distance in one iteration
        float distanceToMove = Time.deltaTime * chargeSpeed;

        transform.position = Vector3.MoveTowards(transform.position, chargeTarget.position, distanceToMove)

        yield return null;
    }
}

但是,对于您的情况,您实际上不需要协程。您可以直接在Update()

中执行此操作
    private bool returnToStart = false;
    private float timer;

    void Update
    {
        float distanceToMove = Time.deltaTime * chargeSpeed;

        if (timer <= 0)
        {
            if (!returnToStart)
            {
                transform.position = Vector3.MoveTowards(transform.position, chargeTarget.position, distanceToMove)

                // Target reached?  If so, start moving back to the original position
                if (Vector3.Distance(transform.position, chargeTarget.position) <= Mathf.Epsilon)
                {
                    returnToStart = true;
                    this.timer = this.chargeRate;
                }
            }
            else
            {
                transform.position = Vector3.MoveTowards(transform.position, tankStartPosition.position, distanceToMove)

                // Original position reached?  If so, start moving to the target
                if (Vector3.Distance(transform.position, tankStartPosition.position) <= Mathf.Epsilon)
                {
                    returnToStart = false;
                    this.timer = this.chargeRate;
                }
            }
        }
        else
        {
            this.timer -= Time.time;
        }
    }