Hello, is there an explanation for why Vector2Int.Clamp doesn’t return Vector2Int struct and is a void?
In the case of Mathf.Clamp, it returns a float, so it’s inconsistent.
If there is no reason, any chance of changing that by Unity devs?
Its not a static method, you are supposed to use it directly on the vector that you want to clamp
so not “Vector2int.Clamp(myVec, a, b)” but “myVec.Clamp(a, b)”
Yeah @eses . That’s what I meant.
I’ve just made an extension method to return IntVector2, but the problem with the built in method stays the same - it is inconvenient because I cannot just clamp the Vector2Int values, I need to set variables to be clamped instead if I want to use it.
It’s conveniance depends on what purpose you need it for.
To keep a value clamped in-place the code is simply myVec.Clamp(min, max)
vs what you want: myVec = Vector2Int.Clamp(myVec, min, max)
(reassign value to itself, if this followed the same approach as Vector2.ClampMagnitude, this would involve alotting new memory to accomodate the result of the clamp method)
It’s only less conveniant if you want to maintain both the clamped and unclamped value, seperatly
Vector2Int clampedVec = unclampedVec; //copy first
clampedVec.Clamp(min, max); //then clamp
vs vector2Int clampedVec = Vector2Int.Clamp(UnclampedVec, min, max);
@hpjohn Using both values after clamping is the most common operation done by me if not the only one in this case so I won’t stand this situation. I’m not setting the clamped value to any variable, I just use the function call as an argument.
I posted above about having to specially make variables for this, don’t need to getting it explained again btw.
Because that’s how it was written. Usually choices like this are done by a single developer on a whim just after coffee break in the midst of their work day. They’re not thinking about every nook and cranny of the API and how their shape/syntax will compare beyond what maybe the ‘code cop’ utility they may use on commit. There’s no strong rationale beyond “I did it that way because that’s how I write it.”
It’d be like asking why I use the left urinal when you use the right urinal. I don’t know… I just do.
See, there’s the thing… it’s “by you”. You prefer a certain way, others may prefer another. Maybe I use the left urinal because I’m left handed.
With that said, the inconsitency is annoying. But if you think THAT is inconsistent. You just wait as you dig into the Unity API. This thing is the most inconsistent thing that will keep a programming standards pedant awake at night with the most horrid nightmares.
I too have complained about the odd inconsistencies.
But then… you reflect on your own work and realize you yourself can’t remain consistent over 10+ years of creating code. How could you expect a team of developers at Unity, many of whom probably weren’t there when the project started, and many who are no longer there. So yeah, inconsistencies are inevitable.
Mathf was written near version 1, Vector2Int was written YEARS later.
You may argue Unity is a big company though and other big companies can remain consistent. Like the .Net framework itself is pretty darn consistent (though really, I could find inconsistencies like this in it). But yeah Microsoft has a much larger budget and therefore can afford to have much higher standards on their developers. Unity wasn’t a very big/well-known company for the first several years of its existence. And we’re talking about comparing parts of the API that existed before and after they finally hit big. And changing API after its been in the wild for years, not easy.
Anyways… Mathf is a static math util (really a wrapper around System.Math with a preference for floats over double). Where as Vector2Int is its own mutatable struct. Mathf is inherently immutable, struct is inherently mutable. There’s some logic for why they are written differently despite what you prefer.
If you wanted a version of Clamp that was more like Mathf.Clamp, why would you make it an extension method? Extension methods are static methods that give syntax sugar so they could be called like member methods. Which means you wrote a method that follows a shape more like Vector2Int.Clamp, but with a return.
What I mean is. Mathf.Clamp is used like so:
value = Mathf.Clamp(value, min, max);
Vector2Int.Clamp is used like so:
value.Clamp(min, max);
If you wanted a version of Vector2Int.Clamp that worked like Mathf.Clamp you’d probably write:
public static class MathUtils
{
public static Vector2Int Clamp(Vector2Int value, Vector2Int min, Vector2Int max)
{
value.Clamp(min, max);
return value;
}
}
And then use it like:
value = MathUtils.Clamp(value, min, max);
Where as if you did it as an extension method… maybe like so:
public static class MathUtils
{
public static Vector2Int ClampAlt(this Vector2Int value, Vector2Int min, Vector2Int max)
{
value.Clamp(min, max);
return value;
}
}
You’d end up with:
value = value.ClampAlt(min, max);
Which is more of a frankenstein of Mathf.Clamp and Vector2Int.Clamp, which you already said were inconsistent. And now are just even more inconsistent with a 3rd shape.
And lets not forget, extension methods can still be called directly as the static method they are.
If Clamp method had return Vector2Int, you could use both options. You’d just need to change abc.Clamp to abc = value.Clamp or abc.Clamp from code above and that’s all. It would be more universal.
But anyway: the life of a programmer is a life of compromises. If some perfectionist wants everything done his way, he needs to make his own engine or somehow override built in things.
And that’s all. Any sensible continuation of this thread would only come if Unity staff really changed the way it works.