Thursday, September 18, 2014

Spatial Audio in Unity3D

I recently acquired an Oculus Rift.

It was easy to integrate into one of my existing projects, however during testing, I discovered Unity does not support 'surround sound' using stereo headphones.

After much research, trial and error I have found that getting 'true' (HRTF) surround sound really requires dedicated hardware. It's too expensive to run realtime on your CPU at the same time as your game.

I read that FMOD has a 'fake HRTF' implementation, however this is not exposed by Unity. Well, at least it can be faked right? After all, reality is not important, perception of reality is!

So I faked it. This is my SpatialAudioSource component.

www.differentmethods.com/packages/SpatialAudioSourceDemo.html

Just drag and drop the component onto any existing audio source. It also features audio occlusion. So if something gets between the Player and the AudioSource, the audio is altered accordingly.

When it's ready, I'll put it on the Asset Store.

Wednesday, June 11, 2014

2500 AI Bots

I'm stress testing React, my behaviour tree AI tool for Unity. The screenshot shows 2500 AI's wandering a plane, obeying orders from their commander. Most of the CPU is being used by the skinned mesh renderer (4085 draw calls!).

The next release of React will add some new features. There is a 'chain of command' component which allows an AI to command a group of other AI, and respond to success or failure of orders. There is also a goal planner, and a swarm movement component in the works.

Tuesday, April 08, 2014

A Web Server inside Unity3D

UniWeb now includes a tiny embedded web server which you can use to do crazy things. That is all.

Monday, December 30, 2013

A Unity Tech Tree Editor

I'm about to release a Tech Tree editor tool for Unity.

To test usability and work out how improve the interface, I used it to build the tech tree used in the game Homeworld, which is split into Research, Structures and Ships groups.



It takes care of build times, resource costs for any number of different resource, mutex branch points as well as multiple factory types.

UPDATE: Now available on the Unity Asset store.

Friday, December 06, 2013

Unity3D Micro Optimisation: Loops

This benchmark answers two questions.

1. What is the performance difference between different loop statements? The two options considered are "for" and "foreach". Why bother? These things matter when dealing with modifying 4000 particles per frame in your latest Unity game on a mobile device.

2. What is the performance difference between different collections? Arrays and Generic lists are commonly used in Unity, and I've always wondered about the performance difference of accessing arrays by index, vs lists by index.

The results are quite surprising. Benchmark code below, but here are my results:

  • For Each Loop over Array: 262 ticks
  • For Loop over Array: 120 ticks
  • For Each Loop over List: 1640 ticks
  • For Loop over List: 598 ticks

The (expected) winner is clearly a plain for loop over an array, but I didn't realise the difference between the loop structures and collections would be so large!


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;

public class LoopBenchmarks : MonoBehaviour
{
    public int iterations = 15;
    public int arraySize = 40;

    void Start ()
    {
        BenchArray ();
        BenchList ();
    }

    void BenchArray ()
    {
        var array = new int[arraySize];
        var clock = new Stopwatch ();
        var foreachTime = 0f;
        var forTime = 0f;
        var mapTime = 0f;
        for (var iteration=0iteration<iterationsiteration++) {
            clock.Start ();
            foreach (var i in array) {
            }
            clock.Stop ();
            foreachTime += clock.ElapsedTicks;
            clock.Reset ();
            clock.Start ();
            for (var idx=0idx<array.Lengthidx++) {
                var i = array [idx];
            }
            clock.Stop ();
            forTime += clock.ElapsedTicks;
            clock.Reset ();
        }
        UnityEngine.Debug.Log (string.Format ("For Each Loop over Array: {0} ticks"foreachTime / iterations));
        UnityEngine.Debug.Log (string.Format ("For Loop over Array: {0} ticks"forTime / iterations));
    }

    void BenchList ()
    {
        var list = new List<int> (new int[arraySize]);
        var clock = new Stopwatch ();
        var foreachTime = 0f;
        var forTime = 0f;
        for (var iteration=0iteration<iterationsiteration++) {
            clock.Start ();
            foreach (var i in list) {
            }
            clock.Stop ();
            foreachTime += clock.ElapsedTicks;
            clock.Reset ();
            clock.Start ();
            for (var idx=0idx<list.Countidx++) {
                var i = list [idx];
            }
            clock.Stop ();
            forTime += clock.ElapsedTicks;
            clock.Reset ();
        }
        UnityEngine.Debug.Log (string.Format ("For Each Loop over List: {0} ticks"foreachTime / iterations));
        UnityEngine.Debug.Log (string.Format ("For Loop over List: {0} ticks"forTime / iterations));
    }
    
}

Popular Posts