godot: Vector2.reflect() result is unexpected

Operating system or device, Godot version, GPU Model and driver (if graphics related): 3.0master build 0dbec3a

When reflecting a vector by a normal, for example to bounce off a surface, the resulting vector isn’t reflected as expected (it’s reversed):

var v1 = Vector2(100, 100)
var n = Vector2(0, -1)
var v2 = v1.reflect(n)

Expected result: (100, -100) Actual result: (-100, 100)

As a workaround, I’ve been using -v1.reflect(n)

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 7
  • Comments: 26 (12 by maintainers)

Most upvoted comments

In Godot, reflect means mathematical reflection and bounce is physical reflection. Documentation describes this behavior.

Reflect typically refers to mathematical reflection, just like glsl reflect function, because that’s what reflecting a vector, an abstract mathematical entity, means. A mathematical vector doesn’t move. Reflection of a light from a surface, both represented by time-dependent vectors, ray is different. Unlike light, a pure mathematical vector doesn’t move in time.

We don’t need to do whatever Unity does.

Then it must be different from other Vector classes I’ve come across.

In Unity: `Vector2 v1 = new Vector2(1, 1);

Vector2 normal = new Vector2(0, -1);

Vector2 reflectedVec = Vector2.Reflect(v1, normal);

print(reflectedVec); `

Output: (1, -1)

This is what reflection means

So then the problem seems to be that we’re defining one dimensional lines with normal vectors instead of a vector in the actual direction of the line? Normal vectors for planes makes sense for 3D but for one dimensional lines in 2D it makes more sense to just define the line.

Not really, the problem (which is not really a problem but a more of a misunderstanding) is that reflect() does a mathematical reflection (which is more like a “flip”) and not a physical reflection, like a ray reflecting of a mirror (which can be accomplished by the bounce() function).

The referred comment is more about how it’s written in the docs. Using a normal vector in this case is perfectly fine, even in 2D.

Ah, I missed that part, yse I agree, that parameter is the normalized reflection line

Can I request that any documentation clarification come with at least one diagram which visualises the difference between bounce() and reflect(), and/or some practical examples of what each is useful for? I still don’t understand how they would differ when operating on a vector.

It probably doesn’t help that existing documentation seems to use the terms “reflect” and “bounce” interchangeably. Eg. Using KinematicBody2D or Vector Math.

@jack-vo No, it’s just that the syntax changed: http://docs.godotengine.org/en/stable/classes/class_vector2.html#class-vector2-reflect

It’s no longer normal.reflect(vector) but vector.reflect(normal), so you should do test.reflect(Vector2(0, -1)).

Yup, but in OP’s case: if reflect uses the normal of the “plane” (in fact a straight line here), with Vector2(0,-1), the plane is the X axis. So the reflection should change the Y coordinate instead of the X one.