Sunday, August 3, 2014

Object Pooling

Object pooling is a pretty cool technique developed to reduce the performance cost of instantiating and destroying objects. Its a commonly used technique for simple things like bullets, but you can pool more complex objects like enemies as well.


What's wrong with just using Instantiate() and Destroy()?

Good question. Instantiate is fairly obvious, every time you call instantiate you need to create the GameObject in memory. There is a bunch of components loaded. Materials, textures. It quickly adds up over multiple frames. Destroy is not so expensive to start with, as all it does is remove the references to your object. However destroyed objects hang on to the memory until the garbage collecter runs. Nothing drops the frame rate like frequent calls to the garbage collecter.


Common traps to avoid

There are multiple ways to code a pool, and the above all the code should suit the application. Here are a few potential problems that are easy to avoid when designing a pool.

Set size pools. Unless you are absolutely certain of the size your pool will be its a bad idea to fix the size. Players have a nasty habit of getting into situations where more bullets are fired then you thought possible. You don't want to be firing blanks because your pool ran out of bullets. One way to overcome this is to use a massive pool size, but this is ultimately a waste of resources. For this reason dynamically sized data containers like Lists are better then fixed size Arrays.

Static references. A first glance these seem like a great idea for a pool. Static references, or singletons are great ways to ensure you can access universal managers from anywhere in the game. But most of the code for an object pool is identical across all pools. If you want more then one pool in the game then you can save yourself rewriting all the code again by avoiding static references from the start.


Tricks

There are a few key differences to using pools that are worth noting. The first is obvious, you don't use instantiate or destroy. The pool should take care of any instantiating and destroying that is needed. Slightly less obvious is that Start, Awake and OnDestroy become less useful. Start and Awake can still be used to initialise things, but these methods are only ever called once. For something like a bullets velocity that needs to be initiated every time a bullet is fired then use OnEnable and OnDisable.


My implementation

I built a Pool class. This class has only two exposed members. The first is a GameObject thing used to determine what to pool. The second is a GameObject nextThing used to get the next object out of the pool. Asinging a GameObject to nextThing will return it to the pool.

Inside the class I use a private List<GameObject> to store the inactive GameObjects. I decided only to store references to the inactive GameObjects, rather then keeping track of all of them. This means that I don't have to deal with any lost or destroyed GameObjects. On the other hand it does require some more trickery when it comes to getting the GameObjects back into the pool.

Most of the real action happens inside the get and set method of nextThing. The get method takes care of a couple of key jobs. The first is instantiating new objects. First we check if there are any available inactive GameObjects in the List. If not a new clone is created using instantiate. The parent of the clone is set to the pool. And a component with a reference back to the pool is added. Then the clone is sent off into the world. If it turns out there are inactives available then one of them is activated and returned.

The set method simply takes a GameObject, disables it, and adds it too the list. One possible improvement to the class would be verification that the passed GameObject actually belongs on the list.

The final piece of the puzzle is a PoolMember component that is added to the GameObject after instantiation. This holds a reference to the Pool that created it. It also has an OnDisable method that returns the GameObejct to the pool to be reused. The beauty of this is that you can simply disable any object that is part of the pool without having to worry about where its going.

By now I think you are ready for some actual code. Enjoy:

    using UnityEngine;  
    using System.Collections;  
    using System.Collections.Generic;
  
    public class Pool : MonoBehaviour {  
        public GameObject thing;  
        private List<GameObject> things = new List<GameObject>();  
        public GameObject nextThing {
            get {  
                if (things.Count < 1){  
                    GameObject newClone = (GameObject)Instantiate (thing);  
                    newClone.transform.parent = transform;  
                    newClone.SetActive (false);  
                    things.Add (newClone);  
                    PoolMember poolMember = newClone.AddComponent<PoolMember>();  
                    poolMember.pool = this;  
                }  
            GameObject clone = things[0];  
            things.RemoveAt (0);  
            clone.SetActive (true);  
            return clone;  
            }  
            set {  
                value.SetActive (false);  
                things.Add (value);  
            }  
        }  
    }  

    using UnityEngine;  
    using System.Collections;  
    public class PoolMember : MonoBehaviour {  
    public Pool pool;  
    
        void OnDisable(){  
            pool.nextThing = gameObject;  
        }  
    }  

