check if player is looking at object?
- Edited
DJMaesen no, use dot product:
float dot ( Vector3 with ) const
Returns the dot product of this vector and with. This can be used to compare the angle between two vectors. For example, this can be used to determine whether an enemy is facing the player.
The dot product will be 0 for a straight angle (90 degrees), greater than 0 for angles narrower than 90 degrees and lower than 0 for angles wider than 90 degrees.
When using unit (normalized) vectors, the result will always be between -1.0 (180 degree angle) when the vectors are facing opposite directions, and 1.0 (0 degree angle) when the vectors are aligned.
Note: a.dot(b) is equivalent to b.dot(a).
angle_to
returns an unsigned
value
Jesusemora angle_to returns an unsigned value
So what? It just returns the arc cosine of the dot product. If you want to deal with specific angles, you'll need to calculate that arc cosine anyway.
xyz returns the arc cosine of the dot product. If you want to deal with specific angles, you'll need to calculate that arc cosine anyway.
1 - I remember having trouble with angle_to
and managing to solve it. it wasn't with dot
product but signed_angle_to
. I think the difference is that signed_angle_to
returns a value in radians
, while dot
is in the -1.0 1.0 range which is better for testing.
2 - a dot product is an extremely simple matrix multiplication that returns a value between -1.0 and 1.0. looking at the code, OP was already using dot product, so should probably read more carefully.
- Edited
Jesusemora Here's what the OP said:
DJMaesen what i want is if the angle is not greater then 0.3 the player should climb
They asked about angle.
And here's their code that looks like it tests for boundary angles:
var angle : float = forward.dot(toOther)
if angle > -0.3 && angle < 0.3:
Using angle_to()
is simple, intuitive and totally adequate here. It's more "in the spirit" of what the code tests for. It's stylistically cleaner. Dot product is fine as well but there's nothing to be gained in this case by using it directly. It just obfuscates the actual meaning of that .3 limit literal the code is testing for, as this value doesn't represent an actual angle, but its cosine. Also dot product gradient is not linear and corelates "inversely" with the angle which all just adds to non-intuitiveness. And last but not least, the script code needs to normalize the vectors before using the dot product in this way whereas angle_to()
does this under the hood in native code, making the script code faster and shorter.
Also @DJMaesen if dot product is between -.3 and .3, that means that the angle between vectors is between acos(-.3) and acos(.3) which in degrees is a range between 72 and 107.
I don't think OP wants to test if it's EXACTLY 30º, since we are talking about the angle between the player and a ladder. this can be adjusted to whatever works.
xyz angle_to() is simple, intuitive and totally adequate here.
I suppose it's a matter of taste. I find dot product to be more intuitive than using radians, at least for these very simple cases that don't need to be perfect, like testing if two vectors are almost aligned or facing opposite directions.
xyz And last but not least, the script code needs to normalize the vectors before using the dot product in this way whereas angle_to() does this under the hood in native code
again, matter of taste. I prefer to normalize my vectors instead of letting the engine methods do some unknown "under the hood".
- Edited
Jesusemora do some unknown "under the hood".
Nothing unknown there. We know precisely how it works as there's only one efficient way to do it. Here's a custom GDScript implementation of angle_to():
func angle_to(v1: Vector3, v2: Vector3) -> float:
return acos(v1.normalized().dot(v2.normalized()))
For 3D vectors there's shorthand version possible that avoids normalization by using cross product:
func angle_to(v1: Vector3, v2: Vector3) -> float:
return atan(v1.cross(v2).length(), v1.dot(v2))
And this is exactly how Godot does it (from Vector3.h in Godot's source):
real_t Vector3::angle_to(const Vector3 &p_to) const {
return Math::atan2(cross(p_to).length(), dot(p_to));
}
Jesusemora no not exactly 30 degrees
but within the range of 30 and -30 degrees
- Edited
somhow looking up or down when entering the trigger doesnt make the trigger activate.
edit
nope it works fine, tnx guys!