如何在Unity中应用缓动算法?

时间:2018-08-28 09:51:06

标签: c# unity3d math

我想平稳移动摄像机,所以我正在编写此脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraScroll : MonoBehaviour {

    public GameObject targetCamera;

    private bool  isScrolling = false;

    private Vector3 initialPosition;
    private Vector3 scrollTarget;

    private float scrollDuration;
    private float scrollTick;

    private float timeStartedScrolling;


#region Easing

    float EasingInOutSine(float time, float start, float change, float duration) {
        return -change/2 * (Mathf.Cos(Mathf.PI*time/duration) - 1) + start;
    }

    float EasingOutSine(float time, float start, float change, float duration) {
        dynamic td = time/duration;
        return change * Mathf.Sin(td * (Mathf.PI/2)) + start;
    }

    float EasingInOutBack(float time, float start, float change, float duration) {

        float td2 = time/(duration/2.0f);

        float s = 1.70158f;

        if ((td2) < 1.0f) {
            return change/2.0f*(td2*td2*(((s*(1.525f))+1.0f)*td2 - (s*(1.525f)))) + start;
        } else {
            return change/2.0f*((td2-2.0f)*(td2-2.0f)*(((s*(1.525f))+1.0f)*(td2-2.0f) + (s*(1.525f))) + 2) + start;
        }

    }

#endregion


    void Start() {

        if (targetCamera == null) {
            targetCamera = GameObject.Find("Main Camera");
        }

        // Tests

        //Scroll(new Vector3(4.0f, 0.0f, -10f), 2f); // seems to be working?
        //Scroll(new Vector3(4.0f, 0.0f, -10f), 0.3f); // easing gets cut off
        Scroll(new Vector3(4.0f, 0.0f, -10f), 1f); // easing gets cut off

    }



    void Update() {

        if (isScrolling) {

            scrollTick += Time.deltaTime;
            float s = scrollTick / scrollDuration;

            float timeSinceStarted   = Time.time - timeStartedScrolling;
            float percentageComplete = timeSinceStarted / scrollDuration;

            if (percentageComplete > 1.0f) {

                isScrolling = false;
                Debug.Log("Scrolling ended");

            } else {

                                           // time,     start, change,                                  duration
                var easing = EasingInOutSine(Time.time, 0,     Mathf.Clamp01(Time.time*scrollDuration), scrollDuration);

                targetCamera.transform.position = Vector3.Lerp(initialPosition, scrollTarget, easing);



            } 

        }

    }

    void Scroll(Vector3 targetPosition, float duration) {

        scrollDuration = duration;
        scrollTarget = targetPosition;
        initialPosition = targetCamera.transform.position;
        timeStartedScrolling = Time.time;
        isScrolling = true;

    }

}

问题是,如果将持续时间设置为1秒或更短,相机的运动将被切断,并且无法正确应用缓动

我希望脚本将来能够使用不同的缓动算法并正确使用deltaTime,我不确定我是否使用正确的方式

1 个答案:

答案 0 :(得分:0)

我认为您只需要不断变化。

随着变化的增加,宽松的放慢效果将被变化增加引起的指数运动所抵消。这种效果在持续时间短的运动中最为明显,因为它永远不会更慢地达到上限,因此它将一直加速直到结束。

由于您使用了缓动算法来输出百分比以输出到lerp中,因此您可能需要使用1的变化,以便缓动在0到1之间插值。