A while ago I started to get quite annoyed at having to create instances of a class just to modify the values of an existing object, instead of directly editing the object fields.

float new_value = (Mathf.Sin( Time.time ) + 1) * 0.5f;

// Works
transform.position = new Vector3( transform.position.x, new_value, transform.position.z );
material.color = new Color( material.color.r, material.color.g, material.color.b, new_value );

// Does not work :(
// transform.position.y = new_value;
// material.color.a = new_value;

To me, it looks wrong to create a new instance when you just want to modify the object. The code gives the incorrect impression of intent, it’s verbose and leaves unnecessary information in the code. Yes, I’m a code nazi.

Luckily, I stumbled upon an article about so-called “Extension Methods” in C# (I hadn’t been using C# for too long at this point) and how you could use them in Unity! This opened up a whole new world of possibilities when it came to “modifying” Unity’s API to become more readable and understandable. And the best part is that it’s extremely easy!

Now, you might be reading this and thinking that using extension methods is obvious. Maybe it is, but I want to leave more traces of this in the context of Unity on the internet so future beginners can have a chance of finding it.

So here goes!

To make an extension (essentially extending a class) you simply create a new script and call it “ClassExtension” (ie ColorExtension, Vector2Extension, etc). Then you make that class static.

public static class ColorExtension {}

You then add methods that are “public static”. What’s special about these methods is that the first parameter has to be a reference to the object that is modified. When using an extended method C# automatically sends in this reference, but it has to be explicitly written into the function as a parameter.

It’s easier to show by example, so here’s an extended Color method I use all the time:

using UnityEngine;
 
public static class ColorExtension 
{
	public static Color WithAlpha( this Color color_, float alpha_ )
	{
		return new Color( color_.r, color_.g, color_.b, alpha_ );
	}
}

To use it, simply call the method on a Color object:

float theta = (Mathf.Sin( Time.time ) + 1) * 0.5f;
material.color = material.color.WithAlpha( theta );

And there you have it. Simple and powerful.

I haven’t explored this as much as I should’ve, but there are many convenient extensions you can make if you use your imagination.

Here are some of my favorite that I use every day:

using UnityEngine;

public static class GameObjectExtension
{
	public static T GetComponentOrAdd<T>( this GameObject go_ ) where T : Component
	{
		T component = go_.GetComponent<T>( );
		if( component == null )
		{
			component = go_.AddComponent<T>( );
		}
		return component;
	}

	public static T GetComponentOrDie<T>( this GameObject go_ ) where T : Component
	{
		T component = go_.GetComponent<T>( );
		if( component == null )
		{
			D.LogError( "Component " + typeof( T ) + " not found on GameOject." );
			Debug.Break( );
		}
		return component;
	}

	public static bool HasComponent<T>( this GameObject go_ ) where T : Component
	{
		return go_.GetComponent<T>( ) != null ? true : false;
	}
}
using UnityEngine;

public static class Vector2Extension 
{
	public static Vector2 WithX( this Vector2 vector_, float x_ )
	{
		return new Vector2( x_, vector_.y );
	}

	public static Vector2 WithY( this Vector2 vector_, float y_ )
	{
		return new Vector2( vector_.x, y_ );
	}
}
using UnityEngine;

public static class Vector3Extension 
{
	public static Vector3 WithX( this Vector3 vector_, float x_ )
	{
		return new Vector3( x_, vector_.y, vector_.z );
	}

	public static Vector3 WithY( this Vector3 vector_, float y_ )
	{
		return new Vector3( vector_.x, y_, vector_.z );
	}

	public static Vector3 WithZ( this Vector3 vector_, float z_ )
	{
		return new Vector3( vector_.x, vector_.y, z_ );
	}

	public static Vector3 WithXY( this Vector3 vector_, float x_, float y_ )
	{
		return new Vector3( x_, y_, vector_.z );
	}

	public static Vector3 WithXZ( this Vector3 vector_, float x_, float z_ )
	{
		return new Vector3( x_, vector_.y, z_ );
	}

	public static Vector3 WithYZ( this Vector3 vector_, float y_, float z_ )
	{
		return new Vector3( vector_.x, y_, z_ );
	}
}

Examples of how I use them:

// Prodecural mesh so we don’t care if the
// object already has the component or not
MeshRenderer renderer = gameObject.GetComponentOrAdd<MeshRenderer>( );
MeshFilter filter = gameObject.GetComponentOrAdd<MeshFilter>( );

// Need this for the object to make sense,
// so throw and error if it’s not there
ImportantComponent important = gameObject.GetComponentOrDie<ImportantComponent>( );

// I don’t care about the x and z value
// and just want to change y
float new_value = (Mathf.Sin( Time.time ) + 1) * 0.5f;
transform.position = transform.position.WithY( new_value );

Do you think this is useful for your work? Feel free to comment with your own ideas!

UPDATE

I’ve been informed that this article doesn’t have any pictures. I didn’t find anything relevant so here’s a cat:

WTF human!