Unity 2017中自定义IntVector2类及全局共享实现方案问询
嘿,这个痛点我太熟悉了——用Vector2存整数然后反复转类型,不仅麻烦还容易踩浮点精度的坑,尤其是和二维数组索引配合的时候。完全可以自己实现一个IntVector2类,完美解决你的需求,而且能在所有脚本里轻松复用!
1. 编写核心的IntVector2类
先创建一个单独的IntVector2.cs文件,放在你项目的Scripts/Utility(或者任何你习惯的工具类目录)里,这样所有脚本都能直接引用。代码里要包含必要的字段、构造函数,还要重载常用运算符,方便和原生Vector2交互:
using UnityEngine; // 加上这个特性,让类能在Unity编辑器的Inspector面板里显示和编辑 [System.Serializable] public struct IntVector2 { public int x; public int y; // 构造函数 public IntVector2(int x, int y) { this.x = x; this.y = y; } // 重载加法运算符 public static IntVector2 operator +(IntVector2 a, IntVector2 b) { return new IntVector2(a.x + b.x, a.y + b.y); } // 重载减法运算符 public static IntVector2 operator -(IntVector2 a, IntVector2 b) { return new IntVector2(a.x - b.x, a.y - b.y); } // 重载相等判断 public static bool operator ==(IntVector2 a, IntVector2 b) { return a.x == b.x && a.y == b.y; } // 重载不等判断 public static bool operator !=(IntVector2 a, IntVector2 b) { return !(a == b); } // 重写Equals方法,配合==运算符 public override bool Equals(object obj) { if (obj is IntVector2 other) { return x == other.x && y == other.y; } return false; } // 重写GetHashCode public override int GetHashCode() { return x.GetHashCode() ^ y.GetHashCode(); } // 转换为Unity原生Vector2(隐式转换,方便直接传入需要Vector2的API) public static implicit operator Vector2(IntVector2 intVec) { return new Vector2(intVec.x, intVec.y); } // 从Vector2转换为IntVector2(显式转换,避免隐式丢失精度) public static explicit operator IntVector2(Vector2 vec) { return new IntVector2(Mathf.RoundToInt(vec.x), Mathf.RoundToInt(vec.y)); } // 可选:转成字符串方便调试 public override string ToString() { return $"({x}, {y})"; } // 可选:直接获取二维数组对应位置的元素,带边界检查 public T GetArrayElement<T>(T[,] array) { if (x < 0 || x >= array.GetLength(0) || y < 0 || y >= array.GetLength(1)) { Debug.LogError($"IntVector2 ({x}, {y}) 超出数组边界!"); return default(T); } return array[x, y]; } }
2. 在脚本中使用IntVector2
现在你可以在任何脚本里直接声明和使用这个类了,和Vector2的用法几乎一样,但全程都是整数:
public class GridManager : MonoBehaviour { // 可以在Inspector面板直接设置这个值 public IntVector2 playerGridPos; private int[,] gridValues = new int[20, 20]; void Update() { // 直接用x和y作为数组索引,完全不用类型转换 gridValues[playerGridPos.x, playerGridPos.y] = 1; // 和Vector2互相转换,兼容Unity的API Vector2 worldPos = transform.position; IntVector2 gridPos = (IntVector2)worldPos; // 使用扩展方法获取数组元素 int currentValue = playerGridPos.GetArrayElement(gridValues); } }
3. 额外优化小技巧
- 如果需要更多运算符(比如乘法、除法),可以照着上面的写法继续重载;
- 可以添加方向常量,比如
public static readonly IntVector2 Up = new IntVector2(0, 1);,方便快速获取常用方向; - 如果需要在Gizmos里绘制这个点,可添加扩展方法:
public static void DrawGizmos(IntVector2 pos, float size = 0.5f) { Gizmos.DrawSphere((Vector2)pos, size); }。
这样你的IntVector2就完全可以替代Vector2在整数场景下的使用,全程不用再担心浮点转整数的问题啦!
内容的提问来源于stack exchange,提问作者Round-Sliced
相关产品推荐
相关产品推荐

