forked from ensemble-ai/ecs179-gameplay-programming-fall-2024-exercise-2-camera-control-CameraControlExercise
-
Notifications
You must be signed in to change notification settings - Fork 0
/
push_zone.gd
149 lines (113 loc) · 6.63 KB
/
push_zone.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
class_name PushZone
extends CameraControllerBase
@export var push_ratio:float
@export var pushbox_top_left:Vector2
@export var pushbox_bottom_right:Vector2
@export var speedup_zone_top_left:Vector2
@export var speedup_zone_bottom_right:Vector2
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
# hello there (nov 1 2:15 am)
super()
position = target.position
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if !current: # process only runs when camera is selected
return
if draw_camera_logic:
draw_logic()
if just_switched: # centers camera on vessel after you toggle to it
global_position.x = target.global_position.x
global_position.z = target.global_position.z
just_switched = false
var tpos = target.global_position
var cpos = global_position
# use normal vector of vessel velocity to extract direction of vessel movement
var input_direction = Vector2(target.velocity.normalized().x, target.velocity.normalized().z)
var camera_to_vessel = Vector2(tpos.x - cpos.x, tpos.z - cpos.z).normalized()
var movement = Vector2(0,0)
# variables used to check if vessel is in speedup zone
var diff_between_left_edges_speedup = (tpos.x - target.WIDTH / 2.0) - (cpos.x + speedup_zone_top_left.x)
var diff_between_right_edges_speedup = (tpos.x + target.WIDTH / 2.0) - (cpos.x + speedup_zone_bottom_right.x)
var diff_between_top_edges_speedup = (tpos.z + target.HEIGHT / 2.0) - (cpos.z + speedup_zone_top_left.y)
var diff_between_bottom_edges_speedup = (tpos.z - target.HEIGHT / 2.0) - (cpos.z - speedup_zone_top_left.y)
# variables used to check if vessel is touching edge of push box
var diff_between_left_edges_pushbox = (tpos.x - target.WIDTH / 2.0) - (cpos.x + pushbox_top_left.x)
var diff_between_right_edges_pushbox = (tpos.x + target.WIDTH / 2.0) - (cpos.x + pushbox_bottom_right.x)
var diff_between_top_edges_pushbox = (tpos.z + target.HEIGHT / 2.0) - (cpos.z + pushbox_top_left.y)
var diff_between_bottom_edges_pushbox = (tpos.z - target.HEIGHT / 2.0) - (cpos.z - pushbox_top_left.y)
if (diff_between_left_edges_speedup < 0 || diff_between_right_edges_speedup > 0
|| diff_between_top_edges_speedup > 0 || diff_between_bottom_edges_speedup < 0):
# if vessel is in the speedup zone, set its velocity to vessel speed * push ratio in direction of vessel movement
movement = input_direction * target.velocity.length() * push_ratio
# check to see if vessel isn't moving towards edges of push box
# if vessel is heading back towards center of camera, do not move camera
if diff_between_left_edges_speedup < 0 && input_direction.x > 0:
movement.x = 0
if diff_between_right_edges_speedup > 0 && input_direction.x < 0:
movement.x = 0
if diff_between_top_edges_speedup > 0 && input_direction.y < 0:
movement.y = 0
if diff_between_bottom_edges_speedup <0 && input_direction.y > 0:
movement.y = 0
if (diff_between_left_edges_pushbox <= 0):
# if vessel touching left edge of pushbox, move camera in x direction at vessel's x velocity
# accomplish by detecting if vessel has left box from left side and then moving camera to vessel's postion
movement.x = diff_between_left_edges_pushbox/delta
if (diff_between_right_edges_pushbox >= 0):
# if vessel touching right edge of pushbox, move camera in x direction at vessel's x velocity
# accomplish by detecting if vessel has left box from right side and then moving camera to vessel's postion
movement.x = diff_between_right_edges_pushbox/delta
if (diff_between_top_edges_pushbox >= 0):
# if vessel touching top edge of pushbox, move camera in y direction at vessel's y velocity
# accomplish by detecting if vessel has left box from top side and then moving camera to vessel's postion
movement.y = diff_between_top_edges_pushbox/delta
if (diff_between_bottom_edges_pushbox <= 0):
# if vessel touching bottom edge of pushbox, move camera in y direction at vessel's y velocity
# accomplish by detecting if vessel has left box from bottom side and then moving camera to vessel's postion
movement.y = diff_between_bottom_edges_pushbox/delta
# update camera's position based on calculations
global_position.x += movement.x * delta
global_position.z += movement.y * delta
super(delta)
func draw_logic() -> void:
var mesh_instance := MeshInstance3D.new()
var immediate_mesh := ImmediateMesh.new()
var material := ORMMaterial3D.new()
mesh_instance.mesh = immediate_mesh
mesh_instance.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
var left_pushbox:float = pushbox_top_left.x
var right_pushbox:float = pushbox_bottom_right.x
var top_pushbox:float = -pushbox_top_left.y
var bottom_pushbox:float = -pushbox_bottom_right.y
immediate_mesh.surface_begin(Mesh.PRIMITIVE_LINES, material)
immediate_mesh.surface_add_vertex(Vector3(right_pushbox, 0, top_pushbox))
immediate_mesh.surface_add_vertex(Vector3(right_pushbox, 0, bottom_pushbox))
immediate_mesh.surface_add_vertex(Vector3(right_pushbox, 0, bottom_pushbox))
immediate_mesh.surface_add_vertex(Vector3(left_pushbox, 0, bottom_pushbox))
immediate_mesh.surface_add_vertex(Vector3(left_pushbox, 0, bottom_pushbox))
immediate_mesh.surface_add_vertex(Vector3(left_pushbox, 0, top_pushbox))
immediate_mesh.surface_add_vertex(Vector3(left_pushbox, 0, top_pushbox))
immediate_mesh.surface_add_vertex(Vector3(right_pushbox, 0, top_pushbox))
var left_speedup:float = speedup_zone_top_left.x
var right_speedup:float = speedup_zone_bottom_right.x
var top_speedup:float = -speedup_zone_top_left.y
var bottom_speedup:float = -speedup_zone_bottom_right.y
immediate_mesh.surface_begin(Mesh.PRIMITIVE_LINES, material)
immediate_mesh.surface_add_vertex(Vector3(right_speedup, 0, top_speedup))
immediate_mesh.surface_add_vertex(Vector3(right_speedup, 0, bottom_speedup))
immediate_mesh.surface_add_vertex(Vector3(right_speedup, 0, bottom_speedup))
immediate_mesh.surface_add_vertex(Vector3(left_speedup, 0, bottom_speedup))
immediate_mesh.surface_add_vertex(Vector3(left_speedup, 0, bottom_speedup))
immediate_mesh.surface_add_vertex(Vector3(left_speedup, 0, top_speedup))
immediate_mesh.surface_add_vertex(Vector3(left_speedup, 0, top_speedup))
immediate_mesh.surface_add_vertex(Vector3(right_speedup, 0, top_speedup))
immediate_mesh.surface_end()
material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
material.albedo_color = Color.BLACK
add_child(mesh_instance)
mesh_instance.global_transform = Transform3D.IDENTITY
mesh_instance.global_position = Vector3(global_position.x, target.global_position.y, global_position.z)
#mesh is freed after one update of _process
await get_tree().process_frame
mesh_instance.queue_free()