64 lines
2.1 KiB
GDScript
64 lines
2.1 KiB
GDScript
extends CharacterBody3D
|
|
|
|
class_name AIBase
|
|
|
|
@export_group("Settings")
|
|
@export var speed: float = 4.0
|
|
var _enable_state_machine: bool = true
|
|
@export var enable_state_machine: bool:
|
|
set(value):
|
|
_enable_state_machine = value
|
|
toggle_enable_state_machine()
|
|
get:
|
|
return _enable_state_machine
|
|
@export var anim_player: AnimationPlayer
|
|
|
|
@export_group("Entities")
|
|
enum EntityType { HUMANOID, ANIMAL }
|
|
@export var entity_type: EntityType = EntityType.HUMANOID
|
|
@export var entity_name: String = ""
|
|
@export var allowed_biomes: Array[String] = []
|
|
@export_range(0.0, 100.0, 0.1) var spawn_uniqueness: float = 1.0
|
|
|
|
@onready var patrol_radius_shape: CollisionShape3D = $%PatrolRadiusShape
|
|
@onready var nav_agent: NavigationAgent3D = $%NavigationAgent3D
|
|
@onready var state_machine: StateMachine = $%StateMachine
|
|
|
|
func _ready() -> void:
|
|
randomize()
|
|
toggle_enable_state_machine()
|
|
|
|
func toggle_enable_state_machine() -> void:
|
|
state_machine.enable = _enable_state_machine
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if !_enable_state_machine:
|
|
return
|
|
|
|
state_machine.physics_process(delta)
|
|
|
|
if nav_agent.is_navigation_finished():
|
|
velocity = Vector3.ZERO
|
|
move_and_slide()
|
|
return
|
|
|
|
var next_point = nav_agent.get_next_path_position()
|
|
var direction = global_position.direction_to(next_point)
|
|
|
|
velocity.x = direction.x * speed
|
|
velocity.z = direction.z * speed
|
|
|
|
if velocity.length_squared() > 0.1:
|
|
var look_dir = Vector3(velocity.x, 0, velocity.z)
|
|
var target_transform = global_transform.looking_at(global_position - look_dir, Vector3.UP)
|
|
global_transform = global_transform.interpolate_with(target_transform, delta * 10.0)
|
|
|
|
move_and_slide()
|
|
|
|
func navigate_to_random_point() -> void:
|
|
var nav_map_rid = get_world_3d().get_navigation_map()
|
|
var patrol_radius = patrol_radius_shape.shape.radius
|
|
var target_point_in_space = global_position + Vector3(randf_range(-1, 1), 0, randf_range(-1, 1)).normalized() * randf_range(0, patrol_radius)
|
|
var closest_valid_point = NavigationServer3D.map_get_closest_point(nav_map_rid, target_point_in_space)
|
|
nav_agent.target_position = closest_valid_point
|