C# 使用Vector2.MoveToward轻松进出
我已经看到了很多使用C# 使用Vector2.MoveToward轻松进出,c#,unity3d,C#,Unity3d,我已经看到了很多使用Vector2.Lerp轻松的例子 但我想使用向量2。移动到,因为我将我的NPC移动的距离随机化,我希望NPC的速度始终保持不变,而不管移动的距离。理想情况下,如果可能的话,我想用动画曲线来控制放松,但是平滑步长功能也可以。下面是我现在使用的简化代码(使用行为设计器,因此方法有点不同): 好的,第一个问题是:永远不要使用=来比较两个浮点值 甚至像5f*0.2f/10f==1f这样的情况也可能失败,因为由于浮点精度的原因,它实际上可能是0.999999或1.0000001 相反
Vector2.Lerp
轻松的例子
但我想使用向量2。移动到,因为我将我的NPC移动的距离随机化,我希望NPC的速度始终保持不变,而不管移动的距离。理想情况下,如果可能的话,我想用动画曲线
来控制放松,但是平滑步长功能也可以。下面是我现在使用的简化代码(使用行为设计器,因此方法有点不同):
好的,第一个问题是:永远不要使用
=
来比较两个浮点值
甚至像5f*0.2f/10f==1f
这样的情况也可能失败,因为由于浮点精度的原因,它实际上可能是0.999999
或1.0000001
相反,你通常更倾向于对照某个范围进行检查,例如
if(Mathf.Abs(a - b) <= someThreshold)
private readonly float Speed = 1.5f;
private Vector2 target;
private Vector2 start;
private float timePassed;
private float duration;
public override void OnStart()
{
target = new Vector2(Random.Range(0.1f, 0.5f), transform.position.y);
start = transform.position;
duration = Vector2.Distance(start, target) / speed;
timePassed = 0f;
}
public override TaskStatus OnUpdate()
{
if (timePassed >= duration)
{
transform.position = target;
return TaskStatus.Success;
}
var factor = timePassed / duration;
//MAGIC
transform.position = Vector2.Lerp(start, target, factor);
timePassed += Time.deltaTime;
return TaskStatus.Running;
}
factor = Mathf.SmoothStep(0, 1, factor);
基本上等于使用
if(Mathf.Abs(a - b) <= Mathf.Epsilon)
到目前为止,这将是一个与以前一样的线性运动;)
因此,让我们来填写魔术
一个非常简单的易入易出选项是使用like,例如
if(Mathf.Abs(a - b) <= someThreshold)
private readonly float Speed = 1.5f;
private Vector2 target;
private Vector2 start;
private float timePassed;
private float duration;
public override void OnStart()
{
target = new Vector2(Random.Range(0.1f, 0.5f), transform.position.y);
start = transform.position;
duration = Vector2.Distance(start, target) / speed;
timePassed = 0f;
}
public override TaskStatus OnUpdate()
{
if (timePassed >= duration)
{
transform.position = target;
return TaskStatus.Success;
}
var factor = timePassed / duration;
//MAGIC
transform.position = Vector2.Lerp(start, target, factor);
timePassed += Time.deltaTime;
return TaskStatus.Running;
}
factor = Mathf.SmoothStep(0, 1, factor);
或者你现在可以用
factor = yourAnimationCurve.Evaluate(factor);
这使您可以完全控制移动的平滑度,但会产生速度的总平均速度
,就好像您会线性应用它一样。您可以发布当前代码吗?到目前为止,你到底是如何移动这些对象的?当然,我已经在我的帖子中添加了代码。你至少可以轻松地查看一下。。然而,使用您当前的方法,很难准确地判断何时应该开始一个新的运动…因此我尝试了这种方法来计算何时应该开始轻松进入/退出,但它没有正常工作:private float GenerateTimeToReachDestination(){float Distance=Vector2.Distance(transform.position,BugDirection.Value);返回距离/速度;}
在更新中,我有这样的逻辑:CurrentTime+=Time.deltaTime;float CurrentSpeed=AnimationMovementCurve.Evaluate(CurrentTime/TimeToReachDestination)代码>不起作用,甚至不接近,即使我把逻辑拉到一个协同程序中。(对奇怪的格式表示抱歉)如前所述,主要问题是:你如何确切地知道一个新动作何时开始,何时结束?BugDirection
是否持续更改?谢谢您的详细回答!我将研究重构我的代码,并删除了有问题的浮点比较。