Edit: If you want to see an example of this check out the git repo on bitbucket. https://bitbucket.org/BoredMormon/object-pooling/src

Sunday, July 20, 2014

Art director assigned

So we have an announcement to make. I have officially employed an art director for my new game. One of the perks of being married to a brilliant artist. We sat down last night and fleshed out a few design details.

We picked a tentative working title of Space Invaders 2.0. There are probably a thousand different reasons we won't be able to use that in the final game, but it works for now. Can't really keep calling it the 'new game' forever.

The story starts soon after the time of classic space invaders. The aliens get together on the mother ship and finally agree that the strategy of going side to side is just not working any more. The humans are able to predict every movement. Various strategies are discussed, moving up and down, diagonals, and sine waves are all discarded. 

Then one alien suggests giving the pilots the ability to change tactics depending on the human tactics. A hush descends over the mothership as the idea sets in. The first few waves are a disaster, but the alien's prove to be fast learners, quickly discovering how to dodge bullets, and how to concentrate firepower for maximum effect.

On the human side it's going to be a classic upgrade game. Play a few levels, earn some cash, buy some bigger and better weapons, repeat. Game play will involve defending this skylines if iconic cities around the world. And maybe a few sheep on the secret level.

And as a final tribute to the original the game will start with a single level of classic play, a tutorial of sorts. Will probably throw some sort of endless play mode in after the campaign too.

Let me know in the comments if there is anything else you'd like to see.

Tuesday, July 15, 2014

The awesome power of coroutines

When I first started learning Unity I saw was introduced to the concept of a coroutine. Coroutine a seemed like a nifty way to cause something to happen later in your script. I scoffed at the idea and built myself custom timers.

There were a couple of reasons I chose not to use coroutines. The first was the complexity. It's far easier to understand what code is doing when you can see everything yourself. The second was a misunderstanding of how coroutines worked. I made the assumption that my code would be just as efficient. After all, how much simpler can you get then updating one float each frame?

So I was doing some research for a question on Unity Answers, when I stumbled across how awesome coroutines actually are.

Coroutines are more efficient then manual timers. This is because Unity handles all of the coroutines on a single event system, with one timer. So where I had one to increment one float per method, Unity has one float that manages all of the coroutines. 

Coroutines also help coding simplicity. No need to check against a timer in you Update loop. In fact well structured coroutines can be set up with a single line of code. In some cases you can eliminate the need for an Update function altogether.

Perhaps the coolest thing about coroutines is they stop running once they are finished. This sounds kind of obvious, but it represents a huge efficiency gain over Update. Take a movement script as an example. The traditional way to code this is to set a bool isMoving. The bool is checked each frame in Update. Each time the bool returns true the movement code executes. Once the target is reached the bool changes to false. However the bool is still checked every frame. Not particularly expensive, true. But do it multiple times on multiple game objects, then run it on an and old mobile phone, and it will all add up.

Contrast this to a coroutine. Once the movement starts there is still an internal check every frame. However as soon as movement finishes, no more overhead. This gets even better when you apply it to a function that gets doesn't execute every frame. 

So that's today's revelation. Still waiting on the computer to get back from the shop, so no progress on any actual games yet...

Saturday, July 12, 2014

From the phone.

So turns out the problem with Megan's computer was a faulty hard drive. We have yet to hear if any of the data can be recovered. And like a genius I didn't back up any of my games. So you won't be seeing any improvements on the tower defense game anytime soon. 

The good news is this frees me up to work on a new project. This one is going to be a remake of space invaders. A good old fashioned 2D space shooter. Complete with pew pew sound effects.

At first glance this is significantly less ambitious then my previous projects. But here is the difference. I will be implementing a learning AI. No more mindless aliens wandering on set, predictable paths. These aliens will be able to learn your play style and adapt to it.

