Unity dengan MVC: Cara Meningkatkan Pengembangan Game Anda

Diterbitkan: 2022-03-11

Pemrogram pemula biasanya mulai mempelajari perdagangan dengan program klasik Hello World . Dari sana, tugas yang lebih besar dan lebih besar pasti akan menyusul. Setiap tantangan baru membawa pulang pelajaran penting:

Semakin besar proyeknya, semakin besar spagetinya.

Segera, mudah untuk melihat bahwa dalam tim besar atau kecil, seseorang tidak dapat sembarangan melakukan apa yang diinginkannya. Kode harus dipertahankan dan dapat bertahan lama. Perusahaan tempat Anda bekerja tidak bisa hanya mencari informasi kontak Anda dan bertanya kepada Anda setiap kali mereka ingin memperbaiki atau meningkatkan basis kode (dan Anda juga tidak menginginkannya).

Inilah sebabnya mengapa pola desain perangkat lunak ada; mereka memaksakan aturan sederhana untuk mendikte keseluruhan struktur proyek perangkat lunak. Mereka membantu satu atau lebih pemrogram memisahkan bagian inti dari proyek besar dan mengaturnya dengan cara standar, menghilangkan kebingungan ketika beberapa bagian yang tidak dikenal dari basis kode ditemukan.

Aturan-aturan ini, jika diikuti oleh semua orang, memungkinkan kode lama untuk dipelihara dan dinavigasi dengan lebih baik, dan kode baru ditambahkan lebih cepat. Lebih sedikit waktu yang dihabiskan untuk merencanakan metodologi pembangunan. Karena masalah tidak datang dalam satu rasa, tidak ada pola desain peluru perak. Seseorang harus hati-hati mempertimbangkan titik kuat dan lemah dari setiap pola, dan menemukan yang paling cocok untuk tantangan yang dihadapi.

Dalam tutorial ini, saya akan menghubungkan pengalaman saya dengan platform pengembangan game Unity yang populer dan pola Model-View-Controller (MVC) untuk pengembangan game. Dalam tujuh tahun pengembangan saya, setelah bergulat dengan spageti pengembang game yang adil, saya telah mencapai struktur kode yang hebat dan kecepatan pengembangan menggunakan pola desain ini.

Saya akan mulai dengan menjelaskan sedikit arsitektur dasar Unity, pola Entity-Component. Kemudian saya akan melanjutkan untuk menjelaskan bagaimana MVC cocok di atasnya, dan menggunakan proyek tiruan kecil sebagai contoh.

Motivasi

Dalam literatur perangkat lunak, kita akan menemukan sejumlah besar pola desain. Meskipun mereka memiliki seperangkat aturan, pengembang biasanya akan melakukan sedikit pembengkokan aturan untuk lebih menyesuaikan pola dengan masalah spesifik mereka.

"Kebebasan pemrograman" ini adalah bukti bahwa kami belum menemukan metode tunggal yang pasti untuk merancang perangkat lunak. Jadi, artikel ini tidak dimaksudkan sebagai solusi akhir untuk masalah Anda, melainkan untuk menunjukkan manfaat dan kemungkinan dari dua pola terkenal: Entity-Component dan Model-View-Controller.

Pola Entitas-Komponen

Entity-Component (EC) adalah pola desain di mana pertama-tama kita mendefinisikan hierarki elemen yang membentuk aplikasi (Entitas), dan kemudian, kita mendefinisikan fitur dan data yang akan dikandung masing-masing (Komponen). Dalam istilah lebih "programmer", Entitas dapat menjadi objek dengan array 0 atau lebih Komponen. Mari kita gambarkan Entitas seperti ini:

 some-entity [component0, component1, ...]

Berikut adalah contoh sederhana dari pohon EC.

 - app [Application] - game [Game] - player [KeyboardInput, Renderer] - enemies - spider [SpiderAI, Renderer] - ogre [OgreAI, Renderer] - ui [UI] - hud [HUD, MouseInput, Renderer] - pause-menu [PauseMenu, MouseInput, Renderer] - victory-modal [VictoryModal, MouseInput, Renderer] - defeat-modal [DefeatModal, MouseInput, Renderer]

