I'm not much of a programmer either, but I think I can point you in the right direction. I suggest using an invisible Spatial node as a child of the 2D object to track its 3D orientation. This way you can use Godot's built-in 3D functions. B)
I figure Euler angles are the output you want for the 2D object. I tried relying on the transformation matrix or a quaternion instead, but kept ending up with Euler angles again when it came time to codify the rotations into something that made sense for calling the sprites/animations.
I've worked with 8-way sprites before, so I've got a nifty equation that provides the desired 45-degree window for a given Euler angle.
extends Spatial
var facing: Vector3
func _ready():
# Deliberately add error to encourage consistent behavior from the start
rotate_y(PI)
rotate_y(-3.1415926)
func _process(delta):
## ...perform rotations as desired... ##
# Get facing and convert to number from 0-7 for every 45 degrees (PI / 4)
facing = transform.basis.get_euler()
facing.x = rad2eight(facing.x)
facing.y = rad2eight(facing.y)
facing.z = rad2eight(facing.z)
func rad2eight(theta):
return fposmod(round(theta * 4 / PI), 8)
Judging from the output console, "facing" exhibits the upside-down flips Euler angles are known for, but I think it could still work:
Once any significant yaw or roll has taken place, facing.x appears to be confined from down to up (6, 7, 0, 1, 2). Keeping that consistent is the purpose of the contents of _ready. Once facing.x is confined, it looks like facing.y and facing.z flip instantly, given such a small resolution for the rotations and the "window" my function provides.
In other words, when the flip occurs (at 90 degrees up or down), the sprite should instantly roll 180 degrees and yaw 180 degrees. I tried to make this consistent to lighten your workload, because it should cut down the number of sprites/animations to assign. Any orientation where the top of the object is pointing below the horizon (basis.y.y is negative) necessitates roll thanks to the Euler flip, so a duplicate like (4, 0, 0) becomes (0, 4, 4).
Maybe the scourge of Euler angles is actually helpful here? :p