00:00
00:00
View Profile MonoFlauta
Indie Game Developer + Senior Software Engineer at Etermax

Facundo Balboa @MonoFlauta

27, Male

Indie Game Developer

Escuela Da Vinci

Buenos Aires, Argentina

Joined on 7/30/08

Level:
27
Exp Points:
7,784 / 8,090
Exp Rank:
3,915
Vote Power:
6.86 votes
Rank:
Police Sergeant
Global Rank:
9,066
Blams:
214
Saves:
805
B/P Bonus:
12%
Whistle:
Bronze
Trophies:
14
Medals:
723
Supporter:
5y 30d

11 Useful Unity C# Extension Methods

Posted by MonoFlauta - July 27th, 2021


Full Post - Twitter Account - DevBlog


Hello, everyone!

This time I will show you a list of useful Unity extensions and the cases where you can use them. I had been looking around to expand my list of useful extensions and some of them were pretty interesting plus I already had a few I normally use.


iu_370264_2529638.webp


What are extension methods and how do you create extension methods in C#

The extension methods in C# are methods that let you extend the functionality of any class. Basically, you can add an extra public method to the class. Beware that you will not be able to access it’s private values while doing this.

In order to create them, you just need a static class, for example ClassToExtendExtensions.cs and add static methods like this:

public static void ExtensionMethodName(this ClassToExtend o)
{
    //Do stuff
}

Apart from the static, take in mind that we are adding a this before the ClassToExtend parameter. You can also ask for more parameters but by having this, you can just do:

myClassToExtendInstance.ExtensionMethodName();

And so, you extended the class without having to actually modify the class. Pretty useful for classes you can’t modify.

Now lets see some useful method extensions!

Vector extensions

You will be probably using a lot of Vector3 or Vector2 in your games. So here are a few extension methods for that:

public static Vector2 SetX(this Vector2 vector, float x)
{
    return new Vector2(x, vector.y);
}

This method sets the value. Since you can’t set the x or y value, you can have this one. I recommend adding the y one and you can do the same for the Vector3.

public static Vector2 AddX(this Vector2 vector, float x)
{
    return new Vector2(vector.x + x, vector.y);
}

As the upper one sets, this one lets you add or substract to a value. The same you can do with y value and with Vector3.

public static Vector2 GetClosestVector2From(this Vector2 vector, Vector2[] otherVectors)
{
    if (otherVectors.Length == 0) throw new Exception("The list of other vectors is empty");
    var minDistance = Vector2.Distance(vector, otherVectors[0]);
    var minVector = otherVectors[0];
    for (var i = otherVectors.Length - 1; i > 0; i--)
    {
        var newDistance = Vector2.Distance(vector, otherVectors[i]);
        if (newDistance < minDistance)
        {
            minDistance = newDistance;
            minVector = otherVectors[i];
        }
    }
    return minVector;
}

Now this one is a bit more complex but you can make many variants from it. This method will bring you the closest vector from a list. You can use it to give a list of positions and know the closest one of them. From this one, you can also make the Vector3 variants, the one that brings you the closest distance (float value) and the farthest version.

GameObject extensions

Every thing you will Instantiate will be a GameObject so it would be wise to have some extensions for it! So here we go:

public static T GetOrAddComponent<T>(this GameObject gameObject) where T : MonoBehaviour
{
    var component = gameObject.GetComponent<T>();
    if (component == null) gameObject.AddComponent<T>();
    return component;
}

With this method you can automatically add a component in case the GameObject doesn’t have it yet. Beware that the component will have nothing assigned if its created, you should be very careful with what components you use this method.

public static bool HasComponent<T>(this GameObject gameObject) where T : MonoBehaviour
{
    return gameObject.GetComponent<T>() != null;
}

And this method will tell you if the GameObject has or not a component. Useful if you are adding constantly components because gameplay requirements.

List extensions

Another thing you will use a lot, or at least we did when making Paw Pals for example, will be List extensions.

iu_370263_2529638.webp

Here is the one I find the most useful one:

public static T GetRandomItem<T>(this IList<T> list)
{
    return list[Random.Range(0, list.Count)];
}

This one will give you a random item from the list. I, personally, use this one a lot https://s.w.org/images/core/emoji/13.1.0/svg/1f642.svg

public static void Shuffle<T>(this IList<T> list)
{
    for (var i = list.Count - 1; i > 1; i--)
    {
        var j = Random.Range(0, i + 1);
        var value = list[j];
        list[j] = list[i];
        list[i] = value;
    }
}

And this one is another one I often use that shuffles a list. You can use this one for example for a random turn based game.

Transform extensions

This two methods I am going to show you I found them recently and I though they were really clever ones.

public static void DestroyChildren(this Transform transform)
{
    for (var i = transform.childCount - 1; i >= 0; i--)
    {
        Object.Destroy(transform.GetChild(i).gameObject);
    }
}

With this one, you can clean for example GameObjects you were using as containers.

public static void ResetTransformation(this Transform transform)
{
    transform.position = Vector3.zero;
    transform.localRotation = Quaternion.identity;
    transform.localScale = Vector3.one;
}

And with this one you can reset the transformation. Setting it as its neutral pose.

Rigidybody extensions

And for last! Two more methods for rigidbodies I had found useful in the past.

public static void ChangeDirection(this Rigidbody rb, Vector3 direction)
{
    rb.velocity = direction.normalized * rb.velocity.magnitude;
}

With this one you can change the current direction of a rigidbody while keeping it’s velocity. Also, you can make the Rigidbody2D alternative.

public static void NormalizeVelocity(this Rigidbody rb, float magnitude = 1)
{
    rb.velocity = rb.velocity.normalized * magnitude;
}

And with this one you can normalize the velocity to a target speed while keeping the direction.


You can finish reading this post at my DevBlog (for free of course!).


Thank you for reading and feel free to ask me if you have any question!


Tags:

Comments (3)

Excelente... y qué bien ese Devlog! Por acá andamos diseñando un point and click en 2d tradicional pero con el Visionaire, viene con su propio lenguaje que consiste en una combinación de Lua con el modelo de objetos propio del soft. ¡Por muchos más videojuegos argentinos en el futuro!

@AndieCiambotti Pifie el mensaje jajajaja. Y no puedo borrar el anterior.
Había querido decir que que bueno! Y que si se podía ver en algún lado algo :)

@MonoFlauta Hasta ahora visual tenemos poco... Hice una maqueta usando todos dibujos viejos de mi novia de cuando era niña jaja sólo para tener un primer approach con el programa y establecer un nivel, un personaje, diálogos y poder agarrar un ítem que se agregue al inventario. Ahora estamos divirtiéndonos armando el documento de diseño; te comparto esto por si te sirve, acá podes encontrar los viejos design documents de LucasArts, me sirvieron mucho para organizar ideas y guiones de escenas: https://web.archive.org/web/20180226005830/http://wilmunder.com/Arics_World/Games.html