Godot Version
Godot 4 v4.6.1 stable
Question
-
The “walk” animation doesn’t play when the player moves left or right.
-
Why isn’t the enemy following me?
My script:
Player:
extends CharacterBody3D
const SPEED = 7.0
const JUMP_VELOCITY = 4.6
@export var mouse_sensitivity: float = 0.002
var type = "player"
var hp = 10
@onready var take_dmg_sprite = $TakeDmgSprite
@onready var camera_3d = $head/Camera3D
@onready var animations_player = $Animations_Player
@onready var camera_animations = $Animations_Player
# Флаг для отслеживания состояния анимации
var is_animation_playing = false
func _ready():
# Захватываем курсор при старте игры
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
# Вращаем персонажа по оси Y при движении мыши по горизонтали
rotate_y(-event.relative.x * mouse_sensitivity)
func _physics_process(delta: float) -> void:
# Гравитация
if not is_on_floor():
velocity += get_gravity() * delta
# Прыжок
if Input.is_action_just_pressed("space") and is_on_floor():
velocity.y = JUMP_VELOCITY
# Движение
var input_dir := Input.get_vector("a", "d", "w", "s")
var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
# Определяем направление движения по оси X (влево/вправо)
if input_dir.x > 0:
# Движение вправо
if not is_animation_playing:
animations_player.play("walk")
camera_animations.play("camera_right")
is_animation_playing = true
elif input_dir.x < 0:
# Движение влево
if not is_animation_playing:
animations_player.play("walk")
camera_animations.play("camera_left")
is_animation_playing = true
else:
# Движение вперёд/назад — только анимация walk
if not is_animation_playing:
animations_player.play("walk")
is_animation_playing = true
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
velocity.z = move_toward(velocity.z, 0, SPEED)
# Останавливаем все анимации и сбрасываем к первому кадру
if is_animation_playing:
animations_player.stop()
camera_animations.stop()
is_animation_playing = false
move_and_slide()
func take_dmg(dmg):
hp -= dmg
take_dmg_sprite.visible = true
Enemy:
extends CharacterBody3D
@onready var dmg_timer : Timer = $DMG_timer
var playerNode: CharacterBody3D
var type = "enemy"
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
var hp = 10
var dmg = 2
var target_point: CharacterBody3D
func set_target_point(target):
target_point = target
func _physics_process(delta: float) -> void:
if target_point:
var directionC = (target_point.global_position - global_position).normalized()
var distance_to_target = global_position.distance_to(target_point.global_position)
look_at(target_point.global_position)
rotate_y(deg_to_rad(180))
if distance_to_target > 0.1:
velocity = directionC * SPEED
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
move_and_slide()
func _on_dmg_body_entered(body: Node3D) -> void:
if body.has_method("take_dmg") and body.type == "player":
dmg_timer.start()
body.take_dmg(dmg)
playerNode = body
func _on_dmg_timer_timeout() -> void:
if playerNode:
playerNode.take_dmg(dmg)
func _on_dmg_body_exited(body: Node3D) -> void:
if body.has_method("take_dmg") and body.type == "player":
dmg_timer.stop()