Extension Methods
Keywordsstatic class, this (first parameter)
CategoryMethods
In UnityDOTween's transform.DOMove(), LINQ's list.Where()

Extension Methods

Extension methods let you add your own methods to types you didn't write, such as Transform, Vector3 or GameObject, and call them as if they were built in. DOTween's transform.DOMove(...) is an extension method.

Stick-on accessories for a phone. You can't open the phone and rebuild it (you don't own Unity's source code), but you can clip on a camera lens that looks and works like part of the phone. Underneath, it's still a separate piece.

How to write one

  1. Create a static class (any name, often ending in "Extensions").
  2. Write a static method.
  3. Put this before the first parameter. Its type is the type you're extending.
using UnityEngine;

public static class VectorExtensions
{
    // Returns a copy with a different y
    public static Vector3 WithY(this Vector3 v, float y)
    {
        return new Vector3(v.x, y, v.z);
    }

    // Ignore height: useful for top-down distances and directions
    public static Vector3 Flat(this Vector3 v) => new Vector3(v.x, 0f, v.z);
}

// Usage: looks like a Vector3 method
transform.position = transform.position.WithY(0f);
Vector3 dir = (target.position - transform.position).Flat().normalized;

Compare with the long version: Vector3 p = transform.position; p.y = 0f; transform.position = p;

More useful examples

using UnityEngine;

public static class UnityExtensions
{
    // Destroy every child
    public static void DestroyChildren(this Transform t)
    {
        for (int i = t.childCount - 1; i >= 0; i--)
            Object.Destroy(t.GetChild(i).gameObject);
    }

    // Is this layer inside a LayerMask?
    public static bool Contains(this LayerMask mask, int layer)
    {
        return (mask.value & (1 << layer)) != 0;
    }

    // Get a component, or add it if it's missing
    public static T GetOrAdd<T>(this GameObject go) where T : Component
    {
        return go.TryGetComponent(out T c) ? c : go.AddComponent<T>();
    }

    // Pick a random element
    public static T RandomItem<T>(this T[] array)
    {
        return array[Random.Range(0, array.Length)];
    }
}

// Usage
inventoryPanel.DestroyChildren();
if (groundMask.Contains(other.gameObject.layer)) { /* landed */ }
var source = gameObject.GetOrAdd<AudioSource>();
AudioClip clip = footsteps.RandomItem();

What happens at runtime

  1. Extension methods are only a nicer way to write the call. The compiler turns pos.WithY(0f) into VectorExtensions.WithY(pos, 0f).
  2. They cost exactly the same as calling a normal static method.
  3. They can only use the public members of the type. They can't reach private fields or add new fields.

Common Mistakes

See also