Game architecture with ScriptableObjects | Open Projects Devlog

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this second devlog we're going to share how we use scriptable objects to design the game architecture of the first unity open project open projects are small open source games where the creator community is free to collaborate and contribute actively to the entire game development journey you can make a contribution to them according to your expertise or learn something new for this first project titled chop chop we went with a classic game genre the action adventure you can find the link to the github project and all the other relevant links to learn more and get involved in the video description below we are making the game using unity 2019.4 lts which will guarantee us the best stability during development but since we wanted to make the contents of this devlog series available to you in the latest unity version we upgraded the project to work on unity 2020.2 the latest version available when recording this devlog you can find this 2020.2 version of the project on a git branch of the original repository called devlog 2 scriptable objects we conceived open projects with the goal of exposing valuable development patterns and techniques and to share useful tools one of our goals is to create a game architecture that is flexible modular and extensible when developing a game it's very common to have multiple game objects or scenes that need to share information or states with each other it's handy and easy to create hard-coded connections between these entities like referencing objects by string or running a search in the scene for a specific type of component but as soon as the project grows rigid connections can lead to serious scalability problems and introduce unexpected errors that can be hard to track down a popular solution is the singleton pattern this programming pattern uses a single globally accessible instance of a class available at all times this is useful to make global managers that hold variables and functions that are globally accessible achieve a persistent state across multiple scenes and are fast to implement with a smaller project this approach can be useful the problems come with larger projects when we're referencing the instance of a singleton class from another script we're creating a dependency between these two classes let's assume we want to test the functionality provided by a certain prefab and we drag and drop it into an empty scene if the prefab contains code that calls and runs something inside a singleton class we also need the singleton game object in the new scene and if the singleton class has other dependencies we're basically recreating the full game logic to test an isolated function one system can exist without the other there are other issues with singletons that we won't go into right now we encourage you to independently look into the singleton pattern to understand the pros and cons of it for our case we went with quite a different approach which relies on scriptable objects used in a specific way before we dive into the specifics let's see what scriptable objects are and how they differ from classic mono behaviors model behaviors commonly referred to as just scripts are components that attach to game objects changes made to their values are reset when you exit play mode scriptable objects on the other hand are assets just like a material or a 3d model and are not components they don't follow the mono behavior life cycle and don't depend on the application's play state therefore we can say that scriptable objects are data containers that can hold values that also exist outside of play mode plus since they are assets the data we store inside them is globally accessible and scene independent if you want to dive more into the basics for scriptable objects you can find links to other dedicated videos in the description below our project indeed uses them as data containers for many features like to store dialog lines sound presets and inventory items you can find them in the assets folder under scriptable objects if you select a dialog line scriptable object you can see how it represents a fragment of a conversation between characters easy to be modified by a designer thanks to all the inspector exposed fields like a databank ready to be accessed and available to all scripts data storage is not the only use case for scriptable objects though for instance they can be a powerful tool to create layers on top of existing unity features to expose and reuse common functionality and bridge systems an example of this is our input reader this scriptable object is not a simple data container but an object capable of listening to the inputs received from the player invoking the relevant unity actions you could say it's a centralized event relayer for example it implements a function called onmove which listens to the move input provided by unity's input system we support both keyboard and gamepad and chop chop and each time unity reads the value of any of these physical devices the onmove function of the scriptable object is executed then this function invokes a unity action so that all the objects subscribed to it will in return execute their callbacks receiving input messages and propagating them from the input reader scriptable object allows us to reuse this logic across the project easily from here an object like the player script can reference the input reader scriptable object to tap into its unity actions and implement a specialized response this solution also improves modularization and project maintainability the input reader doesn't need to know in advance who uses it and accesses it since it lives in an isolated layer and represents a single entry point this means there's only one place to modify if we want to add or remove inputs and the way different objects consume input is consistent and unified almost like a singleton but without the cons let's take scriptable objects a step further and see how we use them to create a flexible event system in chop chop the idea is again to take advantage of the independent nature of scriptable objects usually when we communicate directly through events and delegates we reference the class that owns the data structure and subscribe to start listening for messages this approach creates in-scene dependencies between the objects involved since the event subscribers need to reference the senders to work we solve this using the scriptable objects as an intermediate point of communication we call these scriptable objects channels since like in radio they represent channels to broadcast events on and listen to them creating a connection between two or more communicating parts we have several types of channel scriptable objects in the project for different uses in general the number and types of parameters that travel via the unity action contained in them to find how much a channel type is generic and reusable starting simple we implemented a very generic type called void event channel so which can propagate events with no data attached to them for instance we use this to provide an event channel to close the game if any object races the event on that channel the game shuts down but let's see some more interesting examples from our game we modularize the audio system in the game thanks to a scriptable object class we call audio cue event channel so the unity action contained in it requests three parameters two scriptable object references and a vector3 the two scriptable objects are just data they reference the audio clips we want to play and some playback settings the vector 3 informs the message receiver where we want to play the audio in the 3d space with this structure in place we created two of these scriptable objects one where we propagate sound effects requests and the other for music requests creating different channels helps to organize and keep features logically ordered and subdivided our audio manager script then references both these scriptable object channels and subscribes to their unity actions now each script that wants to play audio can reference these channels too and perform a request by calling the scriptable object's raise event method the audio manager will listen to this request and activate one or more audio sources from its pool it's important to note that with this architecture the audio manager and the game objects that request the sounds can live in different scenes and in fact they do this allows us to play sounds across scenes even when we load a new one in the demo assets we provide look for a scene called audio examples to find different examples of looping one shot and composite sounds using the system another feature we built on top of a scriptable object channel is the loading system the logic is very similar to the audio system and allows by referencing the right scriptable object channel to request a scene change at any time from anywhere in this case the class we use to create scriptable objects is named load event channel so and contains a unity action that accepts an array of game scene so and a boolean value the game scene so is a simple scriptable object asset that stores information on the scene we want to load the boolean value tells us if during the loading phase we want to show a loading screen in our scenes we can now place a game object with a location exit script attached that calls the scriptable object's raise event method when the player triggers the collider this trigger zone is just one of the many possibilities we can implement to request the scene switch as a general note we designed the location loader manager to load all the scenes additively on top of a scene called initialization this separation allows us to use the initialization scene as a container for scripts with functions useful to all scenes like the same location loader or audio manager and then taking advantage of the flexibility of scriptable objects have these communicate with gameplay scenes if an event is invoked without active subscribers we get a null reference exception for this reason in all our channel scripts we check for null before raising the event if there aren't listeners a notification appears in the console thanks to your contributions the project is becoming richer in features and content every day for the team to stay productive it's important to keep everything organized and easy to access especially with scriptable objects used as data containers that reference each other it can be easy for things to get messy one of our next goals is to create custom inspectors to author scriptable objects in a comfortable way and sometimes custom editor windows gather them in one place this aims to reduce the annoying back and forth actions necessary to set up the values stored in different assets you can find an example of a custom inspector in the game scene so editor script we made this enhancement to avoid inserting the scene's name manually this action is error prone and if we update the scenes we may break references used in the scriptable objects now it's possible to choose the scene's name from a list containing the real scene references we hope that after watching this video you'll get a good idea of the advantages that scriptable objects can bring besides being data containers we'd also like to invite you to participate in the development of this open project and maybe to help us improve these scriptable objects workflows feel free to download the project and experiment with it propose new features and reuse parts of it inside your own games keep yourself updated on the first open project by following the roadmap the daily changes in the github repository and the bi-weekly live streams the project will keep upgrading and changing during development on the main branch but remember that you can always find this 2020.2 version in a branch in the repository called devlog2 scriptableobjects we can't wait to see your feedback and contributions thanks for watching
Info
Channel: Unity
Views: 103,986
Rating: undefined out of 5
Keywords: Unity3d, Unity, Game Development, Game Dev, Game Engine, Open Projects, open source, Chop Chop, ScriptableObjects, scriptable objects, scriptable object, singleton, singleton unity, game architecture, game data, c#, better data in unity, how to scriptable objects
Id: WLDgtRNK2VE
Channel Id: undefined
Length: 12min 5sec (725 seconds)
Published: Sat Dec 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.