-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPlayer.gd
99 lines (81 loc) · 2.63 KB
/
Player.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
extends KinematicBody
var velocity = Vector3()
var camera
var gravity = -9.8
var character
enum STATES { IDLE, FOLLOW, WATCHING }
var _state = null
var target_point_world: Vector3
var path = []
const SPEED = 6
func _ready():
character = get_node(".")
_change_state(STATES.IDLE)
func _change_state(new_state):
if new_state == STATES.FOLLOW:
var trip = getTrip()
var map = get_parent().get_node("GridMap")
path = map.get_world_path(trip[0], trip[1])
if path.empty():
_change_state(STATES.IDLE)
return
# The index 0 is the starting cell
# we don't want the character to move back to it in this example
target_point_world = path[1]
_state = new_state
func _input(event):
if event is InputEventMouseButton:
if !event.pressed:
if _state == STATES.WATCHING:
_change_state(STATES.IDLE)
else:
_change_state(STATES.FOLLOW)
func getTrip():
var trip = []
var camera = get_node("target/Camera") as Camera
var mousePos = get_viewport().get_mouse_position()
var start_world_pos = character.get_global_transform().origin;
# Project mouse into a 3D ray
var ray_origin = camera.project_ray_origin(mousePos)
var ray_direction = camera.project_ray_normal(mousePos)
# Cast a ray
var from = ray_origin
var to = ray_origin + ray_direction * 1000.0
var space_state = get_world().get_direct_space_state()
var hit = space_state.intersect_ray(from, to)
if hit.size() != 0:
if hit.collider is GridMap:
var map: GridMap = hit.collider
var start = map.world_to_map(start_world_pos)
trip.append(start)
var destination_world_pos = Vector3(hit.position.x, hit.position.y, hit.position.z)
var destination = map.world_to_map(destination_world_pos)
trip.append(destination)
return trip
return null
func move_to(delta, world_position: Vector3):
var MASS = 10.0
var ARRIVE_DISTANCE = 1.5
var desired_velocity = (world_position - global_transform.origin).normalized() * SPEED
var steering = desired_velocity - velocity
velocity += steering / MASS
velocity.y = delta * gravity
velocity = move_and_slide(velocity, Vector3(0,1,0))
var angle = atan2(velocity.x, velocity.z)
var rotation = get_rotation()
rotation.y = angle
set_rotation(rotation)
var position = global_transform.origin
var arrive_distance = position.distance_to(world_position)
return arrive_distance < ARRIVE_DISTANCE
func _physics_process(delta):
if _state == STATES.FOLLOW:
var arrived_to_next_point = move_to(delta, target_point_world)
if arrived_to_next_point:
path.remove(0)
if path.empty():
_change_state(STATES.IDLE)
return
target_point_world = path[0]
func _on_Camera_is_watching():
_change_state(STATES.WATCHING)