Skip to content

Vectors

Four small value types that show up everywhere in the API. All are structs, so passing them around allocates nothing.

Vector2

Two floats — a 2D position, a direction, a velocity, a screen coordinate.

Member
X, YThe components
Vector2(float x, float y)
Vector2(float scalar)Both components the same
Vector2.Zero(0, 0)
Length()The vector's magnitude

Operators: +, -, * (by a float, either side), / (by a float).

csharp
Vector2 move = m_Move.ReadVector2();
Vector2 velocity = move * m_Speed;

if (velocity.Length() > m_MaxSpeed)
    velocity = velocity / velocity.Length() * m_MaxSpeed;

Vector3

Three floats — a world position. This is what GameEntity.Translation is.

Member
X, Y, ZThe components
Vector3(float x, float y, float z)
Vector3(float scalar)All three the same
Vector3.Zero(0, 0, 0)
XYThe X and Y components as a Vector2. Readable and writable
Length()The vector's magnitude

Operators: +, -, * (by a float, either side), / (by a float).

XY is the everyday convenience in a 2D game, since gameplay is 2D and positions are 3D:

csharp
Vector2 flat = Translation.XY;

Vector3 pos = Translation;
pos.XY += move * m_Speed * ts;
Translation = pos;

Why the copy-modify-assign dance

Translation is a property, so Translation.XY += ... would modify a temporary copy and throw it away — the compiler catches it. Read into a local, change the local, assign it back.

Vector4

Four floats. Used as a colour throughout the API — red, green, blue and alpha, each 0 to 1.

Member
X, Y, Z, WThe components (r, g, b, a when it's a colour)
Vector4(float x, float y, float z, float w)
Vector4(float scalar)All four the same
Vector4(Vector3 xyz, float w)
Vector4.Zero(0, 0, 0, 0)
Length()The vector's magnitude

Operators: +, -, * (by a float, either side), / (by a float).

There is no Color type in 0.1.0

Every colour in the API is a Vector4SpriteRendererComponent.Color, TextComponent.Color, UIImage.Color, ParticleEmitter.TintMultiplier, Material.SetColor. Give yourself named constants:

csharp
public static class Palette
{
    public static readonly Vector4 White       = new Vector4(1, 1, 1, 1);
    public static readonly Vector4 Transparent = new Vector4(1, 1, 1, 0);
    public static readonly Vector4 HitRed      = new Vector4(1, 0.3f, 0.3f, 1);
}

Vector2Int

Two ints — tilemap cell coordinates, and grid maths generally.

Member
X, YThe components
Vector2Int(int x, int y)
Vector2Int(int scalar)Both the same
Vector2Int.Zero(0, 0)

Operators: +, -, ==, !=. It also implements Equals, GetHashCode and ToString, so it works as a dictionary key and prints as (3, 5).

csharp
Vector2Int cell = m_Map.WorldToCell(worldPoint);
Vector2Int above = cell + new Vector2Int(0, 1);

if (m_Map.GetTile(above) == 0)
    m_Map.SetTile(above, Rock);

var visited = new System.Collections.Generic.HashSet<Vector2Int>();
visited.Add(cell);

Vector2Int is the only one with equality

Vector2, Vector3 and Vector4 don't define ==, and comparing floats for exact equality is usually wrong anyway. Compare a distance against a small threshold instead:

csharp
if ((target - Translation).Length() < 0.01f)
    Arrived();

What isn't here

No dot or cross product, no normalize, no lerp, no distance helper, no matrix or quaternion type. Write what you need — the pieces are all public:

csharp
public static class VectorMath
{
    public static float Dot(Vector2 a, Vector2 b) => a.X * b.X + a.Y * b.Y;

    public static Vector2 Normalized(Vector2 v)
    {
        float len = v.Length();
        return len > 0.0001f ? v / len : Vector2.Zero;
    }

    public static Vector2 Lerp(Vector2 a, Vector2 b, float t) => a + (b - a) * t;

    public static float Distance(Vector3 a, Vector3 b) => (b - a).Length();
}

System.Math and System.MathF are available for the scalar side.

See also