Not works properly too, i’ve changed the signal and add that line you mentioned to the random_wonder function:
Enemy AI Movement:
extends State
class_name Idle_State_Skeleton
var move_dir: Vector3
var wonder_time: float = 0
var time_moving: float = 0
var basis_enemy: Basis
func random_wonder():
move_dir = Vector3(randf_range(-1, 1), 0, randf_range(-1, 1)).normalized()
wonder_time = randf_range(1, 3)
time_moving = randf_range(1, 2)
enemy.global_transform.basis = Basis(Vector3.UP, move_dir.angle_to(Vector3.FORWARD))
func Enter():
random_wonder()
func _state_process(delta: float):
if wonder_time > 0:
wonder_time -= delta
else:
random_wonder()
func _state_physics_process(delta: float):
if enemy and time_moving > 0:
enemy.velocity = move_dir * enemy.speed
time_moving -= delta
elif enemy:
enemy.velocity = Vector3(0,enemy.velocity.y,0)
pass
Sprite3D:
extends EnemyTexture
class_name Skeleton_Texture
@onready var idle_dir: String = "idle"
@export var anim_col: int = 0
func animate(velocity: Vector3):
if enemy.can_hit or enemy.can_attack or enemy.can_die:
action_behavior()
else:
move_behavior(velocity)
func move_behavior(velocity: Vector3):
if velocity.x != 0 and velocity.z != 0 and !(enemy.is_attacking or enemy.is_retreating):
play_walk(velocity)
else:
animation.play(idle_dir)
pass
func play_walk_bilboard_camera(_velocity: Vector3):
var player: Player_Skeleton = get_tree().get_first_node_in_group("Player")
var p_fwd = -player.camera_principal.global_transform.basis.z
var fwd = -enemy.global_transform.basis.z
var left = -enemy.global_transform.basis.x
#print("valor pwd:", p_fwd, " fwd:", fwd, " left:", left)
#print("global basis:", enemy.global_transform.basis)
var l_dot: float = left.dot(p_fwd)
var f_dot: float = fwd.dot(p_fwd)
var row: int = 0
print("fdot: ",f_dot, " l_dot:", l_dot)
#print("position diff: ", player.global_position.length() - enemy.global_position.length())
if f_dot < -0.85:
row = 0 #front sprite
elif f_dot > 0.85:
row = 3 #back sprite
else:
if l_dot > 0:
row = 2 #right sprite
elif abs(f_dot) < 0.3:
row = 1 #left sprite
elif f_dot < 0 :
row = 1 #forward left sprite
else:
row = 0 #back sprite
frame = anim_col + row * 9
animation.play("walk_anim_col")
func play_walk(velocity: Vector3):
#print("velocity x:", abs(velocity.x), "velocity z:", abs(velocity.z))
if enemy.player_ref:
animation.play("walk")
else:
play_walk_bilboard_camera(velocity)
#play_walk_axis_bilboard(velocity.z, velocity.x)
pass
func action_behavior():
if enemy.can_hit:
animation.play("damage")
enemy.is_hitting = true
enemy.is_attacking = false
elif enemy.can_die:
enemy.kill_enemy()
pass
elif enemy.can_attack and !enemy.is_attacking and !enemy.is_hitting:
animation.play("attack")
pass
pass
func _on_animation_finished(anim_name:String)->void:
match anim_name:
"walk":
idle_dir = "idle"
"walk_up":
idle_dir = "idle_up"
"walk_right":
idle_dir = "idle_right"
"walk_left":
idle_dir = "idle_left"
"attack":
enemy.can_attack = false
animation.play(idle_dir)
"damage":
enemy.can_hit = false
enemy.is_hitting = false
pass
I’ve modified the movement just to see if his is walking and playing the animation of the right direction:
move_dir = Vector3(randf_range(-1, 1), 0, 0).normalized()
and
func move_behavior(velocity: Vector3):
if velocity.x != 0 and velocity.z != 0 and !(enemy.is_attacking or enemy.is_retreating):
play_walk(velocity)
else:
animation.play(idle_dir)
pass
to
func move_behavior(velocity: Vector3):
if (velocity.x != 0 or velocity.z != 0) and !(enemy.is_attacking or enemy.is_retreating):
play_walk(velocity)
else:
animation.play(idle_dir)
pass
He is going to move only up and down, but the animation keeps playing in the opposite direction of the enemy’s movement. Sometimes it plays correctly, but other times it behaves unpredictably, seemingly playing the animation randomly: