godot-psd-training/sceen/people/Player.gd
2024-07-22 11:18:50 +08:00

83 lines
2.5 KiB
GDScript

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