Reading objects from left to right

I wrote C # Script in Unity, which detects all visible objects. Now I would like to display them from left to right, as they are located on the stage. Each object has a number, but Script displays the objects in ascending order.

My idea:

I was thinking of a for-loop that goes across a horizontal field of view. First, calculate the horizontal FOV by:

 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; } 

And creating a loop:

 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; } 

But unfortunately, this will not work. So how could I read all objects from left to right?

+5
source share
2 answers

I do not use Unity, so I'm sorry if I missed something, but it seems that although you are looking from left to right in the outer for loop, you are not using this information inside the loop. The inner loop checks to see if each visualizer is visible and adds it to the list, so they probably appear in the output list in the order in which they are placed in the renderers collection.

To sort objects from left to right, you should probably calculate their screen coordinates, and then use them to sort them. To calculate this, you can use the Camera.WorldToScreenPoint method. I found several suggestions that may be useful here: http://answers.unity3d.com/questions/49943/is-there-an-easy-way-to-get-on-screen-render-size.html .

To sort objects, you can use the SortedList class, described here: https://msdn.microsoft.com/en-us/library/ms132319(v=vs.110).aspx . After calculating the screen coordinates for each object, simply add it to the list with the X coordinate on the screen as a key, and the list will automatically save the ordered objects.

+2
source

Assuming renderers is a list, you can use the List.Sort method and use a point product to sort objects from left to right.

I created a script that works here, try

  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 ; } 

Sortrenderers

Useful links:

0
source

Source: https://habr.com/ru/post/1270287/


All Articles