【问题标题】:Use Lerp Position and Slerp Rotation together (Unity)一起使用 Lerp Position 和 Slerp Rotation (Unity)
【发布时间】:2015-11-19 10:50:06
【问题描述】:

这是我尝试做的,当我点击一个 UI 元素时,相机会平滑旋转(以查看目标)并同时在目标上方移动。

为了实现这一点,我使用了两个协程,一个用于 Lerp Position,另一个用于 Slerp Rotation。

问题是旋转无法正常工作,通常相机应该向下看以看到目标的顶部,但不是这样做,而是看起来像相机首先看目标然后移动到他的位置.

我希望这是可以理解的;)

这里是c#代码

Vector3 LocationProjectForPos = new Vector3(Loc_X, 100, Loc_Z);
Vector3 LocationProjectForRot = new Vector3(Loc_X, Loc_Y, Loc_Z);
Vector3 MainCameraPos = MainCamera.transform.position;

if(!IsCameraMoving & LocationProjectForPos != MainCameraPos)
        {
            StartCoroutine (CoroutineMovePositionCamera(LocationProjectForPos));
            StartCoroutine (CoroutineMoveRotationCamera(LocationProjectForRot));
        }
    }

使用 Lerp 移动相机的位置

public IEnumerator CoroutineMovePositionCamera(Vector3 LocationProject)
{
    float lerpTime = 5f;
    float currentLerpTime = 0f;

    IsCameraMoving = true;

    Vector3 startPos =  MainCamera.transform.localPosition;
    Vector3 endPos =  LocationProject;

    while (lerpTime > 0)
    {
        lerpTime -= Time.deltaTime;
        currentLerpTime += Time.deltaTime;

        if (currentLerpTime > lerpTime) 
        {
            currentLerpTime = lerpTime;
        }

    float t = currentLerpTime / lerpTime;
    t = t*t*t * (t * (6f*t - 15f) + 10f);
    //t = t*t * (3f - 2f*t);
    //t = 1f - Mathf.Cos(t * Mathf.PI * 0.5f);
    MainCamera.transform.localPosition = Vector3.Lerp(startPos, endPos, t);

    yield return null;  
    }
    IsCameraMoving = false;
}

使用 Slerp 旋转相机

public IEnumerator CoroutineMoveRotationCamera(Vector3 LocationProject)
{
    float lerpTime = 5f;
    float currentLerpTime = 0f;

    IsCameraMoving = true;

    Vector3 relativePos =  LocationProject - MainCamera.transform.localPosition;
    Quaternion rotation = Quaternion.LookRotation(relativePos);
    Quaternion current = MainCamera.transform.localRotation;

    while (lerpTime > 0)
    {
        lerpTime -= Time.deltaTime;
        currentLerpTime += Time.deltaTime;

        if (currentLerpTime > lerpTime) 
        {
            currentLerpTime = lerpTime;
        }

    float t = currentLerpTime / lerpTime;
    t = t*t*t * (t * (6f*t - 15f) + 10f);
    //t = t*t * (3f - 2f*t);
    //t = 1f - Mathf.Cos(t * Mathf.PI * 0.5f);
    MainCamera.transform.localRotation = Quaternion.Slerp(current, rotation, t);

    yield return null;  
    }
    IsCameraMoving = false;
}

感谢您的帮助。

【问题讨论】:

  • 为什么不直接使用 gameObject.transform.LookAt 将相机锁定在目标对象上?您不需要单独的协程来保持相机聚焦在您的目标对象上。
  • 因为我需要平滑的东西,如果我使用lookAt,第一个看目标的动作不会平滑:/
  • 使用 Quaternion.LookRotation 获取目标旋转,然后使用 Quaternion.Slerp 平滑设置旋转。放置此代码的最佳位置是在 LateUpdate 或 Coroutine 中,yield return new WaitForEndOfFrame。
  • 也许我不明白,但这不是我正在做的事情?我尝试使用 WaitforEndOfFrame,不工作:/

标签: c# unity3d coroutine lerp


【解决方案1】:

CoroutineMoveRotationCamera中,需要在while循环中更新relativePostionrotation

当相机移动时,相对位置会发生变化。现在,您的相机会根据您在 while 循环开始之前拍摄的矢量快照旋转。

在yield语句后添加如下代码

relativePos = LocationProject - Camera.main.transform.position;
rotation = Quaternion.LookRotation(relativePos);

【讨论】:

    【解决方案2】:

    在启动协程之前,你应该用成员变量而不是函数本地变量来保存初始变量

    【讨论】:

      猜你喜欢
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      • 2016-11-02
      • 1970-01-01
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多