EC adalah pola yang baik untuk mengurangi masalah pewarisan berganda, di mana struktur kelas yang kompleks dapat menimbulkan masalah seperti masalah berlian di mana kelas D, mewarisi dua kelas, B dan C, dengan kelas dasar yang sama A, dapat menimbulkan konflik karena bagaimana B dan C memodifikasi fitur A secara berbeda.

GAMBAR: MASALAH DIAMOND

Masalah-masalah semacam ini dapat menjadi umum dalam pengembangan game di mana pewarisan sering digunakan secara luas.

Dengan memecah fitur dan penangan data menjadi Komponen yang lebih kecil, mereka dapat dilampirkan dan digunakan kembali di Entitas yang berbeda tanpa bergantung pada banyak pewarisan (yang, omong-omong, bahkan bukan fitur C# atau Javascript, bahasa utama yang digunakan oleh Unity ).

Dimana Entitas-Komponen Gagal

Menjadi satu tingkat di atas OOP, EC membantu mendefrag dan mengatur arsitektur kode Anda dengan lebih baik. Namun, dalam proyek besar, kami masih "terlalu bebas" dan kami dapat menemukan diri kami di "lautan fitur", mengalami kesulitan menemukan Entitas dan Komponen yang tepat, atau mencari tahu bagaimana mereka harus berinteraksi. Ada banyak cara untuk merakit Entitas dan Komponen untuk tugas tertentu.

GAMBAR: EC FITUR LAUT

Salah satu cara untuk menghindari kekacauan adalah dengan menerapkan beberapa pedoman tambahan di atas Entity-Component. Misalnya, salah satu cara saya berpikir tentang perangkat lunak adalah dengan membaginya menjadi tiga kategori berbeda:

  • Beberapa menangani data mentah, memungkinkan untuk dibuat, dibaca, diperbarui, dihapus atau dicari (yaitu, konsep CRUD).
  • Lainnya mengimplementasikan antarmuka untuk elemen lain untuk berinteraksi, mendeteksi peristiwa yang terkait dengan cakupannya dan memicu pemberitahuan saat terjadi.
  • Akhirnya, beberapa elemen bertanggung jawab untuk menerima pemberitahuan ini, membuat keputusan logika bisnis, dan memutuskan bagaimana data harus dimanipulasi.

Untungnya, kita sudah memiliki pola yang berperilaku persis seperti ini.

Pola Model-View-Controller (MVC)

Pola Model-View-Controller (MVC) membagi perangkat lunak menjadi tiga komponen utama: Models (Data CRUD), Views (Interface/Detection) dan Controllers (Keputusan/Tindakan). MVC cukup fleksibel untuk diimplementasikan bahkan di atas ECS atau OOP.

Pengembangan game dan UI memiliki alur kerja yang biasa menunggu input pengguna, atau kondisi pemicu lainnya, mengirimkan pemberitahuan tentang peristiwa tersebut di suatu tempat yang sesuai, memutuskan apa yang harus dilakukan sebagai tanggapan, dan memperbarui data yang sesuai. Tindakan ini dengan jelas menunjukkan kompatibilitas aplikasi ini dengan MVC.

Metodologi ini memperkenalkan lapisan abstraksi lain yang akan membantu perencanaan perangkat lunak, dan juga memungkinkan pemrogram baru untuk menavigasi bahkan dalam basis kode yang lebih besar. Dengan membagi proses berpikir menjadi data, antarmuka, dan keputusan, pengembang dapat mengurangi jumlah file sumber yang harus dicari untuk menambah atau memperbaiki fungsionalitas.

Unity dan EC

Pertama-tama mari kita lihat lebih dekat apa yang diberikan Unity kepada kita di depan.

Unity adalah platform pengembangan berbasis EC, di mana semua Entitas adalah instance dari GameObject dan fitur yang membuatnya menjadi “terlihat”, “dapat dipindahkan”, “dapat berinteraksi”, dan seterusnya, disediakan oleh kelas yang memperluas Component .

Panel Hierarki dan Panel Inspektur editor Unity menyediakan cara yang ampuh untuk merakit aplikasi Anda, melampirkan Komponen, mengonfigurasi status awalnya, dan mem-bootstrap game Anda dengan kode sumber yang jauh lebih sedikit daripada biasanya.

SCREENSHOT: HIERARCHY PANEL
Panel Hirarki dengan empat GameObjects di sebelah kanan

SCREENSHOT: PANEL INSPEKTOR
Panel Inspektur dengan komponen GameObject

Namun, seperti yang telah kita diskusikan, kita dapat menemukan masalah "terlalu banyak fitur" dan menemukan diri kita berada dalam hierarki raksasa, dengan fitur yang tersebar di mana-mana, membuat kehidupan pengembang jauh lebih sulit.

Berpikir dengan cara MVC, kita dapat, sebaliknya, mulai dengan membagi hal-hal menurut fungsinya, menyusun aplikasi kita seperti contoh di bawah ini:

SCREENSHOT: CONTOH STRUKTUR UNITY MVC

Mengadaptasi MVC ke Lingkungan Pengembangan Game

Sekarang, saya ingin memperkenalkan dua modifikasi kecil pada pola MVC generik, yang membantu menyesuaikannya dengan situasi unik yang saya temui saat membangun proyek Unity dengan MVC:

  1. Referensi kelas MVC dengan mudah tersebar di seluruh kode. - Di dalam Unity, pengembang biasanya harus menarik dan melepas instance agar dapat diakses, atau menjangkaunya melalui pernyataan pencarian yang rumit seperti GetComponent( ... ) . - Neraka referensi yang hilang akan terjadi jika Unity mogok atau beberapa bug membuat semua referensi yang diseret menghilang. - Ini membuatnya perlu memiliki objek referensi root tunggal, yang melaluinya semua instance dalam Aplikasi dapat dijangkau dan dipulihkan.
  2. Beberapa elemen merangkum fungsionalitas umum yang harus sangat dapat digunakan kembali, dan yang secara alami tidak termasuk dalam salah satu dari tiga kategori utama Model, View, atau Controller. Ini saya suka sebut saja Components . Mereka juga "Komponen" dalam pengertian Entitas-Komponen tetapi hanya bertindak sebagai pembantu dalam kerangka MVC. - Misalnya, Komponen Rotator , yang hanya memutar benda dengan kecepatan sudut tertentu dan tidak memberi tahu, menyimpan, atau memutuskan apa pun.

Untuk membantu meringankan dua masalah ini, saya membuat pola yang dimodifikasi yang saya sebut AMVCC , atau Application-Model-View-Controller-Component.

GAMBAR: DIAGRAM AMVCC

  • Aplikasi - Titik masuk tunggal ke aplikasi Anda dan wadah semua instans penting dan data terkait aplikasi.
  • MVC - Anda seharusnya sudah mengetahuinya sekarang. :)
  • Komponen - Skrip kecil dan lengkap yang dapat digunakan kembali.

