extends CharacterBody3D ##玩家 class_name Player @onready var people: Node3D = $people @onready var state_machine: StateMachine = $StateMachine ##导航 @onready var navigation_agent_3d: NavigationAgent3D = $NavigationAgent3D ## 运动方式的枚举 enum Exercise_type{ no, #没用运动 navigation, #导航代理 pathFollow, #路径跟随 } var currentExerciseType :Exercise_type = Exercise_type.no var speed:float = 1 var stop_distance:float = 1 signal ArriveTargetPos ##设置目标位(寻路方式运动) func setTargetPos(targetPos:Vector3,stopDistance = 1)-> void: stop_distance = stopDistance navigation_agent_3d.target_position = targetPos navigation_agent_3d.target_position =navigation_agent_3d.get_final_position() ##去目标位 func goToTarget()-> void: currentExerciseType = Exercise_type.navigation $NavigationTimer.start() state_machine.change_state("Walk") ##停止移动 func stopToTarget()-> void: $NavigationTimer.stop() state_machine.change_state("Idle") func _on_navigation_timer_timeout() -> void: var direction_3d = (navigation_agent_3d.get_next_path_position() - global_position).normalized() velocity = direction_3d*speed*4 if global_position != navigation_agent_3d.get_next_path_position() : look_at_from_position(global_position, navigation_agent_3d.get_next_path_position()) if navigation_agent_3d.distance_to_target() > stop_distance : move_and_slide() else : stopToTarget() ArriveTargetPos.emit() currentExerciseType = Exercise_type.no ##区域碰撞检测相关 signal AreaEnter(area: Area3D) signal AreaExit(area: Area3D) func _on_area_3d_area_entered(area: Area3D) -> void: AreaEnter.emit(area) if currentExerciseType == Exercise_type.navigation and area.is_in_group('needStopWalk') : stopToTarget() func _on_area_3d_area_exited(area: Area3D) -> void: AreaExit.emit(area) if currentExerciseType == Exercise_type.navigation and area.is_in_group('needStopWalk') : goToTarget() var frontPeople = 0 func _on_people_front_area_3d_area_entered(area: Area3D) -> void: var peopleWalkFollow = area.get_parent().get_parent() if ( area.is_in_group('player') and peopleWalkFollow.id != self.get_parent().id ) or area.is_in_group('needStopWalk') : frontPeople += 1 func _on_people_front_area_3d_area_exited(area: Area3D) -> void: var peopleWalkFollow = area.get_parent().get_parent() if ( area.is_in_group('player') and peopleWalkFollow.id != self.get_parent().id ) or area.is_in_group('needStopWalk') : frontPeople -= 1 func changeAreaRadius(radius:int) -> void: $Area3D/CollisionShape3D.shape.radius = radius