2017-07-27 63 views
5

Tôi đã viết C# Script in Unity, phát hiện tất cả các đối tượng hiển thị. Bây giờ tôi muốn xuất chúng từ trái sang phải, như cách chúng được định vị trong cảnh. Mỗi đối tượng có một số và kịch bản lệnh xuất ra các đối tượng theo thứ tự tăng dần.Đọc các đối tượng từ trái sang phải

Ý tưởng của tôi:

Tôi nghĩ về một for-loop mà đi dọc theo lĩnh vực ngang xem. Đầu tiên tính FOV ngang bởi:

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

Và tạo vòng lặp theo:

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

Nhưng unfortunally này không hoạt động. Vậy làm thế nào tôi có thể đọc tất cả các đối tượng từ trái sang phải?

+0

Bạn có gặp lỗi hoặc là 'trình kết xuất đồ họa 'trống hoặc chúng không được thêm vào danh sách không? – jhhoff02

+0

Thông tin thêm về cách hoạt động "không hoạt động" sẽ hữu ích. – hatchet

+0

Xin lỗi, tôi có nghĩa là danh sách được tạo, nhưng tất cả các tên (là số) được thêm vào theo thứ tự tăng dần. Và tôi muốn chúng được thêm vào theo thứ tự "vị trí", từ trái sang phải. – Viktoria

Trả lời

2

Tôi không sử dụng Unity, vì vậy xin lỗi nếu tôi thiếu thứ gì đó, nhưng có vẻ như mặc dù ở vòng ngoài for Bạn nhìn từ trái sang phải, Bạn không sử dụng thông tin này bên trong vòng lặp. Vòng lặp bên trong chỉ kiểm tra xem mỗi trình kết xuất có hiển thị hay không và thêm nó vào danh sách, vì vậy chúng có thể xuất hiện trong danh sách đầu ra theo thứ tự chúng được đặt trong bộ sưu tập renderers.

Để sắp xếp các đối tượng từ trái sang phải, bạn có thể tính tọa độ trên màn hình của mình và sau đó sử dụng chúng để sắp xếp. Để tính toán điều này, bạn có thể sử dụng phương thức Camera.WorldToScreenPoint. Tôi đã tìm thấy một số đề xuất có thể hữu ích ở đây: http://answers.unity3d.com/questions/49943/is-there-an-easy-way-to-get-on-screen-render-size.html.

Để sắp xếp các đối tượng, Bạn có thể sử dụng SortedList lớp được mô tả tại đây: https://msdn.microsoft.com/en-us/library/ms132319(v=vs.110).aspx. Sau khi tính toán tọa độ trên màn hình cho từng đối tượng, chỉ cần thêm nó vào danh sách với toạ độ X trên màn hình làm khóa và danh sách sẽ tự động giữ các đối tượng được sắp xếp.

+0

Điều này không hiệu quả vì 'Ràng buộc' không tĩnh – Viktoria

+0

Tôi không chắc chắn ý của bạn là gì. Vui lòng giải thích tại sao 'Ràng buộc' không tĩnh là một vấn đề trong trường hợp này. –

0

Giả sử renderers là một Danh sách, bạn có thể sử dụng phương pháp List.Sort và sử dụng sản phẩm dấu chấm để sắp xếp các đối tượng từ trái sang phải.

Tôi đã thực hiện một kịch bản mà làm việc ở đây, cung cấp cho nó một thử

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

Liên kết hữu ích:

+0

Trong mã của tôi, tôi không kiểm tra xem trình kết xuất có hiển thị hay không. Kiểm tra câu hỏi này để lọc trình kết xuất nếu chúng hiển thị: https://stackoverflow.com/questions/26196/filtering-collections-in-c-sharp – Hellium

Các vấn đề liên quan