However, does it make sense for a ball simulation to make decisions based on what it actually hits? That sounds more like game logic. The only job it has to do is physics integration and reacting whenever the ball hits something.
If we go back to the ball example, we’ve moved the simple physics simulation into a C# class that we call BallSimulation. With this method you want to split up the logic by type of responsibility. On the other hand, if you use regular C# classes, then the editor does not understand the objects, and cannot display them natively in the Inspector, and so on.
#STARCRAFT 2 PROJECT HAVEN CLASSES CODE#
And, regular C# code can be shared with native. Regular C# classes have better language facilities than Unity’s own objects for breaking down code into small, composable chunks. Moving MonoBehaviors to regular C# classes is another method to look at, but what are the benefits of this? One way of doing that is using ScriptableObjects, and there are already some great resources out there on this method. I think that for many games, it’s worthwhile to get as much code as possible out of MonoBehaviors. The general game logic, input handling, physics simulation and presentation could reside within MonoBehaviors, ScriptableObjects or raw C# classes.įor exposing parameters in the Inspector, MonoBehaviors or ScriptableObjects can be used.Įngine event handlers, and the management of a GameObject’s lifetime, need to reside within MonoBehaviors. Here are ways to create those smaller parts: There are a number of different types of responsibilities in these classes–game logic, input handling, physics simulations, presentations and more. There's an opportunity here to break things up into smaller parts. In large code bases it is rare to allow entities to delete themselves the tendency is instead to have owners delete things that they own. That is where the trigger logic deletes its own GameObject. The homemade physics simulation is not just the movement in FixedUpdate() it also encompasses the reaction when the ball hits a wall.ĭeep within the OnTriggerEnter() callback is a Destroy() operation. As soon as the ball starts moving, the information about initial velocity is lost. We are reusing the same variable for two slightly different purposes. It doesn’t look like much, but on closer inspection, we see that the ball has a velocity that is used both by the designer to set the initial velocity vector of the ball, and by the homemade physics simulation to keep track of what the current velocity of the ball is. Let’s look at a simple example as shown in the image above. It’s a principle that you can apply to a code base of any size. If applied correctly you should be able to give short answers to the questions, “what does a particular class do?” as well as “what does it not do?” This makes it easy for every developer on your team to understand what the individual classes do. Let’s see how we can split them up by working from what’s called the Single Responsibility Principle, which stipulates that each class should handle one single thing. If this was a game in actual development, you would see the individual MonoBehaviors grow larger and larger.