获得最近目标的最有效方法是什么 [英] What is the most effective way to get closest target

查看:29
本文介绍了获得最近目标的最有效方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从这两种方法中获得最近目标的最有效和最便宜的方法是什么?

What is the most effective and less expensive way to get closest target from these two methods?

使用 LINQ

GameObject FindClosestTarget(string trgt) 
{
    GameObject[] closestGameObject = GameObject.FindGameObjectsWithTag(trgt)
                      .OrderBy(go => Vector3.Distance(go.transform.position, transform.position)
                      .FirstOrDefault();
         return closestGameObject ;
}

或者这个

 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 形式的代码.

The first example uses Vector3.Distance which requires a quite expensive Sqrt operation, while the second uses code that I'd prefer to throw in favor of the simpler LINQ form.

以下是 sqrMagnitude:

矢量 v 的大小计算为 Mathf.Sqrt(Vector3.Dot(v, v)).但是,Sqrt 计算相当复杂,执行时间比普通算术运算更长.计算平方幅度而不是使用幅度属性要快得多 - 计算基本相同,只是没有缓慢的 Sqrt 调用.如果您只是使用幅度来比较距离,那么您也可以将幅度的平方与距离的平方进行比较,因为比较会得出相同的结果.

The magnitude of a vector v is calculated as Mathf.Sqrt(Vector3.Dot(v, v)). However, the Sqrt calculation is quite complicated and takes longer to execute than the normal arithmetic operations. Calculating the squared magnitude instead of using the magnitude property is much faster - the calculation is basically the same only without the slow Sqrt call. If you are using magnitudes simply to compare distances, then you can just as well compare squared magnitudes against the squares of distances since the comparison will give the same result.

所以你的场景基本上就是他们创建 sqrMagnitude 属性的原因......因为 Sqrt 是一个昂贵的操作,如果你只是想知道,你不需要距离的顺序,不需要实际距离以备后用.

So your scenario is basically exactly why they created the sqrMagnitude property... because Sqrt is an expensive operation that you don't need if you just want to know the order of distance without needing the actual distance for use later.

我个人更喜欢将其作为第三种选择:

Personally I prefer this as a third option:

GameObject FindClosestTarget(string trgt)
{
    Vector3 position = transform.position;
    return GameObject.FindGameObjectsWithTag(trgt)
        .OrderBy(o => (o.transform.position - position).sqrMagnitude)
        .FirstOrDefault();
}

两全其美... LINQ 的简单性(和非常有效的实现),没有多余的 Sqrt 操作来减慢您的速度.

Best of both worlds... the simplicity (and quite efficient implementation) of LINQ with no superfluous Sqrt operations to slow you down.

但与往常一样,当您对代码的实际性能有疑问时,您应该对每种方法进行一些仔细的分析,以查看哪种方法实际上表现更好.有时,优化器会向您抛出一个曲线球并将可怕的 C# 代码转换为非常有效的输出.

But as always, when you have a question about real-world performance of your code you should do some careful profiling of each method to see which one actually performs better. Sometimes the optimizer throws you a curve ball and transforms horrible C# code into quite effective output.

顺便说一下,如果您想将范围限制在特定的最大距离,请将该距离平方并将其与 sqrMaginitude 进行比较以避免邪恶的 Sqrt.

Incidentally, if you wanted to limit your range to a particular maximum distance, square that distance and compare it to the sqrMaginitude to avoid the evil Sqrt.

这篇关于获得最近目标的最有效方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