Bagaimana saya bisa menggambar garis besar di Unity3d?

13

Saya mencoba menyorot persegi panjang dengan tinggi acak. Saya pikir cara termudah untuk melakukan ini adalah dengan membuat objek game "kotak" terpisah yang menguraikan persegi panjang.

Saya sudah mencoba dengan MeshRenderer + Transparent Texture, dan LineRenderer untuk menguraikan empat titik persegi panjang. Tidak ada yang sangat memuaskan.

masukkan deskripsi gambar di sini

(Baris renderer di tengah, skala kubus di sebelah kanan)

Apa cara yang benar untuk melakukan ini? Saya mencoba untuk mendapatkan sesuatu seperti persegi panjang kiri - perimeter sederhana dengan lebar tetap melalui empat titik yang saya pilih.

Raven Dreamer
sumber

Jawaban:

8

Gunakan GUI.Box().

Jika Anda hanya membutuhkan persegi panjang 2D, GUI adalah caranya. Buat GUIStyle baru menggunakan persegi panjang sederhana sebagai tekstur (bagian dalam persegi panjang harus transparan, tentu saja), atur Bordernilainya sehingga tidak melar, dan panggil GUI.Box(new Rect(...),"",myGuiStyle);.

Anda dapat menggunakan Camera.WorldToScreenPointmetode jika Anda ingin menjabarkan sesuatu dalam koordinat dunia (yaitu 3D), ingatlah bahwa dalam koordinat dunia Unity, y bergerak dari bawah ke atas, dan dalam GUI, y bergerak dari atas ke bawah.

Contoh Kode:

void OnGUI()
{
    //top left point of rectangle
    Vector3 boxPosHiLeftWorld = new Vector3(0.5f, 12, 0);
    //bottom right point of rectangle
    Vector3 boxPosLowRightWorld = new Vector3(1.5f, 0, 0);

    Vector3 boxPosHiLeftCamera = Camera.main.WorldToScreenPoint(boxPosHiLeftWorld);
    Vector3 boxPosLowRightCamera = Camera.main.WorldToScreenPoint(boxPosLowRightWorld);

    float width = boxPosHiLeftCamera.x - boxPosLowRightCamera.x;
    float height = boxPosHiLeftCamera.y - boxPosLowRightCamera.y;


     GUI.Box(new Rect(boxPosHiLeftCamera.x, Screen.Height - boxPosHiLeftCamera.y, width, height),"", highlightBox);
}
Lupakan
sumber
Kecuali saya salah, GUI.Box () akan selalu digambar di atas objek apa pun di tempat kejadian? Apakah mungkin untuk memiliki elemen GUI di belakang atau sebagian di belakang objek game?
Raven Dreamer
Ya, GUI selalu digambar setelah benda lain. Ada peretasan yang dapat Anda gunakan untuk membuat kamera terpisah di atas GUI, tapi agak sulit.
Nevermind
Jawaban ini memberi saya apa yang saya butuhkan, tapi saya tetap buka untuk saat ini dengan harapan ada cara yang lebih baik untuk melakukan ini dalam kasus umum.
Raven Dreamer
Saya menerima suntikan Anda menambahkan sampel kode, dan memperbaiki bug GUI-y-terbalik-di dalamnya.
Nevermind
1

Di bawah ini adalah pendekatan non-shader.

Pikirkan kotak 2d Anda sebagai tidak lebih dari empat garis, di mana setiap garis hanya diregangkan dalam satu dimensi (dua dimensi lainnya adalah penampang tepi). Ini seperti jika Anda membuat kotak dalam kehidupan nyata, di mana Anda mengumpulkan kayu dengan panjang variabel yang semuanya memiliki ukuran penampang yang sama.

Dengan mengingat hal itu, Anda dapat menyusun Komponen, katakanlah BoxBuilder, yang ketika dilampirkan ke GameObject, membuat dan mengelola empat GameObjects anak. Setiap objek permainan anak adalah salah satu tepi kotak Anda, dan dapat berupa kubus 3d yang direntangkan hanya dalam satu dimensi. Dengan widthdan heightdidefinisikan BoxBuildertingkat, Anda dapat menghitung posisi yang diperlukan dan skala non-seragam dari empat tepi anak. Ini akan menjadi banyak pos.x=w/2, pos.y=h/2, ..., scale.x=h, scale.y=w, dll semacam kode.

Meskipun saya yakin Anda hanya meminta 2-d, perhatikan bahwa ide yang sama ini dapat diterapkan ke kotak 3d jika diperlukan, di mana BoxBuildersekarang harus membuat dan mengelola 12 tepi anak, tetapi sekali lagi hanya menskalakan setiap tepi dalam satu dimensi lokal.

