Tag Archives: gameObject

Playing a longer running animation in Unity

Continuing on with my list of things that I’ve found in unity (I’m using 5, but have no reason to believe these wouldn’t work for 4), I had cause to execute an attack animation in a character. For reference, the character I’ve been using is here

So far, when playing an animation, I’ve used something similar to this:

gameObject.GetComponent<Animation>().Play("Idle_2");

In fact, if you put that in the Update of the linked object, you’ll get an angry looking chap looking like he’s about to charge. In order to plumb in the attack, it’s necessary to cache the animation. Start with a class level variable:

private Animation _animation;

Then, inside the update statement, something similar to this:

void Update ()
{
    if (_animation != null && _animation.IsPlaying("Attack_1")) return;

    if (Input.GetKeyDown(KeyCode.Space))
    {
        if (_animation == null)
            _animation = gameObject.GetComponent<Animation>();
        _animation.Play("Attack_1");            
    }
}

One of the bizarre things that I learnt about unity while doing this, was that if you have a null reference, it doesn’t crash. It doesn’t work, but it doesn’t crash.

I find this annoying.

Working with the threading system in Unity

Unity seems to have a multi-threaded system, but I could find no way of accessing the dispatcher. Consequently, it’s necessary to create some kind of self-rolled task queue. The specific problem that I faced was with using the timer; here’s the code for the timer:

public class MasterScript : MonoBehaviour
{
    private Timer _timer;

    void Start ()
    {
        _timer = new Timer();
        _timer.Interval = 1000;
        _timer.Elapsed += _timer_Elapsed;
        _timer.Start();
    }

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        SpawnNewObject();
    }
}

The idea being that every second, and new object would appear on the screen. However, as soon as you run this, it crashes (or as close as Unity comes to crashing):

FindGameObjectWithTag can only be called from the main thread

The solution that I came up with was as follows:

public class MasterScript : MonoBehaviour
{
    public static Queue<Action> TaskQueue;

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        SpawnNewObject();
    }

    private void SpawnNewObject()
    {
        TaskQueue.Enqueue(() =>
        {
            var newObj = Instantiate<GameObject>(MyObject);

Then, simply change the Update function to run them:

    void Update ()
    {
        if (TaskQueue.Count > 0)
        {
            TaskQueue.Dequeue().Invoke();
        }
    }

I’ve used the idea of a “Master Script” to deal with the queue, and this can be queued to from somewhere else in the game, which makes it more flexible.