Creating advanced controllers in Unity can be extremely difficult. Once you get a solid base down it can be very hard to add new features or behaviors to your system. The system I have found to work well for me is by using “Modules” and is what I will explain here.

The simple implementation of a Character Controller is to start out with your base CharacterController class -> Create additional components when needed -> Create references between those components. This can very quickly become messy and break when you want to move components around or add new functionality. Dependencies galore. The first thing we can do is get rid of the dependency issue by creating an event system specific for our controller. We can do this in C# by using delegates and it would look something like this.

Now to provide access to these events we need to initialize it in our Base Controller MonoBehaviour. This acts as the entry point, parent, core, or whatever synonym you would like to use. Lets go ahead and set that up. I am just going to call it Player for the sake of example.

We can now access our events from anywhere we have a reference to our Player. We will go over how to register and react to these events in a bit. This brings us to the point where we want to start using modules. A module is basically a MonoBehaviour we can create that will handle a specific part of the Controller as a whole. For example my FPS Controller has modules such as “PlayerAnimationModule”, “StanceModule”, and “ShootingModule”. Each of these manage their own state and behavior by registering to specific events on the player. This gives the flexibility to easily add new behavior without the dependency nightmares. Let us start by making a base abstract “Module” class!

Great! As you may have noticed we need to create a “RegisterModule” function in Player. We will use a simple List to manage these like so! This is the new updated Player class.

So now we have our Registration complete! Note that performing Registration in OnEnable may be preferred since you can use OnDisable to Unregister the module. You would want to implement this functionality in the abstract Module class! Next we want our Player class to execute all of our modules! For this I am going to show you how I do input -> execution. I recommend something similar! Our Player class could now look like this!

Now our whole system should be setup! Finally lets make a module that will handle shooting! Also, just so I can give an example of how the event system can be used to manage state lets not allow the player to “Shoot” while in the air

This shooting module can be added anywhere in the same hierarchy as our Player GameObject. Disabling or removing this will not effect being able to run the controller. This is a great system for modularity and makes it easy to test specific pieces of a system. You could easily change this Shooting module out with another shooting module. Maybe you have a “PlayerAudioModule” that will react to the FirePlayerShotEvent(); Maybe you also have a “CameraShakeModule” that will react to this and apply some amount of shake to the Camera.

Overall this system has worked quite well for me in a very sophisticated system that needs to be networked. It is very flexible and you can still have dependencies if you need.. but this gives you the flexibility to avoid that where appropriate. I am sure there are some things that could be tweaked and made better, but I thought that I would share this with you so that it may help some of you struggling with these types of advanced systems!!

Contact Me: laspencer@live.com