You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:27:35