Kedua modifikasi ini telah memenuhi kebutuhan saya untuk semua proyek tempat saya menggunakannya.

Contoh: 10 Pantulan

Sebagai contoh sederhana, mari kita lihat permainan kecil bernama 10 Bounces , di mana saya akan menggunakan elemen inti dari pola AMVCC.

Pengaturan gimnya sederhana: Ball dengan SphereCollider dan Rigidbody (yang akan mulai jatuh setelah "Mainkan"), Cube sebagai ground dan 5 skrip untuk membentuk AMVCC.

Hirarki

Sebelum membuat skrip, saya biasanya mulai dari hierarki dan membuat garis besar kelas dan aset saya. Selalu mengikuti gaya AMVCC baru ini.

SCREENSHOT: MEMBANGUN HIERARCI

Seperti yang dapat kita lihat, view GameObject berisi semua elemen visual dan juga elemen dengan skrip View lainnya. model dan controller GameObjects, untuk proyek kecil, biasanya hanya berisi skrip masing-masing. Untuk proyek yang lebih besar, mereka akan berisi GameObjects dengan skrip yang lebih spesifik.

Saat seseorang yang menavigasi proyek Anda ingin mengakses:

  • Data: Masuk ke application > model > ...
  • Logika/Alur Kerja: Buka application > controller > ...
  • Rendering/Antarmuka/Deteksi: Buka application > view > ...

