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, Y | The 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).
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, Z | The components |
Vector3(float x, float y, float z) | |
Vector3(float scalar) | All three the same |
Vector3.Zero | (0, 0, 0) |
XY | The 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:
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, W | The 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 Vector4 — SpriteRendererComponent.Color, TextComponent.Color, UIImage.Color, ParticleEmitter.TintMultiplier, Material.SetColor. Give yourself named constants:
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, Y | The 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).
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:
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:
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
- GameEntity —
Translation - Physics2D — queries taking and returning vectors
- TilemapComponent —
Vector2Intcells