TinyAdventure/objects/non_player_character.gd

96 lines
3.1 KiB
GDScript
Raw Normal View History

2024-10-15 21:32:01 +02:00
class_name NonPlayerCharacter
extends CharacterBody3D
@export var reacts_to_player:bool = true :
set (value):
reacts_to_player = _set_reacts_to_player(value)
get:
return reacts_to_player
@export var behaviour:BehaviorTree = null:
set (value):
behaviour = value
if is_instance_valid(bt_player):
bt_player.behavior_tree = behaviour
get:
return behaviour
@onready var geometry: Node3D = null
2024-10-15 21:32:01 +02:00
@onready var player_detection: Area3D = %PlayerDetection
@onready var default_geometry: Node3D = %DefaultGeometry
@onready var animation_player: AnimationPlayer = %AnimationPlayer
@onready var navigation_agent: NavigationAgent3D = %NavigationAgent
@onready var bt_player: BTPlayer = %BTPlayer
2024-10-15 21:32:01 +02:00
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
2024-11-01 18:07:23 +01:00
var tool_damage:bool = false
2024-10-15 21:32:01 +02:00
var tracking_node:Node3D = null
var navigation_active:bool = false
var navigation_query_parameters:NavigationPathQueryParameters3D = NavigationPathQueryParameters3D.new()
var navigation_query_result:NavigationPathQueryResult3D = NavigationPathQueryResult3D.new()
2024-11-15 11:35:37 +01:00
2024-10-15 21:32:01 +02:00
func _set_reacts_to_player(value:bool) -> bool:
if player_detection != null:
player_detection.monitoring = value
return value
func _ready() -> void:
player_detection.monitoring = reacts_to_player
geometry = find_child("Geometry")
if geometry == null:
geometry = default_geometry
else:
default_geometry.visible = false
animation_player.set_root("Geometry")
if is_instance_valid(bt_player):
bt_player.behavior_tree = behaviour
func _physics_process(_delta: float) -> void:
if navigation_active:
var next_position:Vector3 = navigation_agent.get_next_path_position()
if navigation_agent.is_target_reached():
print ("Target reached. Distance: %s" % navigation_agent.distance_to_target())
navigation_active = false
else:
var direction = (next_position - global_position).normalized()
basis = Basis.looking_at(-direction)
velocity = direction * 2
move_and_slide()
2024-10-15 21:32:01 +02:00
func _on_player_detection_body_entered(body: Node3D) -> void:
2024-11-15 11:35:37 +01:00
if body is Player:
tracking_node = body
2024-10-15 21:32:01 +02:00
func _on_player_detection_body_exited(body: Node3D) -> void:
if body == tracking_node:
tracking_node = null
func is_target_navigatable(target_position: Vector3) -> bool:
navigation_query_parameters.map = get_world_3d().navigation_map
navigation_query_parameters.start_position = global_position
navigation_query_parameters.target_position = target_position
navigation_query_parameters.navigation_layers = navigation_agent.navigation_layers
if NavigationServer3D.map_get_iteration_id(navigation_query_parameters.map) == 0:
return false
NavigationServer3D.query_path(navigation_query_parameters, navigation_query_result)
var query_path: PackedVector3Array = navigation_query_result.path
if query_path.size() > 0 and (query_path[query_path.size() - 1] - target_position).length() <= navigation_agent.target_desired_distance:
return true
return false
func navigate_to(target_position: Vector3) -> void:
navigation_agent.target_position = target_position
assert (is_target_navigatable(target_position))
navigation_active = not navigation_agent.is_target_reached()