Unity3D 从V1到移动V2的线性插值

Unity3D Linear interpolation from V1 to moving V2

我在stack math网站上发布了这个问题,但他们看到包括编程在内的问题并不太兴奋。无论如何,现在我在这里:)


  1. 我有一个对象,它位于MyTransform.position (Vector)
  2. 该对象应遵循 DesiredPosition(向量),即 以变​​化的速度向不同的方向移动
  3. MaxDelayDistance (float) 是我的对象允许的最大距离 必须到 DesiredPosition。
  4. DelayRecovery (float) 是我的对象移动的秒数 如果达到 MaxDelayDistance,则到 DesiredPosition。
  5. Time.deltaTime(浮点数)是我们用来描述上次时间的术语 框架更新了。它的价值通常在0.025f左右。

private Vector3 GetLerpedPosition(Vector3 DesiredPosition) {
            //DesiredPosition now contains the goal
            Vector3 dirToDesiredPosition = (DesiredPosition - MyTransform.position).normalized; //Direction to desired position
            Vector3 lerpStart = DesiredPosition + (-dirToDesiredPosition * MaxDelayDistance); //Start the lerp at my farthest allowed position
            float lerpCurrentT = Vector3.Distance(MyTransform.position, DesiredPosition) / Vector3.Distance(lerpStart, DesiredPosition); //My current fragtion (t) of the lerp

            //Now I lerp from lerpStart to DesiredPosition using a calculated fraction
            Vector3 result = Vector3.Lerp(
                lerpStart,
                DesiredPosition,
                lerpCurrentT + (DelayRecovery / MaxDelayDistance * Vector3.Distance(MyTransform.position, DesiredPosition) * Time.deltaTime)
                );
            return result;
        }

主要问题是我的对象没有顺畅地跟随 DesiredPosition。 它从 MaxDelayDistance 跳到 DesiredPosition 并返回。 不知何故,我的 Lerp 函数中的分数 (t) 总是产生大约 1.005 或大约 0.001。你能发现我的方法有什么问题吗?

我看到几个问题,我不确定你选择的方向(至少以前从未见过类似的东西)。

序言:

Vector3.Distance(lerpStart, DesiredPosition)

这是一个常数,是 DesiredPosition 周围的半径。

这是我注意到的一些问题:

问题 1

lerpT 对于比 MaxDelayDistance 更远的每个点(在半径之外)总是 >=1。所以当一个物体比 MaxDelayDistance 更远时,它会立即移动到 DesiredPosition.

问题2

DelayRecovery (float) are the seconds my object has in order to move to the DesiredPosition if the MaxDelayDistance is reached.

不确定是否完全理解了您错综复杂的 lerp,顺便说一句,上面的陈述似乎是错误的。 DelayRecover 在 lerping 时总是被考虑在内,尽管它有距离。

问题3

当您接近 DesiredPosition 时可能被零除(* 运算符在 / 之前计算)

一些注意事项

我会更仔细地阅读你的代码,我会试着弄清楚背后的逻辑。这是我从未见过的。 向给定位置移动的一些通用方法:

  1. 如果起点和终点已知且固定,则 lerping(或 ease function)允许精确控制旅行时间递增 t 参数从 0 到 1。
  2. 如果目的地在移动,您仍然可以使用 lerp 平滑地跟随目标(从理论的角度来看,这可能不是更正确的用法,也不是物理现实的,但无论如何都是有效的)。本例中的 Lerp 因子是一种 "speed toward the goal"。有效地与目标的距离成线性比例。
  3. 一些基于物理的方法。整合。定义某种最大速度和最大加速度并计算下一个位置(最终夹紧以防止超调和振荡)
  4. PID 个控制器。很多力量,但我总是发现它们很难调整。

也考虑使用 Vector3.MoveToward,这是它的实现方式:

public static Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta)
    {
        Vector3 a = target - current;
        float magnitude = a.magnitude;
        if (magnitude <= maxDistanceDelta || magnitude == 0f)
        {
            return target;
        }
        return current + a / magnitude * maxDistanceDelta;
    }

希望这对您有所帮助。