2017-07-27 6 views
5

Ich habe ein C# -Skript in Unity geschrieben, das alle sichtbaren Objekte erkennt. Jetzt möchte ich sie von links nach rechts ausgeben, wie sie in der Szene positioniert sind. Jedes Objekt hat eine Nummer und dennoch gibt das Skript die Objekte in aufsteigender Reihenfolge aus.Objekte von links nach rechts lesen

Meine Idee:

Ich dachte an eine for-loop, die sich entlang der horizontalen Sichtfeld geht. Erste Berechnung der horizontalen FOV von:

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

und die Schaffung der Schleife durch:

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

Aber unfortunally funktioniert das nicht. Wie könnte ich also alle Objekte von links nach rechts lesen?

+0

Erhalten Sie einen Fehler oder sind 'Renderer' leer oder werden sie nicht zur Liste hinzugefügt? – jhhoff02

+0

Weitere Informationen dazu, wie es "nicht funktioniert" wäre hilfreich. – hatchet

+0

Sorry, ich meine, die Liste ist erstellt, aber alle Namen (die Zahlen sind) werden in aufsteigender Reihenfolge hinzugefügt. Und ich möchte, dass sie von der Position "Position" hinzugefügt werden, von links nach rechts. – Viktoria

Antwort

2

Ich verwende nicht Unity, so tut mir leid, wenn ich etwas vermisse, aber es scheint, dass, obwohl in der äußeren for Schleife Sie von links nach rechts schauen, Sie diese Informationen nicht innerhalb der Schleife verwenden. Die innere Schleife prüft nur, ob jeder Renderer sichtbar ist, und fügt ihn der Liste hinzu, so dass sie wahrscheinlich in der Reihenfolge in der Ausgabeliste erscheinen, in der sie in der renderers Sammlung abgelegt sind.

Um die Objekte von links nach rechts zu sortieren, sollten Sie wahrscheinlich ihre Bildschirmkoordinaten berechnen und sie dann zum Sortieren verwenden. Um dies zu berechnen, können Sie Camera.WorldToScreenPoint Methode verwenden. Ich habe einige Vorschläge gefunden, die hier hilfreich sein können: http://answers.unity3d.com/questions/49943/is-there-an-easy-way-to-get-on-screen-render-size.html.

Um die Objekte zu sortieren, können Sie die hier beschriebene SortedList Klasse verwenden: https://msdn.microsoft.com/en-us/library/ms132319(v=vs.110).aspx. Nachdem Sie die Bildschirmkoordinaten für jedes Objekt berechnet haben, fügen Sie es einfach zur Liste mit der X-Koordinate auf dem Bildschirm als Schlüssel hinzu, und die Liste behält automatisch die bestellten Objekte bei.

+0

Das funktioniert nicht, weil 'Bound' nicht statisch ist. – Viktoria

+0

Ich bin mir nicht sicher, was Sie meinen. Bitte erklären Sie, warum 'Bound' nicht statisch ist, ist in diesem Fall ein Problem. –

0

Angenommen, renderers ist eine Liste, können Sie die List.Sort Methode verwenden und das Punktprodukt verwenden, um die Objekte von links nach rechts zu sortieren.

ich ein Drehbuch gemacht haben, die hier arbeitet, versuchen Sie es mal

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

Nützliche Links:

+0

In meinem Code überprüfe ich nicht, ob der Renderer sichtbar ist. Aktivieren Sie diese Frage, um den Renderer zu filtern, sofern sie sichtbar sind: https://stackoverflow.com/questions/26196/filtering-collections-in-c-sharp – Hellium

Verwandte Themen