Godot Version
4.6.2 Stable
Question
Godot beginner here, go easy on me. Thanks in advance.
Issue 1: If I’m moving Right and then add Up and Down, everything behaves as expected but if I am facing Right (no velocity) and just press up or down, the sprite moves up and down and then flips to face the Left once I stop pressing the button. Additionally Left and Right trigger the animations just fine but Up or Down by themselves stay in the idle animation and just slide Up or Down.
To note: My player is separated into three AnimatedSprite2Ds: Body, Head, and Gun
Issue 2: Input: Down + Right = player moving down and right (diagonally) and the PlayerHead and PlayerGun rotate to match the angle. Continue pressing Down but switch to Left = the same thing, to the left, as wanted.
But if I press Sprint while doing the same thing, the player will move down + left but the head and gun rotate to point Up and Right.
Issue 3:
My code for rotating the head and gun to match the angle works on the Left, Right, and Diagonals but doesn’t do anything for just straight Up or Down. I feel like there’s a connection but I can’t see it.
I’m stumped.
My goal is to have 8 directions. The body can face in 2 directions, left and right. The head and gun can face in 2 directions, left and right, but can be rotated to “point” in all8 directions. I had this working at one point but between adding actual left frames, ditching flip_h in the process and trying to implement new features and systems, I completely broke it and had to start fresh. So here I am.
I do not want to post my code for anyone to see but I need some help so I’m sorry for anyone who sees it lol I’ve been at this project and others (basically the same one just restarted over and over) for like 10-12 hours a day for a solid week or so now so I’m willing to be that it’s a simple fix but I can’t look at code anymore, I’m positive that my brain is actually changing what I see to look right at this point lol
Here’s a video showcasing the issues. Pretty sure the quality is going to take a massive dive, so sorry in advance, hopefully it still gets the point across.
extends CharacterBody2D
var speed: int = 10
var speed_scale: float = 1.5
var direction: Vector2
var look_direction: Vector2 = Vector2.RIGHT
var is_sprinting: bool = false
var is_strafing: bool = false
var is_reloading: bool = false
var is_shooting: bool = false
func _physics_process(_delta: float) -> void:
get_input()
movement()
move_and_slide()
animation()
func get_input():
# DIRECTIONAL INPUT
#--------------------------------------------------------------
direction = Input.get_vector("left", "right", "up", "down")
if direction != Vector2.ZERO:
velocity = direction * speed
look_direction = direction
else:
velocity = Vector2.ZERO
# MOVEMENT INPUT
#--------------------------------------------------------------
if Input.is_action_pressed("sprint"):
is_sprinting = true
velocity *= speed_scale
else:
is_sprinting = false
if Input.is_action_pressed("strafe") and velocity !=Vector2.ZERO:
is_strafing = true
direction.x *= -1
velocity.y = 0
else:
is_strafing = false
# ACTION INPUT
#--------------------------------------------------------------
if Input.is_action_just_pressed("shoot"): #add shoot timer here
print("shoot")
shoot()
if Input.is_action_just_pressed("reload") and not is_reloading:
print("reloaded")
reload()
func movement():
# SPRITE MOVEMENT-BASED ROTATION
#--------------------------------------------------------------
#if LEFT and UP and is NOT Strafing
if direction.x < 0 and direction.y < 0 and not is_strafing:
$PlayerWeapon.rotation_degrees = 45
$PlayerHead.rotation_degrees = 20
#if LEFT and DOWN and is NOT Strafing
elif direction.x < 0 and direction.y > 0 and not is_strafing:
$PlayerWeapon.rotation_degrees = -45
$PlayerHead.rotation_degrees = -20
#if RIGHT and UP and is NOT Strafing
elif direction.x > 0 and direction.y < 0 and not is_strafing:
$PlayerWeapon.rotation_degrees = -45
$PlayerHead.rotation_degrees = -20
#if RIGHT and DOWN and is NOT Strafing
elif direction.x > 0 and direction.y > 0 and not is_strafing:
$PlayerWeapon.rotation_degrees = 45
$PlayerHead.rotation_degrees = 20
#if last dir_x was LEFT and we go down
elif look_direction.x < 0 and direction.y == 1:
$PlayerWeapon.rotation_degrees = -90
$PlayerHead.rotation_degrees = -45
#if last dir_x was RIGHT and we go down
elif look_direction.x > 0 and direction.y == -1:
$PlayerWeapon.rotation_degrees = -90
$PlayerHead.rotation_degrees = -45
elif look_direction.x > 0 and direction.y == 1:
$PlayerWeapon.rotation_degrees = 90
$PlayerHead.rotation_degrees = 45
elif look_direction.x < 0 and direction.y == -1:
$PlayerWeapon.rotation_degrees = 90
$PlayerHead.rotation_degrees = 45
#------------------------------------------------------------
#rotation of the weapon sprite when strafing
#------------------------------------------------------------
#if LEFT and UP and IS Strafing
elif direction.x < 0 and direction.y < 0 and is_strafing:
$PlayerWeapon.rotation_degrees = 45
$PlayerHead.rotation_degrees = 20
#if LEFT and DOWN and IS Strafing
elif direction.x < 0 and direction.y > 0 and is_strafing:
$PlayerWeapon.rotation_degrees = -45
$PlayerHead.rotation_degrees = -20
#if RIGHT and UP and IS Strafing
elif direction.x > 0 and direction.y < 0 and is_strafing:
$PlayerWeapon.rotation_degrees = -45
$PlayerHead.rotation_degrees = -20
#if RIGHT and DOWN and IS Strafing
elif direction.x > 0 and direction.y > 0 and is_strafing:
$PlayerWeapon.rotation_degrees = 45
$PlayerHead.rotation_degrees = 20
#------------------------------------------------------------
#this makes the rotation snap back to 0 when not pressing up or down
else:
$PlayerWeapon.rotation_degrees = 0
$PlayerHead.rotation_degrees = 0
func animation():
if is_shooting or is_reloading:
return
if velocity and not is_sprinting:
if direction == Vector2.LEFT:
$PlayerBody.play("walk_left")
$PlayerWeapon.play("walk_left")
$PlayerHead.play("walk_left")
elif direction == Vector2.RIGHT:
$PlayerBody.play("walk_right")
$PlayerWeapon.play("walk_right")
$PlayerHead.play("walk_right")
elif direction.x < 0 and velocity.y != 0:
$PlayerBody.play("walk_left")
$PlayerWeapon.play("walk_left")
$PlayerHead.play("walk_left")
elif direction.x > 0 and velocity.y != 0:
$PlayerBody.play("walk_right")
$PlayerWeapon.play("walk_right")
$PlayerHead.play("walk_right")
if velocity and is_sprinting:
if direction == Vector2.LEFT:
$PlayerBody.play("run_left")
$PlayerWeapon.play("run_left")
$PlayerHead.play("run_left")
elif direction == Vector2.RIGHT:
$PlayerBody.play("run_right")
$PlayerWeapon.play("run_right")
$PlayerHead.play("run_right")
if velocity == Vector2.ZERO:
if look_direction.x > 0:
$PlayerBody.play("idle_right")
$PlayerWeapon.play("idle_right")
$PlayerHead.play("idle_right")
else:
$PlayerBody.play("idle_left")
$PlayerWeapon.play("idle_left")
$PlayerHead.play("idle_left")
func shoot():
is_shooting = true
if look_direction.x > 0:
$PlayerWeapon.play("shoot_right")
$PlayerHead.play("shoot_right")
elif look_direction.x < 0:
$PlayerWeapon.play("shoot_left")
$PlayerHead.play("shoot_left")
await $PlayerHead.animation_finished
await $PlayerWeapon.animation_finished
is_shooting = false
func reload():
is_reloading = true
if look_direction.x > 0:
$PlayerWeapon.play("reload_right")
$PlayerHead.play("reload_right")
elif look_direction.x < 0:
$PlayerWeapon.play("reload_left")
$PlayerHead.play("reload_left")
await $PlayerHead.animation_finished
await $PlayerWeapon.animation_finished
is_reloading = false