从左到右读取对象
Posted
技术标签:
【中文标题】从左到右读取对象【英文标题】:Read objects from left to right 【发布时间】:2018-01-03 14:11:18 【问题描述】:我在 Unity 中编写了一个 C# 脚本,它可以检测所有可见对象。现在我想从左到右输出它们,就像它们在场景中的位置一样。每个对象都有一个数字,但脚本按升序输出对象。
我的想法:
我想到了一个沿着水平视野的for-loop
。首先计算水平FOV:
private static float horizontalFOV()
float radAngle = Camera.main.fieldOfView * Mathf.Deg2Rad;
float radHFOV = 2 * Mathf.Atan(Mathf.Tan(radAngle / 2) * Camera.main.aspect);
float hFOV = Mathf.Rad2Deg * radHFOV;
return hFOV;
并通过以下方式创建循环:
public static string OutputVisibleRenderers (List<Renderer> renderers)
float hFov = horizontalFOV ();
if (null == renderers)
throw new System.ArgumentNullException ("renderers are null");
for (int i = 0; i < hFov; i++)
foreach (var renderer in renderers)
if (IsVisible (renderer))
myList.Add (renderer.name);
string itemsInOneLine = string.Join ("-", myList.ToArray());
myList.Clear ();
print (itemsInOneLine);
print ("--------------------------------------------------");
return itemsInOneLine;
但不幸的是,这不起作用。那么我怎么能从左到右读取所有对象呢?
【问题讨论】:
您是否遇到错误或renderers
为空,或者他们没有被添加到列表中?
更多关于它如何“不起作用”的信息会有所帮助。
对不起,我的意思是创建了列表,但所有名称(都是数字)都是按升序添加的。我希望它们按“位置”顺序从左到右添加。
你需要对它们进行排序,你可以使用每个对象的transform.position
作为排序的值。
@Draco18s 我怎么能意识到?
【参考方案1】:
我不使用 Unity,如果我遗漏了什么,很抱歉,但似乎虽然在外部 for
循环中您从左到右查看,但您没有在循环内使用此信息。内部循环只是检查每个渲染器是否可见并将其添加到列表中,因此它们可能会按照它们在 renderers
集合中的放置顺序出现在输出列表中。
为了从左到右对对象进行排序,您可能应该计算它们在屏幕上的坐标,然后使用它们进行排序。要计算这个,您可以使用Camera.WorldToScreenPoint 方法。我在这里找到了一些可能有用的建议:http://answers.unity3d.com/questions/49943/is-there-an-easy-way-to-get-on-screen-render-size.html。
要对对象进行排序,您可以使用此处描述的SortedList
类:https://msdn.microsoft.com/en-us/library/ms132319(v=vs.110).aspx。
计算出每个对象的屏幕坐标后,只需将其添加到以屏幕X坐标为键的列表中,列表将自动保持对象的有序。
【讨论】:
我不确定你的意思。请解释为什么Bound
在这种情况下不是静态的是一个问题。【参考方案2】:
假设renderers
是一个List,你可以使用List.Sort
方法并使用点积将对象从左到右排序。
我已经制作了一个可以在这里使用的脚本,试试看
public System.Collections.Generic.List<Renderer> renderers ;
private void Start()
var sortedRenderers = new System.Collections.Generic.List<Renderer>( renderers ) ;
sortedRenderers.Sort( SortLeftToRight ) ;
for( int i = 0 ; i < sortedRenderers.Count ; ++i )
Debug.Log( sortedRenderers[i].name ) ;
private int SortLeftToRight( Renderer r1, Renderer r2 )
Transform camTransform = Camera.main.GetComponent<Transform>(); // You can optimize if you cache the transform of the camera
Vector3 axis = camTransform.right ;
Transform t1 = r1.gameObject.GetComponent<Transform>();
Transform t2 = r2.gameObject.GetComponent<Transform>();
float dot1 = Vector3.Dot( axis, t1.position - camTransform.position );
float dot2 = Vector3.Dot( axis, t2.position - camTransform.position );
if( Mathf.Abs( dot1 - dot2 ) < 0.001f )
return 0 ;
return dot1 < dot2 ? -1 : 1 ;
有用的链接:
https://msdn.microsoft.com/fr-fr/library/w56d4y5z(v=vs.110).aspx https://docs.unity3d.com/Manual/UnderstandingVectorArithmetic.html【讨论】:
在我的代码中,我不检查渲染器是否可见。检查此问题以过滤渲染器是否可见:***.com/questions/26196/…以上是关于从左到右读取对象的主要内容,如果未能解决你的问题,请参考以下文章