I decided to start making a game with “DooM” or “Duke Nukem”. Got movement down, getting stairs working. But right now, I’m working on functional enemy sprites. I followed some older tutorials and used some templates but compared to the actual thing, its buggy. So instead of of automating this through GDScript… I propose a more node based way of doing it. With RayCasts and stuff.
Now I know, this isn’t as efficient and will probably be buggy as all hell. But… how would one make this?
Cause I was thing, what if I added some kind of detector on each angle the RayCast previously mentioned would
detect them and change the sprite column.
If this viable? And if so… how do I aprouch this challenge?
The sprite3d should work fine for your idea. What’s buggy about it? I am using sprite3d for my top-down 3d game for mobs and it works fine. For furniture I use a textured plane mesh, maybe you can try that too?
What do you mean by sprite column? Is that used in animation?
Basicly I added a Sprite3D into the scene. No collisions and stuff. Just the Sprite3d. From what I tested on the other stuff I mentioned, And the sprite angles change based of of camera rotation. Not the literal angle of the sprite relative to the camera location wise. I played DooM || for 2 hours as reference, got addicted and finished the first 5 maps and continued to trying and gave up.
And when I say column, I mean I’m using a DooM Imp sprite sheet as a placeholder with… 4 horizontal columns for the walk animation, which I loop and auto start, and 5 vertical columns for the rotation. I intent to flip the side sprites if making them is tedious.
Okay, I finally got my idea to work lol. So basicly I made a Node3D, made it look at the player entity and then I used it’s y rotation as a means to get the right angles. This is has 5 angles but adds the extra 3 by flipping the side angles, though this can be changed if you’re spritesheet has said angles.
But anyways, here the code. Should any unfortunate soul meet my previous errors, I bear the solution. : D
Summary
extends CharacterBody3D
# Registers nodes in the scene for easier use in the script.
@onready var sprite: Sprite3D = $body
@onready var angle_handler: Node3D = $anglehandler
var player_entity: CharacterBody3D
func _ready():
# Finds the player entity in the scene tree.
player_entity = get_tree().get_first_node_in_group("player")
func _process(_delta):
# Converts node3d (angle_handler) y rotation into degrees.
var rotation_y_deg = rad_to_deg(angle_handler.rotation.y)
# Rotates angle_handler to face the player for use in managing what angle to use.
angle_handler.look_at(player_entity.global_position)
# Change the sprite's vframe and flip based on the rotation of angle_handler.
if abs(rotation_y_deg) < 22.5:
sprite.frame_coords.y = 4 # Front view.
sprite.flip_h = false
elif rotation_y_deg >= 22.5 and rotation_y_deg < 67.5:
sprite.frame_coords.y = 3 # Front-left view.
sprite.flip_h = true
elif rotation_y_deg >= 67.5 and rotation_y_deg < 112.5:
sprite.frame_coords.y = 2 # Left view.
sprite.flip_h = true
elif rotation_y_deg >= 112.5 and rotation_y_deg < 157.5:
sprite.frame_coords.y = 1 # Back-left view.
sprite.flip_h = true
elif abs(rotation_y_deg) >= 157.5:
sprite.frame_coords.y = 0 # Back view.
sprite.flip_h = false
elif rotation_y_deg <= -22.5 and rotation_y_deg > -67.5:
sprite.frame_coords.y = 3 # Front-right view (flip from front-right).
sprite.flip_h = false
elif rotation_y_deg <= -67.5 and rotation_y_deg > -112.5:
sprite.frame_coords.y = 2 # Right view (flip from right).
sprite.flip_h = false
elif rotation_y_deg <= -112.5 and rotation_y_deg > -157.5:
sprite.frame_coords.y = 1 # Back-right view (flip from back-right).
sprite.flip_h = false