4 ms·
Instead of having your game sub-systems and components reference each other in a scene, you'd better off designing your game architecture in a data-oriented way
by Audiophilip 6y ago
Instead of having your game sub-systems and components reference each other in a scene, you'd better off designing your game architecture in a data-oriented way.
Try organizing your code around the data your components have to work with and let your code react to changes to that data. Using Scriptable-objects is a great way to facilitate this model, because with them your game components will reference data assets instead of other components, reducing dependencies, which gets harder and harder to manage as the complexity of your application grows.
I can really recommend watching Ryan Hipple's presentation titled "Game Architecture with Scriptable Objects". [0]
At our studio we've built a framework based on these ideas for a high-complexity game project and we're very happy with it so far. We have a clean and well-performing codebase that's easy to maintain and test, because no sub-system has any hard dependency on any other sub-system.
[0] https://www.youtube.com/watch?v=raQ3iHhE_Kk https://www.youtube.com/watch?v=raQ3iHhE_Kk
- mattlondon 6y agoThanks (and to the other comment who suggested the same talk). This was useful. The tl;dr for anyone who can't spend an hour watching (why are so many Unity things done as videos?!?! so infuriating!) is that you use "Scriptable Objects" (new to me - this is a first-class thing in Unity) to store common state and so break statically defined dependencies between Game Objects by having them share the Scriptable Object rather than reference each other. So you might have a Scriptable Object that contains the player's score/coins picked-up/zombies killed etc. On its own this is conceptually basically just a number/several values/etc wrapped in a small singleton class. You then reference that Scriptable Object in your player game object/script that will mutate that value. Anything else that needs to know the score/coins picked-up/zombies killed (e.g. UI code) references the same Scriptable Object. So now two separate parts of the game share the state without being statically bound to each other (they are only bound to the Scriptable Object). Plug in as many or as few new components all using the same state stored in the same Scriptable Object and nothing else needs to change as they only share the Scriptable Object. No references to other game objects required. You can do the same for events - create a Scriptable Object for an event (e.g. PlayerHurt or PlayerShoot etc). Since Scriptable Objects can contain code like any other class, you can have GameObjects register their interest in this shared singleton event by calling "PlayerHurt.RegisterListener(this)" etc, and then have another GameObject trigger/raise/activate the event ScriptableObject ("PlayerHurt.Trigger()" etc). Neither side know about each other, so you can plug in as many or as few listeners as you want. The talk uses some extra cleverness to use a UnityEvent to allow for a function call in reaction to the event being triggered - this means a lot can be done directly in the unity editor, but that seems separate from the main secret-sauce of the scriptable object as the mechanism for shared state. Site here that basically repeats the video nearly verbatim: https://unity.com/how-to/architect-game-code-scriptable-objects https://unity.com/how-to/architect-game-code-scriptable-obje... Cheers!