c# - Unity - 在没有物理的情况下将变换移动到特定位置(以特定速度)的最佳方法?

标签 c# unity3d

我想知道我应该如何将变换移动到特定点(不使用物理)。

目前我让我的物体看向目标位置:

transform.LookAt(m_TargetPos, UnityEngine.Vector3.up);

然后我用一定的速度在每一帧更新它的位置:

transform.position += transform.forward * (m_Speed * Time.deltaTime);

最后,我使用 sqrMagnitude 来了解转换是否到达了位置:

if ((transform.position - m_TargetPos).sqrMagnitude < 0.0025f) // 0.0025 = 0.05f * 0.05f
        return true;

我面临的问题是有时实体会超出目标位置永远向前推进。

我应该如何对条件进行编码以使其永远不会超出目标位置?

非常感谢。

最佳答案

使用MoveTowards这最终避免了过度:

Calculate a position between the points specified by current and target, moving no farther than the distance specified by maxDistanceDelta.

transform.position = Vector3.MoveTowards(transform.position, m_TargetPos, m_Speed * Time.deltaTime);

要检查您是否已经到达位置,您可以简单地使用 ==

if (transform.position == m_TargetPos)
    return true;

它的精度为 1e-5 所以它等于使用 Vector3.Distance阈值为 0.00001

if(Vector3.Distance(transform.position, m_TargetPos) < 0.00001f)
    return true;

在这里你现在可以定义一个更宽的阈值

if(Vector3.Distance(transform.position, m_TargetPos) < 0.0025f)
    return true;

或者更精确的例子,例如

if(Vector3.Distance(transform.position, m_TargetPos) < 0.0000001f)
    return true;

根据您的需要。


如果你想使用Lerp我宁愿使用 Coroutine简而言之

// TODO: either block concurrent routines with a bool flag
// TODO: or stop the running routine before starting a new one
StartCoroutine(MoveTo(targetPosition, speed));

...

private IEnumerator MoveTo(Vector3 targetPos, float speed)
{
    var currentPos = transform.position;
    var distance = Vector3.Distance(currentPos, targetPos);
    // TODO: make sure speed is always > 0
    var duration = distance / speed;

    var timePassed = 0f;
    while(timePassed < duration)
    {
        // always a factor between 0 and 1
        var factor = timePassed / duration;

        transform.position = Vector3.Lerp(currentPos, targetPos, factor);

        // increase timePassed with Mathf.Min to avoid overshooting
        timePassed += Math.Min(Time.deltaTime, duration - timePassed);

        // "Pause" the routine here, render this frame and continue
        // from here in the next frame
        yield return null;
    }

    transform.position = targetPos;

    // Something you want to do when moving is done
}

关于c# - Unity - 在没有物理的情况下将变换移动到特定位置(以特定速度)的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58917580/

相关文章:

c# - 如何从 DataTable 中检索一对列作为字典

c# - 使用刷新 token 的 C#sharp 身份验证的 Google.Apis 客户端

c# - 使用 Azure.ResourceManager 在 C#/dotnet 中获取 Azure VM PowerState

c# - Google Plus LoadFriends 失败

c# - 如何测试对话机器人本地主机

c# - 将对象列表打印到控制台

android - 使用 Unity 作为 subview 给了我一个黑屏

c# - 不使用 Fortune 算法生成 Voronoi 图

c# - 尝试使用脚本实时更新网格的顶点位置时 Unity 游戏引擎崩溃

unity3d - 不允许重定向 url localhost 和 127.0.0.1 时如何在 Unity 中从 Sign in with Apple 获取代码