首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >统一-在没有物理的情况下,移动到特定位置(在特定速度上)的最佳方法?

统一-在没有物理的情况下,移动到特定位置(在特定速度上)的最佳方法?
EN

Stack Overflow用户
提问于 2019-11-18 15:10:38
回答 1查看 3K关注 0票数 1

我想知道我应该如何转换到一个特定的点(不使用物理)。

目前,我让我的对象看目标位置:

代码语言:javascript
复制
transform.LookAt(m_TargetPos, UnityEngine.Vector3.up);

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

代码语言:javascript
复制
transform.position += transform.forward * (m_Speed * Time.deltaTime);

最后,我使用一个sqrMagnitude来知道转换是否到达了这个位置:

代码语言:javascript
复制
if ((transform.position - m_TargetPos).sqrMagnitude < 0.0025f) // 0.0025 = 0.05f * 0.05f
        return true;

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

我应该如何编码条件,使它永远不会超出目标位置?

在此之前,非常感谢您。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-18 15:31:57

使用MoveTowards,避免过度使用:

计算当前和目标指定的点之间的位置,移动不超过maxDistanceDelta指定的距离。

代码语言:javascript
复制
transform.position = Vector3.MoveTowards(transform.position, m_TargetPos, m_Speed * Time.deltaTime);

若要检查是否已达到此位置,只需使用==

代码语言:javascript
复制
if (transform.position == m_TargetPos)
    return true;

这具有1e-5的精度,因此它等于使用阈值为0.00001Vector3.Distance

代码语言:javascript
复制
if(Vector3.Distance(transform.position, m_TargetPos) < 0.00001f)
    return true;

在这里,您可以定义一个更宽的阈值

代码语言:javascript
复制
if(Vector3.Distance(transform.position, m_TargetPos) < 0.0025f)
    return true;

或者是更精确的。

代码语言:javascript
复制
if(Vector3.Distance(transform.position, m_TargetPos) < 0.0000001f)
    return true;

取决于你的需要。

如果你想使用Lerp,我宁愿使用柯鲁丁,简而言之

代码语言:javascript
复制
// 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
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58917580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档