【问题标题】:Camera Behaviour相机行为
【发布时间】:2018-10-31 06:52:18
【问题描述】:

此相机脚本旨在在玩家移动时旋转并观察玩家,并在玩家不移动时缓慢捕捉到玩家。 (玩家在开始移动之前经过 Vector3 beforeMoving)。我的问题是我想慢慢地“喂”deltaPosition,所以它不是突然的,而是一个缓慢而平稳的过渡,如果到达也停止添加。

    private void LateUpdate()
{
    if (player.isMoving)
    {
        desiredPosition = player.beforeMoving + offset;
    }
    else
    {
        Vector3 deltaPosition = player.transform.position - player.beforeMoving; 
        desiredPosition += deltaPosition * Time.deltaTime;
    }
    Quaternion camTurnAngle =
    Quaternion.AngleAxis(input * rotationSpeed, Vector3.up);
    desiredPosition = camTurnAngle * desiredPosition;
    transform.position = Vector3.Slerp(transform.position, desiredPosition, smoothFactor);
    transform.LookAt(player.transform);
}

编辑:我想我会分享最终代码。

    private void LateUpdate()
{
    Quaternion rotation = Quaternion.Euler(GetDegree(), input.x * rotationSpeed, 0f);
    if (player.isMoving)
    {
        desiredPosition = player.beforeMoving + offset;
        CalculatePanTime();
    }
    else if (!player.isMoving)
    {
        desiredPosition = player.transform.position + offset;
    }
    transform.position = Vector3.Slerp(transform.position, rotation * desiredPosition, GetSpeed());
    transform.LookAt(player.transform);
}

private void CalculatePanTime()
{
    stoppedTime = Time.time;
    playerDelta = Vector3.Distance(player.transform.position, player.beforeMoving);
    timeToPan = (playerDelta / snappingSpeed) * Time.deltaTime;
}

private float GetSpeed()
{
    if (Time.time < stoppedTime + timeToPan)
    {
        controlsDisabled = true; return snappingSpeed;
    }
    else
    {
        controlsDisabled = false; return smoothSpeed;
    }
}

【问题讨论】:

  • 什么是 beforeMoving?

标签: c# unity3d camera


【解决方案1】:

您告诉我们您希望代码做什么,这很好。您还发布了实现目标的代码,这也很好。您能否告诉我们,由于该代码,您希望它工作的原因是什么?

据我了解,它是“Vector3 deltaPosition = player.transform.position - player.beforeMoving; desiredPosition += deltaPosition * Time.deltaTime; " 这与您预期的不一样

也许可以试试这样的:

private void LateUpdate()
{
    // snap the rotation center slowly to the player's position if not moving, or player's position before he started moving
    desiredPosition = Vector3.Lerp(desiredPosition, player.beforeMoving, 0.1f);

    // rotate around rotation center
    Quaternion camTurnAngle = Quaternion.AngleAxis(rotationSpeed * Time.time, Vector3.up);      
    desiredPosition += camTurnAngle * offset;

    // set the position to rotate around rotation center, and look towards player
    transform.position = Vector3.Lerp(transform.position, desiredPosition, smoothFactor);
    transform.LookAt(player.transform);
}

您的代码的问题在于您过冲。如果您想实现一些决定相机拍摄速度或拍摄时间的东西,请尝试引入一个浮动 player.timeStopMoving = Time.time ,您可以使用它来正确计算他不移动时的位置校正.

if(player.isMoving)
{
    desiredPosition = player.beforeMoving;
}
else
{
    const float timeNeededToSnap = 2f;
    // or float timeNeededToSnap = (player.transform.position - player.beforeMoving).magnitude; // (which you could compute only once in player script, when he stops moving, and then reuse the value instead of performing a ".magnitude" every frame)
    if(Time.time < player.timeStopMoving + timeNeededToSnap)
    {
        desiredPosition = Vector3.Lerp(desiredPosition, player.transform.position, (Time.time - player.timeStopMoving) / timeNeededToSnap);
    }
    else
    {
        // an other problem here is: if the player starts moving AGAIN before your desiredPosition got the value, do you want desired position to glich to the new player.beforeMoving?...
        desiredPosition = player.transform.position;
    }
}

编辑:

为了让他不那么线性,你可以使用:

if(Time.time < player.timeStopMoving + timeNeededToSnap)
{
    var t = Mathf.Cos(Maths.Pi * 0.5f * (Time.time - player.timeStopMoving) / timeNeededToSnap); // as timeDelta/totalTime goes from 0->1, multiply it by Pi/2 and the Cos will also go from 0->1 but with a smoothing speed
    desiredPosition = Vector3.Lerp(desiredPosition, player.transform.position, t);
}

【讨论】:

  • 很抱歉你是对的。本质上,我希望我的相机根据玩家的位置有 3 种行为。(1)当玩家停止时,根据鼠标 X 围绕它旋转(距离是玩家位置和初始偏移量,我在开始时将其保存为变量) . (2)如果它在移动,只看它,不要移动,(3)一旦它停止,慢慢捕捉它,然后切换到只是围绕它旋转。由于在单个帧中使用 Vector3.Lerp 覆盖了所有距离,因此问题总是捕捉太快。
  • 正如我所说:如果你使用 player.timeWhenStoppedMoving,你可以控制捕捉速度。使用 or Maths.Cos(Time.time - player.timeWhenStoppedMoving) 作为 lerp 中的 t,您甚至可以使捕捉快速淡入淡出
  • 使用停止时间作为参考对我来说解决了一些问题,现在需要稍微调整一下,非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 1970-01-01
相关资源
最近更新 更多