Technologies
2021-07-12
3 min. read

unity

Decoupling direct calls from Unity classes

Decoupling direct calls from Unity classes

contest-blog-list-mobile

Contents

Background

When I was working on unity games embedded in React Native app, I saw a lot of potential for combining hybrid apps with unity. This app help users to develop the skills they need to achieve their individual goals.

So we bring ours technical experience in another area to unity games. The project is a Greenfield, so we start to develop games from scratch. 

A lot of calls between classes

A few weeks later, when games are more and more complicated. The more things happen.

One of the everyday tasks is to change the color smoothly, run particle system, spawn new objects, recalculating the score.  So the problem was direct calls between classes. How to eliminate it?

Answer (and TL;DR)

The answer is Events.

Just attach a script with EventBus. We decided to use github.com/ThomasKomarnicki/GameEventBus

using GameEventBus;

public class GameController : MonoBehaviour {
  public static EventBus Bus = new EventBus();
}
 
Now each class can send an event, and any interested class can subscribe to itself to interact with it. 
 
public class Hud : MonoBehaviour {
  void Start() {
    GameController.Bus.Subscribe(OnBulletCollision);
  }

  void OnBulletCollision(BulletCollisionEvent event) {
    Debug.Log("Our HUD was notified of a bullet collision!")
  }

  void OnDestroy() {
    GameController.Bus.Unsubscribe(OnBulletCollision);
  }
}

Now ‘using’ in our classes are cleaner and dependencies between them too!

Example

In Tetris-like game states of Tetris box are manage by Finite-state machine pattern. So boxes are changing from one form to another in response to some inputs. But each state triggers action like play state transition music, show some particles, start a graphic transition between them, and more stuff to bring life to the game. 

It is also possible to associate action with a state and an entry action when entering the state or exit action state. 

How Tetris box class looks like now:

using MDevelopers.Unity.Statemachine;
using UnityEngine;

namespace MDevelopers.Unity.Tetris
{
    public class TetrisBox : MonoBehaviour
    {
        internal FallingDownState fallingState;
        internal MoveLeftState moveLeftState;
        internal MoveRightState moveRightState;
        internal MoveDownState moveDownState;
        internal MoveRotateState rotateState;
        internal StateMachine stateMachine;

        void Start()
        {
            InitStateMachine();
        }
	(…)
}

Ok. But show me how classes change with events bus.

For example, earlier, I have something like an EndGame state it small and simple: 

using MDevelopers.Unity.Distractors;
using MDevelopers.Unity.Statemachine;
using MDevelopers.Unity.Utilities;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.SceneManagement;

    internal class EndGameState : State
    {
    	(…)

        private void EndGame()
        {
		//Create result object 
       		 //Calculate results
		//Send message to ReactNative
		//End background transition
           	//Change scene
        }
    }

Just by using we can see, there is something wrong with this class. On the other hand, what endgame has in common with the Tetris box is now a box. The box can end the game by cross the up line, but it's not an internal state of the box. So I realize I need to remove it.  And after refactoring to event-based. I remove this class. And MoveDawn and FallingDown state using standard type to check the correctness of the move and sending an event about ending the game. Here is what the content of the method looks like:

using MDevelopers.Unity.Statemachine;
using UnityEngine;

namespace MDevelopers.Unity.Tetris
{
    public static class Falling
    {
	internal static void Down(TetrisBox box, StateMachine machine, ParticleSystem particleSystem)
        {
                if (TetrisPlayfield.IsGameEnd(box.transform))
                 {
                    TetrisGameController.Bus.Publish(new EndGameEvent());
                    return;
                }
                TetrisGameController.Bus.Publish(new SpawnNextEvent());
(…)

And yes. I tried not to use the ‘else’ keyword. To not necessarily nested my code. But it is a topic to cover in the next blog post. 

Learn how tokick your unity game performance

 

Conclusion

Event systems can help decouple direct calls between classes, add structure to the code, clean up dependencies in scripts, and quickly add callbacks.

Adrian Kujawski

 
About the author
Peter Koffer - Chief Technology Officer

With 13 years of experience in the IT industry and in-depth technical training, Peter could not be anything but our CTO. He had contact with every possible architecture and helped create many solutions for large and small companies. His daily duties include managing clients' projects, consulting on technical issues, and managing a team of highly qualified developers.

Piotr Koffer

Share this article


Contents


mDevelopers logo

Software development company

Clutch mDevelopers

We’ve been in the business for over 13 years and have delivered over 200 mobile and web projects. We know what it takes to be a reliable software partner.


Cookies.

By using this website, you automatically accept that we use cookies.