main_camera.gd 4,7 КБ
Newer Older
magcourier's avatar
magcourier включено в состав коммита
1
2
3
4
5
6
7
8
9
10
11
12
13
extends Camera

export var enabled = true setget set_enabled
export(int, "Visible", "Hidden", "Captured, Confined") var mouse_mode = 2

# Freelook settings
export var freelook = true
export (float, 0.0, 1.0) var sensitivity = 0.5
export (float, 0.0, 0.999, 0.001) var smoothness = 0.5 setget set_smoothness
export (int, 0, 360) var yaw_limit = 360
export (int, 0, 360) var pitch_limit = 360

# Pivot Settings
magcourier's avatar
magcourier включено в состав коммита
14
export(NodePath) var privot setget set_privot # true - камера следит за кораблём
magcourier's avatar
magcourier включено в состав коммита
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
export var rotate_privot = false
var distance =25.0
var distance_smooth
export var distance_min = 10
export var distance_max = 100
export var distance_step: float = 2.0

# Movement settings
export (float, 0.0, 1.0) var acceleration = 0.1
export (float, 0.0, 0.0, 1.0) var deceleration = 0.1
export var max_speed = Vector3(1.0, 1.0, 1.0)
export var local = true

# Intern variables.
var _mouse_offset = Vector2()
var _rotation_offset = Vector2()
var _yaw = 0.0
var _pitch = 0.0
var _total_yaw = 0.0
var _total_pitch = 0.0

var _direction = Vector3(0.0, 0.0, 0.0)
var _speed = Vector3(0.0, 0.0, 0.0)

const ROTATION_MULTIPLIER = 500
func _ready():
Artur Ahmadiev's avatar
Artur Ahmadiev включено в состав коммита
41
42
43
44
45
46
47
48
49
50
51
	# Управление камерой при RU раскладке клав.
	var event = InputEventKey.new()
	var a = ord ("ф")
	var w = ord ("ц")
	var s = ord ("ы")
	var d = ord ("в")
	event.unicode = a
	event.unicode = w
	event.unicode = s
	event.unicode = d
	#
magcourier's avatar
magcourier включено в состав коммита
52
53
	Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED)

magcourier's avatar
magcourier включено в состав коммита
54
func _unhandled_input(event):
magcourier's avatar
magcourier включено в состав коммита
55
56
57
58
59
60
61
	if freelook:
		if Input.get_action_strength("right_click"):
			Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
			if event is InputEventMouseMotion:
				_mouse_offset = event.relative
		else:
			Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
magcourier's avatar
magcourier включено в состав коммита
62
63

func _input(event):
magcourier's avatar
magcourier включено в состав коммита
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
	if privot:
		if event.is_action_pressed("wheel_down"):
			distance-=distance_step
		if event.is_action_pressed("wheel_up"):
			distance += distance_step
		distance += (Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")) * distance_step * 0.5
		distance = clamp(distance,distance_min,distance_max)
	else:
		_direction.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
		_direction.y = Input.get_action_strength("ui_page_up") - Input.get_action_strength("ui_page_down")
		_direction.z = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")
		

func _physics_process(delta):
	collide()
	if privot:
		distance_smooth =lerp(distance_smooth,distance,0.05)
		set_translation(privot.get_translation())
		translate_object_local(Vector3(0.0, 0.0, distance_smooth))
	else:
		_update_movement(delta)
	if freelook:
		_update_rotation(delta)
			
func collide():
	if privot:
		if $down.is_colliding():
			_mouse_offset.y = 1
		if $up.is_colliding():
			_mouse_offset.y = -1
		if $left.is_colliding():
			_mouse_offset.x = 1
		if $right.is_colliding():
			_mouse_offset.x = -1
		if $forward.is_colliding():
			distance +=distance_step 
		if $back.is_colliding():
			distance -=distance_step 
	else:
		if $down.is_colliding():
			_direction.y = 2
		if $up.is_colliding():
			_direction.y = -2
		if $left.is_colliding():
			_direction.x = 2
		if $right.is_colliding():
			_direction.x = -2
		if $forward.is_colliding():
			_direction.z =2 
		if $back.is_colliding():
			_direction.z =-2 
			
func _update_movement(delta):
	var offset = max_speed * acceleration * _direction

	_speed.x = clamp(_speed.x + offset.x, -max_speed.x, max_speed.x)
	_speed.y = clamp(_speed.y + offset.y, -max_speed.y, max_speed.y)
	_speed.z = clamp(_speed.z + offset.z, -max_speed.z, max_speed.z)

	# Apply deceleration if no input
	if _direction.x == 0:
		_speed.x *= (1.0 - deceleration)
	if _direction.y == 0:
		_speed.y *= (1.0 - deceleration)
	if _direction.z == 0:
		_speed.z *= (1.0 - deceleration)

	if local:
		translate_object_local(_speed * delta)
	else:
		global_translate(_speed * delta)

func _update_rotation(delta):
	var offset = Vector2();
	
	offset += _mouse_offset * sensitivity
		
	_mouse_offset = Vector2()

	_yaw = _yaw * smoothness + offset.x * (1.0 - smoothness)
	_pitch = _pitch * smoothness + offset.y * (1.0 - smoothness)

	if yaw_limit < 360:
		_yaw = clamp(_yaw, -yaw_limit - _total_yaw, yaw_limit - _total_yaw)
	if pitch_limit < 360:
		_pitch = clamp(_pitch, -pitch_limit - _total_pitch, pitch_limit - _total_pitch)
	_total_yaw += _yaw
	_total_pitch += _pitch
	
	rotate_y(deg2rad(-_yaw))
	rotate_object_local(Vector3(1,0,0), deg2rad(-_pitch))

func set_privot(value):
	privot = value
	if privot:
		distance = 25
	else:
		distance = 0
	distance_smooth = distance

func set_enabled(value):
	enabled = value
	#Input.set_mouse_mode(mouse_mode)
	set_process_input(enabled)
	set_physics_process(enabled)

func set_smoothness(value):
	smoothness = clamp(value, 0.001, 0.999)