how do i make a sprite 3d change sprites depending on which angle the camera is looking from

Godot Version

godot 4

Question

so im new to godot and trying to make this 3d game with a 2d player character.i already know how to billboard the character but how do i change the sprite depending on the angle the camera is pointing at it?

Get the vector from sprite to camera by subtracting their positions. Convert it into 2d vector by eliminating the y component and get its angle using Vector2::angle(). Snap this angle to the angle step the sprite frames are rotated by using snapped(), divide that by the angle step and you’ll get the frame index.

maybe im just bad at coding but it’s not working for me

If you can share your code, you’ll get more help, as it’s too little info at the moment.

Make sure you post the code in proper formatting within triple backticks!

#billboarding stuff

@onready var sprite = AnimatedSprite3D
@export var camera: Camera3D

const TOTAL_DIRECTIONS = 9
const ANGLE_STEP = TAU / TOTAL_DIRECTIONS

func _process(delta):
var dir_3d = camera.global_position - global_position
var dir_2d = Vector2(dir_3d.x, dir_3d.z)

var angle = dir_2d.angle()

var snapped_angle = snapped(angle, ANGLE_STEP)

var frame = int(snapped_angle / ANGLE_STEP) % TOTAL_DIRECTIONS

if frame < 0:
	frame += TOTAL_DIRECTIONS

sprite.frame = frame

i wrote some code but i don’t think it works right

I could be wrong, but is TAU defined? Is this the whole script? Also the formatting is a bit off as you can see, and indents matter too. Does the editor throw you an error somewhere?

this is the script that just has to do with billboarding the object. i could also drop the whole script too? btw what do you mean by “is TAU defined”? and the editor throws me an error every time i run the code specifically these lines → E 0:00:01:729 _process: Invalid access to property or key ‘global_position’ on a base object of type ‘Nil’.
2d_player.gd:49 @ _process()
2d_player.gd:49 @ _process()

What is the script attached to? It’s telling you you’re trying to call global_position on nothing.

it’s attached to my character body 3d

Did you forget to assign camera in the inspector?

pretty sure i did

print(camera) in _process() to check its value.

I mean, the error informs us global_position is tried on base object nil.something is not connected correctly. Can you share some screenshots of your tree and editor perchance?

i think the problem here is a lack of understanding for godot so i’m gonna try and read up on the documentation to help me out here

I’ve done this in a shader before, it’s not super easy if you’re unfamiliar with shaders.

Technically thought the idea I use is the same in gdscript also. I use the dot product of a direction to know how aligned with a side of the character I am, and then pick the sprite based on that.