Changed Focus Handling to que-based pattern, WIP
This commit is contained in:
parent
04937e270e
commit
e1c93f7be0
|
|
@ -0,0 +1,21 @@
|
||||||
|
extends Area3D
|
||||||
|
|
||||||
|
var has_mouse: bool = false
|
||||||
|
var has_focus: bool = false:
|
||||||
|
set(focus):
|
||||||
|
_on_mouse_entered()
|
||||||
|
$UiWrapper/UiSprite/SubViewport/Collectable_ui.has_focus = focus
|
||||||
|
has_focus = focus
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready():
|
||||||
|
connect("mouse_entered", Callable(self, "_on_mouse_entered"))
|
||||||
|
|
||||||
|
func _on_mouse_entered():
|
||||||
|
input_ray_pickable = false
|
||||||
|
$UiWrapper.show()
|
||||||
|
$UiWrapper/UiSprite/SubViewport/Collectable_ui.show()
|
||||||
|
has_mouse = true
|
||||||
|
|
||||||
|
func _on_mouse_exited():
|
||||||
|
assert(false)
|
||||||
|
|
@ -36,7 +36,12 @@ func _update_scene(new_mode) -> int:
|
||||||
emit_signal("freeze")
|
emit_signal("freeze")
|
||||||
elif new_mode == Modes.FREEZE:
|
elif new_mode == Modes.FREEZE:
|
||||||
emit_signal("freeze")
|
emit_signal("freeze")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return new_mode
|
return new_mode
|
||||||
|
|
||||||
|
func _unhandled_input(event):
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
if event.pressed:
|
||||||
|
print("passed")
|
||||||
|
#State.pass_focus_to($PlayerController)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
extends Area3D
|
extends Area3D
|
||||||
|
|
||||||
|
@onready var sprite: Sprite3D = $UiSprite
|
||||||
@onready var s: Sprite3D = $Sprite3D
|
@onready var viewport: SubViewport = $UiSprite/SubViewport
|
||||||
@onready var v: SubViewport = $Sprite3D/SubViewport
|
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
var camera = get_viewport().get_camera_3d()
|
var camera = get_viewport().get_camera_3d()
|
||||||
|
|
@ -16,24 +15,26 @@ func _process(delta):
|
||||||
|
|
||||||
func _unhandled_input(event):
|
func _unhandled_input(event):
|
||||||
if event is InputEventMouse:
|
if event is InputEventMouse:
|
||||||
# Handled via _on_input_event.
|
if event is InputEventMouseButton:
|
||||||
|
if event.button_index == MOUSE_BUTTON_RIGHT:
|
||||||
|
assert(false)
|
||||||
return
|
return
|
||||||
v.push_input(event)
|
viewport.push_input(event)
|
||||||
|
|
||||||
func _on_input_event(_camera: Camera3D, event: InputEvent, pos: Vector3, _normal: Vector3, _shape_idx: int):
|
func _on_input_event(_camera: Camera3D, event: InputEvent, pos: Vector3, _normal: Vector3, _shape_idx: int):
|
||||||
# Position of the event in Sprite3D local coordinates.
|
# Position of the event in Sprite3D local coordinates.
|
||||||
var texture_3d_position = s.get_global_transform().affine_inverse() * pos
|
var texture_3d_position = sprite.get_global_transform().affine_inverse() * pos
|
||||||
#if !is_zero_approx(texture_3d_position.z):
|
#if !is_zero_approx(texture_3d_position.z):
|
||||||
# # Discard event because event didn't happen on the side of the Sprite3D.
|
# # Discard event because event didn't happen on the side of the Sprite3D.
|
||||||
# return
|
# return
|
||||||
# Position of the event relative to the texture.
|
# Position of the event relative to the texture.
|
||||||
var texture_position: Vector2 = Vector2(texture_3d_position.x, -texture_3d_position.y) / s.pixel_size - s.get_item_rect().position
|
var texture_position: Vector2 = Vector2(texture_3d_position.x, -texture_3d_position.y) / sprite.pixel_size - sprite.get_item_rect().position
|
||||||
# Send mouse event.
|
# Send mouse event.
|
||||||
var e: InputEvent = event.duplicate()
|
var e: InputEvent = event.duplicate()
|
||||||
if e is InputEventMouse:
|
if e is InputEventMouse:
|
||||||
e.set_position(texture_position)
|
e.set_position(texture_position)
|
||||||
e.set_global_position(texture_position)
|
e.set_global_position(texture_position)
|
||||||
v.push_input(e)
|
viewport.push_input(e)
|
||||||
|
|
||||||
func _on_button_pressed():
|
func _on_button_pressed():
|
||||||
print("Button pressed")
|
print("Button pressed")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
@tool
|
||||||
|
extends Button
|
||||||
|
|
||||||
|
func hide():
|
||||||
|
if visible == true:
|
||||||
|
var tween:Tween = create_tween()
|
||||||
|
custom_minimum_size = get_minimum_size()
|
||||||
|
var tmp = text
|
||||||
|
text = ""
|
||||||
|
tween.tween_property(self, "custom_minimum_size", Vector2(size.x, 0), 0.2)
|
||||||
|
update_minimum_size()
|
||||||
|
await tween.finished
|
||||||
|
visible = false
|
||||||
|
text = tmp
|
||||||
|
update_minimum_size()
|
||||||
|
|
||||||
|
func show():
|
||||||
|
if visible == false:
|
||||||
|
var tmp = text
|
||||||
|
var tween:Tween = create_tween()
|
||||||
|
tween.tween_property(self, "custom_minimum_size", get_minimum_size(), 0.2)
|
||||||
|
text = ""
|
||||||
|
update_minimum_size()
|
||||||
|
visible = true
|
||||||
|
await tween.finished
|
||||||
|
text = tmp
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
[gd_scene format=3 uid="uid://52mr50b01ibd"]
|
||||||
|
|
||||||
|
[node name="Control" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="Button" type="Button" parent="."]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_left = 495.0
|
||||||
|
offset_top = 163.0
|
||||||
|
offset_right = 634.0
|
||||||
|
offset_bottom = 235.0
|
||||||
|
text = "small boi"
|
||||||
|
|
||||||
|
[node name="Button2" type="Button" parent="."]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 0
|
||||||
|
offset_left = 441.0
|
||||||
|
offset_top = 119.0
|
||||||
|
offset_right = 694.0
|
||||||
|
offset_bottom = 320.0
|
||||||
|
text = "big boi"
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
@tool
|
||||||
|
extends CenterContainer
|
||||||
|
class_name Collectable_Ui
|
||||||
|
|
||||||
|
@export var collapsed = true:
|
||||||
|
set(collapse):
|
||||||
|
if is_inside_tree():
|
||||||
|
if State.reduce_motion:
|
||||||
|
collapsed = false
|
||||||
|
return
|
||||||
|
if collapse and not collapsed:
|
||||||
|
if is_inside_tree():
|
||||||
|
_hide_buttons()
|
||||||
|
collapsed = collapse
|
||||||
|
elif not collapse and collapsed:
|
||||||
|
if is_inside_tree():
|
||||||
|
_show_buttons()
|
||||||
|
collapsed = collapse
|
||||||
|
|
||||||
|
@export var is_story: bool = false
|
||||||
|
@export var has_focus: bool = false:
|
||||||
|
set(focused):
|
||||||
|
if has_focus == focused: return
|
||||||
|
|
||||||
|
if focused:
|
||||||
|
has_focus = State.request_focus(self)
|
||||||
|
if has_focus:
|
||||||
|
collapsed = false
|
||||||
|
if collected:
|
||||||
|
$Panel/Content/Buttons/VBoxContainer/put_back.grab_focus()
|
||||||
|
else:
|
||||||
|
$Panel/Content/Buttons/VBoxContainer/collect_or_listen.grab_focus()
|
||||||
|
elif has_focus:
|
||||||
|
has_focus = false
|
||||||
|
State.drop_own_focus(self)
|
||||||
|
get_viewport().gui_release_focus()
|
||||||
|
hide()
|
||||||
|
|
||||||
|
if not visible:
|
||||||
|
show()
|
||||||
|
|
||||||
|
|
||||||
|
@export var collected: bool = false:
|
||||||
|
set(set_collected):
|
||||||
|
collected = set_collected
|
||||||
|
if set_collected:
|
||||||
|
$Panel/Content/Buttons/VBoxContainer/put_back.show()
|
||||||
|
if is_story:
|
||||||
|
$Content/Buttons/VBoxContainer/put_back.disabled = true
|
||||||
|
$Content/Buttons/VBoxContainer/collect_or_listen.text = "listen again"
|
||||||
|
if State.allow_skipping:
|
||||||
|
$Content/Buttons/VBoxContainer/skip.text = "discard cards (skip)"
|
||||||
|
else:
|
||||||
|
$Content/Buttons/VBoxContainer/collect_or_listen.disabled = true
|
||||||
|
$Content/Buttons/VBoxContainer/put_back.show()
|
||||||
|
else:
|
||||||
|
$Content/Buttons/VBoxContainer/collect_or_listen.disabled = false
|
||||||
|
|
||||||
|
@export var skipped: bool = false
|
||||||
|
|
||||||
|
@export var item_name: String = "":
|
||||||
|
set(new_name):
|
||||||
|
item_name = new_name
|
||||||
|
$Content/Name.text = new_name
|
||||||
|
|
||||||
|
@export var content_notes: String = "":
|
||||||
|
set(new_notes):
|
||||||
|
content_notes = new_notes
|
||||||
|
$Content/Name.text = new_notes
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready():
|
||||||
|
#$Panel/Content/ContentNotes.visible = State.show_content_notes
|
||||||
|
#$Panel/Content/Buttons/VBoxContainer/Summary.visible = State.provide_summaries
|
||||||
|
#$Panel/Content/Buttons/VBoxContainer/skip.visible = State.allow_skipping
|
||||||
|
if visible and not collapsed: _show_buttons()
|
||||||
|
|
||||||
|
func _hide_buttons():
|
||||||
|
if not State.reduce_motion: $AnimationPlayer.play_backwards("show_buttons")
|
||||||
|
|
||||||
|
func _show_buttons():
|
||||||
|
if State.reduce_motion:
|
||||||
|
$AnimationPlayer.play("show_buttons")
|
||||||
|
else:
|
||||||
|
$AnimationPlayer.play("RESET")
|
||||||
|
|
||||||
|
func hide():
|
||||||
|
if visible:
|
||||||
|
_hide_buttons()
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.tween_property(self, "modulate", 0, 0.4)
|
||||||
|
_hide_buttons()
|
||||||
|
await tween.finished
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
func show():
|
||||||
|
if not collapsed:
|
||||||
|
_show_buttons()
|
||||||
|
modulate = Color()
|
||||||
|
visible = true
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.tween_property(self, "modulate", Color(1, 1, 1), 0.4)
|
||||||
|
|
||||||
|
func _yoink_focus():
|
||||||
|
State.request_focus(self, true)
|
||||||
|
|
@ -1,22 +1,120 @@
|
||||||
[gd_scene format=3 uid="uid://cceyp2yd6o3sq"]
|
[gd_scene load_steps=9 format=3 uid="uid://cceyp2yd6o3sq"]
|
||||||
|
|
||||||
[node name="CenterContainer" type="CenterContainer"]
|
[ext_resource type="Theme" uid="uid://b056fn288p8ha" path="res://logic-scenes/themes/messy.theme" id="1_2apkb"]
|
||||||
|
[ext_resource type="Script" path="res://logic-scenes/collectable/collectable_ui.gd" id="1_tgjc2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="3_63j61"]
|
||||||
|
|
||||||
|
[sub_resource type="GDScript" id="GDScript_g0qhf"]
|
||||||
|
script/source = "@tool
|
||||||
|
extends Button
|
||||||
|
|
||||||
|
func hide():
|
||||||
|
if visible == true and not State.reduce_motion:
|
||||||
|
var tween:Tween = create_tween()
|
||||||
|
custom_minimum_size = get_minimum_size()
|
||||||
|
var tmp = text
|
||||||
|
text = \"\"
|
||||||
|
tween.tween_property(self, \"custom_minimum_size\", Vector2(size.x, 0), 0.2)
|
||||||
|
update_minimum_size()
|
||||||
|
await tween.finished
|
||||||
|
visible = false
|
||||||
|
text = tmp
|
||||||
|
update_minimum_size()
|
||||||
|
else:
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
func show():
|
||||||
|
if visible == false and not State.reduce_motion:
|
||||||
|
var tmp = text
|
||||||
|
var tween:Tween = create_tween()
|
||||||
|
tween.tween_property(self, \"custom_minimum_size\", get_minimum_size(), 0.2)
|
||||||
|
text = \"\"
|
||||||
|
update_minimum_size()
|
||||||
|
visible = true
|
||||||
|
await tween.finished
|
||||||
|
text = tmp
|
||||||
|
else:
|
||||||
|
visible = true
|
||||||
|
|
||||||
|
"
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_rhsmi"]
|
||||||
|
length = 0.001
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("Panel/Content/Buttons:custom_minimum_size")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector2(0, 256)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_bq4rh"]
|
||||||
|
resource_name = "invisible"
|
||||||
|
length = 0.001
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("Panel/Content/Buttons:custom_minimum_size")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector2(0, 0)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_rx43a"]
|
||||||
|
resource_name = "show_buttons"
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("Panel/Content/Buttons:custom_minimum_size")
|
||||||
|
tracks/0/interp = 2
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.4, 0.6),
|
||||||
|
"transitions": PackedFloat32Array(1, 1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector2(0, 0), Vector2(0, 135), Vector2(0, 130)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="AnimationLibrary" id="AnimationLibrary_jad23"]
|
||||||
|
_data = {
|
||||||
|
"RESET": SubResource("Animation_rhsmi"),
|
||||||
|
"invisible": SubResource("Animation_bq4rh"),
|
||||||
|
"show_buttons": SubResource("Animation_rx43a")
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="CollectableUi" type="CenterContainer"]
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
theme = ExtResource("1_2apkb")
|
||||||
|
script = ExtResource("1_tgjc2")
|
||||||
|
collapsed = null
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
[node name="Panel" type="PanelContainer" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="Name" type="Label" parent="VBoxContainer"]
|
[node name="Content" type="VBoxContainer" parent="Panel"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="Name" type="Label" parent="Panel/Content"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_type_variation = &"HeaderLarge"
|
theme_type_variation = &"HeaderLarge"
|
||||||
text = "old Mask"
|
text = "old Mask"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|
||||||
[node name="Content Notes" type="RichTextLabel" parent="VBoxContainer"]
|
[node name="ContentNotes" type="RichTextLabel" parent="Panel/Content"]
|
||||||
|
visible = false
|
||||||
custom_minimum_size = Vector2(256, 0)
|
custom_minimum_size = Vector2(256, 0)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
|
|
@ -25,21 +123,55 @@ Food, Blood, Gore, Whatever, I need a second line.
|
||||||
[/center]"
|
[/center]"
|
||||||
fit_content = true
|
fit_content = true
|
||||||
|
|
||||||
[node name="collect_or_listen" type="Button" parent="VBoxContainer"]
|
[node name="Buttons" type="ScrollContainer" parent="Panel/Content"]
|
||||||
|
custom_minimum_size = Vector2(0, 256)
|
||||||
|
layout_mode = 2
|
||||||
|
horizontal_scroll_mode = 0
|
||||||
|
vertical_scroll_mode = 3
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/Content/Buttons"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="collect_or_listen" type="Button" parent="Panel/Content/Buttons/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
tooltip_text = "Take this with you, and listen to it's story."
|
tooltip_text = "Take this with you, and listen to it's story."
|
||||||
text = "Collect"
|
text = "Collect"
|
||||||
|
script = SubResource("GDScript_g0qhf")
|
||||||
|
|
||||||
[node name="Summary" type="Button" parent="VBoxContainer"]
|
[node name="Summary" type="Button" parent="Panel/Content/Buttons/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
tooltip_text = "Take this with you, but get a neutral description of it's story."
|
tooltip_text = "Take this with you, but get a neutral description of it's story."
|
||||||
text = "get neutral summary"
|
text = "get neutral summary"
|
||||||
|
script = SubResource("GDScript_g0qhf")
|
||||||
|
|
||||||
[node name="skip" type="Button" parent="VBoxContainer"]
|
[node name="skip" type="Button" parent="Panel/Content/Buttons/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
tooltip_text = "Choose this to entirely skip this Item without being unable to progress in the story. Skipped Segments can still be interacted with via the Pause Screen, if you decide to change your mind."
|
tooltip_text = "Choose this to entirely skip this Item without being unable to progress in the story. Skipped Segments can still be interacted with via the Pause Screen, if you decide to change your mind."
|
||||||
text = "skip"
|
text = "skip"
|
||||||
|
script = SubResource("GDScript_g0qhf")
|
||||||
|
|
||||||
[node name="put_back" type="Button" parent="VBoxContainer"]
|
[node name="put_back" type="Button" parent="Panel/Content/Buttons/VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "put back"
|
text = "put back"
|
||||||
|
script = SubResource("GDScript_g0qhf")
|
||||||
|
|
||||||
|
[node name="StartFrame" type="TextureRect" parent="Panel"]
|
||||||
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
texture = ExtResource("3_63j61")
|
||||||
|
expand_mode = 2
|
||||||
|
stretch_mode = 4
|
||||||
|
|
||||||
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||||
|
autoplay = "invisible"
|
||||||
|
libraries = {
|
||||||
|
"": SubResource("AnimationLibrary_jad23")
|
||||||
|
}
|
||||||
|
|
||||||
|
[connection signal="resized" from="Panel/Content/Buttons/VBoxContainer" to="Panel/Content/Buttons" method="_on_v_box_container_resized"]
|
||||||
|
[connection signal="focus_entered" from="Panel/Content/Buttons/VBoxContainer/collect_or_listen" to="." method="_yoink_focus"]
|
||||||
|
[connection signal="focus_entered" from="Panel/Content/Buttons/VBoxContainer/Summary" to="." method="_yoink_focus"]
|
||||||
|
[connection signal="focus_entered" from="Panel/Content/Buttons/VBoxContainer/skip" to="." method="_yoink_focus"]
|
||||||
|
[connection signal="focus_entered" from="Panel/Content/Buttons/VBoxContainer/put_back" to="." method="_yoink_focus"]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,33 @@
|
||||||
extends RigidBody3D
|
extends RigidBody3D
|
||||||
|
|
||||||
@export var active: bool = true : set = set_active
|
@export var has_focus: bool = true :
|
||||||
|
set(focused):
|
||||||
|
if has_focus != focused:
|
||||||
|
if focused:
|
||||||
|
has_focus = State.request_focus(self)
|
||||||
|
if is_inside_tree() and has_focus:
|
||||||
|
camera.make_current()
|
||||||
|
get_viewport().gui_release_focus()
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
|
var jitter_tween: Tween = create_tween()
|
||||||
|
jitter_tween.tween_property(self, "jitter_strength", 1, 1)
|
||||||
|
if has_entered: emit_signal("ui_entered")
|
||||||
|
elif has_focus:
|
||||||
|
camera.current = true
|
||||||
|
jitter_strength = 1
|
||||||
|
else:
|
||||||
|
if is_inside_tree() and has_focus:
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||||
|
var jitter_tween: Tween = create_tween()
|
||||||
|
jitter_tween.tween_property(self, "jitter_strength", 0, 0.5)
|
||||||
|
if has_entered: emit_signal("ui_exited")
|
||||||
|
else:
|
||||||
|
jitter_strength = 0
|
||||||
|
has_focus = false
|
||||||
|
State.drop_own_focus(self)
|
||||||
|
|
||||||
|
sleeping = has_focus
|
||||||
|
|
||||||
@export_range (0, 10) var max_speed: float = 3
|
@export_range (0, 10) var max_speed: float = 3
|
||||||
@export_range (0, 10) var max_acceleration: float = 5
|
@export_range (0, 10) var max_acceleration: float = 5
|
||||||
@export_range (0, 20) var damp: float = 10
|
@export_range (0, 20) var damp: float = 10
|
||||||
|
|
@ -30,36 +57,32 @@ var on_crouch_cooldown:bool = false
|
||||||
@onready var pitch:Node3D = $Yaw/Pitch
|
@onready var pitch:Node3D = $Yaw/Pitch
|
||||||
@onready var mount:Node3D = $Yaw/Pitch/Mount
|
@onready var mount:Node3D = $Yaw/Pitch/Mount
|
||||||
@onready var camera:Camera3D = $Yaw/Pitch/Mount/Camera3D
|
@onready var camera:Camera3D = $Yaw/Pitch/Mount/Camera3D
|
||||||
|
@onready var focus_ray: RayCast3D = $Yaw/Pitch/Mount/Camera3D/RayCast3D
|
||||||
|
|
||||||
func set_active(activate):
|
signal ui_entered
|
||||||
active = activate
|
var has_entered:bool = false
|
||||||
if !is_inside_tree(): return
|
signal ui_exited
|
||||||
if activate:
|
|
||||||
camera.make_current()
|
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
|
||||||
var jitter_tween: Tween = create_tween()
|
|
||||||
jitter_tween.tween_property(self, "jitter_strength", 1, 1)
|
|
||||||
else:
|
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
|
||||||
var jitter_tween: Tween = create_tween()
|
|
||||||
jitter_tween.tween_property(self, "jitter_strength", 0, 0.5)
|
|
||||||
sleeping = active
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
|
||||||
if active:
|
|
||||||
set_active(active)
|
|
||||||
jitter_strength = 1
|
|
||||||
|
|
||||||
_handle_jitter(0)
|
_handle_jitter(0)
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
if Input.is_action_just_pressed("ui_cancel"):
|
|
||||||
set_active(!active)
|
if focus_ray.get_collider() != null:
|
||||||
|
emit_signal("ui_entered")
|
||||||
|
has_entered = true
|
||||||
|
|
||||||
|
if has_entered:
|
||||||
|
if focus_ray.get_collider() == null:
|
||||||
|
emit_signal("ui_exited")
|
||||||
|
has_entered = false
|
||||||
|
if Input.is_action_just_pressed("ui_accept"):
|
||||||
|
State.pass_focus_to(focus_ray.get_collider())
|
||||||
|
|
||||||
func _physics_process(delta:float):
|
func _physics_process(delta:float):
|
||||||
_handle_movement(delta)
|
if has_focus:
|
||||||
_handle_rotation(delta)
|
_handle_movement(delta)
|
||||||
|
_handle_rotation(delta)
|
||||||
if jitter_strength > 0: _handle_jitter(delta)
|
if jitter_strength > 0: _handle_jitter(delta)
|
||||||
|
|
||||||
func _handle_movement(delta:float):
|
func _handle_movement(delta:float):
|
||||||
|
|
@ -122,9 +145,19 @@ func _handle_mouse_input(event:InputEventMouseMotion):
|
||||||
current_mouse_rotation = event.relative
|
current_mouse_rotation = event.relative
|
||||||
|
|
||||||
func _unhandled_input(event:InputEvent):
|
func _unhandled_input(event:InputEvent):
|
||||||
if active:
|
if has_focus:
|
||||||
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||||
_handle_mouse_input(event)
|
_handle_mouse_input(event)
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
if event is InputEventMouseButton and has_entered:
|
||||||
|
has_focus = false
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
if event.is_action("ui_accept"):
|
||||||
|
State.pass_focus_to(focus_ray.get_collider())
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
|
||||||
|
func _on_empty_click():
|
||||||
|
State.pass_focus_to(self)
|
||||||
|
|
||||||
func _on_bed_enter(_body):
|
func _on_bed_enter(_body):
|
||||||
if not (crouched or on_crouch_cooldown):
|
if not (crouched or on_crouch_cooldown):
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,12 @@ transform = Transform3D(1, 0, 0, 0, 0.5, -0.866025, 0, 0.866025, 0.5, 0, 0.25649
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.202, 0.157)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.202, 0.157)
|
||||||
current = true
|
current = true
|
||||||
|
|
||||||
|
[node name="RayCast3D" type="RayCast3D" parent="Yaw/Pitch/Mount/Camera3D"]
|
||||||
|
target_position = Vector3(0, 0, -1.3)
|
||||||
|
collision_mask = 17
|
||||||
|
collide_with_areas = true
|
||||||
|
collide_with_bodies = false
|
||||||
|
|
||||||
[node name="PlayerCollision" type="CollisionShape3D" parent="."]
|
[node name="PlayerCollision" type="CollisionShape3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.322255, 0)
|
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.322255, 0)
|
||||||
shape = SubResource("8")
|
shape = SubResource("8")
|
||||||
|
|
|
||||||
|
|
@ -9,33 +9,48 @@ var show_content_notes: bool = false
|
||||||
var provide_summaries: bool = false
|
var provide_summaries: bool = false
|
||||||
var allow_skipping: bool = false
|
var allow_skipping: bool = false
|
||||||
|
|
||||||
var current_focus: Node
|
var focus_list:Array = []
|
||||||
|
var lock_focus: bool = false
|
||||||
|
|
||||||
func request_focus(new_focus: Node, yoink:bool = false) -> bool:
|
func request_focus(new_focus: Node, reclaim_focus: bool = false) -> bool:
|
||||||
if (current_focus == null or yoink) and new_focus != null:
|
assert(is_instance_valid(new_focus))
|
||||||
current_focus = new_focus
|
if not focus_list.size() == 0: _pass_focus_of(focus_list[0])
|
||||||
|
if not lock_focus or get_tree().paused:
|
||||||
|
push_warning(new_focus.name, " attempted to get focus while tree was paused or fokus had been locked.")
|
||||||
|
return false
|
||||||
|
elif reclaim_focus:
|
||||||
|
if focus_list.has(new_focus):
|
||||||
|
while not focus_list[0] == new_focus: focus_list.pop_front()
|
||||||
|
return true
|
||||||
|
else:
|
||||||
|
focus_list.push_front(new_focus)
|
||||||
|
push_warning(new_focus.name, " attempted to reclaim focus it did not previousely have.")
|
||||||
|
return true
|
||||||
|
else:
|
||||||
|
focus_list.append(new_focus)
|
||||||
return true
|
return true
|
||||||
else: return false
|
|
||||||
|
|
||||||
func pass_focus_to(to: Node) -> bool:
|
|
||||||
if "has_focus" in to:
|
func assign_focus_to(focusable: Node) -> bool:
|
||||||
if not current_focus == null:
|
if "has_focus" in focusable:
|
||||||
drop_focus_of(current_focus)
|
if not focus_list.size() == 0:
|
||||||
to.has_focus = true
|
_pass_focus_of(focus_list[0])
|
||||||
|
focusable.has_focus = true
|
||||||
return true
|
return true
|
||||||
else: return false
|
else: return false
|
||||||
|
|
||||||
func drop_own_focus(node: Node):
|
func drop_own_focus(node: Node):
|
||||||
if current_focus == node:
|
if focus_list[0] == node:
|
||||||
current_focus = null
|
focus_list.pop_front().has_focus = false
|
||||||
|
assert(focus_list.size() > 0)
|
||||||
|
focus_list[0].has_focus = true
|
||||||
else:
|
else:
|
||||||
push_error(node.name + " attempted to drop focus while not owning it!")
|
push_warning(node.name + " attempted to drop focus while not owning it.")
|
||||||
|
|
||||||
func drop_focus_of(node: Node):
|
func clear_focus_with(focus: Node):
|
||||||
if current_focus == node:
|
assert(is_instance_valid(focus))
|
||||||
current_focus = null
|
if focus_list.size() > 0: focus_list[0].has_focus = false
|
||||||
if node.has_focus: node.has_focus = false
|
focus_list = [focus]
|
||||||
else:
|
|
||||||
node.has_focus = false
|
|
||||||
push_warning("Attempted to drop Focus for " + node.name + " while it wasn't focused!")
|
|
||||||
|
|
||||||
|
func _pass_focus_of(previous_focus: Node):
|
||||||
|
previous_focus.has_focus = false
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue