XML Database for Unity (Part 2)

Asset Bundle Setup

Asset Bundle Setup

Asynchronous Asset Loading using XML Database

In Part 1 of this article, we saw how game data can be defined in C#, authored in XML, and stored in a database at runtime.  This provides an easy and extensible way to manage content in your game which lives outside of the Unity scene graph.  If you have not already done so, download the example projects here.  This article will use the AssetBundleExample project.

In Part 2, we will apply this technique to build an asynchronous resource loading pipeline using Asset Bundles. Continue reading

XML Database for Unity (Part 1)

Unity manages its data using a data structure called a scene graph.  Anyone who has worked a bit in Unity (or probably any other 3D DCC tool) understands what a scene graph is: there’s a Scene which contains any number of GameObjects in a spatial hierarchy.  These GameObjects have a collection of Components which in turn reference Assets or other GameObjects.  This setup is very intuitive and convenient, particularly if your game is broken into a number of levels.  But what about games with data that doesn’t live in a scene graph, or which builds its levels at runtime?

Many games don’t have the concept of a “level,” at least at design-time.  Strategy games, Roguelikes and Minecraftlikes (I went there) all build levels at runtime out of pieces which don’t exist in a scene graph.  Even games that do have levels in many cases still have to manage lots of data which doesn’t live in a level (UI icons, character customization pieces, server-side data representations, etc).

Unity provides the Resources and Asset Bundles APIs for loading assets that don’t live in a scene.  These are great APIs (albeit a bit boilerplate), but they are only half of the equation.  How do we author and organize this data?  How does the game’s logic access and filter it?  These are questions I will address with an XML Database.

I have built two sample Unity projects to illustrate this problem.  I recommend you download the examples from GitHub here.  In this article, we will be looking at the SimpleExamples project.  The AssetBundleExamples project will be the subject of Part 2.

The example projects are the beginnings of a strategy game (go figure) with a procedurally generated map.  The map has four different types of terrain Tiles: water, grass, dirt and stone, and any number of Features which can be placed on the tiles (trees, rocks, gems, etc).  When you run the game, it looks like this:

Procedural Map

Our Procedural map example. Special thanks to Daniel Cook for the awesome art.

Continue reading

A Type-Safe Event System for Unity3D

The Event Listener pattern is an extremely common design pattern. Using Events instead of method calls let an object communicate with another object (or many objects) without explicit knowledge of the other object. With events acting as an implicit interface between objects, we can write much more loosely coupled (thus more reusable) code.

Unity’s own message passing system can be leveraged to achieve this effect, but there are a few problems with it. First, sending messages is hierarchy-dependent. You either need a reference to the object you wish to send the message (event) to, or you need a reference to that object’s parent object. This is not loosely coupled. Secondly, it’s not statically type-safe.

There have been several solutions to this problem (for example, FlashBang’s messaging system or this one on the UnifyCommunity wiki). These still lack type-safety, and won’t quite do.

Here is my event system implementation. It looks quite a bit like the event system in AS3:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class GameEvent
{
 
}
 
public class Events
{
    private static Events eventsInstance = null;
    public static Events instance
    {
        get
        {
            if (eventsInstance == null)
            {
                eventsInstance = new Events();
            }
 
            return eventsInstance;
        }
    }
 
    public delegate void EventDelegate<T> (T e) where T : GameEvent;
 
    private Dictionary<System.Type, System.Delegate> delegates = new Dictionary<System.Type, System.Delegate>();
 
    public void AddListener<T> (EventDelegate<T> del) where T : GameEvent
    {
        if (delegates.ContainsKey(typeof(T)))
        {
            System.Delegate tempDel = delegates[typeof(T)];
 
            delegates[typeof(T)] = System.Delegate.Combine(tempDel, del);
        }
        else
        {
            delegates[typeof(T)] = del;
        }
    }
 
    public void RemoveListener<T> (EventDelegate<T> del) where T : GameEvent
    {
        if (delegates.ContainsKey(typeof(T)))
        {
            var currentDel = System.Delegate.Remove(delegates[typeof(T)], del);
 
            if (currentDel == null)
            {
                delegates.Remove(typeof(T));
            }
            else
            {
                delegates[typeof(T)] = currentDel;
            }
        }
    }
 
    public void Raise (GameEvent e)
    {
        if (e == null)
        {
            Debug.Log("Invalid event argument: " + e.GetType().ToString());
            return;
        }
 
        if (delegates.ContainsKey(e.GetType()))
        {
            delegates[e.GetType()].DynamicInvoke(e);
        }
    }
}

To use this thing, first we declare a GameEvent subclass. This event can carry with it all of the parameters needed by the objects listening for the event.

public class SomethingHappenedEvent : GameEvent
{
	// Add event parameters here
}

Registering to listen for the event looks like this:

public class SomeObject : MonoBehaviour
{
	void OnEnable ()
	{
		Events.instance.AddListener<SomethingHappenedEvent>(OnSomethingHappened);
	}
 
	void OnDisable ()
	{
		Events.instance.RemoveListener<SomethingHappenedEvent>(OnSomethingHappened);
	}
 
	void OnSomethingHappened (SomethingHappenedEvent e)
	{
		// Handle event here
	}
}

And finally, to raise the event, do this:

Events.instance.Raise(new SomethingHappenedEvent());

The cool thing about this implementation is that it’s type-safe (listener registration errors will be caught at compile time, and no casting of events or event arguments) and it doesn’t require listening objects to implement a special interface or use Unity’s built-in message passing system.

The interface for this system is almost identical to that presented by Mike Mittleman at Unite 08, and I’d wager our implementations are similar. If you really want a rundown of the benefits and pitfalls of event-driven Unity development, I suggest watching his presentation on Unity’s website.

UPDATE:

I’ve made a Gist for this thing with revisions suggested in the comments:

C Coroutines for Game Entity State Management

State management is one of the more difficult aspects of game programming. Entities in your game must behave differently depending on their internal state, and may depend on the state of other objects as well.

There are several approaches to solving this problem – the naive approach being lots and lots of conditionals. Finite state machines approach the problem by objectifying state and state transitions. More recently, with the growing popularity of higher level languages like Lua, Python, and C#, coroutines have become a popular choice for mitigating the complexities of managing state.

I have implemented coroutines in C, and it’s turning out great. Here’s how to do it!
Continue reading