Vector3是如何实现的?为什么属性是只读的?

6
Vector3 v = new Vector3(1, 1, 1);
v.x = 5;

为什么我不能这样做?我必须执行 v = new Vector3(5, v.y, v.z);

我猜测这背后的原因是出于性能考虑。但我无法猜测为什么这是必要的。


编辑:

我撒了谎,实际上这确实可以工作。我一直在使用 transform.positionVector3总是返回自己的副本,这就是为什么在它上面设置值不起作用的原因。某种Unity的魔力。


它们不符合MSDN的规范:http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector3_members.aspx。但你很幸运..通常情况下,结构体是小型不可变对象(如DateTime)。 - Simon Whitehead
@SimonWhitehead 我正在使用Unity3D,它支持C#。我以为一切都是一样的,也许这只是Unity的特殊情况?有人能确认一下吗? - Farzher
Vector3 定义在哪里?上面的注释中链接的类型来自 XNA。那很可能不是你正在使用的类型。 - Brian Rasmussen
很抱歉多次编辑标签。Vector3上下文不清楚。此外,vector标签与向量组件结构无关。 - Austin Brunkhorst
关于实际问题,根据文档,您可以使用.Set(x, y, z)分别更新每个组件的值。 - Austin Brunkhorst
4个回答

6
我撒谎了,这实际上是有效的。 我一直在使用的Vector3 transform.position总是返回其自身的副本,这就是为什么在其上设置值不起作用的原因。 这是某种Unity魔法。
实际上,原因是Vector3是结构体。 在C#中,结构体是值类型。 因此,它们始终按值返回,而类可以通过引用传递/返回。 对于所有包装结构成员(例如Rect,Vector2等)的属性,行为将相同。
由于这是属性,当您调用它时,get方法将返回结构体位置的副本值。 您始终需要将其分配给本地引用,对其进行修改,然后重新分配它:
Vector3 t_Pos = transform.position;
t_Pos.Normalize();
transform.position = t_Pos;

2

Unity不允许直接访问Transform.position,因为position是派生的。换句话说,Unity在内部存储了一个变换矩阵,因此当你获取位置时,它会从变换矩阵中抓取一个副本。

因此,获取position可能类似于以下内容:

public class Transform
{
    public Vector3 position
    {
        get
        {
            // it would be this if the matrix itself is in world space
            return new Vector3(matrix.m30, matrix.m31, matrix.m32);
        }

        set
        {
            // it probably doesn't use these mono bindings, but
            // I'll use them here for this example
            matrix.SetRow(3, new Vector4(value.x, value.y, value.z));
        }
    }
}

1

(免责声明:我不是Unity开发者)

我看到的每个示例都初始化了一个新的Vector3.. 这意味着在Unity中这些属性可能是只读的(在XNA中不是只读的)。

但是,文档显示Vector3有一个Set()方法。所以你可以(显然)这样做:

v.Set(5, v.y, v.z);

无法与transform.position Vector3一起使用。据我所知,这是因为当您使用'transform.position'时,它会返回一个新的vector3,而不是给您实际位置的引用。然后,当您使用Vector3.Set()时,它修改了返回的Vector3,而实际上并没有更改原始位置!真是令人困惑的Unity。 - Farzher

1

Unity中的Vector3也是结构体,因此即使只更改一个值,您也需要创建一个新实例。至于问题本身,正如您已经提到的那样,Vector3的属性并不是只读的。

来源


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接