The "problem"
I appreciate this is similar to a question that has been asked many times before, I am aware of why this "problem" exists but I am now just trying to find a way to mitigate it.
Using Unity's transform class as an example, as we all likely know to change one of it's Vector3's position axis on it's own like x, y or z requires 3 lines of code, something similar to:
Vector3 position = transform.position;
position.x = 100f;
transform.position = position;
This will always be the case because it is using a getter so cannot be set, in other words we have to replace the entire position struct rather than modify it while attached to the transform object. There is something about this that just doesn't "feel nice", having to use 3 lines, create a new variable each time just to set it instantly and use it then be done with it, I hope I'm not the only one that feels this way! I have gone about a few different ways of trying to turn this into a one liner. One option is by adding extension methods for each internal value such as:
/* Transform
------------------------------------------*/
public static void SetX(this Transform transform, float x) {
Vector3 position = transform.position;
position.x = x;
transform.position = position;
}
public static void SetY(this Transform transform, float y) {
Vector3 position = transform.position;
position.y = y;
transform.position = position;
}
And can be used like this:
transform.SetX(100f);
However this keeps on coming up with other objects in Unity like Color/Color32 and a few others that are commonly used, and it would be nice to have a catch all solution, rather than having to write an extension method for every single internal value of every single struct like this.
My attempt at turning this into a one liner: Please know that I am aware my soltion below is pretty hideous, however it does work:
public static T ModifyInternalValue<T>(T obj, Func<T, T> action)
{
return action.Invoke(obj);
}
And this would be used like so:
transform.position = ModifyInternalValue<Vector3>(transform.position, p => {p.x = 100f; return p;});
It is disgusting in alot of ways, but my final question is quite simple:
Is there a way of simplifying this process? Neatening it up or making a short one liner for assigning a struct's internal values?
Thanks in advance for any advice :)
CodePudding user response:
transform.position = new Vector3(100, transform.position.y, transform.position.z);
CodePudding user response:
In C# 10, with expressions can be used on structs too:
transform.position = transform.position with { x = 100 };
That is a lot shorter than your ModifyInternalValue.
However, I don't think Unity supports C# 10 at the time of writing.
Before C# 10, with expressions only work with records, unfortunately.
Do note that both Vector3 and Color provide overloaded operators and static fields for unit vectors. You can also do this, which is also a similar length:
// using static UnityEngine.Vector3;
transform.position = (transform.position.x - 100) * left;
A similar thing can be done with Color with red, green and blue, though whether that is readable is questionable.