Promised features for the game. You can hold me to this list later.
- Movement and firing of the player spaceship. Gotta put in one goal I know I can meet
- Multiple guns for the human player to choose from
- Aliens with the ability to sense and respond to their environment
- An alien overlord able to spawn aliens better suited to your play style
Stretch goals
- Powerups that can be picked up by the player or the alien
- Multiple alien spaceships driven by pilots of differing personalities
- A leaderboard fully intergrated with Facebook so you can brag to your friends
- An editon for mobile. I can put whatever I like here, something else is bound to distract me before I get this far

Speaking I which, I think I see something shinny...

Sunday, July 6, 2014

Cycling through targets on a tower defense game

Someone over on Unity Answers asked my to explain how to cycle through a list of targets for a tower defence game. The post responding became too long for a comment, so here it is.
The process in a nut shell
  1. Each tower has a trigger attached. OnTriggerEnter adds the enemy to a list. OnTriggerExit removes it from the list.
  2. Any null targets are removed from the list.
  3. The list is then scanned. The targets are scored, and the highest scoring target is returned
  4. The best scoring target is used in the towers aiming system.
If that's enough for you to implement then good on you, stop reading. If you want to see some code then read on. Note this code is untested and will probably have errors if copied straight into Unity. Also note the code is in C#. To be honest I'm not sure why Unity bothers with any other languages

The tower class

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

public class TargetFinder : MonoBehaviour  {

    // The main point of this class is to keep this target set
    // Hence we don't do anything unless something is actually looking for a target
    public Transform Target {
        get {
            return FindTarget();
        }
    }

    // This list holds all of the targets that are in range
    // I've chosen to populate the list using triggers
    // For a slower firing tower you could populate the list with an overlap sphere
    private List<transform> targets = new List<transform>();

    // The tower needs a trigger to determine if a target is in range
    // This code assumes the only colliders running around are enemies.
    //If not you will want to use tag checking or some other method to verify the collider is actually an enemy
    void OnTriggerEnter (Collider other) {
        targets.add(other.transform);
    }

    // The tower removes targets from the list that move out of range.
    void OnTriggerExit (Collider other){
        if (targets.contains(other.transform){
            targets.remove(other.transform);
        }
    }

    // This method is the work horse of the class
    // Be sure to understand this method, even if you don't get anything else
    private Transform FindTarget (){

        // First job is to see if there is anything in the list
        // No point running expensive code if nothing is in range
        if (targets.count <= 0){
            return null;
        }

        // Now we remove everything that is null from the list
        // Null transforms get on the list when a target is in range and destroyed
        // This is called a lambda function. Don't ask how it works, but it does.
        targets.RemoveAll(item => item == null);

        // And then we check again if there are any items left
                if (targets.count <= 0){
            return null;
        }

        // Now we check each remaining target in turn to see which one we should be aiming at
        // The code will check each possible target in turn to calculate a score
        // The score will be compared to the current best score
        // We will store the best target and score in bestTarget and bestScore
        Transform bestTarget;
        float bestScore = -999999;
        foreach (Transform currentTarget in targets){
            float currentScore = ScoreTarget(currentTarget);
            if (currentScore > bestScore){
                bestTarget = currentTarget;
                bestScore = currentScore;
            }
        }

        // Now our only job is to return the target we found
        return bestTarget;
    }

    // This method is used to score the targets
    // My implementation will just check the distance from the tower, closer targets get a higher score
    // However you can make this as complex as you like
    private float ScoreTarget (Transform target){
        float score = 0;
        score = 100 - (target.position - transform.position).sqrMagnitude;
        return score;
    }
}

Sunday, February 16, 2014

Mind blowing images from the other dimension

No, its not a couch, sorry to disappoint.


In fact its not really from another dimension either, except in an abstract mathematical sense.


I did not set out to create these pictures, they were entirely a side effect of my game design.


I think they are pretty enough to stay in the final version.


Let me know what you think in the comments. I'll post more screenshots as the game develops.

Tuesday, January 28, 2014

New Hobby Alert

Seems I post these more than anything else. :) Learning to programme my own video games at the moment with Unity3D. If the time comes that anything gets to a launch date I might throw something up here.