Jika semua tim mengikuti aturan sederhana ini, proyek lama tidak akan menjadi masalah.

Perhatikan bahwa tidak ada wadah Component karena, seperti yang telah kita bahas, mereka lebih fleksibel dan dapat dilampirkan ke elemen yang berbeda di waktu luang pengembang.

membuat skrip

Catatan: Skrip yang ditampilkan di bawah ini adalah versi abstrak dari implementasi dunia nyata. Implementasi yang mendetail tidak akan banyak bermanfaat bagi pembaca. Namun, jika Anda ingin menjelajahi lebih lanjut, inilah tautan ke kerangka kerja MVC pribadi saya untuk Unity, Unity MVC. Anda akan menemukan kelas inti yang mengimplementasikan kerangka kerja struktural AMVCC yang diperlukan untuk sebagian besar aplikasi.

Mari kita lihat struktur skrip untuk 10 Bouncing .

Sebelum memulai, bagi mereka yang tidak terbiasa dengan alur kerja Unity, mari kita perjelas secara singkat bagaimana skrip dan GameObjects bekerja bersama. Dalam Unity, "Komponen," dalam pengertian Entity-Component, diwakili oleh kelas MonoBehaviour . Agar ada selama runtime, pengembang harus menarik dan melepaskan file sumbernya ke dalam GameObject (yang merupakan "Entitas" dari pola Entity-Component) atau menggunakan perintah AddComponent<YourMonobehaviour>() . Setelah ini, skrip akan dipakai dan siap digunakan selama eksekusi.

Untuk memulai, kita mendefinisikan kelas Aplikasi ("A" di AMVCC), yang akan menjadi kelas utama yang berisi referensi ke semua elemen game yang dipakai. Kami juga akan membuat kelas dasar pembantu yang disebut Element , yang memberi kami akses ke instance Aplikasi dan instance MVC turunannya.

Dengan mengingat hal ini, mari kita definisikan kelas Application ("A" di AMVCC), yang akan memiliki instance unik. Di dalamnya, tiga variabel, model , view , dan controller , akan memberi kita titik akses untuk semua instance MVC selama runtime. Variabel ini harus MonoBehaviour s dengan referensi public ke skrip yang diinginkan.

Kemudian, kita juga akan membuat kelas dasar pembantu yang disebut Element , yang memberi kita akses ke instance Application. Akses ini akan memungkinkan setiap kelas MVC untuk menjangkau satu sama lain.

Perhatikan bahwa kedua kelas memperluas MonoBehaviour . Mereka adalah "Komponen" yang akan dilampirkan ke "Entitas" GameObject.

 // BounceApplication.cs // Base class for all elements in this application. public class BounceElement : MonoBehaviour { // Gives access to the application and all instances. public BounceApplication app { get { return GameObject.FindObjectOfType<BounceApplication>(); }} } // 10 Bounces Entry Point. public class BounceApplication : MonoBehaviour { // Reference to the root instances of the MVC. public BounceModel model; public BounceView view; public BounceController controller; // Init things here void Start() { } }