DuckMaestro
sumber
Bisa diterapkan, tetapi WAY terlalu rumit.
Nevermind
Jika saya harus melakukannya dengan cara ini, saya hanya akan menggunakan 4 renderers baris ...
Raven Dreamer
Namun ini benar-benar menangani kedalaman.
DuckMaestro
1

Cara sederhana adalah dengan menggunakan Shader dengan dua Pass: Pass pertama menggunakan vertex shader untuk memperbesar objek sedikit dan menggunakan pixel shader untuk mewarnainya menjadi warna solid yang cocok dengan warna yang Anda inginkan untuk memiliki garis, dan kemudian Pass kedua melakukan rendering biasa.

UBSophung
sumber
Bisakah Anda memberikan contoh kode untuk lebih menjelaskan apa yang Anda maksud?
Raven Dreamer
Ini hanya akan bekerja untuk objek cembung (seperti persegi panjang) yang asalnya di pusat geometris itu.
rootlocus
1

Saya punya masalah yang sama membuat garis besar, kecuali saya harus membuat "stroke" untuk 3d cube, dan menemukan cara baru untuk melakukannya yang saya tidak melihat di tempat lain secara online.

Pada gambar di bawah ini ada dua bentuk dengan garis besar. Yang di sebelah kanan adalah kubus yang dibangun dengan LineRenderer, yang membangun wajah datar yang selalu mengarah ke pengguna. Saya menemukan metode ini sangat glitchy, dengan "stroke" acak muncul yang menirukan segitiga yang membentuk wajah.

Yang di sebelah kiri adalah "inovasi" saya dengan 12 kubus kurus terpisah yang membentuk garis besar. Untuk mengubah ukuran "stroke" dalam garis besar saya perlu menambah / mengurangi ukuran dua sisi masing-masing dari 12 kubus kurus. Ini juga akan berfungsi untuk garis besar 2d. Cukup terapkan bahan untuk mengubah warna dan voila!

dua garis besar yang berbeda

Pada gambar ini Anda bisa melihat detail struktur kubus ini. Ini semua bisa dibuat saat runtime tapi saya membuatnya dengan tangan dan menggunakannya sebagai cetakan.

detail

ow3n
sumber
0

Saya saat ini menghadapi masalah yang sama, dan solusi saya persis seperti yang disarankan DuckMaestro dan Raven Dreamer - Memiliki skrip yang membuat 4 objek anak saat runtime yang masing-masing mewakili sisi perbatasan dan melampirkan penyaji baris ke masing-masing.

Dalam kasus saya, saya perlu mengubah ukuran perbatasan terus-menerus agar tetap di sekitar objek saya (Jaring teks [yang menggunakan renderer jala] untuk bidang teks khusus) sehingga setiap pembaruan yang saya lakukan ini:


float width = Mathf.Max(renderer.bounds.size.x + paddingX * 2, minWidth);      
float x = renderer.bounds.center.x - width / 2;
float height = renderer.bounds.size.y + paddingY * 2;
float y = renderer.bounds.center.y - height / 2;

AlterBorder(0, new Vector3(x - thickness / 2, y, 0), new Vector3(x + width + thickness / 2, y, 0)); //Bottom edge going left to right
AlterBorder(1, new Vector3(x + width, y + thickness / 2, 0), new Vector3(x + width, y + height - thickness / 2, 0)); //Right edge going bottom to top
AlterBorder(2, new Vector3(x + width + thickness / 2, y + height, 0), new Vector3(x - thickness / 2, y + height, 0)); //Top edge going right to left
AlterBorder(3, new Vector3(x, y + height - thickness / 2, 0), new Vector3(x, y + thickness / 2, 0)); //Left edge going top to bottom

AlterBorder() cukup mengakses renderer baris yang sesuai (ditentukan oleh parameter pertama) dan atur awal dan akhirnya masing-masing ke vektor pertama dan kedua.

Perhatikan bahwa saya digunakan renderersebagai referensi saya untuk ukuran, tetapi jelas Anda dapat menggunakan persegi panjang apa saja, selama x, y adalah sudut kiri atas.

Dari apa yang saya tahu ini bekerja dengan sangat baik, tampak hebat dalam permainan karena saya dapat dengan mudah memindahkan objek berbatasan di sekitar semua sumbu 3 (Bahkan memutarnya, dan karena penyaji garis selalu menghadap kamera itu tidak terlihat aneh), dan tidak sulit diimplementasikan.

Roma
sumber