-
Notifications
You must be signed in to change notification settings - Fork 38
/
OQ_ButtonPressable.gd
110 lines (79 loc) · 2.85 KB
/
OQ_ButtonPressable.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
# This is a first draft of a pressable toggle button
# At the moment it interacts with any area that enters it
extends Spatial
signal button_pressed
var touching := false
var at_default_pos := true
var triggering := false
var is_on := false
var hand_area: Area
var button_half_length_vector
var hand_pos: Vector3
var prev_hand_pos: Vector3
var dist := 0.0
var lerp_weight: float
var start_time := 0.0
var speed := 2.0
onready var initial_pos_local: = get_transform().origin
onready var initial_pos_global: = get_global_transform().origin
onready var button_forward_vector_norm = get_transform().basis.z.normalized()
onready var z_scale = scale.z
onready var button_mesh := $MeshInstance
export var press_distance := 0.008
export(Material) var off_material
export(Material) var on_material
export var on_on_start := false
func _ready():
# connect to signals
$ButtonArea.connect("area_entered", self, "_on_ButtonArea_area_entered")
$ButtonArea.connect("area_exited", self, "_on_ButtonArea_area_exited")
button_half_length_vector = initial_pos_local + button_forward_vector_norm * z_scale / 2
# switch to correct material
if (on_on_start):
is_on = true
switch_mat(is_on)
func _process(delta):
if touching:
# if hand is touching the button, we need to know how far in it is pressed
# check how much hand pos has changed in buttons local z direction
hand_pos = hand_area.global_transform.origin
var hand_pos_change = hand_pos - prev_hand_pos
var hand_pos_change_z_component = hand_pos_change.slide(button_forward_vector_norm)
dist = hand_pos_change_z_component.length()
var new_origin = Vector3(initial_pos_local.x, initial_pos_local.y, transform.origin.z - dist)
# only keep pushing back until press_distance is reached
if initial_pos_local.z - new_origin.z < press_distance:
transform.origin = new_origin
elif !triggering:
# trigger button press
triggering = true
button_press(hand_area)
prev_hand_pos = hand_pos
elif !at_default_pos:
# if not touching and not at default pos, bring back to default pos
lerp_weight = start_time / speed
var move_by = lerp(dist, 0, lerp_weight)
var new_origin = Vector3(initial_pos_local.x, initial_pos_local.y, initial_pos_local.z + move_by)
transform.origin = new_origin
start_time += delta
if lerp_weight > 0:
start_time = 0.0
at_default_pos = true
triggering = false
func _on_ButtonArea_area_entered(area):
touching = true
at_default_pos = false
hand_area = area
hand_pos = hand_area.global_transform.origin
prev_hand_pos = hand_area.global_transform.origin
func _on_ButtonArea_area_exited(area):
touching = false
func button_press(other_area: Area):
is_on = !is_on
switch_mat(is_on)
emit_signal("button_pressed")
func switch_mat(_is_on):
if _is_on:
button_mesh.set_material_override(on_material)
else:
button_mesh.set_material_override(off_material)