Another datatype, or two if you want. Integer Vectors in 2D and 3D. They work nearly identically to the standard Vector2 and Vector3 types, but use integers only. I did not write these myself. The original idea was a request in the Unity3D forums and the original implementation was done there by Lysander. I only made some minor changes to it.
<pre>using UnityEngine; using System; // Integer Vector2 // © Lysander from the Unity3D Forums namespace Utilities { [Serializable] public struct Int2 : IEquatable<Int2> { // Properties public int x { get; set; } public int y { get; set; } public Int2 normalized { get { Int2 newVector = new Int2(x, y); newVector.Normalize(); return newVector; } } public float magnitude { get { return Mathf.Sqrt(x * x + y * y); } } public float sqrMagnitude { get { return x * x + y * y; } } // Indexer public int this[int index] { get { switch(index) { case 0: return x; case 1: return y; default: throw new IndexOutOfRangeException("Invalid Int2 index"); } } set { switch(index) { case 0: x = value; break; case 1: y = value; break; default: throw new IndexOutOfRangeException("Invalid Int2 index"); } } } // Constructors public Int2(int vX, int vY) : this() { x = vX; y = vY; } // Static Conversions From Other Types public static Int2 FromVector2(Vector2 vector2) { return new Int2 { x = Mathf.RoundToInt(vector2.x), y = Mathf.RoundToInt(vector2.y) }; } public static Int2 FromVector3(Vector3 vector3) { return new Int2 { x = Mathf.RoundToInt(vector3.x), y = Mathf.RoundToInt(vector3.y) }; } public static Int2 FromInt3(Int3 int3) { return new Int2 { x = int3.x, y = int3.y }; } // Conversions To Other Types public Vector2 ToVector2() { return new Vector2(x, y); } public Vector3 ToVector3() { return new Vector3(x, y, 0f); } public Int3 ToInt3() { return new Int3(x, y, 0); } // Static Int2 Values public static readonly Int2 zero = new Int2(0, 0); public static readonly Int2 up = new Int2(0, 1); public static readonly Int2 down = new Int2(0, -1); public static readonly Int2 right = new Int2(1, 0); public static readonly Int2 left = new Int2(-1, 0); public static readonly Int2 one = new Int2(1, 1); // Other Static Functions public static Int2 Scale(Int2 a, Int2 b) { return new Int2(a.x * b.x, a.y * b.y); } public static Int2 Reflect(Int2 inDirection, Int2 inNormal) { return -2f * Dot(inNormal, inDirection) * inNormal + inDirection; } public static float Dot(Int2 a, Int2 b) { return a.x * b.x + a.y * b.y; } public static float Angle(Int2 from, Int2 to) { return Mathf.Acos(Mathf.Clamp(Dot(from.normalized, to.normalized), -1f, 1f)) * 57.29578f; } public static float Distance(Int2 a, Int2 b) { return (a - b).magnitude; } public static Int2 ClampMagnitude(Int2 vector, float maxLength) { if(vector.sqrMagnitude > maxLength * maxLength) { return vector.normalized * maxLength; } return vector; } public static Int2 Min(Int2 a, Int2 b) { return new Int2(Mathf.Min(a.x, b.x), Mathf.Min(a.y, b.y)); } public static Int2 Max(Int2 a, Int2 b) { return new Int2(Mathf.Max(a.x, b.x), Mathf.Max(a.y, b.y)); } // Other Functions public void Set(int vX, int vY) { x = vX; y = vY; } public void Scale(Int2 scale) { x *= scale.x; y *= scale.y; } public void Normalize() { float num = magnitude; if(num > 1E-05f) this /= num; else this = zero; } public void ShiftAll(int amount) { x += amount; y += amount; } public void ShiftAll(float amount) { ShiftAll(Mathf.RoundToInt(amount)); } // Int2 & Int2 Operator Overloads public static Int2 operator +(Int2 a, Int2 b) { return new Int2(a.x + b.x, a.y + b.y); } public static Int2 operator -(Int2 a, Int2 b) { return new Int2(a.x - b.x, a.y - b.y); } public static Int2 operator -(Int2 a) { return new Int2(-a.x, -a.y); } public static Int2 operator *(Int2 a, Int2 b) { return new Int2(a.x * b.x, a.y * b.y); } public static Int2 operator /(Int2 a, Int2 b) { return new Int2(a.x / b.x, a.y / b.y); } // Int2 & Int Operator Overloads public static Int2 operator *(Int2 a, int d) { return new Int2(a.x * d, a.y * d); } public static Int2 operator *(Int2 a, float d) { return new Int2(Mathf.RoundToInt(a.x * d), Mathf.RoundToInt(a.y * d)); } public static Int2 operator *(int d, Int2 a) { return new Int2(a.x * d, a.y * d); } public static Int2 operator *(float d, Int2 a) { return new Int2(Mathf.RoundToInt(a.x * d), Mathf.RoundToInt(a.y * d)); } public static Int2 operator /(Int2 a, int d) { return new Int2(a.x / d, a.y / d); } public static Int2 operator /(Int2 a, float d) { return new Int2(Mathf.RoundToInt(a.x / d), Mathf.RoundToInt(a.y / d)); } // Equality and Inequality Operator Overloads public static bool operator ==(Int2 i1, Int2 i2) { return i1.x.Equals(i2.x) && i1.y.Equals(i2.y); } public static bool operator !=(Int2 i1, Int2 i2) { return !i1.x.Equals(i2.x) || !i1.y.Equals(i2.y); } // miscellaneous overrides public override bool Equals(object obj) { if(obj is Int2) { Int2 vector = (Int2)obj; return x.Equals(vector.x) && y.Equals(vector.y); } return false; } public bool Equals(Int2 vector) { return x.Equals(vector.x) && y.Equals(vector.y); } public override int GetHashCode() { return x.GetHashCode() ^ y.GetHashCode() << 2; } public override string ToString() { return "(" + x + ", " + y + ")"; } public static implicit operator Vector2(Int2 vector) { return new Vector2(vector.x, vector.y); } } }
using UnityEngine; using System; // Integer Vector3 // © Lysander from the Unity3D Forums namespace Utilities { [Serializable] public struct Int3 : IEquatable<Int3> { // Properties public int x { get; set; } public int y { get; set; } public int z { get; set; } public Int3 normalized { get { Int3 newVector = new Int3(x, y, z); newVector.Normalize(); return newVector; } } public float magnitude { get { return Mathf.Sqrt(x * x + y * y + z * z); } } public float sqrMagnitude { get { return x * x + y * y + z * z; } } // Indexer public int this[int index] { get { switch(index) { case 0: return x; case 1: return y; case 2: return z; default: throw new IndexOutOfRangeException("Invalid Int3 index!"); } } set { switch(index) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new IndexOutOfRangeException("Invalid Int3 index!"); } } } // Constructors public Int3(int vX, int vY, int vZ) : this() { x = vX; y = vY; z = vZ; } public Int3(int vX, int vY) : this() { x = vX; y = vY; z = 0; } // Static Conversions From Other Types public static Int3 FromVector2(Vector2 vector2) { return new Int3 { x = Mathf.RoundToInt(vector2.x), y = Mathf.RoundToInt(vector2.y) }; } public static Int3 FromVector3(Vector3 vector3) { return new Int3 { x = Mathf.RoundToInt(vector3.x), y = Mathf.RoundToInt(vector3.y), z = Mathf.RoundToInt(vector3.z) }; } public static Int3 FromInt2(Int2 int2) { return new Int3 { x = int2.x, y = int2.y }; } // Conversions To Other Types public Vector2 ToVector2() { return new Vector2(x, y); } public Vector3 ToVector3() { return new Vector3(x, y, z); } public Int2 ToInt2() { return new Int2(x, y); } // Static Int2 Values public static readonly Int3 zero = new Int3(0, 0, 0); public static readonly Int3 forward = new Int3(0, 0, 1); public static readonly Int3 back = new Int3(0, 0, -1); public static readonly Int3 up = new Int3(0, 1, 0); public static readonly Int3 down = new Int3(0, -1, 0); public static readonly Int3 right = new Int3(1, 0, 0); public static readonly Int3 left = new Int3(-1, 0, 0); public static readonly Int3 one = new Int3(1, 1, 1); // Other Static Functions public static Int3 Scale(Int3 a, Int3 b) { return new Int3(a.x * b.x, a.y * b.y, a.z * b.z); } public static Int3 Cross(Int3 a, Int3 b) { return new Int3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } public static Int3 Reflect(Int3 inDirection, Int3 inNormal) { return -2f * Dot(inNormal, inDirection) * inNormal + inDirection; } public static float Dot(Int3 a, Int3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } public static float Angle(Int3 from, Int3 to) { return Mathf.Acos(Mathf.Clamp(Dot(from.normalized, to.normalized), -1f, 1f)) * 57.29578f; } public static float Distance(Int3 a, Int3 b) { Int3 vector = new Int3(a.x - b.x, a.y - b.y, a.z - b.z); return Mathf.Sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z); } public static Int3 ClampMagnitude(Int3 vector, float maxLength) { if(vector.sqrMagnitude > maxLength * maxLength) { return vector.normalized * maxLength; } return vector; } public static Int3 Min(Int3 a, Int3 b) { return new Int3(Mathf.Min(a.x, b.x), Mathf.Min(a.y, b.y), Mathf.Min(a.z, b.z)); } public static Int3 Max(Int3 a, Int3 b) { return new Int3(Mathf.Max(a.x, b.x), Mathf.Max(a.y, b.y), Mathf.Max(a.z, b.z)); } // Other Functions public void Set(int vX, int vY, int vZ) { x = vX; y = vY; z = vZ; } public void Scale(Int3 scale) { x *= scale.x; y *= scale.y; z *= scale.z; } public void Normalize() { float num = magnitude; if(num > 1E-05f) this /= num; else this = zero; } public void ShiftAll(int amount) { x += amount; y += amount; z += amount; } public void ShiftAll(float amount) { ShiftAll(Mathf.RoundToInt(amount)); } // Int2 & Int2 Operator Overloads public static Int3 operator +(Int3 a, Int3 b) { return new Int3(a.x + b.x, a.y + b.y, a.z + b.z); } public static Int3 operator -(Int3 a, Int3 b) { return new Int3(a.x - b.x, a.y - b.y, a.z - b.z); } public static Int3 operator -(Int3 a) { return new Int3(-a.x, -a.y, -a.z); } public static Int3 operator *(Int3 a, Int3 b) { return new Int3(a.x * b.x, a.y * b.y, a.z * b.z); } public static Int3 operator /(Int3 a, Int3 b) { return new Int3(a.x / b.x, a.y / b.y, a.z / b.z); } // Int2 & Int Operator Overloads public static Int3 operator *(Int3 a, int d) { return new Int3(a.x * d, a.y * d, a.z * d); } public static Int3 operator *(Int3 a, float d) { return new Int3(Mathf.RoundToInt(a.x * d), Mathf.RoundToInt(a.y * d), Mathf.RoundToInt(a.z * d)); } public static Int3 operator *(int d, Int3 a) { return new Int3(a.x * d, a.y * d, a.z * d); } public static Int3 operator *(float d, Int3 a) { return new Int3(Mathf.RoundToInt(a.x * d), Mathf.RoundToInt(a.y * d), Mathf.RoundToInt(a.z * d)); } public static Int3 operator /(Int3 a, int d) { return new Int3(a.x / d, a.y / d, a.z / d); } public static Int3 operator /(Int3 a, float d) { return new Int3(Mathf.RoundToInt(a.x / d), Mathf.RoundToInt(a.y / d), Mathf.RoundToInt(a.z / d)); } // Equality and Inequality Operator Overloads public static bool operator ==(Int3 a, Int3 b) { return a.x.Equals(b.x) && a.y.Equals(b.y) && a.z.Equals(b.z); } public static bool operator !=(Int3 a, Int3 b) { return !a.x.Equals(b.x) || !a.y.Equals(b.y) || !a.z.Equals(b.z); } // Overrides & Implementations public override bool Equals(object obj) { if(obj is Int3) { Int3 vector = (Int3)obj; return x.Equals(vector.x) && y.Equals(vector.y) && z.Equals(vector.z); } return false; } public bool Equals(Int3 vector) { return x.Equals(vector.x) && y.Equals(vector.y) && z.Equals(vector.z); } public override int GetHashCode() { return x.GetHashCode() ^ y.GetHashCode() << 2 ^ z.GetHashCode() >> 2; } public override string ToString() { return "(" + x + ", " + y + ", " + z + ")"; } public static implicit operator Vector3(Int3 vector) { return new Vector3(vector.x, vector.y, vector.z); } } }
Comments