Bagaimana membuat garis Line Renderer tetap datar?


10

Saya perhatikan bahwa ketika saya menambahkan lebih banyak vertex ke baris Renderer Line, garis itu berputar dan berhenti menjadi garis yang halus.

masukkan deskripsi gambar di sini

.GIF Di Sini: http://i.imgur.com/hRAhCXM.gif

Semua garis berada pada level z yang sama, bahkan jika saya menghapus materi, garis-garis itu masih tampak melintir.

Saya tidak tahu mengapa ini melakukan ini, atau bagaimana cara mengatasinya, ada saran? C #


Ini adalah masalah dengan algoritma yang digunakan LineRenderer untuk memposisikan simpulnya, yang berurusan buruk dengan sudut tajam. Anda dapat memperbaikinya sedikit dengan menambahkan lebih banyak poin untuk melengkapi sudut-sudutnya, tetapi metode paling kuat yang saya temukan adalah menduplikasi fungsinya untuk diri Anda sendiri dengan algoritma yang lebih baik, dengan membuat Mesh dinamis dengan simpul yang Anda butuhkan, atau secara kreatif mengeksploitasi ParticleSystem untuk menggambar rantai poin.
DMGregory

1
Pembaruan: Versi selanjutnya dari Unity (5 5+) telah meningkatkan algoritma LineRenderer , sehingga pengguna yang mempertimbangkan menggunakan LineRenderers dapat menemukan hasil out-of-the-box jauh lebih baik hari ini.
DMGregory

Jawaban:


11

Masalahnya pada dasarnya adalah ini:

masukkan deskripsi gambar di sini

LineRenderer sedang mencoba untuk menghubungkan posisi titik merah. Ini menciptakan simpul hijau untuk membuat mesh. Jadi segmen garis atas tampak hebat. Tapi kemudian LineRenderer mencoba menjadi ekonomis, ia menggunakan kembali simpul dari ujung segmen satu baris di akhir segmen baris kedua. Ketika ada sudut yang tajam, Anda mendapatkan masalah yang Anda lihat. Segmen baris kedua terjepit di persimpangan karena 'tutup ujung' tidak tegak lurus dengan 'tutup ujung' lainnya.

Solusinya adalah membuat pembuat baris sendiri, dan tidak membuatnya jadi ekonomis. Anda dapat melakukan ini dengan menghasilkan mesh dinamis . Mesh akan terdiri dari serangkaian paha depan tipis. Untuk setiap segmen garis, Anda dapat menghitung empat sudut quad dengan menghitung normal garis dan lebar garis yang ditentukan:

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

Di sini, a, b, cdan dmembuat empat sudut dari segmen garis tunggal, seperti titik-titik hijau pada gambar di atas. Verteks ini akan ditambahkan ke jala, dan Anda juga akan menambahkan indeks untuk membuat empat simpul menjadi dua segitiga (jadi, enam indeks akan ditambahkan, abc dan bdc).

Ini jelas bisa menjadi agak rumit. Saya percaya alasan lain Unity menerapkan LineRenderer mereka dengan cara yang mereka lakukan adalah karena melakukannya dengan cara itu menghindari masalah lain, sudut. Saat Anda mulai menggambar setiap segmen garis, Anda akan mulai melihat di mana kedua segmen garis itu menyatu dan membentuk sambungan yang jelek. Ada beberapa cara untuk mengatasinya dengan menghitung normal bersama di antara kedua garis dan memperbarui simpulnya ke normal bersama, tetapi ini hanya menyelesaikan sebagian masalah, karena Anda masih dapat dengan mudah berakhir dengan garis terjepit. Solusi paling kuat adalah dengan menghasilkan simpul tambahan pada sambungan untuk bertindak sebagai sudut.


1
Anda juga mungkin bisa lolos dengan menggunakan renderer garis persatuan dan memasukkan poin tambahan untuk membuat mitra kecil. Letakkan satu titik sedikit jalan menuju titik berikutnya dari titik sebelumnya.
mklingen

Byte, terima kasih. Saya mungkin akan mencoba dan melihat apakah saya tidak dapat menghasilkan lebih banyak poin di setiap sudut, jika itu tidak berhasil dengan baik, saya akan pergi ke depan dan mencoba tangan saya membuat jaring dinamis. Terima kasih.
Douglas Gaskell

1

Saya memiliki masalah yang sama dan saya menyelesaikannya dengan menambahkan lebih banyak poin untuk memperhalus tepi itu bukan solusi yang elegan tetapi sederhana dan berfungsi. Setidaknya untuk saya. Saya menulis fungsi untuk melakukan ini:

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

Salah satu cara untuk mengatasi ini untuk garis buram adalah dengan membuat lingkaran di setiap sambungan. Lingkaran harus memiliki diameter yang sama dengan lebar garis. Ini membutuhkan beberapa simpul tambahan untuk ditampilkan, tetapi terlihat sangat bagus. Anda juga dapat menyingkirkan normals bersama antara sendi.

Ini masih mengharuskan Anda menulis kode rendering sendiri alih-alih menggunakan Unity Line Renderer.

Saya membuat aset yang melakukan ini di http://u3d.as/nFE


0

Cara saya menghindari ini adalah bahwa saya selalu mengatur posisi z ke 0 dalam metode LineRenderer.SetPosition (). Jadi alih-alih menulis

LineRenderer.SetPosition(i, myVector3);

saya menulis

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

Tapi itu bukan solusi terbaik karena Anda masih akan mendapatkan garis aneh itu. Solusi terbaik yang dapat saya pikirkan adalah membuat garis terpisah. Itu bekerja dengan baik untuk saya. Semoga ini bisa membantu Anda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.