从这两种方法中获得最接近目标的最有效且最便宜的方法是什么?
使用LINQ
GameObject FindClosestTarget(string trgt)
{
GameObject[] closestGameObject = GameObject.FindGameObjectsWithTag(trgt)
.OrderBy(go => Vector3.Distance(go.transform.position, transform.position)
.FirstOrDefault();
return closestGameObject ;
}
or this
GameObject FindClosestTarget(string trgt)
{
GameObject[] gos= GameObject.FindGameObjectsWithTag(trgt);
GameObject closest=null;
float distance = Mathf.Infinity;
Vector3 position = transform.position;
foreach (GameObject go in gos) {
Vector3 diff = go.transform.position - position;
float curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = go;
distance = curDistance;
}
}
return closest;
}
第一个示例使用Vector3.Distance
这需要相当昂贵的Sqrt
操作,而第二个使用我更喜欢使用更简单的 LINQ 形式的代码。
以下是 Unity 脚本 API 文档的摘录:sqrMagnitude http://docs.unity3d.com/ScriptReference/Vector3-sqrMagnitude.html:
矢量 v 的大小计算如下Mathf.Sqrt(Vector3.Dot(v, v))
。但是,那Sqrt
计算相当复杂,并且比普通算术运算需要更长的时间来执行。计算平方幅度而不是使用幅度属性要快得多 - 计算基本相同,只是没有慢Sqrt
称呼。如果您只是使用幅度来比较距离,那么您也可以将幅度的平方与距离的平方进行比较,因为比较会给出相同的结果。
所以你的场景基本上就是他们创建的原因sqrMagnitude
财产...因为Sqrt
是一项昂贵的操作,如果您只想知道距离的顺序而不需要actual距离供以后使用。
我个人更喜欢将其作为第三种选择:
GameObject FindClosestTarget(string trgt)
{
Vector3 position = transform.position;
return GameObject.FindGameObjectsWithTag(trgt)
.OrderBy(o => (o.transform.position - position).sqrMagnitude)
.FirstOrDefault();
}
两全其美...LINQ 的简单性(并且实现非常高效),没有多余的东西Sqrt
操作来减慢你的速度。
但与往常一样,当您对代码的实际性能有疑问时,您应该对每种方法进行仔细的分析,看看哪种方法实际上性能更好。有时,优化器会向您抛出一个曲线球,并将可怕的 C# 代码转换为非常有效的输出。
顺便说一句,如果您想将范围限制为特定的最大距离,请对该距离进行平方并将其与sqrMaginitude
以避免邪恶Sqrt
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)