Làm thế nào để làm cho dòng Line Renderer không thay đổi?


10

Tôi đã nhận thấy rằng khi tôi thêm nhiều đỉnh vào dòng Line Renderer, đường xoắn và dừng lại là một đường trơn.

nhập mô tả hình ảnh ở đây

.GIF Tại đây: http://i.imgur.com/hRAhCXM.gif

Tất cả các dòng đều ở cùng cấp z, ngay cả khi tôi loại bỏ các vật liệu, các dòng dường như vẫn bị xoắn.

Tôi không biết tại sao nó làm điều này, hoặc làm thế nào để giải quyết nó, bất kỳ đề xuất nào? C #


Đây là một vấn đề với thuật toán mà LineRenderer sử dụng để định vị các đỉnh của nó, nó xử lý kém với các góc nhọn. Bạn có thể cải thiện phần nào bằng cách thêm nhiều điểm hơn để làm tròn các góc, nhưng phương pháp mạnh nhất mà tôi đã tìm thấy là sao chép chức năng của nó cho chính mình bằng thuật toán tốt hơn, bằng cách tạo Lưới động với các đỉnh bạn cần hoặc sáng tạo khai thác một ParticleSystem để vẽ chuỗi các điểm.
DMGregory

1
Cập nhật: Các phiên bản sau của Unity (5 5+) đã cải thiện thuật toán LineRenderer , vì vậy người dùng cân nhắc sử dụng LineRenderers có thể thấy kết quả vượt trội hơn đáng kể trong những ngày này.
DMGregory

Câu trả lời:


11

Vấn đề cơ bản là thế này:

nhập mô tả hình ảnh ở đây

LineRenderer đang cố gắng kết nối các vị trí chấm đỏ. Nó tạo ra các đỉnh màu xanh lá cây để tạo lưới. Vì vậy, phân khúc hàng đầu trông tuyệt vời. Nhưng sau đó LineRenderer cố gắng tiết kiệm, nó sử dụng lại các đỉnh từ cuối đoạn một dòng ở cuối đoạn thứ hai. Khi có một góc nhọn, bạn sẽ gặp vấn đề bạn đang gặp phải. Đoạn đường thứ hai bị chèn ép tại giao lộ vì 'nắp cuối' của nó không vuông góc với 'nắp cuối' khác.

Giải pháp là tạo trình kết xuất dòng của riêng bạn và không làm cho nó quá kinh tế. Bạn có thể làm điều này bằng cách tạo ra một lưới năng động . Lưới sẽ bao gồm một loạt các hình tứ giác mỏng. Đối với mỗi phân đoạn dòng, bạn có thể tính toán bốn góc của hình tứ giác bằng cách tính mức bình thường của dòng và độ rộng dòng được chỉ định:

Vector3 normal = Vector3.Cross(start, end);
Vector3 side = Vector3.Cross(normal, end-start);
side.Normalize();
Vector3 a = start + side * (lineWidth / 2);
Vector3 b = start + side * (lineWidth / -2);
Vector3 c = end + side * (lineWidth / 2);
Vector3 d = end + side * (lineWidth / -2);

Ở đây, a, b, cdtạo nên bốn góc của một đoạn thẳng duy nhất, giống như các dấu chấm màu xanh lá cây trong hình trên. Các đỉnh này sẽ được thêm vào lưới và bạn cũng sẽ thêm các chỉ số để biến bốn đỉnh thành hai hình tam giác (vì vậy, sáu chỉ số sẽ được thêm vào, abc và bdc).

