- Home /
Create custom constructors for certain Value types/Objects (Vector3, Transform, etc...)
I'm interested in extending/creating new Vector3 constructors for my project, but this could be extended to any Monobehavior object. There are extension methods you can create for them, but the change I want to do would be on construction time. For example, I'd like to be able to construct a vector like so;
Vector2 xy = new Vector2(1,1);
float z = 0;
// Constructor takes in Vector2 for the x and y coordinates, and a float for the z
Vector3 newVect = new Vector3(xy, z);
Is there any way to do this without creating a subclass of Vector3 with its own constructors?
Answer by Bunny83 · Dec 12, 2017 at 04:53 PM
As Bonfire said this has nothing to do with MonoBehaviours so your question title is misleading. MonoBehaviour derived classes can't be created with "new" so contructors are pretty irrelevant for those.
Vector3 is a value type. A constructor for value type is more like an initialization method since value types do not have to be "created" / allocated.
Unity's vector types have implicit type conversion operators which allow implicit conversion between Vector2 / Vector3 / Vector4
If you need to just change a single component of a vector you may just create some extension methods like those. They all return a Vector4 but as i said it can be implicitly converted into Vector3 or 2.
With those you can simply do:
Vector2 vec = new Vector2(1, 2);
Vector3 newVect = vec.XY__(5); // (1, 2, 5)
But also things like
Vector3 v2 = vec.X_Y_(0, 5); // (2, 0, 1, 5)
Vector4 v3 = vec.XY__().YXZW().XXYY(); // (1,2) --> (2,1,0,0) --> (2, 2, 1, 1)
The method names simply represents the layout of the returned vector "ABCD" where "A" will be the new x component "B" the new y component and so on. An underscore stands for a parameter / placeholder. So "_X_Y" returns the incoming x as y the incoming y as w and the x and z components are the parameters to the method. If you don't pass a parameter it results to "0".
It's a bit like the cg shader swizzle components just not that advanced.
A better answer than $$anonymous$$e, Bunny having taken the trouble to explain about value types. And extension methods are simpler to use than my factory approach.
I'd add a $$anonymous$$or point though, following my comment about names telling you what things do...
I would name those extension methods more explicitly eg Create_X_Y_()
or something like that, so that one doesn't have to look at the methods' definitions to know whether they give you a new instance or not (the same signature could have been used for a method which modifies the vector passed in).
Answer by Bonfire-Boy · Dec 12, 2017 at 02:29 PM
You could create a factory method...
static class VectorFactory
{
public static Vector3 CreateWithZ(Vector3 v, float z)
{
v.z = z;
return v;
}
}
And call it with
Vector3 newVect = VectorFactory.CreateWithZ(xy, z);
Note that
1) this has nothing to do with MonoBehaviours.
2) No, you can't create a new constructor for Vector3
2) Even if you could create a new constructor for Vector3, the factory approach has significant advantages... The name of the function tells you what it does, and it leaves room to create similar functions that (for example) modify the x or y values (if using constructors, how would you distinguish them?).