为什么我们在初始化 Vector3 时使用 "new" 关键字,而不是整数?



为什么如果我要初始化字符串或整数,我可以简单地这样做:

int number = 1;
string word = "word";

但是如果我想初始化一个 Vector3,那么我必须这样做:

Vector3 coordinate = new Vector3(1f,1f,1f);

这样做的背景是,我正在创建一个相当大的数组,并且必须写出新的 Vector3...每次都变得非常乏味:

Vector3[,] coordsList = new Vector3[11, 11]
{
    {new Vector3(-1.32f,1.32f), new Vector3(-1.08f,1.32f), new Vector3(-0.84f,1.32f), new Vector3(-0.6f,1.32f), new Vector3(-0.36f,1.32f), new Vector3(-0.12f,1.32f), new Vector3(0.12f,1.32f), new Vector3(0.36f,1.32f), new Vector3(0.6f,1.32f), new Vector3(0.84f,1.32f), new Vector3(1.08f,1.32f) },
    {new Vector3(-1.32f,1.08f), new Vector3(-1.08f,1.08f), new Vector3(-0.84f,1.08f), new Vector3(-0.6f,1.08f), new Vector3(-0.36f,1.08f), new Vector3(-0.12f,1.08f), new Vector3(0.12f,1.08f), new Vector3(0.36f,1.08f), new Vector3(0.6f,1.08f), new Vector3(0.84f,1.08f), new Vector3(1.08f,1.08f) },
    {new Vector3(-1.32f,0.84f), new Vector3(-1.08f,0.84f), new Vector3(-0.84f,0.84f), new Vector3(-0.6f,0.84f), new Vector3(-0.36f,0.84f), new Vector3(-0.12f,0.84f), new Vector3(0.12f,0.84f), new Vector3(0.36f,1.32f), new Vector3(0.6f,0.84f), new Vector3(0.84f,0.84f), new Vector3(1.08f,0.84f) },
    {new Vector3(-1.32f,0.60f), new Vector3(-1.08f,0.60f), new Vector3(-0.84f,0.60f), new Vector3(-0.6f,0.60f), new Vector3(-0.36f,0.60f), new Vector3(-0.12f,0.60f), new Vector3(0.12f,0.60f), new Vector3(0.36f,0.60f), new Vector3(0.6f,0.60f), new Vector3(0.84f,0.60f), new Vector3(1.08f,0.60f) },
    {new Vector3(-1.32f,0.36f), new Vector3(-1.08f,0.36f), new Vector3(-0.84f,0.36f), new Vector3(-0.6f,0.36f), new Vector3(-0.36f,0.36f), new Vector3(-0.12f,0.36f), new Vector3(0.12f,0.36f), new Vector3(0.36f,0.36f), new Vector3(0.6f,0.36f), new Vector3(0.84f,0.36f), new Vector3(1.08f,0.36f) },
    {new Vector3(-1.32f,0.12f), new Vector3(-1.08f,0.12f), new Vector3(-0.84f,0.12f), new Vector3(-0.6f,0.12f), new Vector3(-0.36f,0.12f), new Vector3(-0.12f,0.12f), new Vector3(0.12f,0.12f), new Vector3(0.36f,0.12f), new Vector3(0.6f,0.12f), new Vector3(0.84f,0.12f), new Vector3(1.08f,0.12f) },
    {new Vector3(-1.32f,-0.12f), new Vector3(-1.08f,-0.12f), new Vector3(-0.84f,-0.12f), new Vector3(-0.6f,-0.12f), new Vector3(-0.36f,-0.12f), new Vector3(-0.12f,-0.12f), new Vector3(0.12f,1.32f), new Vector3(0.36f,-0.12f), new Vector3(0.6f,-0.12f), new Vector3(0.84f,-0.12f), new Vector3(1.08f,-0.12f) },
    {new Vector3(-1.32f,-0.36f), new Vector3(-1.08f,-0.36f), new Vector3(-0.84f,-0.36f), new Vector3(-0.6f,-0.36f), new Vector3(-0.36f,-0.36f), new Vector3(-0.12f,-0.36f), new Vector3(0.12f,-0.36f), new Vector3(0.36f,-0.36f), new Vector3(0.6f,-0.36f), new Vector3(0.84f,-0.36f), new Vector3(1.08f,-0.36f) },
    {new Vector3(-1.32f,-0.6f), new Vector3(-1.08f,-0.6f), new Vector3(-0.84f,-0.6f), new Vector3(-0.6f,-0.6f), new Vector3(-0.36f,-0.6f), new Vector3(-0.12f,-0.6f), new Vector3(0.12f,-0.6f), new Vector3(0.36f,-0.6f), new Vector3(0.6f,-0.6f), new Vector3(0.84f,-0.6f), new Vector3(1.08f,-0.6f) },
    {new Vector3(-1.32f,-0.84f), new Vector3(-1.08f,-0.84f), new Vector3(-0.84f,-0.84f), new Vector3(-0.6f,-0.84f), new Vector3(-0.36f,-0.84f), new Vector3(-0.12f,-0.84f), new Vector3(0.12f,-0.84f), new Vector3(0.36f,-0.84f), new Vector3(0.6f,-0.84f), new Vector3(0.84f,-0.84f), new Vector3(1.08f,-0.84f) },
    {new Vector3(-1.32f,-1.08f), new Vector3(-1.08f,-1.08f), new Vector3(-0.84f,-1.08f), new Vector3(-0.6f,-1.08f), new Vector3(-0.36f,-1.08f), new Vector3(-0.12f,-1.08f), new Vector3(0.12f,-1.08f), new Vector3(0.36f,-1.08f), new Vector3(0.6f,-1.08f), new Vector3(0.84f,-1.08f), new Vector3(1.08f,-1.08f) },
};