Dari BounceElement kita dapat membuat kelas inti MVC. BounceModel , BounceView , dan BounceController biasanya bertindak sebagai wadah untuk instance yang lebih khusus, tetapi karena ini adalah contoh sederhana, hanya View yang akan memiliki struktur bersarang. Model dan Controller dapat dilakukan dalam satu script untuk masing-masing:

 // BounceModel.cs // Contains all data related to the app. public class BounceModel : BounceElement { // Data public int bounces; public int winCondition; }
 // BounceView .cs // Contains all views related to the app. public class BounceView : BounceElement { // Reference to the ball public BallView ball; }
 // BallView.cs // Describes the Ball view and its features. public class BallView : BounceElement { // Only this is necessary. Physics is doing the rest of work. // Callback called upon collision. void OnCollisionEnter() { app.controller.OnBallGroundHit(); } }
 // BounceController.cs // Controls the app workflow. public class BounceController : BounceElement { // Handles the ball hit event public void OnBallGroundHit() { app.model.bounces++; Debug.Log(“Bounce ”+app.model.bounce); if(app.model.bounces >= app.model.winCondition) { app.view.ball.enabled = false; app.view.ball.GetComponent<RigidBody>().isKinematic=true; // stops the ball OnGameComplete(); } } // Handles the win condition public void OnGameComplete() { Debug.Log(“Victory!!”); } }

Dengan semua skrip yang dibuat, kita dapat melanjutkan untuk melampirkan dan mengonfigurasinya.

Tata letak hierarki harus seperti ini:

 - application [BounceApplication] - model [BounceModel] - controller [BounceController] - view [BounceView] - ... - ball [BallView] - ...

Menggunakan BounceModel sebagai contoh, kita dapat melihat tampilannya di editor Unity:

SCREENSHOT: BounceModel DI INSPEKTOR
BounceModel dengan bidang bounces dan winCondition .

Dengan semua skrip disetel dan game berjalan, kita akan mendapatkan output ini di Panel Konsol .

SCREENSHOT: OUTPUT KONSOL

Notifikasi

Seperti yang ditunjukkan pada contoh di atas, saat bola menyentuh tanah, pandangannya mengeksekusi app.controller.OnBallGroundHit() yang merupakan metode. Tidaklah, dengan cara apapun, "salah" untuk melakukan itu untuk semua notifikasi dalam aplikasi. Namun, dalam pengalaman saya, saya telah mencapai hasil yang lebih baik menggunakan sistem notifikasi sederhana yang diterapkan di kelas Aplikasi AMVCC.

Untuk mengimplementasikannya, mari kita update layout BounceApplication menjadi:

 // BounceApplication.cs class BounceApplication { // Iterates all Controllers and delegates the notification data // This method can easily be found because every class is “BounceElement” and has an “app” // instance. public void Notify(string p_event_path, Object p_target, params object[] p_data) { BounceController[] controller_list = GetAllControllers(); foreach(BounceController c in controller_list) { c.OnNotification(p_event_path,p_target,p_data); } } // Fetches all scene Controllers. public BounceController[] GetAllControllers() { /* ... */ } }

Selanjutnya, kita memerlukan skrip baru di mana semua pengembang akan menambahkan nama acara notifikasi, yang dapat dikirim selama eksekusi.

 // BounceNotifications.cs // This class will give static access to the events strings. class BounceNotification { static public string BallHitGround = “ball.hit.ground”; static public string GameComplete = “game.complete”; /* ... */ static public string GameStart = “game.start”; static public string SceneLoad = “scene.load”; /* ... */ }

Sangat mudah untuk melihat bahwa, dengan cara ini, keterbacaan kode ditingkatkan karena pengembang tidak perlu mencari di seluruh kode sumber untuk metode controller.OnSomethingComplexName untuk memahami tindakan seperti apa yang dapat terjadi selama eksekusi. Dengan hanya memeriksa satu file, dimungkinkan untuk memahami perilaku aplikasi secara keseluruhan.

Sekarang, kita hanya perlu mengadaptasi BallView dan BounceController untuk menangani sistem baru ini.

 // BallView.cs // Describes the Ball view and its features. public class BallView : BounceElement { // Only this is necessary. Physics is doing the rest of work. // Callback called upon collision. void OnCollisionEnter() { app.Notify(BounceNotification.BallHitGround,this); } }
 // BounceController.cs // Controls the app workflow. public class BounceController : BounceElement { // Handles the ball hit event public void OnNotification(string p_event_path,Object p_target,params object[] p_data) { switch(p_event_path) { case BounceNotification.BallHitGround: app.model.bounces++; Debug.Log(“Bounce ”+app.model.bounce); if(app.model.bounces >= app.model.winCondition) { app.view.ball.enabled = false; app.view.ball.GetComponent<RigidBody>().isKinematic=true; // stops the ball // Notify itself and other controllers possibly interested in the event app.Notify(BounceNotification.GameComplete,this); } break; case BounceNotification.GameComplete: Debug.Log(“Victory!!”); break; } } }

