使用代码:
someVector.FixRounding(); //round vector's values to integers if the difference is 1 epsilon
float x = someVector.x; //still getting old value
public static void FixRounding(this Vector3 v)
{
if (Mathf.Approximately(v.x, Mathf.Round(v.x))) v.x = Mathf.Round(v.x);
if (Mathf.Approximately(v.y, Mathf.Round(v.y))) v.y = Mathf.Round(v.y);
if (Mathf.Approximately(v.z, Mathf.Round(v.z))) v.z = Mathf.Round(v.z);
}
尽管Mathf.Approximately返回true,但FixRounding方法实际上并没有改变向量的值。
答案 0 :(得分:6)
此声明:
public static void FixRounding(this Vector3 v)
...意味着v
正在通过值传递 ,并且它是一个结构,假设documentation是正确的。因此,您对其所做的任何更改都不会对调用方可见。您需要将其设为常规方法,并通过引用传递v
:
public static void FixRounding(ref Vector3 v)
并将其命名为:
TypeDeclaringMethod.FixRounding(ref pos);
这里展示了尝试修改值失败传递的结构的扩展方法:
using System;
struct Vector3
{
public float x, y, z;
public override string ToString() => $"x={x}; y={y}; z={z}";
}
static class Extensions
{
public static void DoubleComponents(this Vector3 v)
{
v.x *= 2;
v.y *= 2;
v.z *= 2;
}
public static void DoubleComponentsByRef(ref Vector3 v)
{
v.x *= 2;
v.y *= 2;
v.z *= 2;
}
}
class Test
{
static void Main()
{
Vector3 vec = new Vector3 { x = 10, y = 20, z = 30 };
Console.WriteLine(vec); // x=10; y=20; z=30
vec.DoubleComponents();
Console.WriteLine(vec); // Still x=10; y=20; z=30
Extensions.DoubleComponentsByRef(ref vec);
Console.WriteLine(vec); // x=20; y=40; z=60
}
}
现在,如果Vector3
是一个类,则打印的第二行将是x = 20; Y = 40; z = 60 ...但是因为它是一个结构,修改传递的值并不会从调用者的角度改变它。通过引用传递它,因此修正了第三行。