Initiative: Red Dawn

May 27, 2016

Code abstraction: Events and delegates

As a one-man team, indie developer, or hobbyist game developer, your time is more limited than that of a big company or a big team. As such, you need to optimize your development process as much as possible. Often, your scripts need to contact each other for several reasons: a city finishes up producing a unit and needs to tell the unit manager script that its done and it should actually Instantiate the GameObject and set it up; or a ship arrived at its destination and needs to tell the planet it has arrived and needs to be stored in a hangar. Whatever your case is, you need to contact other scripts. And sometimes, you need to contact more than one script. The usual way is to have properties (variables) pointing at the other scripts and running methods. Here’s an example of a production gauge with a timer that notifies the city the production is done
ProductionGauge.cs ——-   UnitManager unitManager; CityManager cityManager; void Update () { […] when production of a unit finishes // Tell the unit manager to actually create the unit unitManager.Create(unitType); // Tell the city the unit has finished production cityManager.FindByName(“Rome”).ProductionDone(unitType); […] } Now this is fine, but as I started, you need to optimize your speed as much as possible. In order to do that, you need to create your own set of scripts that you can re-use in future projects. If we keep the code like this, if you want to use the ProductionGauge.cs in another project and you drag just that file, then you’ll end up with errors because the UnitManager and the CityManager are not there, so you need to remove all the code related to those scripts, and of course, you need to modify this new ProductionGauge.cs to fit the needs of your new project (call the PlanetManager instead if its a space game, for instance). This is a maintenance nightmare, because if you happen to find a bug on ProductionGauge.cs, suddenly you realize you have that bug in both your games, the city game and the space game, so you should go back and fix the city game as well. But you can’t just copy back the ProductionGauge.cs into your city game, because it already contains all the logic for that particular game. Well, you get the idea. Here’s where Events and Delegates come handy. They allow a layer of abstraction between scripts. Basically, what you can achieve is for the ProductionGauge.cs to shout “hey! I’m finished producing!”, and any script can listen and act accordingly. Therefore, you don’t need any specific references inside ProductionGauge.cs to any other script. It just shouts to mid air. Here’s the same example of ProductionGauge.cs with events and delegates:
ProductionGauge.cs ——————– // Declare the delegate and the event public delegate void ProductionGaugeFinishedEventHandler (ProductionGauge pg); public static event ProductionGaugeFinishedEventHandler OnFinishedEvent; void Update () { […] when production is done // Always check if event is not null before raising it because if // it is null, then no-one is watching if (OnFinishedEvent != null) { // Raise the event which will be executed on all scripts // that are actively listening to this OnFinishedEvent(this); } […] } And on the City.cs side, this would be like so:
City.cs ————– void Start () { ProductionGauge.OnFinishedEvent += MyOwnFinishedMethod; } void OnDisable () { ProductionGauge.OnFinishedEvent -= MyOwnFinishedMethod; } void MyOwnFinishedMethod (ProductionGauge pg) { // This method will be executed whenever the ProductionGauge raises its event } As you can see, the ProductionGauge.cs does not refer to any other script now, so you can easily use it between projects. Also, even if you don’t share the code between projects, if with the example above we need the HUD to also listed for that event, the HUD script can simply add itself as listener and it will also get notified when production finished. So you should use Events on all the scripts you want to re-use in another project or when you need to notify several scripts about something. Don’t forget to follow us on twitter for news regarding articles and game development. @IndelveStudios @NickVarcha

Leave a Reply