Удалить задержку между lerps - PullRequest
0 голосов
/ 24 декабря 2018

Я сделал простой скрипт, который переходит к одной путевой точке, а затем к следующей.

Моя проблема в том, что при переходе от путевой точки1 к путевой точке2 возникает задержка, и я не знаю почему: enter image description here

¿Почему происходит такая задержка и как я могу ее устранить?

using UnityEngine;
using System.Collections;

public class Missile : MonoBehaviour
{
 public Vector3 finalTarget;
 public Transform forwardObject;

 public GameObject impactAreaPrefab;

 float smoothingDelay = 0.1f;
 bool fired = false;
 bool powerPhase = true;
 Vector3 currentTarget;

 private void OnEnable() {
     fire(new Vector3(-25.29f, 0.5f, -10.638f));
 }

 void fire(Vector3 coords) {
     currentTarget = forwardObject.position;
     finalTarget = coords;
     Instantiate(impactAreaPrefab, finalTarget, Quaternion.identity);
     fired = true;
 }

 void Update() {
     if (!fired) {
         return;
     }

     if (powerPhase && transform.position == currentTarget) {
         powerPhase = false;
         currentTarget = finalTarget;
         smoothingDelay = 0.05f;
     }

     transform.position = Vector3.Lerp(transform.position, currentTarget, Time.deltaTime / smoothingDelay);
     transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(Vector3.RotateTowards(transform.forward, currentTarget, 1, 0.0f)), Time.deltaTime / smoothingDelay);
 }
 }

Ответы [ 3 ]

0 голосов
/ 25 декабря 2018

Я рекомендую использовать iTween для плавного движения.

В какой-то момент я изменил iTween, чтобы я мог делать все, что захочу.как это:

    public static void Rotate (Transform transform, Vector3 target, float transitionTime, Action onEnd = null, bool ignoreTimescale = false, iTween.EaseType ease = iTween.EaseType.easeInOutQuad, float delay = 0)
    {
        Vector3 from, to;

        from = transform.localEulerAngles;
        to = target;

        Action <object> onUpdateAction = (rotation => 
        {
            transform.localEulerAngles = (Vector3) rotation;
        });

        Action <object> onCompleteAction = (data => 
        {
            if (onEnd != null)
                onEnd ();
        });

        Hashtable hash = new Hashtable ();
        hash.Add ("from", from);
        hash.Add ("to", to);
        hash.Add ("time", transitionTime);
        hash.Add ("delay", delay);
        hash.Add ("easetype", iTween.EaseType.easeInOutQuad);
        hash.Add ("ignoretimescale", ignoreTimescale);
        hash.Add ("onupdate", onUpdateAction);
        hash.Add ("oncomplete", onCompleteAction);

        iTween.ValueTo (transform.gameObject, hash);
    }

Это дает мне полный контроль в различных сценариях.

Вот код, если вы хотите его реализовать.

https://drive.google.com/open?id=1nLEEYTp-q4Kfh2n3nWQJcMXmPNtVPLLP

0 голосов
/ 26 декабря 2018

Итак, во-первых, прочитайте этот пост, чтобы лучше понять функцию Lerp - https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/ http://www.kinematicsoup.com/news/2016/8/9/rrypp5tkubynjwxhxjzd42s3o034o8

Теперь вы должны лучше понимать lerp.В итоге lerp делает действительно простую вещь.Скажем, у вас есть два значения X и Y. Для этого примера давайте дадим им какое-то значение, X = 0, Y = 1. Теперь вы хотите получить значение между ними в несколько процентов, как вы хотите получить значение, которое составляет 50%.из X и Y. Вы можете догадаться, что ответ 0,5.Уравнение lerp для этого будет

Mathf.Lerp(0, 1, 0.5f);

Итак, просто учитывая два значения, x и y, Mathf.Lerp возвращает значение, равное t процентам между ними.

Теперь для правильного использованияLerp вам нужно кэшировать позицию перед началом lerp.В большинстве случаев я использую сопрограмму, чтобы получить этот эффект работает довольно хорошо, а затем вы можете использовать кривую анимации, чтобы изменить третий параметр, чтобы создать сумасшедшие хорошие эффекты.Например, при использовании кривой анимации просто прокомментируйте, я напишу это.

Для этой вашей проблемы у вас есть два варианта -

1) Липп, как профессионал, использующий кривую анимации для управления скоростью.Помните, что вы также можете создавать анимационные кривые во время выполнения.

IENumerator Move(Transform toMove, Vector3 end, float duration){
    Vector3 startPos = toMove.position;
    float elapsed = 0f;
    while(elapsed < duration){
        elapsed += Time.deltaTime;
        toMove.position = Vector3.Lerp(startPos, end, elapsed / duration);//manipulate the last parameter to move the object linearly
        yield return null;//basically wait for next frame
    }
    toMove.position = end;//after lerp ends
}

Теперь вы можете вместо продолжительности использовать скорость, а затем с ее помощью вы рассчитываете требуемое время и изменяете скорость, чтобы сделать это быстрее

float distance = Vector3.Distance(startPos, end);
toMove.position = Vector3.Lerp(startPos, end, elapsed / (distance/(speed * multiplier)));

2) Используйте Vector3.MoveTowards -Эта функция перемещает точку в конечную точку с заданным максимальным шагом, требует трех параметров (currentPosition, end, step), вы можете умножить шаг на переменную для управления скоростью, оба работают очень хорошо.Использовать это намного проще в большинстве случаев. Пример -

float step = speed * Time.deltaTime;//to make it framerate independent
transform.position = Vector3.MoveTowards(transform.position, end, step * multiplier);

Надеюсь, это поможет.Мне жаль, что я не смог правильно отформатировать свой ответ, надеюсь, мне будет легче ответить.Любые изменения для улучшения ответа приветствуются:)

0 голосов
/ 25 декабря 2018

Это происходит, потому что вы используете lerp не совсем правильно.Если вы хотите получить линейное движение, вы должны кэшировать свой первый аргумент (положение / вращение в начале) и предоставить увеличивающийся третий параметр.Эта задержка происходит потому, что если ваша пуля находится очень близко к конечной позиции, и она все еще пытается туда добраться, но ваше текущее расстояние | finalPos - transform.position |он настолько мал, что ваш шаг Time.deltaTime / smoothingDelay почти не перемещает его.

Vector3 startPos;
Vector3 finalPos;
float currentT = 0.0f;

void Update()
{
    currentT += Time.deltaTime;
    transform.position = Vector3.Lerp(startPos, finalPos, currentT);
}

Проверка, не является ли Vector3 == Vector3 также плохой идеей.Используйте шаблон сверху и убедитесь, что currentT больше или равно 1. Если это правда, то вы находитесь на последней позиции.Вы также получаете некоторый контроль над продолжительностью движения, разделяя currentT.

...