Hi,
I've been stuck on this for literal days, completely unable to make progress, and really need some handholding.
I'm trying to make a system like old 2.5d games with 8 directional sprites. Depending on the angle between the NPC and player, the NPC sprite should change.
I could get this working until the NPC is rotated.
Here's the relevant code:
var dir = rad2deg((NPC.get_rotation().y))
var player_adj_origin : Vector2
player_adj_origin.x = player.global_transform.origin.x - NPC.global_transform.origin.x
player_adj_origin.y = player.global_transform.origin.z - NPC.global_transform.origin.z
var raddir = deg2rad(dir)
angle_to_player = rad2deg(Vector2(cos(raddir),sin(raddir)).angle_to(player_adj_origin))
# simple checker to show which sprite is displayed at which angles
if (abs(angle_to_player) < 22.5):
sprite_dir_string = "Front"
elif (angle_to_player>=22.5 and angle_to_player<67.5):
sprite_dir_string = "FrontRight"
elif (angle_to_player>=67.5 and angle_to_player<112.5):
sprite_dir_string = "Right"
elif (angle_to_player>=112.5 and angle_to_player<157.5):
sprite_dir_string = "BackRight"
elif (abs(angle_to_player)>=157.5):
sprite_dir_string = "Back"
elif (angle_to_player<=-112.5 and angle_to_player>-157.5):
sprite_dir_string = "BackLeft"
elif (angle_to_player<=-67.5 and angle_to_player>-112.5):
sprite_dir_string = "Left"
elif (angle_to_player<=-22.5 and angle_to_player>-67.5):
sprite_dir_string = "FrontLeft"
If this was working, then I would be able to stand directly (1 unit) in front of my NPC, in the direction of its rotation, and Vector2 player_adj_origin would be equal to Vector2(cos(raddir),sin(raddir)).
Also, if standing in front of the NPC, angle_to_player should be 0.
But the results I get do not match at all, and weirdly, when I try rotating my NPC at different angles, the results of player_adj_origin and angle_to_player change in ways that I cannot easily understand.
Here's what I'm seeing at each 45 degree angle:
**get_rotation().y = 0**
angle_to_player = -90
cos,sin = 1, 0
player_adj_origin = 0,-1
**get_rotation().y = -45**
angle_to_player = 0
cos,sin = 0.707107, -0.707107
player_adj_origin = 0.707107, -0.707107
**get_rotation().y = -90**
angle_to_player = 90
cos,sin = -0, -1
player_adj_origin = 1,0
**get_rotation().y = -135**
angle_to_player = 180
cos,sin = -0.707107, -0.707107
player_adj_origin = 0.707107, 0.707107
**get_rotation().y = 180**
angle_to_player = -90
cos,sin = -1, -0
player_adj_origin = 0,1
**get_rotation().y = 135**
angle_to_player = 0
cos,sin = -0.707107, 0.707107
player_adj_origin = -0.707107, 0.707107
**get_rotation().y = 90**
angle_to_player = 90
cos,sin = -0, 1
player_adj_origin = -1,-0
**get_rotation().y = 45**
angle_to_player = 180
cos,sin = 0.707107, 0.707107
player_adj_origin = -0.707107, -0.707107
Note how at -45 degrees and 135 degrees, everything matches and it works.
The best way I can understand it is that is seems there are two coordinate systems, or two bases. Imagine two unit circles. On the first, 0 degrees is N, -90 is E, what you'd expect. On the second, -90 degrees is N, 0 is E, 180 is W.
It's like when the first one is rotated clockwise, the second one is rotated counterclockwise, if that makes any sense. I think it has something to do with the coordinate system used for the angle_to() function?
I don't know where to go from here. Can somebody please walk me through how to fix this? I don't think a link to the documentation will be enough, I've been reading it for hours and do not think I can solve this without seeing specific code.
Thank you SO much for taking the time to read this and respond!