Как непрерывно перемещать GameObject между двумя позициями? - PullRequest
2 голосов
/ 24 мая 2019

Я кодирую поведение своего игрового босса, и на последнем этапе битвы босс должен атаковать игрока, а затем вернуться в исходное положение.Подождите 5 секунд, а затем сделайте то же самое.

Я пытался добиться этого с помощью сопрограмм и Vector2.MoveTowards (), но не получил желаемого эффекта, сначала босс не «Двигается навстречу» игроку, номгновенно появляется в 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 Ответ

1 голос
/ 24 мая 2019

Вызов 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;
        }
    }    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...