Proyek yang lebih besar akan memiliki banyak notifikasi. Jadi, untuk menghindari struktur switch-case yang besar, disarankan untuk membuat pengontrol yang berbeda dan membuatnya menangani cakupan notifikasi yang berbeda.

AMVCC di Dunia Nyata

Contoh ini telah menunjukkan kasus penggunaan sederhana untuk pola AMVCC. Menyesuaikan cara berpikir Anda dalam kaitannya dengan tiga elemen MVC, dan belajar memvisualisasikan entitas sebagai hierarki yang teratur, adalah keterampilan yang harus dipoles.

Dalam proyek yang lebih besar, pengembang akan dihadapkan dengan skenario yang lebih kompleks dan keraguan tentang apakah sesuatu harus berupa View atau Controller, atau jika kelas tertentu harus dipisahkan secara lebih menyeluruh dalam yang lebih kecil.

Aturan Praktis (oleh Eduardo)

Tidak ada "Panduan Universal untuk penyortiran MVC" di mana pun. Tetapi ada beberapa aturan sederhana yang biasanya saya ikuti untuk membantu saya menentukan apakah akan mendefinisikan sesuatu sebagai Model, View, atau Controller dan juga kapan harus membagi kelas tertentu menjadi bagian-bagian yang lebih kecil.

Biasanya, ini terjadi secara organik ketika saya memikirkan arsitektur perangkat lunak atau selama pembuatan skrip.

Penyortiran Kelas

model

  • Tahan data dan status inti aplikasi, seperti health pemain atau ammo senjata .
  • Buat serial, deserialize, dan/atau konversi antar tipe.
  • Muat/simpan data (secara lokal atau di web).
  • Beritahu Pengendali kemajuan operasi.
  • Simpan Status Game untuk Mesin Status Hingga Game.
  • Jangan pernah mengakses Tampilan.

Tampilan

  • Dapat memperoleh data dari Model untuk merepresentasikan status game terkini kepada pengguna. Misalnya, metode View player.Run() secara internal dapat menggunakan model.speed untuk mewujudkan kemampuan pemain.
  • Seharusnya tidak pernah mengubah Model.
  • Mengimplementasikan fungsionalitas kelasnya dengan ketat. Sebagai contoh:
    • PlayerView tidak boleh mengimplementasikan deteksi input atau memodifikasi Status Game.
    • Tampilan harus bertindak sebagai kotak hitam yang memiliki antarmuka dan memberi tahu peristiwa penting.
    • Tidak menyimpan data inti (seperti kecepatan, kesehatan, nyawa,…).

Pengendali

  • Jangan simpan data inti.
  • Terkadang dapat memfilter notifikasi dari Tampilan yang tidak diinginkan.
  • Perbarui dan gunakan data Model.
  • Mengelola alur kerja adegan Unity.

Hirarki Kelas

Dalam hal ini, tidak banyak langkah yang saya ikuti. Biasanya, saya merasa bahwa beberapa kelas perlu dipecah ketika variabel mulai menunjukkan terlalu banyak "awalan", atau terlalu banyak varian dari elemen yang sama mulai muncul (seperti kelas Player di MMO atau jenis Gun di FPS).

Misalnya, Model tunggal yang berisi data Player akan memiliki banyak playerDataA, playerDataB, playerDataA, playerDataB,... atau Controller yang menangani pemberitahuan Player akan memiliki OnPlayerDidA,OnPlayerDidB,... . Kami ingin mengurangi ukuran skrip dan menyingkirkan awalan player dan OnPlayer .

Biarkan saya mendemonstrasikan menggunakan kelas Model karena lebih mudah dipahami menggunakan data saja.

