extends State class_name CharacterState @export var character : CharacterBody3D @export var move_speed : float = 3 @export var body_turn_speed : float = 3 @export var turret_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)