Files
fps_project_1/scripts/CharacterStates.gd

92 lines
3.4 KiB
GDScript

extends State
class_name CharacterState
@export var character: CharacterBody3D
@export var move_speed: float = 3
@export var body_turn_speed: float = 3
@export var head_turn_speed: float = 6.0
@export var can_see: bool = true # indicates whether the character is able to see things in the state
@export var poi_investigate: bool = false
@export var poi_change_to_search: bool = false
@export var poi_update_waypoint_immediately: bool = false
var move_target
var look_target
func character_has_target():
if character.player_last_seen != null:
return true
if character.point_of_interest != null:
return true
return false
func update_move_target():
if character.player_last_seen != null:
return character.player_last_seen
elif character.point_of_interest != null:
return character.point_of_interest["point"]
else:
return character.global_position
func search_on_lost_target():
if !character.is_player_visible():
Transitioned.emit(self, "attack")
func move_target_adj(position):
return Vector3(position.x, character.global_position.y, position.z)
func rotate_to_face2D(object, target, target_offset_angle, delta, turn_speed):
#to allow both nodes and positions to be passed to this function, test the target and use Vector3 coords
var target_transformed
if target == null:
target_transformed = object.global_position
elif target is Vector3:
target_transformed = target
elif target is Node3D:
target_transformed = target.global_position
var pos2d = Vector2(object.global_position.x, object.global_position.z)
var target_pos2d = Vector2(target_transformed.x, target_transformed.z)
var direction = (pos2d - target_pos2d)
return lerp_angle(object.global_rotation.y, atan2(direction.x, direction.y) + deg_to_rad(target_offset_angle), delta * turn_speed)
func rotate_to_face3D(object: Node3D, target, target_offset_angle: Vector3, delta: float, turn_speed: float):
if target == null:
return
var target_positon
if target is Vector3:
target_positon = target
else:
target_positon = target.global_position
var desired_rotation = object.global_transform.looking_at(target_positon, Vector3.UP).basis.get_euler()
var current_rotation = object.global_rotation
#Interpolate each axis
current_rotation.x = lerp_angle(current_rotation.x, desired_rotation.x + target_offset_angle.x, delta * turn_speed)
current_rotation.y = lerp_angle(current_rotation.y, desired_rotation.y + target_offset_angle.y, delta * turn_speed)
current_rotation.z = lerp_angle(current_rotation.z, desired_rotation.z + target_offset_angle.z, delta * turn_speed)
#clamp pitch
var max_downward_pitch = deg_to_rad(85)
var min_upward_pitch = deg_to_rad(-45)
current_rotation.x = clamp(current_rotation.x, min_upward_pitch, max_downward_pitch)
object.global_rotation = current_rotation
func move_to_nav_point(delta):
var destination = character.nav_agent.get_next_path_position()
var local_destination = destination - character.global_position
var new_velocity = local_destination.normalized() * move_speed
character.nav_agent.set_velocity(new_velocity)
character.global_rotation.y = rotate_to_face2D(character, destination, 0, delta, body_turn_speed)
func velocity_computed(safe_velocity):
character.velocity = character.velocity.move_toward(safe_velocity, .25)
func update_minimap(priority, duration, color):
SignalBus.emit_signal("ui_minimap_point", character, character.global_position, 1, duration, color)