While doing a tutorial from KidsCanCode, it dawned upon me that the clamp()
function allows for floats/ints to be clamped, but not other variable types like Vector2
s, Vector3
s, or Color
s that one might want to clamp to a range. What I'm proposing is to allow just that, as I don't imagine it would be too hard to implement and it would allow for code to be condensed a little more.
For example, for a Vector2
named position
, this functionality would allow this code snippet:
position.x = clamp(position.x, 0, get_viewport_rect().size.x)
position.y = clamp(position.y, 0, get_viewport_rect().size.y)
to be simplified to this:
position = clamp(position, Vector2(), get_viewport_rect().size)
(You can see how this might be useful for a Color
, where there might be a lot more values to clamp.)
Ideally, I would like to see clamp()
allowed for Vector2
, Vector3
, and Color
, at the least. (Though other types similar in nature to those three might be nice to allow clamping for too!)
Hope this isn't too much to ask for. :)
Similar to #8071
Not sure whether to close this then or leave it open, if it's just similar and not a duplicate. :/
It's not a duplicate in my opinion.
If https://github.com/godotengine/godot/issues/8071 were implemented, wouldn't it cover this issue? If the API is to be consistent then it shouldn't just cover the clamp function, but should cover as many math functions as possible, right? It does seem like a duplicate to me. :)
@NathanWarden I agree, but than there's Godot's reality, that the more you ask for, the less you generally get into the core :-)
@poke1024 I suppose in some cases that's true, it is easier to ask for one thing (and it be implemented) than to ask for an entire library to be extended :)
@NathanWarden Adding onto what poke1024 said, I feel clamp()
would be more useful than any of the other math functions. Not to mention, this would be a great short-term improvement, with the rest of the math functions being a long-term improvement.
@LikeLakers2 Thanks for pointing that out, I can see some functions being more useful than others on a regular basis with other data types.
So, Vector2 already has a function called clamped()
, but this doesn't do the same as clamping a float or int. Vector2's clamped
is basically if vector.length() > val: vector = vector.normalized() * val
. What should be done about this? It would be confusing to have both Vector2.clamp()
and Vector2.clamped()
since they are similar names. Note: Vector3 does not have clamped
(https://github.com/godotengine/godot/issues/30058).
I think the existing method might make more sense as "limit" or something, since it effectively puts a cap on the length of the vector. But changing this breaks compat and would probably need to wait until Godot 4.0. We can keep clamped
as an alias but add "limit" or similar in 3.2, but again, having both clamp
and clamped
would be confusing, so adding clamp
should wait until 4.0. #16863
I'd vote for renaming the existing method .. limit sounds good or maybe limit_length. The old method is so specific I doubt it is used much outside the 2 mentions in the godot source. In fact there's an argument to get rid of the old method altogether.
Since discovering it a few months ago I've used Vector2's clamped
in every project I have, so if there's an argument to get rid of it altogether I'd like to hear it
I'm not sure limit
conveys better info than clamp
. Both sound the same and expect the user to "guess" they are referring to length, which is not directly a value of the vector. I'd just name this clamp_length
, or limit_length
(besides it would otherwise occupy the space for a memberwise clamp
which in my sense would be the consistent/standard way of calling such function, however Vector2/Vector3 don't have it, so....).
API proposal:
Rename Vector2.clamped
to Vector2.limit_length
.
Add Vector3.limit_length
to be consistent with Vector2
.
Add Vector2.clamp(min, max)
where min
and max
are of type Vector2
.
Add Vector3.clamp(min, max)
where min
and max
are of type Vector3
.
Add Color.clamp(min, max)
where min
and max
are of type Color
.
Bonus idea: We could allow Color.clamp
to have default values of min = Color(0, 0, 0, 0)
and max = Color(1, 1, 1, 1)
, since clamping a color to this range seems like it would be a relatively common operation.
Bonus idea part 2: With the above, you could override only min
to Color.black
, which would clamp to non-transparent colors, since black is Color(0, 0, 0, 1)
.
Thoughts?
@aaronfranke I would of preferred to have it under the global clamp()
function, but at the same time, your proposal is probably miles easier to implement. So no complaints from me. It sounds like a fine proposal.
@aaronfranke I really like the idea and I think that is how it has to be implemented. But however it will break the current API maybe for 4.0 as already a lot is broken in 4.0 API.
Most helpful comment
API proposal:
Rename
Vector2.clamped
toVector2.limit_length
.Add
Vector3.limit_length
to be consistent withVector2
.Add
Vector2.clamp(min, max)
wheremin
andmax
are of typeVector2
.Add
Vector3.clamp(min, max)
wheremin
andmax
are of typeVector3
.Add
Color.clamp(min, max)
wheremin
andmax
are of typeColor
.Bonus idea: We could allow
Color.clamp
to have default values ofmin = Color(0, 0, 0, 0)
andmax = Color(1, 1, 1, 1)
, since clamping a color to this range seems like it would be a relatively common operation.Bonus idea part 2: With the above, you could override only
min
toColor.black
, which would clamp to non-transparent colors, since black isColor(0, 0, 0, 1)
.Thoughts?