Mengelola keadaan dan acara antar komponen di GameObject

Mengelola keadaan dan acara antar komponen di GameObject


Tautan ke proyek

Seperti semua orang tahu, kurang lebih akrab dengan platform Unity, setiap objek game GameObject terdiri dari komponen (built-in atau custom, yang biasanya disebut "script"). Komponen mewarisi dari kelas dasar MonoBehavior .



Dan biasanya, baik atau sering, tautan langsung dibuat untuk mengikat komponen.



Yaitu dalam satu komponen, untuk mendapatkan data dari komponen lain, kami mendapatkan yang terakhir menggunakan metode GetComponent <...> () , misalnya seperti ini:



Dalam contoh ini, referensi ke komponen tipe SomeComponent akan ditempatkan dalam variabel someComponent .

Dengan pendekatan "penggabungan ketat" ini, terutama ketika ada sejumlah besar komponen, cukup mudah untuk menjadi bingung dan mempertahankan integritas koneksi semacam itu. Misalnya, jika nama properti atau metode dalam satu komponen berubah, maka Anda harus memperbaikinya di semua komponen yang menggunakan ini. Dan ini adalah pendarahan.

Di bawah terpotong banyak gambar

Menciptakan solusi berdasarkan "keterhubungan kuat" komponen


Kami akan membuat proyek kosong untuk mereproduksi situasi yang biasa ketika kami memiliki komponen tertentu dan masing-masingnya merujuk satu sama lain, untuk menerima data atau untuk mengontrol.



Saya menambahkan dua skrip, FirstComponent dan SecondComponent , yang akan digunakan sebagai komponen dalam objek game:



Sekarang saya akan mendefinisikan struktur sederhana untuk masing-masing komponen yang diperlukan untuk percobaan.





Sekarang bayangkan sebuah situasi di mana kita perlu mendapatkan nilai-nilai bidang state1 dari komponen FirstComponent dan memanggil metode ChangeState (...) di komponen SecondComponent . Untuk melakukan ini, Anda perlu mendapatkan tautan ke komponen dan meminta data yang diperlukan di komponen SecondComponent :



Setelah kami memulai permainan di konsol, akan terlihat bahwa kami menerima data dari FisrtComponent dari SecondComponent dan mengubah status pertama



Sekarang, dengan cara yang persis sama, kita bisa mendapatkan data dan dalam arah yang berlawanan dari komponen FirstComponent untuk mendapatkan data komponen SecondComponent .



Setelah memulai permainan, juga akan terlihat bahwa kami menerima data dan dapat mengontrol komponen SecondComponent dari FirstComponent .



Ini adalah contoh yang cukup sederhana, dan untuk memahami masalah seperti apa yang ingin saya uraikan, akan sangat perlu menyulitkan struktur dan hubungan semua komponen, tetapi artinya jelas. Sekarang koneksi antar komponen adalah sebagai berikut:





Memperluas bahkan satu objek game dengan komponen baru, jika mereka perlu berinteraksi dengan yang sudah ada, akan agak rutin. Dan terutama jika, misalnya, nama bidang state1 di komponen FirstComponent berubah, misalnya, menjadi state_1 dan Anda harus mengubah nama tempat itu digunakan di semua komponen. Atau ketika komponen memiliki terlalu banyak bidang, maka itu menjadi sangat sulit untuk dinavigasi.

Menciptakan solusi berdasarkan "Keadaan umum" antar komponen


Sekarang bayangkan bahwa kita tidak perlu mendapatkan tautan ke setiap komponen yang diminati dan memperoleh data darinya, tetapi akan ada objek tertentu yang berisi status dan data semua komponen dalam objek game. Dalam diagram, akan terlihat seperti ini:



Keadaan umum atau objek Keadaan umum (SharedState) juga merupakan komponen yang akan memainkan peran komponen layanan dan menyimpan status semua komponen objek game.

Saya akan membuat komponen baru dan beri nama SharedState:



Dan saya akan menentukan kode untuk komponen universal ini. Ini akan menyimpan kamus tertutup dan pengindeks untuk pekerjaan yang lebih nyaman dengan kamus komponen, juga akan enkapsulasi dan tidak akan bekerja secara langsung dengan kamus dari komponen lain.



Sekarang komponen ini perlu ditempatkan pada objek gim agar komponen lain dapat mengaksesnya:



