Mengelola keadaan dan acara antar komponen di GameObject
Tautan ke proyekSeperti 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 gambarMenciptakan 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