I made a simple animatedsprite2d which changes depending on mouse direction. But, whenever I tried to get the angle from the sprite to the mouse cursor in degrees using the int(get_angle_to(get_global_mouse_position())), the sprite won’t change, and I get an error saying:
E 0:00:00:0276 two_way_sprite.gd:4 @ @implicit_new(): Parameter "get_viewport()" is null.
<C++ Source> scene/main/canvas_item.cpp:1112 @ get_global_mouse_position()
<Stack Trace> two_way_sprite.gd:4 @ @implicit_new()
Any help is welcome, here’s the code:
extends AnimatedSprite2D
@onready var anim = get_node("/root/TwoWaySprite")
var direction = int(get_angle_to(get_global_mouse_position()))
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if direction >= -90 && direction <= 90:
anim.play("south")
if direction < -90 && direction > 90:
anim.play("north")
@kozxd2000 yeah you are right but as he using the direction variable multi times in the process function, he also need to assign its value for multi times in the process function. So there is no need to use @onready and define it early.
Thanks. It did work somehow. But the sprites switch at wierd intervals.
So, I converted it from radians to degrees by simply adding the rad_to_deg() function.
So, I added this at the end:
if Input.is_action_just_released("spacebar"):
print (str(direction))
The output seems to be that the 0 degrees is somewhere in the south-east of the object. Placing your mouse directly south of the object gives you “57”.
I managed to fix this issue by deleting the int() function and replacing it with this: direction = (rad_to_deg(get_angle_to(get_global_mouse_position())) - 90)
Now comes the problem, the sprite will always point “south”. If the sprite is initially set to “north”, putting your mouse cursor to below the sprite causes it to be set to “south” and you can’t change it back to “north”.
Similarly, if I expand the if statements to 4 ways as in this:
if direction >= -45 && direction <= 45:
anim.play("south")
if direction <= -135 && direction >= 135:
anim.play("north")
if direction > -135 && direction < -45:
anim.play("east")
if direction < 135 && direction > 45:
anim.play("west")
The only sprites showing are “south”, “east”, and “north”, with “south” and “east” occupying their respective places and “north” being north and also occupying “west”.
How do I fix that?
If you only want the cardinal directions it may be better to avoid angles all together and compare the largest distance from the player to the mouse.
var diff: Vector2 = get_global_mouse_position() - global_position
if absf(diff.x) > absf(diff.y):
# X is greater, east/west
if diff.x < 0.0:
anim.play("west")
else:
anim.play("east")
else:
# Y is greater or equal, north/south
if diff.y < 0.0:
anim.play("north")
else:
anim.play("south")
It might not be shorter, but the math will be faster for the computer every frame.
This somehow fulfills as an answer, although I am expecting that direction variable be kept, so if I want to have the object point at another object instead of a cursor, then I’ll just have the variable set to the angle from the object to the other object.