78 lines
2.3 KiB
GDScript
78 lines
2.3 KiB
GDScript
extends Unit
|
|
class_name Enemy
|
|
|
|
# Класс противника
|
|
|
|
@export var detection_range: float = 10.0
|
|
@export var attack_range: float = 2.0
|
|
@export var attack_damage: float = 10.0
|
|
@export var attack_cooldown: float = 1.0
|
|
|
|
var target: Node3D = null
|
|
var attack_timer: float = 0.0
|
|
|
|
func _ready():
|
|
super._ready()
|
|
|
|
func _physics_process(delta):
|
|
attack_timer -= delta
|
|
|
|
# Поиск цели (игрока)
|
|
if target == null or not is_instance_valid(target):
|
|
find_target()
|
|
|
|
# Движение к цели
|
|
if target and is_instance_valid(target):
|
|
var distance = global_position.distance_to(target.global_position)
|
|
|
|
if distance <= attack_range:
|
|
# Атака - поворачиваемся к цели
|
|
var look_direction = (target.global_position - global_position)
|
|
look_direction.y = 0
|
|
if look_direction.length() > 0.1:
|
|
var angle = atan2(look_direction.x, look_direction.z)
|
|
rotation.y = angle
|
|
|
|
if attack_timer <= 0:
|
|
attack(target)
|
|
attack_timer = attack_cooldown
|
|
elif distance <= detection_range:
|
|
# Преследование - поворачиваемся и бежим к цели
|
|
var direction = (target.global_position - global_position).normalized()
|
|
velocity.x = direction.x * speed
|
|
velocity.z = direction.z * speed
|
|
|
|
# Поворачиваем врага в сторону цели
|
|
var look_direction = (target.global_position - global_position)
|
|
look_direction.y = 0
|
|
if look_direction.length() > 0.1:
|
|
var angle = atan2(look_direction.x, look_direction.z)
|
|
rotation.y = angle
|
|
else:
|
|
# Остановка - не поворачиваемся
|
|
velocity.x = move_toward(velocity.x, 0, speed)
|
|
velocity.z = move_toward(velocity.z, 0, speed)
|
|
else:
|
|
# Остановка если нет цели
|
|
velocity.x = move_toward(velocity.x, 0, speed)
|
|
velocity.z = move_toward(velocity.z, 0, speed)
|
|
|
|
# Применяем гравитацию
|
|
if not is_on_floor():
|
|
velocity.y -= 9.8 * delta
|
|
else:
|
|
velocity.y = 0
|
|
|
|
super._physics_process(delta)
|
|
|
|
func find_target():
|
|
# Ищем игрока в сцене
|
|
var players = get_tree().get_nodes_in_group("player")
|
|
if players.size() > 0:
|
|
target = players[0]
|
|
|
|
func attack(target_unit: Node3D):
|
|
# Атака цели
|
|
if target_unit.has_method("take_damage"):
|
|
target_unit.take_damage(attack_damage)
|