Struct extension methods

With code:

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);
}

the FixRounding method doesn't actually change the vector's values although Mathf.Approximately returns true.

Jon Skeet
people
quotationmark

This declaration:

public static void FixRounding(this Vector3 v)

... means v is being passed by value, and it's a struct, assuming the documentation is correct. Therefore any changes you make to it won't be visible to the caller. You need to make it a regular method, and pass v by reference:

public static void FixRounding(ref Vector3 v)

and call it as:

TypeDeclaringMethod.FixRounding(ref pos);

Here's a demonstration of extension methods that try to modify structs passed by value failing:

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
    }
}

Now if Vector3 were a class, the second line printed would be x=20; y=40; z=60... but because it's a struct, modifying the value that's passed doesn't change it from the caller's perspective. Passing it by reference fixes that, hence the third line of output.

people

See more on this question at Stackoverflow