Selama pemrograman, saya biasanya mulai dengan satu kelas Model yang menyimpan semua data untuk game.

 // Model.cs class Model { public float playerHealth; public int playerLives; public GameObject playerGunPrefabA; public int playerGunAmmoA; public GameObject playerGunPrefabB; public int playerGunAmmoB; // Ops Gun[CDE ...] will appear... /* ... */ public float gameSpeed; public int gameLevel; }

Sangat mudah untuk melihat bahwa semakin kompleks permainan, semakin banyak variabel yang akan didapat. Dengan kompleksitas yang cukup, kita bisa berakhir dengan kelas raksasa yang berisi variabel model.playerABCDFoo . Elemen bersarang akan menyederhanakan penyelesaian kode dan juga memberikan ruang untuk beralih di antara variasi data.

 // Model.cs class Model { public PlayerModel player; // Container of the Player data. public GameModel game; // Container of the Game data. }
 // GameModel.cs class GameModel { public float speed; // Game running speed (influencing the difficulty) public int level; // Current game level/stage loaded }
 // PlayerModel.cs class PlayerModel { public float health; // Player health from 0.0 to 1.0. public int lives; // Player “retry” count after he dies. public GunModel[] guns; // Now a Player can have an array of guns to switch ingame. }
 // GunModel.cs class GunModel { public GunType type; // Enumeration of Gun types. public GameObject prefab; // Template of the 3D Asset of the weapon. public int ammo; // Current number of bullets public int clips; // Number of reloads possible }

Dengan konfigurasi kelas ini, pengembang dapat secara intuitif menavigasi dalam kode sumber satu konsep pada satu waktu. Mari kita asumsikan permainan penembak orang pertama, di mana senjata dan konfigurasinya bisa sangat banyak. Fakta bahwa GunModel terkandung dalam sebuah kelas memungkinkan pembuatan daftar Prefabs (GameObject yang telah dikonfigurasi sebelumnya untuk dengan cepat diduplikasi dan digunakan kembali dalam game) untuk setiap kategori dan disimpan untuk digunakan nanti.

Sebaliknya, jika semua informasi senjata disimpan bersama dalam satu kelas GunModel , dalam variabel seperti gun0Ammo , gun1Ammo , gun0Clips , dan seterusnya, maka pengguna, ketika dihadapkan dengan kebutuhan untuk menyimpan data Gun , perlu menyimpan seluruh Model termasuk data Player yang tidak diinginkan. Dalam hal ini, jelas bahwa kelas GunModel baru akan lebih baik.

GAMBAR: HIERARKI KELAS
Memperbaiki hierarki kelas.

Seperti segala sesuatu, ada dua sisi mata uang. Terkadang seseorang dapat secara tidak perlu membagi-bagi dan meningkatkan kompleksitas kode. Hanya pengalaman yang cukup mengasah keterampilan Anda untuk menemukan penyortiran MVC terbaik untuk proyek Anda.

Pengembang game baru Kemampuan Khusus tidak terkunci: Game Unity dengan pola MVC.
Menciak

Kesimpulan

Ada banyak sekali pola perangkat lunak di luar sana. Dalam posting ini, saya mencoba menunjukkan salah satu yang paling membantu saya dalam proyek-proyek sebelumnya. Pengembang harus selalu menyerap pengetahuan baru tetapi juga selalu mempertanyakannya. Saya harap tutorial ini membantu Anda mempelajari sesuatu yang baru, dan pada saat yang sama, berfungsi sebagai batu loncatan saat Anda mengembangkan gaya Anda sendiri.

Juga, saya sangat mendorong Anda untuk meneliti pola lain dan menemukan yang paling cocok untuk Anda. Satu titik awal yang baik adalah artikel Wikipedia ini, dengan daftar pola dan karakteristiknya yang luar biasa.

Jika Anda menyukai pola AMVCC dan ingin mengujinya, jangan lupa untuk mencoba perpustakaan saya, Unity MVC , yang berisi semua kelas inti yang diperlukan untuk memulai aplikasi AMVCC.


Bacaan Lebih Lanjut di Blog Teknik Toptal:

  • Pengembangan Unity AI: Tutorial Mesin kondisi-terbatas