-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathEditorCamera.gd
183 lines (151 loc) · 5.45 KB
/
EditorCamera.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
class_name EditorCameraOld
extends Camera3D
# Modifier keys' speed multiplier
const SHIFT_MULTIPLIER = 3.5
const ALT_MULTIPLIER = 1.0 / SHIFT_MULTIPLIER
# @export_range(0.0, 1.0) var sensitivity: float = 0.25
# Mouse state
var _mouse_position = Vector2(0.0, 0.0)
var _total_pitch = 0.0
# Movement state
var _direction = Vector3(0.0, 0.0, 0.0)
var _velocity = Vector3(0.0, 0.0, 0.0)
var _acceleration = 30
var _deceleration = -10
var _vel_multiplier = 80
# Keyboard state
var _w = false
var _s = false
var _a = false
var _d = false
var _q = false
var _e = false
var _shift = false
var _alt = false
signal mouseCaptureExited()
func _ready():
global_position = Vector3.UP * 128
var inputEnabled = true
func _unhandled_input(event):
if !inputEnabled:
return
# Receives mouse motion
if event is InputEventMouseMotion:
_mouse_position = event.relative
# Receives mouse button input
# if event is InputEventMouseButton:
# match event.button_index:
# MOUSE_BUTTON_RIGHT: # Only allows rotation if right click down
# Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED if event.pressed else Input.MOUSE_MODE_VISIBLE)
# MOUSE_BUTTON_WHEEL_UP: # Increases max velocity
# _vel_multiplier = clamp(_vel_multiplier * 1.1, 0.2, 20)
# MOUSE_BUTTON_WHEEL_DOWN: # Decereases max velocity
# _vel_multiplier = clamp(_vel_multiplier / 1.1, 0.2, 20)
# if event.is_action("editor_look_around"):
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED if Input.is_action_pressed("editor_look_around") else Input.MOUSE_MODE_VISIBLE)
mouseCaptured = Input.is_action_pressed("editor_look_around")
if Input.is_action_just_released("editor_look_around"):
mouseCaptureExited.emit()
# Receives key input
# if event is InputEventKey:
# match event.keycode:
# KEY_W:
# _w = event.pressed
# KEY_S:
# _s = event.pressed
# KEY_A:
# _a = event.pressed
# KEY_D:
# _d = event.pressed
# KEY_Q:
# _q = event.pressed
# KEY_E:
# _e = event.pressed
# KEY_SHIFT:
# _shift = event.pressed
# KEY_ALT:
# _alt = event.pressed
_w = Input.is_action_pressed("editor_move_forward")
_s = Input.is_action_pressed("editor_move_backward")
_a = Input.is_action_pressed("editor_move_left")
_d = Input.is_action_pressed("editor_move_right")
# _q = Input.is_action_pressed("editor_up")
# _e = Input.is_action_pressed("editor_down")
_shift = Input.is_action_pressed("editor_move_fast")
# Updates mouselook and movement every frame
func _process(delta):
_update_mouselook()
_update_movement(delta)
# Updates camera movement
var velocityLength = 0.0
var mouseCaptured = false
func _update_movement(delta):
# Computes desired direction from key states
_direction = Vector3(
(_d as float) - (_a as float),
(_e as float) - (_q as float),
(_s as float) - (_w as float)
)
# Computes the change in velocity due to desired direction and "drag"
# The "drag" is a constant acceleration on the camera to bring it's velocity to 0
var offset = _direction.normalized() * _acceleration * _vel_multiplier * delta \
+ _velocity.normalized() * _deceleration * _vel_multiplier * delta
# Compute modifiers' speed multiplier
var speed_multi = 1
if _shift: speed_multi *= SHIFT_MULTIPLIER
if _alt: speed_multi *= ALT_MULTIPLIER
# Checks if we should bother translating the camera
if _direction == Vector3.ZERO and offset.length_squared() > _velocity.length_squared():
# Sets the velocity to 0 to prevent jittering due to imperfect deceleration
_velocity = Vector3.ZERO
else:
# Clamps speed to stay within maximum value (_vel_multiplier)
_velocity.x = clamp(_velocity.x + offset.x, -_vel_multiplier, _vel_multiplier)
_velocity.y = clamp(_velocity.y + offset.y, -_vel_multiplier, _vel_multiplier)
_velocity.z = clamp(_velocity.z + offset.z, -_vel_multiplier, _vel_multiplier)
if !mouseCaptured:
# # Change velocity here to not move on global y axis
# ...
# translate(_velocity * delta * speed_multi)
var globalVelocity = global_transform.basis * _velocity
globalVelocity.y = 0
global_position += globalVelocity * delta * speed_multi
return
translate(_velocity * delta * speed_multi)
# Updates mouse look
func _update_mouselook():
# Only rotates mouse if the mouse is captured
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
# _mouse_position *= sensitivity
_mouse_position *= GlobalProperties.MOUSE_SENSITIVITY / 100
var yaw = _mouse_position.x
var pitch = _mouse_position.y
_mouse_position = Vector2(0, 0)
# Prevents looking up/down too far
pitch = clamp(pitch, -90 - _total_pitch, 90 - _total_pitch)
_total_pitch += pitch
rotate_y(deg_to_rad(-yaw))
rotate_object_local(Vector3(1,0,0), deg_to_rad(-pitch))
func getPositionInFrontOfCamera(distance: float) -> Vector3:
return global_position - global_transform.basis.z * distance
func getGridAlignedBasis() -> Basis:
var gridAlignedBasis = global_transform.basis
# relative x axis
gridAlignedBasis.x.y = 0
if abs(gridAlignedBasis.x.x) > abs(gridAlignedBasis.x.z):
gridAlignedBasis.x.z = 0
else:
gridAlignedBasis.x.x = 0
gridAlignedBasis.x = gridAlignedBasis.x.normalized()
# relative z axis
# gridAlignedBasis.z.y = 0
# if gridAlignedBasis.z.x > gridAlignedBasis.z.z:
# gridAlignedBasis.z.z = 0
# else:
# gridAlignedBasis.z.x = 0
# gridAlignedBasis.z = gridAlignedBasis.z.normalized()
# irrelevant, can be calculated from x and y
# constant y axis
gridAlignedBasis.y = Vector3.UP
gridAlignedBasis.z = gridAlignedBasis.x.cross(gridAlignedBasis.y)
return gridAlignedBasis