Điều này rõ ràng có thể trở nên khá phức tạp. Tôi tin rằng một lý do khác khiến Unity triển khai LineRenderer của họ theo cách họ đã làm là vì làm theo cách đó để tránh một vấn đề khác, các góc. Khi bạn bắt đầu vẽ từng đoạn đường, bạn sẽ bắt đầu thấy hai đoạn đường nối với nhau và tạo thành một khớp xấu xí. Có nhiều cách để giải quyết vấn đề này bằng cách tính toán bình thường được chia sẻ giữa cả hai dòng và cập nhật các đỉnh của chúng thành bình thường được chia sẻ, nhưng điều này chỉ giải quyết được một phần vấn đề, vì bạn vẫn có thể dễ dàng kết thúc với các dòng bị chèn ép. Giải pháp mạnh mẽ nhất là tạo ra các đỉnh bổ sung tại các khớp để hoạt động như các góc.


1
Bạn cũng có thể thoát khỏi việc sử dụng trình kết xuất dòng thống nhất và chèn các điểm bổ sung để tạo một chỉ số nhỏ. Chỉ cần đặt một điểm một chút về điểm tiếp theo từ điểm trước.
mklingen

Byte giải thích tuyệt vời, cảm ơn. Có lẽ tôi sẽ thử và xem liệu tôi không thể tạo ra nhiều điểm hơn ở mỗi góc hay không, nếu điều đó không tốt, tôi sẽ tiếp tục và thử làm một lưới năng động. Cảm ơn bạn.
Douglas Gaskell

1

Tôi đã có cùng một vấn đề và tôi giải quyết nó thêm nhiều điểm hơn để làm mịn các khía cạnh không phải là một giải pháp tao nhã mà đơn giản và hiệu quả. Ít nhất là đối với tôi. Tôi đã viết một chức năng để làm điều này:

Vector3[] Generate_Points(Vector3[] keyPoints, int segments=100){
    Vector3[] Points = new Vector3[(keyPoints.Length - 1) * segments + keyPoints.Length];
    for(int i = 1; i < keyPoints.Length;i++){
        Points [(i - 1) * segments + i - 1] = new Vector3(keyPoints [i-1].x,keyPoints [i-1].y,0);
        for (int j = 1;j<=segments;j++){
            float x = keyPoints [i - 1].x;
            float y = keyPoints [i - 1].y;
            float z = 0;//keyPoints [i - 1].z;
            float dx = (keyPoints [i].x - keyPoints [i - 1].x)/segments;
            float dy = (keyPoints [i].y - keyPoints [i - 1].y)/segments;
            Points [(i - 1) * segments + j + i - 1] = new Vector3 (x+dx*j,y+dy*j,z);
        }
    }
    Points [(keyPoints.Length - 1) * segments + keyPoints.Length - 1] = new Vector3(keyPoints [keyPoints.Length-1].x,keyPoints [keyPoints.Length-1].y,0);
    return Points;
}


0

Một cách để giải quyết điều này cho các đường mờ đục là hiển thị một vòng tròn ở mỗi khớp. Vòng tròn cần phải có đường kính bằng chiều rộng đường. Điều này đòi hỏi một số đỉnh bổ sung được hiển thị, nhưng trông thực sự tốt đẹp. Sau đó, bạn cũng có thể thoát khỏi các quy tắc chung giữa các khớp.

Điều này vẫn yêu cầu bạn viết mã kết xuất của riêng bạn thay vì sử dụng Trình kết xuất dòng Unity.

Tôi đã tạo một tài sản chỉ làm điều này tại http://u3d.as/nFE


0

Cách tôi tránh điều này là tôi luôn đặt vị trí z thành 0 trong phương thức LineRenderer.SetPocation (). Vì vậy, thay vì viết

LineRenderer.SetPosition(i, myVector3);

tôi đã viết

LineRenderer.SetPosition(i, new Vector3(myVector3.x, myVector3.y, 0));

Nhưng đó không phải là giải pháp tốt nhất vì bạn vẫn sẽ nhận được những dòng lạ đó. Giải pháp tốt nhất mà tôi có thể nghĩ đến là tạo các dòng riêng biệt. Điều đó làm việc hoàn hảo cho tôi. Hy vọng điều này sẽ giúp bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.