扩展方法无意中复制参数

时间:2015-02-05 23:53:18

标签: vector reference unity3d extension-methods

我无法使用扩展方法,它会运行,但我作为参数输入的Vector3与我在TurnClockWiseXZ方法中操作的向量不同。

这是调用方法的类。

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {

    void FixedUpdate () {

        Vector3 test = new Vector3(2,0,3);

        Debug.Log ("1: "+test); 
        test.TurnClockWiseXZ();
        Debug.Log ("2: "+test);
    }
}

这是我添加方法的地方:

using UnityEngine;
using System.Collections;

public static class ExtendClass {

    public static void TurnClockWiseXZ( this Vector3 vector){
        float x = vector.z;
        float y = vector.y;
        float z = -vector.x;
        vector.Set(x,y,z);
    }
}

这是我收到的调试信息:

1:(2.0,0.0,3.0)

2:(2.0,0.0,3.0)

这就是我想要的:

1:(2.0,0.0,3.0)

2:(3.0,0.0,-2.0)

1 个答案:

答案 0 :(得分:1)

不幸的是,因为Vector3是 struct (因此是 value 类型),所以它总是通过制作副本传递给方法本身(通过价值)。因此,扩展方法中的任何修改只会影响副本。

我看到了一些替代方案。

1)使您的扩展方法返回 new 复制的向量并重置外部变量。调用时会出现这种情况:test = test.TurnClockwiseXZ();

2)使用静态方法(而不是扩展方法)返回void,但将vector作为ref参数。所以它看起来像这样:ExtendClass.TurnClockwiseXZ(ref test);定义将是public void TurnClockwiseXZ(ref Vector3 vect)这通过引用传递向量,因此它修改了函数内部的外部变量。

3)如果你只是在大部分时间内修改变换中的位置(就像我一样),那么你可以让扩展方法直接在变换上运行。因为转换是一个类(而不是结构),所以它默认通过引用传递,并且扩展方法可以工作。该解决方案看起来像这样:

public void TurnClockwiseXZ(this Transform transform) {
     float x = transform.position.z;
     float y = transform.position.y;
     float z = -transform.position.x;
     transform.position = new Vector3(x,y,z);
}

用作:transform.TurnClockwiseXZ();

我个人在变换上有SetX,SetY和SetZ的扩展方法,可以轻松修改位置。省去了一些麻烦。