但是,如果它是一个整数数组,它会容易得多?Vector3 需要这个new关键字而整数或字符串不需要的关键字是什么?

Vector3[][] list = new (float x, float y)[][]
{
    new[] { (1.5f, 3.4f), (1.5f, 6.8f) },
    new[] { (1.5f, 3.4f), (1.5f, 6.8f) },
    new[] { (1.5f, 3.4f), (1.5f, 6.8f) },
    new[] { (1.5f, 3.4f), (1.5f, 6.8f) },
}.Select(r => r.Select(v => new Vector3(v.x, v.y)).ToArray()).ToArray();

您可以使用值元组(最新版本的 Unity 2018.3 现在支持)以可读且不那么乏味的方式构建数据 - 然后您可以使用 Select 将这些转换为 Vector3。

我认为大多数评论都足以涵盖您关于此处新关键字的方式和原因的问题。

Vector3需要 new 关键字的原因是Vector3是 Unity 中内置的结构,因此每次使用 new 关键字时,您都会创建 Vector3 结构的新实例,而对于 stringint,这些基本数据类型来自 C#。

希望这有助于解释差异!

根据最近的评论,我想提出这个解决方案(通过扩展方法)。

var list  = new (float X, float Y, float Z)[2, 2]
{
    {(-1.32f, 0f, 1.32f), (-1.32f, 0f, 1.32f)},
    {(-1.32f, 0f, 1.32f), (-1.32f, 0f, 1.32f)}
};
Vector3[,] coordsList = list.ToVector3();

然后你可以使用扩展方法...

public static class Vector3Extensions
{
    public static Vector3[,] ToVector3(this (float X, float Y, float Z)[,] value)
    {
        int columnCount = value.GetUpperBound(0);
        int rowCount = value.GetLength(0);
        
        var result = new Vector3[rowCount, columnCount];
        for (int i = 0; i < rowCount; i++)
        {
            for (int j = 0; j < columnCount; j++)
            {
                var tuple = ((float X, float Y, float Z))value.GetValue(i, j);
                result[i, j] = tuple.ToVector3();
            }
        }
        
        return result;
    }
    
    public static Vector3 ToVector3(this (float X, float Y, float Z) value)
    {
        return new Vector3(value.X, value.Y, value.Z);
    }
}

当然,原始解决方案会更有效率,但我不知道您当时使用的是 Unity 的结构。但是,此解决方案仍然尝试解决相同的可读性和重复代码问题。

<小时 />

原始帖子

我假设你的问题的目的是关于可读性和重构重复代码。您可以将元组与隐式运算符一起使用,以使其更像您想要的。

public class Vector3
{
    public Vector3(float x, float y)
    {
        this.X = x;
        this.Y = y;
    }
    
    public float X { get; set; }
    public float Y { get; set; }
    
    public static implicit operator (float X, float Y)(Vector3 value)
    {
        return (value.X, value.Y);
    }
    public static implicit operator Vector3 ((float X, float Y) value)
    {
        return new Vector3(value.X, value.Y);
    }
}

然后你可以这样构建它...

Vector3[,] coordsList  = new Vector3[2, 2]
{
    {(-1.32f,1.32f), (-1.32f,1.32f)},
    {(-1.32f,1.32f), (-1.32f,1.32f)}
};

您的坐标是一个 XY 镜像网格,这意味着您只有大约 6 个唯一值。 但是,为了使事情变得更容易,我们也会跟踪负面的。

float[] values = new float[] { 
    1.32f,  1.08f,  0.84f,  0.6f,  0.36f,  0.12f, 
   -0.12f, -0.36f, -0.6f, -0.84f, -1.08f, -1.32f };

现在使用嵌套的 for 循环来填充你的坐标数组:

Vector3[,] coordsList = new Vector3[11,11];
void Init() { 
    for ( int x = 0; x < coordsList.GetLength(0); x++) {
        for ( int y = 0; y < coordsList.GetLength(1); y++ ) {
            coordsList[x, y] = new Vector3(-values[x], values[y]);
        }
    }
}

如果要维护不同的坐标(即,不是网格映射),那么还有其他方法可以形成输入数据,但是转换为Vector3根本不会改变太多。

最新更新