Better Way to Change Sprite Frames In Code?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By scrubswithnosleeves

Hey All,

I often do something like this:

func _physics_process():
  if "looking left":
    $sprite.set_frame(0)
  else:
    $sprite.set_frame(1)

But this is setting the sprite’s frame every physics frame. is there a more efficient way to do this or is this fine / not something that is going to slow down the engine? I haven’t noticed any issues, but I just imagine that doing this every frame for 10 different instances of a class might have some consequences. lmk if I am overthinking this.

:bust_in_silhouette: Reply From: jgodfrey

General advice, don’t attempt to over-optimize your code until it becomes a problem. Now, that doesn’t mean you should write intentionally unoptimized code, or that you shouldn’t think about it as you progress, but having clean, easy-to-understand code is generally better than highly-optimized code that’s hard to follow.

I’d say the posted code is fine, until/unless you find out it’s not (which I doubt will be the case).

:bust_in_silhouette: Reply From: CharlesMerriam

It does seem odd to do it in physics. Are you expecting to update the direction of looking when something happens or every now and then?

If doing it with something happens, you set the frame when it happens and then just ignore it. That is, “Noise was made, everyone look towards it”.

If doing it now and then, you might want your own timer. It can be slow, like 0.25 seconds per tick.

In any case, you should have a heuristic to skip the “looking left” part when nothing relevant has changed. Usually, any distance calculation is slooooow.

Tells us more?

Keep hacking; keep notes.

I couldn’t figure out a way to do this NOT in _physics_process(). I am making sentry like turrets that have rotating heads and they change thier sprite frame based on which direction they are looking (different sprite for up/down/left/right). I thought about using flags, but then you would have to set the flag every frame! Like I said, its working fine and I think I am going to take @jgodfrey 's advice and not mess with it until I have an issue.

Heres a slightly simplified version of what I am doing in case you are interested:

func _physics_process():
                current_look_direction = Vector2.RIGHT.rotated(rotation).normalized()
                look_animation_handling()

func look_animation_handling():
	#DOWN
	if current_look_direction.angle() > 0.785398 and current_look_direction.angle() < 2.35619:
		set_frame(2)
		scale.y = -1
	#RIGHT
	elif current_look_direction.angle() > 0 and current_look_direction.angle() < PI/4 or current_look_direction.angle() < 0 and current_look_direction.angle() > -PI/4:
		set_frame(0)
		scale.y = 1
	#UP
	elif current_look_direction.angle() < -0.785398 and current_look_direction.angle() > -2.35619:
		set_frame(1)
		scale.y = 1
	#LEFT
	else:
		set_frame(3)
		scale.y = -1

scrubswithnosleeves | 2020-11-05 19:58