Unity Tips

Here’s a few generic programming things we use in Unity to make our lives easier. These might be useful to other people.

Singleton Component

GameManager, SteamClient, yadda yadda. You probably have a component somewhere where you only want one of them and you probably want to get access to it from everywhere for some reason. So we added SingletonComponent.

public class MainCamera : SingletonComponent
{
	public void DoStuff()
	{
	}

	public static Vector3 position { get { return Instance.transform.position; } }
}

Now you can access the component via MainCamera.Instance

MainCamera.Instance.DoStuff()

Source here.

List Component

You probably have a bunch of components that you want to keep a constantly updated list of too. Maybe all your enemies, or maybe all your bullets.

public class EnemyBullet : ListComponent
{
	public void Explode()
	{
	}
}

You can access the list via EnemyBullet.InstanceList (be aware of destroying while iterating etc)

foreach ( var bullet in EnemyBullet.InstanceList )
{
	bullet.Explode();
}

Source Here.

Interfaces

Components can implement interfaces and now Interfaces can be grabbed using the GetComponent methods.

We use this in Rust to tag components with functionality and to mark them as cullable on the client/server (which means our build system will remove that component from all prefabs when targeting specific platforms).

public interface INeedsToStartDisabled { }
public interface IEditorComponent { }
public interface IServerComponent { }
public interface IClientComponent { }
public interface IServerComponentEx { void PreServerComponentCull( IPrefabProcessor p ); }
public interface IClientComponentEx { void PreClientComponentCull( IPrefabProcessor p ); }
public class Decal : MonoBehaviour, IClientComponent 
{

Extensions

Not many people know that you can add extended class functionality in c#.

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

namespace UnityEngine
{
	public static class TransformEx
	{
		public static string Log( this Transform transform, string strText )
		{
			Debug.Log( transform.name + ": " + strText );
		}
	}
}

This lets you do

transform.Log( "Testing testing" );

More info.

Prefab Attribute

In Rust we have a problem with memory usage because of the pure number of GameObjects we have. We noticed early on that the more components the more memory.

It’s also pretty common that when you have a component it’s usually identical and unchanged on every prefab, being used only to hold variables that go unchanged. So we added prefab attributes. These are like regular components except they get removed before the prefab is spawned.

Our doorway prefab looks like this:

But everything selected here is an attribute

In this example, the sockets relate to the building system. They are snap points, they define where this building piece can attach to, and where other pieces can attach to it. Each socket has rules, more gameobjects, more components. All of which are static, they hold no variables specific to an in-game object.

So we delete them all on the first spawn of the prefab but keep them all around. Even though they’re deleted we can still access the functions and the variables. We store their local positions and rotations and can then transform them to the real in-game objects to be able to run tests etc based on their in-game locations.

This all means that when 5,000 doorway entities are spawned on a server, we’re spawning ~20,000 components instead of 300,000+

9 thoughts on “Unity Tips

  1. I like the idea of a base class for Singletons, I’ve typically just done it manually for each behavior. However, why have both a generic and simple base class?

  2. Interesting post!

    I use s couple of these patterns myself (in non Unity games).
    It does bother me though that you use a regular List for storing the ListComponents. That makes for O(n) removal, which is not ideal.

    At least for situations where objects are deleted a lot (i.e. bullets) I would use a custom collection, like for example the one in this post:
    http://genericgamedev.com/general/on-collections/
    (Disclaimer: my own blog)

    I still have to look more into things like prefabs however. I can already see many situations where they might come in handy.

  3. Oh the singleton looks really good. I was using other way but the problem was to write all the time the same thing in other scripts which can be solved with your example.

  4. Great article though I happened to be wanting to know if you may create a litte regarding this subject matter?

    I’d getting most grateful if you might elaborate a
    bit more. Bless your!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s