Selanjutnya, Anda perlu membuat beberapa perubahan pada komponen FirstComponent dan SecondComponent sehingga mereka menggunakan komponen SharedState untuk menyimpan status atau data mereka:





Seperti yang dapat Anda lihat dari kode komponen, kami tidak lagi menyimpan bidang, melainkan kami menggunakan status umum dan memiliki akses ke datanya menggunakan kunci "state1" atau "counter". Sekarang data ini tidak terikat pada komponen apa pun, dan jika komponen ketiga muncul, maka memiliki akses ke SharedState ia akan dapat mengakses semua data ini.

Sekarang, untuk mendemonstrasikan operasi skema ini, Anda perlu mengubah metode Pembaruan di kedua komponen. Dalam FisrtComponent :



Dan dalam komponen SecondComponent :



Sekarang komponen tidak tahu asal dari nilai-nilai ini, yaitu, sebelum mereka beralih ke beberapa komponen tertentu untuk mendapatkannya, dan sekarang mereka hanya disimpan di ruang bersama dan setiap komponen memiliki akses ke sana.

Setelah memulai permainan, Anda dapat melihat bahwa komponen mendapatkan nilai yang diinginkan:



Sekarang kita tahu cara kerjanya, kita dapat memperoleh infrastruktur dasar untuk mengakses keadaan umum di kelas dasar, agar tidak melakukan semuanya di setiap komponen secara terpisah:



Dan saya akan membuatnya abstrak, agar tidak secara tidak sengaja membuat contohnya ... Dan juga disarankan untuk menambahkan atribut yang menunjukkan bahwa komponen dasar ini memerlukan komponen SharedState :



Sekarang Anda perlu mengubah komponen FirstComponent dan SecondComponent sehingga mereka mewarisi dari SharedStateComponent dan menghapus semua yang tidak perlu:





Ok Bagaimana dengan metode menelepon? Diusulkan untuk melakukan ini juga tidak secara langsung, tetapi melalui pola Penerbit-Pelanggan. Disederhanakan.

Untuk mengimplementasikan ini, Anda perlu menambahkan komponen umum lainnya, mirip dengan komponen yang berisi data, kecuali bahwa komponen ini hanya akan berisi langganan dan akan disebut SharedEvents :



Prinsipnya adalah sebagai berikut. Komponen yang ingin memanggil beberapa metode pada komponen lain tidak akan melakukan ini secara langsung, tetapi dengan memanggil suatu peristiwa, hanya dengan nama, saat kita mendapatkan data dari keadaan umum.

Setiap komponen berlangganan beberapa acara yang siap dilacak. Dan jika dia menangkap kejadian ini, dia mengeksekusi handler, yang didefinisikan dalam komponen itu sendiri.
Buat komponen SharedEvents :



Dan kami akan mendefinisikan struktur yang diperlukan untuk mengelola langganan dan publikasi.



Untuk pertukaran data antara langganan, publikasi, kelas dasar didefinisikan, yang spesifik akan ditentukan untuk penulis setiap acara secara independen, maka beberapa contoh akan didefinisikan:



Sekarang Anda perlu menambahkan komponen baru ke objek game:



dan perluas sedikit kelas dasar SharedStateComponent dan tambahkan persyaratan bahwa objek tersebut berisi SharedEvents



Seperti halnya objek keadaan umum, objek berlangganan umum harus diperoleh dari objek game:





Sekarang kami mendefinisikan langganan acara, yang akan kami proses di FisrtComponent dan kelas untuk mentransfer data melalui jenis acara ini, dan juga mengubah SecondComponent sehingga acara untuk langganan ini dipublikasikan:





Sekarang kami telah berlangganan ke acara apa pun yang disebut "Writeomedata" di komponen FirstComponent dan cukup mencetak pesan ke konsol ketika itu terjadi. Dan itu muncul dalam contoh ini dengan meminta publikasi suatu peristiwa dengan nama "Writeomedata" dalam komponen SecondComponent dan mengirimkan beberapa informasi yang dapat digunakan dalam komponen yang menangkap peristiwa dengan nama itu.

Setelah memulai permainan dalam 5 detik, kita akan melihat hasil pemrosesan acara di FirstComponent :



Ringkasan


Sekarang, jika Anda perlu memperluas komponen objek game ini, yang juga akan menggunakan keadaan umum dan peristiwa umum, Anda perlu menambahkan kelas dan cukup mewarisi dari SharedStateComponent :



Kelanjutan topik

Source: https://habr.com/ru/post/id438554/


All Articles