Saya mencari solusi untuk perilaku "Opsi Klik Kanan".
Pada dasarnya setiap dan setiap item dalam game, ketika diklik kanan, dapat menampilkan serangkaian opsi berdasarkan objek apa pun itu.
Contoh klik kanan untuk skenario yang berbeda :
Inventaris: Helm menunjukkan opsi (Lengkapi, Gunakan, Jatuhkan, Deskripsi)
Bank: Helm menunjukkan opsi (Ambil 1, Ambil X, Ambil Semua, Deskripsi)
Lantai: Helm menunjukkan opsi (Ambil, Jalan Di Sini, Deskripsi)
Jelas setiap opsi entah bagaimana menunjuk ke metode tertentu yang melakukan apa yang dikatakan. Ini adalah bagian dari masalah yang saya coba selidiki. Dengan begitu banyak opsi potensi untuk satu item, bagaimana kelas saya dirancang sedemikian rupa agar tidak menjadi sangat berantakan?
- Saya sudah berpikir tentang warisan tetapi itu bisa sangat panjang lebar dan rantai bisa sangat besar.
- Saya sudah berpikir tentang menggunakan antarmuka, tetapi ini mungkin akan membatasi saya sedikit karena saya tidak akan dapat memuat data item dari file Xml dan menempatkannya ke dalam kelas "Item" umum.
Saya mendasarkan hasil akhir yang saya inginkan pada permainan yang disebut Runescape. Setiap objek dapat diklik kanan dalam permainan dan tergantung pada apa itu, dan di mana itu (inventaris, lantai, bank dll) menampilkan serangkaian opsi yang tersedia untuk pemain untuk berinteraksi.
Bagaimana saya bisa mencapai ini? Pendekatan apa yang harus saya ambil untuk pertama-tama, memutuskan opsi mana yang HARUS ditampilkan dan setelah diklik, cara memanggil metode yang sesuai.
Saya menggunakan C # dan Unity3D, tetapi setiap contoh yang diberikan tidak harus terkait dengan salah satu dari mereka karena saya mencari pola yang bertentangan dengan kode aktual.
Setiap bantuan sangat dihargai dan jika saya belum jelas dalam pertanyaan saya atau hasil yang diinginkan, silakan kirim komentar dan saya akan cenderung ASAP.
Inilah yang saya coba sejauh ini:
- Saya sebenarnya telah berhasil mengimplementasikan kelas "Item" umum yang menampung semua nilai untuk berbagai jenis item (serangan ekstra, pertahanan ekstra, biaya dll ...). Variabel-variabel ini diisi oleh data dari file Xml.
- Saya telah berpikir tentang menempatkan setiap metode interaksi yang mungkin dalam kelas Item tapi saya pikir ini adalah bentuk yang berantakan dan buruk. Saya mungkin telah mengambil pendekatan yang salah untuk menerapkan sistem semacam ini dengan hanya menggunakan satu kelas dan tidak sub-klasifikasi ke item yang berbeda, tetapi itu satu-satunya cara saya bisa memuat data dari Xml dan menyimpannya di kelas.
- Alasan saya memilih untuk memuat semua item saya dari file Xml adalah karena permainan ini memiliki kemungkinan untuk lebih dari 40.000 item. Jika matematika saya benar, kelas untuk setiap item adalah banyak kelas.
sumber
Jawaban:
Seperti halnya segala sesuatu dalam pengembangan perangkat lunak, tidak ada solusi yang ideal. Hanya solusi yang ideal untuk Anda dan proyek Anda. Berikut beberapa yang bisa Anda gunakan.
Opsi 1: Model prosedural
The
kunousangmetode lama-sekolah.Semua item adalah tipe data sederhana-lama-bodoh tanpa metode apa pun tetapi banyak atribut publik yang mewakili semua properti yang dimiliki suatu item, termasuk beberapa boolean flags seperti
isEdible
,isEquipable
dll. Yang menentukan entri menu konteks apa yang tersedia untuk itu (mungkin Anda juga bisa lakukan tanpa flag-flag ini ketika Anda dapat menurunkannya dari nilai atribut lainnya). Memiliki beberapa metode sepertiEat
,Equip
dll. Di kelas pemain Anda yang mengambil item dan yang memiliki semua logika untuk memprosesnya sesuai dengan nilai atribut.Opsi 2: Model berorientasi objek
Ini lebih merupakan solusi OOP-oleh-the-book yang didasarkan pada warisan dan polimorfisme.
Memiliki kelas dasar
Item
dari mana barang-barang lain sukaEdibleItem
,EquipableItem
dll mewarisi. Kelas dasar harus memiliki metode publikGetContextMenuEntriesForBank
,GetContextMenuEntriesForFloor
dll. Yang mengembalikan daftarContextMenuEntry
. Setiap kelas pewarisan akan mengganti metode ini untuk mengembalikan entri menu konteks yang sesuai untuk jenis item ini. Itu juga bisa memanggil metode yang sama dari kelas dasar untuk mendapatkan beberapa entri default yang berlaku untuk semua jenis barang. ItuContextMenuEntry
akan menjadi kelas dengan metodePerform
yang kemudian memanggil metode yang relevan dari Item yang membuatnya (Anda bisa menggunakan delegasi untuk ini).Mengenai masalah Anda dengan menerapkan pola ini saat membaca data dari file XML: Pertama-tama periksa simpul XML untuk setiap item untuk menentukan jenis item, kemudian gunakan kode khusus untuk setiap jenis untuk membuat turunan dari sub-kelas yang sesuai.
Opsi 3: Model berbasis komponen
Pola ini menggunakan komposisi alih-alih warisan dan lebih dekat dengan cara kerja Unity lainnya. Bergantung pada bagaimana Anda menyusun game Anda, ada kemungkinan / bermanfaat untuk menggunakan sistem komponen Unity untuk ini ... atau tidak, jarak tempuh Anda mungkin berbeda-beda.
Setiap objek dari kelas
Item
akan memiliki daftar komponen sepertiEquipable
,Edible
,Sellable
,Drinkable
, dll Item dapat memiliki satu atau tidak masing-masing komponen (misalnya, helm yang terbuat dari cokelat akan baikEquipable
danEdible
, dan jika tidak plot-kritis item pencarian jugaSellable
). Logika pemrograman yang khusus untuk komponen diimplementasikan dalam komponen itu. Ketika pengguna mengklik kanan pada suatu item, komponen-komponen dari item itu diulang dan entri menu konteks ditambahkan untuk setiap komponen yang ada. Ketika pengguna memilih salah satu entri ini, komponen yang menambahkan entri itu memproses opsi.Anda dapat mewakili ini dalam file XML Anda dengan memiliki sub-node untuk setiap komponen. Contoh:
sumber
Jadi, Mike Hunt, pertanyaan Anda sangat menarik bagi saya, saya memutuskan untuk menerapkan solusi lengkap. Setelah tiga jam mencoba hal yang berbeda, saya berakhir dengan solusi selangkah demi selangkah ini:
(Harap dicatat, bahwa ini BUKAN kode yang sangat bagus, jadi saya akan menerima suntingan)
Membuat Panel Konten
(Panel ini akan menjadi wadah untuk tombol menu konteks kami)
UI Panel
anchor
ke kiri bawahwidth
ke 300 (sesuai keinginan)Vertical Layout Group
dan aturChild Alignment
ke tengah-atas,Child Force Expand
ke lebar (bukan tinggi)Content Size Fitter
dan setelVertical Fit
ke Ukuran Min(Pada titik ini Panel kami akan menyusut menjadi satu garis. Itu normal. Panel ini akan menerima tombol sebagai anak-anak, menyelaraskannya secara vertikal dan meregangkan ke ketinggian isi ringkasan)
Membuat Tombol Sampel
(Tombol ini akan dipakai dan disesuaikan untuk menampilkan item menu konteks)
anchor
ke kiri atasLayout Element
, aturMin Height
ke 30,Preferred Height
ke 30Membuat skrip ContextMenu.cs
(Skrip ini memiliki metode yang membuat dan menampilkan Menu Konteks)
ContentPanel
prefab ke slot yang sesuai, dan seret Kanvas itu sendiri ke slotCanvas
.Membuat skrip ItemController.cs
Cube
), tempatkan agar dapat dilihat oleh kamera dan lampirkan script ini padanya. Seret n-dropsampleButton
prefab ke slot yang sesuai.Sekarang, coba jalankan. Ketika Anda mengklik kanan objek, menu konteks akan muncul, diisi dengan daftar yang kami buat. Menekan tombol akan mencetak ke konsol beberapa teks, dan menu konteks akan dihancurkan.
Kemungkinan peningkatan:
Contoh proyek (Unity Personal 5.2.0, Plugin VisualStudio): https://drive.google.com/file/d/0B7iGjyVbWvFwUnRQRVVaOGdDc2M/view?usp=sharing
sumber