diff --git a/addons/guide/LICENSE.md b/addons/guide/LICENSE.md new file mode 100644 index 0000000..7510144 --- /dev/null +++ b/addons/guide/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (c) 2024-present Jan Thomä + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/addons/guide/debugger/guide_debugger.gd b/addons/guide/debugger/guide_debugger.gd new file mode 100644 index 0000000..346a5d1 --- /dev/null +++ b/addons/guide/debugger/guide_debugger.gd @@ -0,0 +1,104 @@ +extends MarginContainer + +@onready var _actions:Container = %Actions +@onready var _inputs:Container = %Inputs +@onready var _priorities:Container = %Priorities +@onready var _formatter:GUIDEInputFormatter = GUIDEInputFormatter.for_active_contexts() + + +func _ready(): + process_mode = Node.PROCESS_MODE_ALWAYS + GUIDE.input_mappings_changed.connect(_update_priorities) + _update_priorities() + +func _process(delta): + if not is_visible_in_tree(): + return + + var index:int = 0 + for mapping in GUIDE._active_action_mappings: + var action:GUIDEAction = mapping.action + + var action_name:String = action.name + if action_name == "": + action_name = action._editor_name() + + var action_state:String = "" + match(action._last_state): + GUIDEAction.GUIDEActionState.COMPLETED: + action_state = "Completed" + GUIDEAction.GUIDEActionState.ONGOING: + action_state = "Ongoing" + GUIDEAction.GUIDEActionState.TRIGGERED: + action_state = "Triggered" + + var action_value:String = "" + match(action.action_value_type): + GUIDEAction.GUIDEActionValueType.BOOL: + action_value = str(action.value_bool) + GUIDEAction.GUIDEActionValueType.AXIS_1D: + action_value = str(action.value_axis_1d) + GUIDEAction.GUIDEActionValueType.AXIS_2D: + action_value = str(action.value_axis_2d) + GUIDEAction.GUIDEActionValueType.AXIS_3D: + action_value = str(action.value_axis_3d) + + + + + var label := _get_label(_actions, index) + label.text = "[%s] %s - %s" % [action_name, action_state, action_value] + + index += 1 + + # Clean out all labels we don't need anymore + _cleanup(_actions, index) + + index = 0 + for input in GUIDE._active_inputs: + var input_label = _formatter.input_as_text(input, false) + var input_value:String = str(input._value) + + var label := _get_label(_inputs, index) + label.text = "%s - %s" % [input_label, input_value] + index += 1 + + _cleanup(_inputs, index) + + +func _get_label(container:Container, index:int) -> Label: + var label:Label = null + if container.get_child_count() > index: + # reuse existing label + label = container.get_child(index) + else: + # make a new one + label = Label.new() + label.mouse_filter = Control.MOUSE_FILTER_IGNORE + container.add_child(label) + return label + +func _cleanup(container:Container, index:int) -> void: + while container.get_child_count() > index: + var to_free = container.get_child(index) + container.remove_child(to_free) + to_free.queue_free() + +func _update_priorities(): + # since we don't update these per frame, we can just clear them out and + # rebuild them when mapping contexts change + _cleanup(_priorities, 0) + + for mapping:GUIDEActionMapping in GUIDE._active_action_mappings: + var action := mapping.action + if GUIDE._actions_sharing_input.has(action): + var label := Label.new() + var names = ", ".join(GUIDE._actions_sharing_input[action].map(func(it): return it._editor_name())) + label.text = "[%s] > [%s]" % [action._editor_name(), names] + _priorities.add_child(label) + + + if _priorities.get_child_count() == 0: + var label := Label.new() + label.text = "" + _priorities.add_child(label) diff --git a/addons/guide/debugger/guide_debugger.gd.uid b/addons/guide/debugger/guide_debugger.gd.uid new file mode 100644 index 0000000..3a878a2 --- /dev/null +++ b/addons/guide/debugger/guide_debugger.gd.uid @@ -0,0 +1 @@ +uid://cqfnsis3hhdrv diff --git a/addons/guide/debugger/guide_debugger.tscn b/addons/guide/debugger/guide_debugger.tscn new file mode 100644 index 0000000..0e7caf4 --- /dev/null +++ b/addons/guide/debugger/guide_debugger.tscn @@ -0,0 +1,50 @@ +[gd_scene load_steps=2 format=3 uid="uid://dkr80d2pi0d41"] + +[ext_resource type="Script" path="res://addons/guide/debugger/guide_debugger.gd" id="1_ckdvj"] + +[node name="GuideDebugger" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +script = ExtResource("1_ckdvj") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 2 +mouse_filter = 2 + +[node name="Label" type="Label" parent="VBoxContainer"] +layout_mode = 2 +text = "G.U.I.D.E - Debugger" + +[node name="Label2" type="Label" parent="VBoxContainer"] +layout_mode = 2 +text = "Actions" + +[node name="Actions" type="VFlowContainer" parent="VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 + +[node name="Label3" type="Label" parent="VBoxContainer"] +layout_mode = 2 +text = "Inputs" + +[node name="Inputs" type="VFlowContainer" parent="VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 + +[node name="Label4" type="Label" parent="VBoxContainer"] +layout_mode = 2 +text = "Action Priority" + +[node name="Priorities" type="VFlowContainer" parent="VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 diff --git a/addons/guide/editor/action_mapping_editor/action_mapping_editor.gd b/addons/guide/editor/action_mapping_editor/action_mapping_editor.gd new file mode 100644 index 0000000..4d8a267 --- /dev/null +++ b/addons/guide/editor/action_mapping_editor/action_mapping_editor.gd @@ -0,0 +1,140 @@ +@tool +extends MarginContainer + +const ActionSlot = preload("../action_slot/action_slot.gd") +const Utils = preload("../utils.gd") +const ArrayEdit = preload("../array_edit/array_edit.gd") + +signal delete_requested() +signal duplicate_requested() + +@export var input_mapping_editor_scene:PackedScene +@onready var _action_slot:ActionSlot = %ActionSlot +@onready var _input_mappings:ArrayEdit = %InputMappings + +const ClassScanner = preload("../class_scanner.gd") + +var _plugin:EditorPlugin +var _scanner:ClassScanner +var _undo_redo:EditorUndoRedoManager + +var _mapping:GUIDEActionMapping + +func _ready(): + _action_slot.action_changed.connect(_on_action_changed) + _input_mappings.delete_requested.connect(_on_input_mapping_delete_requested) + _input_mappings.add_requested.connect(_on_input_mappings_add_requested) + _input_mappings.move_requested.connect(_on_input_mappings_move_requested) + _input_mappings.clear_requested.connect(_on_input_mappings_clear_requested) + _input_mappings.duplicate_requested.connect(_on_input_mappings_duplicate_requested) + _input_mappings.collapse_state_changed.connect(_on_input_mappings_collapse_state_changed) + +func initialize(plugin:EditorPlugin, scanner:ClassScanner): + _plugin = plugin + _scanner = scanner + _undo_redo = _plugin.get_undo_redo() + + +func edit(mapping:GUIDEActionMapping): + assert(_mapping == null) + _mapping = mapping + + _mapping.changed.connect(_update) + + _update() + + +func _update(): + _input_mappings.clear() + + _action_slot.action = _mapping.action + + for i in _mapping.input_mappings.size(): + var input_mapping = _mapping.input_mappings[i] + var input_mapping_editor = input_mapping_editor_scene.instantiate() + _input_mappings.add_item(input_mapping_editor) + + input_mapping_editor.initialize(_plugin, _scanner) + input_mapping_editor.edit(input_mapping) + + _input_mappings.collapsed = _mapping.get_meta("_guide_input_mappings_collapsed", false) + + +func _on_action_changed(): + _undo_redo.create_action("Change action") + _undo_redo.add_do_property(_mapping, "action", _action_slot.action) + _undo_redo.add_undo_property(_mapping, "action", _mapping.action) + _undo_redo.commit_action() + + +func _on_input_mappings_add_requested(): + var values = _mapping.input_mappings.duplicate() + var new_mapping = GUIDEInputMapping.new() + values.append(new_mapping) + + _undo_redo.create_action("Add input mapping") + + _undo_redo.add_do_property(_mapping, "input_mappings", values) + _undo_redo.add_undo_property(_mapping, "input_mappings", _mapping.input_mappings) + + _undo_redo.commit_action() + + +func _on_input_mapping_delete_requested(index:int): + var values = _mapping.input_mappings.duplicate() + values.remove_at(index) + + _undo_redo.create_action("Delete input mapping") + _undo_redo.add_do_property(_mapping, "input_mappings", values) + _undo_redo.add_undo_property(_mapping, "input_mappings", _mapping.input_mappings) + + _undo_redo.commit_action() + + +func _on_input_mappings_move_requested(from:int, to:int): + var values = _mapping.input_mappings.duplicate() + var mapping = values[from] + values.remove_at(from) + if from < to: + to -= 1 + values.insert(to, mapping) + + _undo_redo.create_action("Move input mapping") + _undo_redo.add_do_property(_mapping, "input_mappings", values) + _undo_redo.add_undo_property(_mapping, "input_mappings", _mapping.input_mappings) + + _undo_redo.commit_action() + + +func _on_input_mappings_clear_requested(): + var values:Array[GUIDEInputMapping] = [] + _undo_redo.create_action("Clear input mappings") + _undo_redo.add_do_property(_mapping, "input_mappings", values) + _undo_redo.add_undo_property(_mapping, "input_mappings", _mapping.input_mappings) + + _undo_redo.commit_action() + +func _on_input_mappings_duplicate_requested(index:int): + var values = _mapping.input_mappings.duplicate() + var copy:GUIDEInputMapping = values[index].duplicate() + copy.input = Utils.duplicate_if_inline(copy.input) + + for i in copy.modifiers.size(): + copy.modifiers[i] = Utils.duplicate_if_inline(copy.modifiers[i]) + + for i in copy.triggers.size(): + copy.triggers[i] = Utils.duplicate_if_inline(copy.triggers[i]) + + # insert copy after original + values.insert(index+1, copy) + + _undo_redo.create_action("Duplicate input mapping") + _undo_redo.add_do_property(_mapping, "input_mappings", values) + _undo_redo.add_undo_property(_mapping, "input_mappings", _mapping.input_mappings) + + _undo_redo.commit_action() + + +func _on_input_mappings_collapse_state_changed(new_state:bool): + _mapping.set_meta("_guide_input_mappings_collapsed", new_state) + diff --git a/addons/guide/editor/action_mapping_editor/action_mapping_editor.gd.uid b/addons/guide/editor/action_mapping_editor/action_mapping_editor.gd.uid new file mode 100644 index 0000000..8817bef --- /dev/null +++ b/addons/guide/editor/action_mapping_editor/action_mapping_editor.gd.uid @@ -0,0 +1 @@ +uid://dp8xv83uhxpjo diff --git a/addons/guide/editor/action_mapping_editor/action_mapping_editor.tscn b/addons/guide/editor/action_mapping_editor/action_mapping_editor.tscn new file mode 100644 index 0000000..3730f92 --- /dev/null +++ b/addons/guide/editor/action_mapping_editor/action_mapping_editor.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=5 format=3 uid="uid://361aipcef24h"] + +[ext_resource type="Script" path="res://addons/guide/editor/action_mapping_editor/action_mapping_editor.gd" id="1_2k0pi"] +[ext_resource type="PackedScene" uid="uid://du4x7ng6ntuk4" path="res://addons/guide/editor/action_slot/action_slot.tscn" id="1_hguf2"] +[ext_resource type="PackedScene" uid="uid://c323mdijdhktg" path="res://addons/guide/editor/input_mapping_editor/input_mapping_editor.tscn" id="2_a8nbp"] +[ext_resource type="PackedScene" uid="uid://cly0ff32fvpb2" path="res://addons/guide/editor/array_edit/array_edit.tscn" id="4_ehr5j"] + +[node name="ActionMappingEditor" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 0 +theme_override_constants/margin_bottom = 5 +script = ExtResource("1_2k0pi") +input_mapping_editor_scene = ExtResource("2_a8nbp") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_vertical = 0 + +[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 + +[node name="ActionSlot" parent="HBoxContainer/HBoxContainer" instance=ExtResource("1_hguf2")] +unique_name_in_owner = true +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +size_flags_stretch_ratio = 4.0 + +[node name="InputMappings" parent="HBoxContainer/VBoxContainer" instance=ExtResource("4_ehr5j")] +unique_name_in_owner = true +layout_mode = 2 +title = "Input mappings" +add_tooltip = "Add input mapping" +clear_tooltip = "Clear input mappings" diff --git a/addons/guide/editor/action_slot/action_slot.gd b/addons/guide/editor/action_slot/action_slot.gd new file mode 100644 index 0000000..9c46041 --- /dev/null +++ b/addons/guide/editor/action_slot/action_slot.gd @@ -0,0 +1,70 @@ +@tool +extends Control + +signal action_changed() + +@onready var _line_edit:LineEdit = %LineEdit +@onready var _type_icon:TextureRect = %TypeIcon + +var index:int + +var action:GUIDEAction: + set(value): + if is_instance_valid(action): + action.changed.disconnect(_refresh) + + action = value + + if is_instance_valid(action): + action.changed.connect(_refresh) + + # action_changed can only be emitted by + # dragging an action into this, not when setting + # the property + _refresh() + + +func _refresh(): + if not is_instance_valid(action): + _line_edit.text = "" + _line_edit.tooltip_text = "" + _type_icon.texture = preload("missing_action.svg") + _type_icon.tooltip_text = "Missing action" + else: + _line_edit.text = action._editor_name() + _line_edit.tooltip_text = action.resource_path + ## Update the icon to reflect the given value type. + match action.action_value_type: + GUIDEAction.GUIDEActionValueType.AXIS_1D: + _type_icon.texture = preload("action_value_type_axis1d.svg") + _type_icon.tooltip_text = "Axis1D" + GUIDEAction.GUIDEActionValueType.AXIS_2D: + _type_icon.texture = preload("action_value_type_axis2d.svg") + _type_icon.tooltip_text = "Axis2D" + GUIDEAction.GUIDEActionValueType.AXIS_3D: + _type_icon.texture = preload("action_value_type_axis3d.svg") + _type_icon.tooltip_text = "Axis3D" + _: + # fallback is bool + _type_icon.texture = preload("action_value_type_bool.svg") + _type_icon.tooltip_text = "Boolean" + + + + +func _gui_input(event): + if event is InputEventMouseButton: + if event.pressed and event.button_index == MOUSE_BUTTON_LEFT: + if is_instance_valid(action): + EditorInterface.edit_resource(action) + + + +func _on_line_edit_action_dropped(new_action:GUIDEAction): + action = new_action + action_changed.emit() + + +func _on_line_edit_focus_entered(): + if is_instance_valid(action): + EditorInterface.edit_resource(action) diff --git a/addons/guide/editor/action_slot/action_slot.gd.uid b/addons/guide/editor/action_slot/action_slot.gd.uid new file mode 100644 index 0000000..f84919b --- /dev/null +++ b/addons/guide/editor/action_slot/action_slot.gd.uid @@ -0,0 +1 @@ +uid://ysrbdsqui5cn diff --git a/addons/guide/editor/action_slot/action_slot.tscn b/addons/guide/editor/action_slot/action_slot.tscn new file mode 100644 index 0000000..f48cc53 --- /dev/null +++ b/addons/guide/editor/action_slot/action_slot.tscn @@ -0,0 +1,29 @@ +[gd_scene load_steps=3 format=3 uid="uid://du4x7ng6ntuk4"] + +[ext_resource type="Script" path="res://addons/guide/editor/action_slot/action_slot.gd" id="1_w5nxd"] +[ext_resource type="Script" path="res://addons/guide/editor/action_slot/action_slot_line_edit.gd" id="2_ram7b"] + +[node name="ActionSlot" type="HBoxContainer"] +offset_right = 40.0 +offset_bottom = 40.0 +size_flags_horizontal = 3 +script = ExtResource("1_w5nxd") + +[node name="TypeIcon" type="TextureRect" parent="."] +unique_name_in_owner = true +layout_mode = 2 +expand_mode = 3 +stretch_mode = 4 + +[node name="LineEdit" type="LineEdit" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +text = "Name" +editable = false +selecting_enabled = false +script = ExtResource("2_ram7b") + +[connection signal="action_dropped" from="LineEdit" to="." method="_on_line_edit_action_dropped"] +[connection signal="focus_entered" from="LineEdit" to="." method="_on_line_edit_focus_entered"] diff --git a/addons/guide/editor/action_slot/action_slot_line_edit.gd b/addons/guide/editor/action_slot/action_slot_line_edit.gd new file mode 100644 index 0000000..ee8e8d8 --- /dev/null +++ b/addons/guide/editor/action_slot/action_slot_line_edit.gd @@ -0,0 +1,24 @@ +@tool +extends LineEdit + +signal action_dropped(action:GUIDEAction) + + +func _can_drop_data(at_position, data) -> bool: + if not data is Dictionary: + return false + + if data.has("files"): + for file in data["files"]: + if ResourceLoader.load(file) is GUIDEAction: + return true + + return false + + +func _drop_data(at_position, data) -> void: + for file in data["files"]: + var item = ResourceLoader.load(file) + if item is GUIDEAction: + action_dropped.emit(item) + diff --git a/addons/guide/editor/action_slot/action_slot_line_edit.gd.uid b/addons/guide/editor/action_slot/action_slot_line_edit.gd.uid new file mode 100644 index 0000000..0a59dc6 --- /dev/null +++ b/addons/guide/editor/action_slot/action_slot_line_edit.gd.uid @@ -0,0 +1 @@ +uid://b12uq0dpsgj7u diff --git a/addons/guide/editor/action_slot/action_value_type_axis1d.svg b/addons/guide/editor/action_slot/action_value_type_axis1d.svg new file mode 100644 index 0000000..09c5f34 --- /dev/null +++ b/addons/guide/editor/action_slot/action_value_type_axis1d.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/guide/editor/action_slot/action_value_type_axis1d.svg.import b/addons/guide/editor/action_slot/action_value_type_axis1d.svg.import new file mode 100644 index 0000000..c6339d9 --- /dev/null +++ b/addons/guide/editor/action_slot/action_value_type_axis1d.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://du55fdegui0t0" +path="res://.godot/imported/action_value_type_axis1d.svg-47cde6e873b547282e811542e4ee320d.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/editor/action_slot/action_value_type_axis1d.svg" +dest_files=["res://.godot/imported/action_value_type_axis1d.svg-47cde6e873b547282e811542e4ee320d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/editor/action_slot/action_value_type_axis2d.svg b/addons/guide/editor/action_slot/action_value_type_axis2d.svg new file mode 100644 index 0000000..4232027 --- /dev/null +++ b/addons/guide/editor/action_slot/action_value_type_axis2d.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/guide/editor/action_slot/action_value_type_axis2d.svg.import b/addons/guide/editor/action_slot/action_value_type_axis2d.svg.import new file mode 100644 index 0000000..74457aa --- /dev/null +++ b/addons/guide/editor/action_slot/action_value_type_axis2d.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bw3r81rgkbeic" +path="res://.godot/imported/action_value_type_axis2d.svg-82a12ec01234cc4464e5fb9b94ba28f0.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/editor/action_slot/action_value_type_axis2d.svg" +dest_files=["res://.godot/imported/action_value_type_axis2d.svg-82a12ec01234cc4464e5fb9b94ba28f0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/editor/action_slot/action_value_type_axis3d.svg b/addons/guide/editor/action_slot/action_value_type_axis3d.svg new file mode 100644 index 0000000..32fe1e3 --- /dev/null +++ b/addons/guide/editor/action_slot/action_value_type_axis3d.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/guide/editor/action_slot/action_value_type_axis3d.svg.import b/addons/guide/editor/action_slot/action_value_type_axis3d.svg.import new file mode 100644 index 0000000..8bfdc6b --- /dev/null +++ b/addons/guide/editor/action_slot/action_value_type_axis3d.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dcsfko8g6vjor" +path="res://.godot/imported/action_value_type_axis3d.svg-6c96e9bad6748ae9f491c37a99292ee2.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/editor/action_slot/action_value_type_axis3d.svg" +dest_files=["res://.godot/imported/action_value_type_axis3d.svg-6c96e9bad6748ae9f491c37a99292ee2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/editor/action_slot/action_value_type_bool.svg b/addons/guide/editor/action_slot/action_value_type_bool.svg new file mode 100644 index 0000000..69226b0 --- /dev/null +++ b/addons/guide/editor/action_slot/action_value_type_bool.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/guide/editor/action_slot/action_value_type_bool.svg.import b/addons/guide/editor/action_slot/action_value_type_bool.svg.import new file mode 100644 index 0000000..14ea23e --- /dev/null +++ b/addons/guide/editor/action_slot/action_value_type_bool.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bla3yu6pdqyt5" +path="res://.godot/imported/action_value_type_bool.svg-552c954344c23690bcca901351d04f59.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/editor/action_slot/action_value_type_bool.svg" +dest_files=["res://.godot/imported/action_value_type_bool.svg-552c954344c23690bcca901351d04f59.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/editor/action_slot/missing_action.svg b/addons/guide/editor/action_slot/missing_action.svg new file mode 100644 index 0000000..8880f50 --- /dev/null +++ b/addons/guide/editor/action_slot/missing_action.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/addons/guide/editor/action_slot/missing_action.svg.import b/addons/guide/editor/action_slot/missing_action.svg.import new file mode 100644 index 0000000..505cec8 --- /dev/null +++ b/addons/guide/editor/action_slot/missing_action.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cdi5eoc1e8ha0" +path="res://.godot/imported/missing_action.svg-31774fd8d1b787aab90de376faa436ea.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/editor/action_slot/missing_action.svg" +dest_files=["res://.godot/imported/missing_action.svg-31774fd8d1b787aab90de376faa436ea.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/editor/array_edit/array_edit.gd b/addons/guide/editor/array_edit/array_edit.gd new file mode 100644 index 0000000..0c5bfaa --- /dev/null +++ b/addons/guide/editor/array_edit/array_edit.gd @@ -0,0 +1,113 @@ +@tool +extends Container +const Utils = preload("../utils.gd") + +@export var item_scene:PackedScene + +@export var title:String = "": + set(value): + title = value + _refresh() + +@export var add_tooltip:String: + set(value): + add_tooltip = value + _refresh() + +@export var clear_tooltip:String: + set(value): + clear_tooltip = value + _refresh() + +@export var item_separation:int = 8: + set(value): + item_separation = value + _refresh() + + +@export var collapsed:bool = false: + set(value): + collapsed = value + _refresh() + +signal add_requested() +signal delete_requested(index:int) +signal move_requested(from:int, to:int) +signal insert_requested(index:int) +signal duplicate_requested(index:int) +signal clear_requested() +signal collapse_state_changed(collapsed:bool) + +@onready var _add_button:Button = %AddButton +@onready var _clear_button:Button = %ClearButton +@onready var _contents:Container = %Contents +@onready var _title_label:Label = %TitleLabel +@onready var _collapse_button:Button = %CollapseButton +@onready var _expand_button:Button = %ExpandButton +@onready var _count_label:Label = %CountLabel + +func _ready(): + _add_button.icon = get_theme_icon("Add", "EditorIcons") + _add_button.pressed.connect(func(): add_requested.emit()) + + _clear_button.icon = get_theme_icon("Clear", "EditorIcons") + _clear_button.pressed.connect(func(): clear_requested.emit()) + + _collapse_button.icon = get_theme_icon("Collapse", "EditorIcons") + _collapse_button.pressed.connect(_on_collapse_pressed) + + _expand_button.icon = get_theme_icon("Forward", "EditorIcons") + _expand_button.pressed.connect(_on_expand_pressed) + + + _refresh() + + +func _refresh(): + if is_instance_valid(_add_button): + _add_button.tooltip_text = add_tooltip + if is_instance_valid(_clear_button): + _clear_button.tooltip_text = clear_tooltip + _clear_button.visible = _contents.get_child_count() > 0 + + if is_instance_valid(_contents): + _contents.add_theme_constant_override("separation", item_separation) + _contents.visible = not collapsed + + if is_instance_valid(_collapse_button): + _collapse_button.visible = not collapsed + + if is_instance_valid(_expand_button): + _expand_button.visible = collapsed + + if is_instance_valid(_title_label): + _title_label.text = title + + if is_instance_valid(_count_label): + _count_label.text = "(%s)" % [_contents.get_child_count()] + + +func clear(): + Utils.clear(_contents) + _refresh() + + +func add_item(new_item:Control): + var item_wrapper = item_scene.instantiate() + _contents.add_child(item_wrapper) + item_wrapper.initialize(new_item) + item_wrapper.move_requested.connect(func(from:int, to:int): move_requested.emit(from, to)) + item_wrapper.delete_requested.connect(func(idx:int): delete_requested.emit(idx) ) + item_wrapper.duplicate_requested.connect(func(idx:int): duplicate_requested.emit(idx) ) + _refresh() + + +func _on_collapse_pressed(): + collapsed = true + collapse_state_changed.emit(true) + + +func _on_expand_pressed(): + collapsed = false + collapse_state_changed.emit(false) + diff --git a/addons/guide/editor/array_edit/array_edit.gd.uid b/addons/guide/editor/array_edit/array_edit.gd.uid new file mode 100644 index 0000000..6b5d747 --- /dev/null +++ b/addons/guide/editor/array_edit/array_edit.gd.uid @@ -0,0 +1 @@ +uid://whm2ksw6nc4h diff --git a/addons/guide/editor/array_edit/array_edit.tscn b/addons/guide/editor/array_edit/array_edit.tscn new file mode 100644 index 0000000..c6c7408 --- /dev/null +++ b/addons/guide/editor/array_edit/array_edit.tscn @@ -0,0 +1,88 @@ +[gd_scene load_steps=5 format=3 uid="uid://cly0ff32fvpb2"] + +[ext_resource type="Script" path="res://addons/guide/editor/array_edit/array_edit.gd" id="1_y3qyt"] +[ext_resource type="PackedScene" uid="uid://cjabwsa4gmlpp" path="res://addons/guide/editor/array_edit/array_edit_item.tscn" id="2_n3ncl"] + +[sub_resource type="Image" id="Image_efj5n"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 16, +"mipmaps": false, +"width": 16 +} + +[sub_resource type="ImageTexture" id="ImageTexture_uapko"] +image = SubResource("Image_efj5n") + +[node name="Array" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_y3qyt") +item_scene = ExtResource("2_n3ncl") +item_separation = 10 + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="Panel" type="Panel" parent="VBoxContainer/MarginContainer"] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/MarginContainer"] +layout_mode = 2 + +[node name="CollapseButton" type="Button" parent="VBoxContainer/MarginContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(32, 0) +layout_mode = 2 +size_flags_horizontal = 0 +tooltip_text = "Collapse" +icon = SubResource("ImageTexture_uapko") + +[node name="ExpandButton" type="Button" parent="VBoxContainer/MarginContainer/HBoxContainer"] +unique_name_in_owner = true +visible = false +custom_minimum_size = Vector2(48, 0) +layout_mode = 2 +size_flags_horizontal = 0 +tooltip_text = "Expand" +icon = SubResource("ImageTexture_uapko") + +[node name="AddButton" type="Button" parent="VBoxContainer/MarginContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 0 +icon = SubResource("ImageTexture_uapko") + +[node name="ClearButton" type="Button" parent="VBoxContainer/MarginContainer/HBoxContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +size_flags_horizontal = 0 +icon = SubResource("ImageTexture_uapko") + +[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/MarginContainer/HBoxContainer"] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/MarginContainer/HBoxContainer/MarginContainer"] +layout_mode = 2 + +[node name="TitleLabel" type="Label" parent="VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="CountLabel" type="Label" parent="VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "(0)" + +[node name="Contents" type="VBoxContainer" parent="VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_constants/separation = 10 diff --git a/addons/guide/editor/array_edit/array_edit_item.gd b/addons/guide/editor/array_edit/array_edit_item.gd new file mode 100644 index 0000000..13c8a03 --- /dev/null +++ b/addons/guide/editor/array_edit/array_edit_item.gd @@ -0,0 +1,84 @@ +@tool +extends Container +const Utils = preload("../utils.gd") +const Dragger = preload("dragger.gd") + +signal move_requested(from:int, to:int) +signal delete_requested(index:int) +signal duplicate_requested(index:int) + +@onready var _dragger:Dragger = %Dragger +@onready var _content:Container = %Content +@onready var _before_indicator:ColorRect = %BeforeIndicator +@onready var _after_indicator:ColorRect = %AfterIndicator +@onready var _popup_menu:PopupMenu = %PopupMenu + + +const ID_DELETE = 2 +const ID_DUPLICATE = 3 + +func _ready(): + _dragger.icon = get_theme_icon("GuiSpinboxUpdown", "EditorIcons") + _before_indicator.color = get_theme_color("box_selection_stroke_color", "Editor") + _after_indicator.color = get_theme_color("box_selection_stroke_color", "Editor") + _before_indicator.visible = false + _after_indicator.visible = false + _dragger._parent_array = get_parent() + _dragger._index = get_index() + _dragger.pressed.connect(_show_popup_menu) + + _popup_menu.clear() + _popup_menu.add_icon_item(get_theme_icon("Duplicate", "EditorIcons"), "Duplicate", ID_DUPLICATE) + _popup_menu.add_icon_item(get_theme_icon("Remove", "EditorIcons"), "Delete", ID_DELETE) + _popup_menu.id_pressed.connect(_on_popup_menu_id_pressed) + +func initialize(content:Control): + Utils.clear(_content) + _content.add_child(content) + + +func _can_drop_data(at_position:Vector2, data) -> bool: + if data is Dictionary and data.has("parent_array") and data.parent_array == get_parent() and data.index != get_index(): + var height = size.y + + var is_before = not _is_last_child() or (at_position.y < height/2.0) + if is_before and data.index == get_index() - 1: + # don't allow the previous child to be inserted at its + # own position + return false + + _before_indicator.visible = is_before + _after_indicator.visible = not is_before + return true + + return false + + +func _drop_data(at_position, data): + var height = size.y + var is_before = not _is_last_child() or (at_position.y < height/2.0) + var from = data.index + var to = get_index() if is_before else get_index() + 1 + move_requested.emit(data.index, to) + _before_indicator.visible = false + _after_indicator.visible = false + +func _is_last_child() -> bool: + return get_index() == get_parent().get_child_count() - 1 + + +func _on_mouse_exited(): + _before_indicator.visible = false + _after_indicator.visible = false + + +func _show_popup_menu(): + _popup_menu.popup(Rect2(get_global_mouse_position(), Vector2.ZERO)) + + +func _on_popup_menu_id_pressed(id:int): + match id: + ID_DELETE: + delete_requested.emit(get_index()) + ID_DUPLICATE: + duplicate_requested.emit(get_index()) diff --git a/addons/guide/editor/array_edit/array_edit_item.gd.uid b/addons/guide/editor/array_edit/array_edit_item.gd.uid new file mode 100644 index 0000000..1de2ee1 --- /dev/null +++ b/addons/guide/editor/array_edit/array_edit_item.gd.uid @@ -0,0 +1 @@ +uid://dhqhut5enoj43 diff --git a/addons/guide/editor/array_edit/array_edit_item.tscn b/addons/guide/editor/array_edit/array_edit_item.tscn new file mode 100644 index 0000000..be3b43b --- /dev/null +++ b/addons/guide/editor/array_edit/array_edit_item.tscn @@ -0,0 +1,83 @@ +[gd_scene load_steps=5 format=3 uid="uid://cjabwsa4gmlpp"] + +[ext_resource type="Script" path="res://addons/guide/editor/array_edit/array_edit_item.gd" id="1_ujx05"] +[ext_resource type="Script" path="res://addons/guide/editor/array_edit/dragger.gd" id="2_53e2r"] + +[sub_resource type="Image" id="Image_efj5n"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 16, +"mipmaps": false, +"width": 16 +} + +[sub_resource type="ImageTexture" id="ImageTexture_uapko"] +image = SubResource("Image_efj5n") + +[node name="ArrayEditItem" type="MarginContainer"] +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 8.0 +grow_horizontal = 2 +script = ExtResource("1_ujx05") + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_top = 2 +theme_override_constants/margin_bottom = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] +layout_mode = 2 + +[node name="Dragger" type="Button" parent="MarginContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 0 +tooltip_text = "Drag to reorder, click for options." +focus_mode = 0 +mouse_filter = 1 +icon = SubResource("ImageTexture_uapko") +script = ExtResource("2_53e2r") + +[node name="Content" type="MarginContainer" parent="MarginContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 2 +mouse_filter = 2 + +[node name="BeforeIndicator" type="ColorRect" parent="VBoxContainer"] +unique_name_in_owner = true +visible = false +custom_minimum_size = Vector2(0, 2) +layout_mode = 2 +mouse_filter = 2 +color = Color(0, 0, 0, 1) + +[node name="Control" type="Control" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 + +[node name="AfterIndicator" type="ColorRect" parent="VBoxContainer"] +unique_name_in_owner = true +visible = false +custom_minimum_size = Vector2(0, 2) +layout_mode = 2 +mouse_filter = 2 +color = Color(0, 0, 0, 1) + +[node name="PopupMenu" type="PopupMenu" parent="."] +unique_name_in_owner = true +item_count = 2 +item_0/text = "Duplicate" +item_0/icon = SubResource("ImageTexture_uapko") +item_0/id = 3 +item_1/text = "Delete" +item_1/icon = SubResource("ImageTexture_uapko") +item_1/id = 2 + +[connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"] diff --git a/addons/guide/editor/array_edit/dragger.gd b/addons/guide/editor/array_edit/dragger.gd new file mode 100644 index 0000000..629283e --- /dev/null +++ b/addons/guide/editor/array_edit/dragger.gd @@ -0,0 +1,8 @@ +@tool +extends Button + +var _parent_array:Variant +var _index:int + +func _get_drag_data(at_position): + return { "parent_array" : _parent_array, "index" : _index } diff --git a/addons/guide/editor/array_edit/dragger.gd.uid b/addons/guide/editor/array_edit/dragger.gd.uid new file mode 100644 index 0000000..7abf211 --- /dev/null +++ b/addons/guide/editor/array_edit/dragger.gd.uid @@ -0,0 +1 @@ +uid://d3cob8fbf0xk8 diff --git a/addons/guide/editor/binding_dialog/binding_dialog.gd b/addons/guide/editor/binding_dialog/binding_dialog.gd new file mode 100644 index 0000000..96a1b02 --- /dev/null +++ b/addons/guide/editor/binding_dialog/binding_dialog.gd @@ -0,0 +1,148 @@ +@tool +extends Window + +const ClassScanner = preload("../class_scanner.gd") +const Utils = preload("../utils.gd") + +signal input_selected(input:GUIDEInput) + +@onready var _input_display = %InputDisplay +@onready var _available_types:Container = %AvailableTypes +@onready var _none_available:Control = %NoneAvailable +@onready var _some_available:Control = %SomeAvailable +@onready var _select_bool_button:Button = %SelectBoolButton +@onready var _select_1d_button:Button = %Select1DButton +@onready var _select_2d_button:Button = %Select2DButton +@onready var _select_3d_button:Button = %Select3DButton +@onready var _instructions_label:Label = %InstructionsLabel +@onready var _accept_detection_button:Button = %AcceptDetectionButton +@onready var _input_detector:GUIDEInputDetector = %InputDetector +@onready var _detect_bool_button:Button = %DetectBoolButton +@onready var _detect_1d_button:Button = %Detect1DButton +@onready var _detect_2d_button:Button = %Detect2DButton +@onready var _detect_3d_button:Button = %Detect3DButton + +var _scanner:ClassScanner +var _last_detected_input:GUIDEInput + + +func initialize(scanner:ClassScanner): + _scanner = scanner + _setup_dialog() + +func _setup_dialog(): + # we need to bind this here. if we bind it in the editor, the editor + # will crash when opening the scene because it will delete the node it + # just tries to edit. + focus_exited.connect(_on_close_requested) + + _show_inputs_of_value_type(GUIDEAction.GUIDEActionValueType.BOOL) + _instructions_label.text = tr("Press one of the buttons above to detect an input.") + _accept_detection_button.visible = false + + +func _on_close_requested(): + hide() + queue_free() + + +func _show_inputs_of_value_type(type:GUIDEAction.GUIDEActionValueType) -> void: + var items:Array[GUIDEInput] = [] + + _select_bool_button.set_pressed_no_signal(type == GUIDEAction.GUIDEActionValueType.BOOL) + _select_1d_button.set_pressed_no_signal(type == GUIDEAction.GUIDEActionValueType.AXIS_1D) + _select_2d_button.set_pressed_no_signal(type == GUIDEAction.GUIDEActionValueType.AXIS_2D) + _select_3d_button.set_pressed_no_signal(type == GUIDEAction.GUIDEActionValueType.AXIS_3D) + + var all_inputs = _scanner.find_inheritors("GUIDEInput") + for script in all_inputs.values(): + var dummy:GUIDEInput = script.new() + if dummy._native_value_type() == type: + items.append(dummy) + + _some_available.visible = not items.is_empty() + _none_available.visible = items.is_empty() + + if items.is_empty(): + return + + items.sort_custom(func(a,b): return a._editor_name().nocasecmp_to(b._editor_name()) < 0) + Utils.clear(_available_types) + + for item in items: + var button = Button.new() + button.text = item._editor_name() + button.tooltip_text = item._editor_description() + button.pressed.connect(_deliver.bind(item)) + button.size_flags_horizontal = Control.SIZE_EXPAND_FILL + + _available_types.add_child(button) + + +func _deliver(input:GUIDEInput): + input_selected.emit(input) + hide() + queue_free() + + +func _on_select_bool_button_pressed(): + _show_inputs_of_value_type(GUIDEAction.GUIDEActionValueType.BOOL) + + +func _on_select_1d_button_pressed(): + _show_inputs_of_value_type(GUIDEAction.GUIDEActionValueType.AXIS_1D) + + +func _on_select_2d_button_pressed(): + _show_inputs_of_value_type(GUIDEAction.GUIDEActionValueType.AXIS_2D) + + +func _on_select_3d_button_pressed(): + _show_inputs_of_value_type(GUIDEAction.GUIDEActionValueType.AXIS_3D) + + +func _on_input_detector_detection_started(): + _instructions_label.text = tr("Actuate the input now...") + + +func _on_input_detector_input_detected(input:GUIDEInput): + _instructions_label.visible = false + _input_display.visible = true + _input_display.input = input + _accept_detection_button.visible = true + _last_detected_input = input + + +func _begin_detect_input(type:GUIDEAction.GUIDEActionValueType): + _last_detected_input = null + _instructions_label.visible = true + _instructions_label.text = tr("Get ready...") + _accept_detection_button.visible = false + _input_display.visible = false + _input_detector.detect(type) + + +func _on_detect_bool_button_pressed(): + _detect_bool_button.release_focus() + _begin_detect_input(GUIDEAction.GUIDEActionValueType.BOOL) + + +func _on_detect_1d_button_pressed(): + _detect_1d_button.release_focus() + _begin_detect_input(GUIDEAction.GUIDEActionValueType.AXIS_1D) + + +func _on_detect_2d_button_pressed(): + _detect_2d_button.release_focus() + _begin_detect_input(GUIDEAction.GUIDEActionValueType.AXIS_2D) + + +func _on_detect_3d_button_pressed(): + _detect_3d_button.release_focus() + _begin_detect_input(GUIDEAction.GUIDEActionValueType.AXIS_3D) + + +func _on_accept_detection_button_pressed(): + input_selected.emit(_last_detected_input) + hide() + queue_free diff --git a/addons/guide/editor/binding_dialog/binding_dialog.gd.uid b/addons/guide/editor/binding_dialog/binding_dialog.gd.uid new file mode 100644 index 0000000..7355c4b --- /dev/null +++ b/addons/guide/editor/binding_dialog/binding_dialog.gd.uid @@ -0,0 +1 @@ +uid://dfuj0dl8ob6r6 diff --git a/addons/guide/editor/binding_dialog/binding_dialog.tscn b/addons/guide/editor/binding_dialog/binding_dialog.tscn new file mode 100644 index 0000000..056fdac --- /dev/null +++ b/addons/guide/editor/binding_dialog/binding_dialog.tscn @@ -0,0 +1,216 @@ +[gd_scene load_steps=5 format=3 uid="uid://dic27bm4pfw3q"] + +[ext_resource type="Script" path="res://addons/guide/editor/binding_dialog/binding_dialog.gd" id="1_tknjd"] +[ext_resource type="PackedScene" uid="uid://dsv7s6tfmnsrs" path="res://addons/guide/editor/input_display/input_display.tscn" id="2_83ieu"] +[ext_resource type="Script" path="res://addons/guide/remapping/guide_input_detector.gd" id="3_c6q6r"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3e874"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(1, 0.365, 0.365, 1) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +corner_detail = 1 + +[node name="BindingDialog" type="Window"] +title = "Input Configuration" +initial_position = 4 +size = Vector2i(1200, 600) +popup_window = true +min_size = Vector2i(1200, 600) +script = ExtResource("1_tknjd") + +[node name="MarginContainer" type="MarginContainer" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_bottom = 5 + +[node name="BGPanel" type="Panel" parent="MarginContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_3e874") + +[node name="MarginContainer" type="MarginContainer" parent="MarginContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/MarginContainer"] +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/MarginContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="LeftPanel" type="Panel" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_constants/separation = 10 + +[node name="Label" type="Label" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Detect Input" +horizontal_alignment = 1 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="DetectBoolButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +text = "Boolean" + +[node name="Detect1DButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +text = "1D" + +[node name="Detect2DButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +text = "2D" + +[node name="Detect3DButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(80, 0) +layout_mode = 2 +size_flags_horizontal = 3 +text = "3D" + +[node name="InstructionsLabel" type="Label" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 6 +text = "3..2..1.." +horizontal_alignment = 1 +vertical_alignment = 1 +autowrap_mode = 2 + +[node name="InputDisplay" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer" instance=ExtResource("2_83ieu")] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 6 + +[node name="AcceptDetectionButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 4 +text = "Accept" + +[node name="MarginContainer2" type="MarginContainer" parent="MarginContainer/MarginContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="RightPanel" type="Panel" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2"] +layout_mode = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_constants/separation = 10 + +[node name="Label" type="Label" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Select Input" +horizontal_alignment = 1 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="SelectBoolButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(80, 0) +layout_mode = 2 +size_flags_horizontal = 3 +toggle_mode = true +text = "Boolean" + +[node name="Select1DButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(80, 0) +layout_mode = 2 +size_flags_horizontal = 3 +toggle_mode = true +text = "1D" + +[node name="Select2DButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(80, 0) +layout_mode = 2 +size_flags_horizontal = 3 +toggle_mode = true +text = "2D" + +[node name="Select3DButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(80, 0) +layout_mode = 2 +size_flags_horizontal = 3 +toggle_mode = true +text = "3D" + +[node name="NoneAvailable" type="Label" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 6 +size_flags_vertical = 6 +text = "No matching inputs available." + +[node name="SomeAvailable" type="ScrollContainer" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 + +[node name="AvailableTypes" type="VBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer/SomeAvailable"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="InputDetector" type="Node" parent="."] +unique_name_in_owner = true +script = ExtResource("3_c6q6r") + +[connection signal="close_requested" from="." to="." method="_on_close_requested"] +[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer/DetectBoolButton" to="." method="_on_detect_bool_button_pressed"] +[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer/Detect1DButton" to="." method="_on_detect_1d_button_pressed"] +[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer/Detect2DButton" to="." method="_on_detect_2d_button_pressed"] +[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer/HBoxContainer/Detect3DButton" to="." method="_on_detect_3d_button_pressed"] +[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/MarginContainer/MarginContainer/VBoxContainer/AcceptDetectionButton" to="." method="_on_accept_detection_button_pressed"] +[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer/HBoxContainer/SelectBoolButton" to="." method="_on_select_bool_button_pressed"] +[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer/HBoxContainer/Select1DButton" to="." method="_on_select_1d_button_pressed"] +[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer/HBoxContainer/Select2DButton" to="." method="_on_select_2d_button_pressed"] +[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/MarginContainer2/MarginContainer/VBoxContainer/HBoxContainer/Select3DButton" to="." method="_on_select_3d_button_pressed"] +[connection signal="detection_started" from="InputDetector" to="." method="_on_input_detector_detection_started"] +[connection signal="input_detected" from="InputDetector" to="." method="_on_input_detector_input_detected"] diff --git a/addons/guide/editor/class_scanner.gd b/addons/guide/editor/class_scanner.gd new file mode 100644 index 0000000..d37e3da --- /dev/null +++ b/addons/guide/editor/class_scanner.gd @@ -0,0 +1,91 @@ +## Scanner to find inheriting classes. Used to detect inheritors of +## modifiers and triggers. Ideally this would be built into the editor +## but sometimes one has to hack their way around the limitations. +## This only scans to the extent needed to drive the UI, it's not a general +## purpose implementation. +@tool + +const GUIDESet = preload("../guide_set.gd") + +var _dirty:bool = true + +# looks like we only get very limited access to the script's inheritance tree, +# so we need to do a little caching ourselves +var _script_lut:Dictionary = {} + +func _init(): + EditorInterface.get_resource_filesystem().script_classes_updated.connect(_mark_dirty) + + +func _mark_dirty(): + _dirty = true + +## Returns all classes that directly or indirectly inherit from the +## given class. Only works for scripts in the project, e.g. doesn't +## scan the whole class_db. Key is class name, value is the Script instance +func find_inheritors(clazz_name:StringName) -> Dictionary: + var result:Dictionary = {} + + var root := EditorInterface.get_resource_filesystem().get_filesystem() + + # rebuild the LUT when needed + if _dirty: + _script_lut.clear() + _scan(root) + _dirty = false + + + var open_set:GUIDESet = GUIDESet.new() + # a closed set just to avoid infinite loops, we'll never + # look at the same class more than once. + var closed_set:GUIDESet = GUIDESet.new() + + open_set.add(clazz_name) + + while not open_set.is_empty(): + var next = open_set.pull() + closed_set.add(next) + if not _script_lut.has(next): + # we don't know this script, ignore, move on + continue + + # now find all scripts that extend the one we + # are looking at + for item:ScriptInfo in _script_lut.values(): + if item.extendz == next: + # put them into the result + result[item.clazz_name] = item.clazz_script + # and put their class in the open set + # unless we already looked at it. + if not closed_set.has(item.clazz_name): + open_set.add(item.clazz_name) + + return result + + +func _scan(folder:EditorFileSystemDirectory): + for i in folder.get_file_count(): + var script_clazz = folder.get_file_script_class_name(i) + if script_clazz != "": + var info := _script_lut.get(script_clazz) + if info == null: + info = ScriptInfo.new() + info.clazz_name = script_clazz + info.clazz_script = ResourceLoader.load(folder.get_file_path(i)) + _script_lut[script_clazz] = info + + var script_extendz = folder.get_file_script_class_extends(i) + info.extendz = script_extendz + + for i in folder.get_subdir_count(): + _scan(folder.get_subdir(i)) + + +class ScriptInfo: + var clazz_name:StringName + var extendz:StringName + var clazz_script:Script + + func _to_string() -> String: + return clazz_name + ":" + extendz + diff --git a/addons/guide/editor/class_scanner.gd.uid b/addons/guide/editor/class_scanner.gd.uid new file mode 100644 index 0000000..940c514 --- /dev/null +++ b/addons/guide/editor/class_scanner.gd.uid @@ -0,0 +1 @@ +uid://b1trdjs8ofe7c diff --git a/addons/guide/editor/input_display/input_display.gd b/addons/guide/editor/input_display/input_display.gd new file mode 100644 index 0000000..eb21aef --- /dev/null +++ b/addons/guide/editor/input_display/input_display.gd @@ -0,0 +1,39 @@ +@tool +extends RichTextLabel +signal clicked() + +var _formatter:GUIDEInputFormatter = GUIDEInputFormatter.new(64) + +var input:GUIDEInput: + set(value): + if value == input: + return + + if is_instance_valid(input): + input.changed.disconnect(_refresh) + + input = value + + if is_instance_valid(input): + input.changed.connect(_refresh) + + _refresh() + +func _refresh(): + if not is_instance_valid(input): + parse_bbcode("[center][i][/i][/center]") + tooltip_text = "" + return + + var text := await _formatter.input_as_richtext_async(input, false) + parse_bbcode("[center]" + text + "[/center]") + tooltip_text = _formatter.input_as_text(input) + + +func _gui_input(event): + if event is InputEventMouseButton: + if event.pressed and event.button_index == MOUSE_BUTTON_LEFT: + clicked.emit() + + + diff --git a/addons/guide/editor/input_display/input_display.gd.uid b/addons/guide/editor/input_display/input_display.gd.uid new file mode 100644 index 0000000..1b4dfcf --- /dev/null +++ b/addons/guide/editor/input_display/input_display.gd.uid @@ -0,0 +1 @@ +uid://cgf2qrodwja32 diff --git a/addons/guide/editor/input_display/input_display.tscn b/addons/guide/editor/input_display/input_display.tscn new file mode 100644 index 0000000..4cd79a3 --- /dev/null +++ b/addons/guide/editor/input_display/input_display.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=3 format=3 uid="uid://dsv7s6tfmnsrs"] + +[ext_resource type="Script" path="res://addons/guide/editor/input_display/input_display.gd" id="1_ne6sd"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_0bp65"] + +[node name="InputDisplay" type="RichTextLabel"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_styles/normal = SubResource("StyleBoxEmpty_0bp65") +bbcode_enabled = true +fit_content = true +script = ExtResource("1_ne6sd") diff --git a/addons/guide/editor/input_mapping_editor/input_mapping_editor.gd b/addons/guide/editor/input_mapping_editor/input_mapping_editor.gd new file mode 100644 index 0000000..e4c428c --- /dev/null +++ b/addons/guide/editor/input_mapping_editor/input_mapping_editor.gd @@ -0,0 +1,299 @@ +@tool +extends MarginContainer + +const ArrayEdit = preload("../array_edit/array_edit.gd") +const ClassScanner = preload("../class_scanner.gd") +const Utils = preload("../utils.gd") + +@export var modifier_slot_scene:PackedScene +@export var trigger_slot_scene:PackedScene +@export var binding_dialog_scene:PackedScene + +@onready var _edit_input_mapping_button:Button = %EditInputMappingButton +@onready var _input_display = %InputDisplay +@onready var _edit_input_button:Button = %EditInputButton +@onready var _clear_input_button:Button = %ClearInputButton + +@onready var _modifiers:ArrayEdit = %Modifiers +@onready var _add_modifier_popup:PopupMenu = %AddModifierPopup + +@onready var _triggers:ArrayEdit = %Triggers +@onready var _add_trigger_popup:PopupMenu = %AddTriggerPopup + +var _plugin:EditorPlugin +var _scanner:ClassScanner +var _undo_redo:EditorUndoRedoManager + +var _mapping:GUIDEInputMapping + +func _ready(): + _edit_input_button.icon = get_theme_icon("Edit", "EditorIcons") + _clear_input_button.icon = get_theme_icon("Remove", "EditorIcons") + _edit_input_mapping_button.icon = get_theme_icon("Tools", "EditorIcons") + + _modifiers.add_requested.connect(_on_modifiers_add_requested) + _modifiers.delete_requested.connect(_on_modifier_delete_requested) + _modifiers.duplicate_requested.connect(_on_modifier_duplicate_requested) + _modifiers.move_requested.connect(_on_modifier_move_requested) + _modifiers.clear_requested.connect(_on_modifiers_clear_requested) + _modifiers.collapse_state_changed.connect(_on_modifiers_collapse_state_changed) + + _triggers.add_requested.connect(_on_triggers_add_requested) + _triggers.delete_requested.connect(_on_trigger_delete_requested) + _triggers.duplicate_requested.connect(_on_trigger_duplicate_requested) + _triggers.move_requested.connect(_on_trigger_move_requested) + _triggers.clear_requested.connect(_on_triggers_clear_requested) + _triggers.collapse_state_changed.connect(_on_triggers_collapse_state_changed) + + +func initialize(plugin:EditorPlugin, scanner:ClassScanner) -> void: + _plugin = plugin + _scanner = scanner + _undo_redo = plugin.get_undo_redo() + _input_display.clicked.connect(_on_input_display_clicked) + + +func edit(mapping:GUIDEInputMapping) -> void: + assert(_mapping == null) + _mapping = mapping + _mapping.changed.connect(_update) + _update() + + +func _update(): + _modifiers.clear() + _triggers.clear() + + _input_display.input = _mapping.input + for i in _mapping.modifiers.size(): + var modifier_slot = modifier_slot_scene.instantiate() + _modifiers.add_item(modifier_slot) + + modifier_slot.modifier = _mapping.modifiers[i] + modifier_slot.changed.connect(_on_modifier_changed.bind(i, modifier_slot)) + + for i in _mapping.triggers.size(): + var trigger_slot = trigger_slot_scene.instantiate() + _triggers.add_item(trigger_slot) + + trigger_slot.trigger = _mapping.triggers[i] + trigger_slot.changed.connect(_on_trigger_changed.bind(i, trigger_slot)) + + _modifiers.collapsed = _mapping.get_meta("_guide_modifiers_collapsed", false) + _triggers.collapsed = _mapping.get_meta("_guide_triggers_collapsed", false) + + +func _on_modifiers_add_requested(): + _fill_popup(_add_modifier_popup, "GUIDEModifier") + _add_modifier_popup.popup(Rect2(get_global_mouse_position(), Vector2.ZERO)) + + +func _on_triggers_add_requested(): + _fill_popup(_add_trigger_popup, "GUIDETrigger") + _add_trigger_popup.popup(Rect2(get_global_mouse_position(), Vector2.ZERO)) + + +func _fill_popup(popup:PopupMenu, base_clazz:StringName): + popup.clear(true) + + var inheritors := _scanner.find_inheritors(base_clazz) + for type in inheritors.keys(): + var class_script:Script = inheritors[type] + var dummy = class_script.new() + popup.add_item(dummy._editor_name()) + popup.set_item_tooltip(popup.item_count -1, dummy._editor_description()) + popup.set_item_metadata(popup.item_count - 1, class_script) + +func _on_input_display_clicked(): + if is_instance_valid(_mapping.input): + EditorInterface.edit_resource(_mapping.input) + + +func _on_input_changed(input:GUIDEInput): + _undo_redo.create_action("Change input") + + _undo_redo.add_do_property(_mapping, "input", input) + _undo_redo.add_undo_property(_mapping, "input", _mapping.input) + + _undo_redo.commit_action() + + if is_instance_valid(input): + EditorInterface.edit_resource(input) + + +func _on_edit_input_button_pressed(): + var dialog:Window = binding_dialog_scene.instantiate() + EditorInterface.popup_dialog_centered(dialog) + dialog.initialize(_scanner) + dialog.input_selected.connect(_on_input_changed) + + +func _on_clear_input_button_pressed(): + _undo_redo.create_action("Delete bound input") + + _undo_redo.add_do_property(_mapping, "input", null) + _undo_redo.add_undo_property(_mapping, "triggers", _mapping.input) + + _undo_redo.commit_action() + + +func _on_add_modifier_popup_index_pressed(index:int) -> void: + var script = _add_modifier_popup.get_item_metadata(index) + var new_modifier = script.new() + + _undo_redo.create_action("Add " + new_modifier._editor_name() + " modifier") + var modifiers = _mapping.modifiers.duplicate() + modifiers.append(new_modifier) + + _undo_redo.add_do_property(_mapping, "modifiers", modifiers) + _undo_redo.add_undo_property(_mapping, "modifiers", _mapping.modifiers) + + _undo_redo.commit_action() + + +func _on_add_trigger_popup_index_pressed(index): + var script = _add_trigger_popup.get_item_metadata(index) + var new_trigger = script.new() + + _undo_redo.create_action("Add " + new_trigger._editor_name() + " trigger") + var triggers = _mapping.triggers.duplicate() + triggers.append(new_trigger) + + _undo_redo.add_do_property(_mapping, "triggers", triggers) + _undo_redo.add_undo_property(_mapping, "triggers", _mapping.triggers) + + _undo_redo.commit_action() + + +func _on_modifier_changed(index:int, slot) -> void: + var new_modifier = slot.modifier + + _undo_redo.create_action("Replace modifier") + var modifiers = _mapping.modifiers.duplicate() + modifiers[index] = new_modifier + + _undo_redo.add_do_property(_mapping, "modifiers", modifiers) + _undo_redo.add_undo_property(_mapping, "modifiers", _mapping.modifiers) + + _undo_redo.commit_action() + + +func _on_trigger_changed(index:int, slot) -> void: + var new_trigger = slot.trigger + + _undo_redo.create_action("Replace trigger") + var triggers = _mapping.triggers.duplicate() + triggers[index] = new_trigger + + _undo_redo.add_do_property(_mapping, "triggers", triggers) + _undo_redo.add_undo_property(_mapping, "triggers", _mapping.triggers) + + _undo_redo.commit_action() + + +func _on_modifier_move_requested(from:int, to:int) -> void: + _undo_redo.create_action("Move modifier") + var modifiers = _mapping.modifiers.duplicate() + var modifier = modifiers[from] + modifiers.remove_at(from) + if from < to: + to -= 1 + modifiers.insert(to, modifier) + + _undo_redo.add_do_property(_mapping, "modifiers", modifiers) + _undo_redo.add_undo_property(_mapping, "modifiers", _mapping.modifiers) + + _undo_redo.commit_action() + + +func _on_trigger_move_requested(from:int, to:int) -> void: + _undo_redo.create_action("Move trigger") + var triggers = _mapping.triggers.duplicate() + var trigger = triggers[from] + triggers.remove_at(from) + if from < to: + to -= 1 + triggers.insert(to, trigger) + + _undo_redo.add_do_property(_mapping, "triggers", triggers) + _undo_redo.add_undo_property(_mapping, "triggers", _mapping.triggers) + + _undo_redo.commit_action() + +func _on_modifier_duplicate_requested(index:int) -> void: + _undo_redo.create_action("Duplicate modifier") + var modifiers = _mapping.modifiers.duplicate() + var copy = Utils.duplicate_if_inline(modifiers[index]) + modifiers.insert(index+1, copy) + + _undo_redo.add_do_property(_mapping, "modifiers", modifiers) + _undo_redo.add_undo_property(_mapping, "modifiers", _mapping.modifiers) + + _undo_redo.commit_action() + +func _on_trigger_duplicate_requested(index:int) -> void: + _undo_redo.create_action("Duplicate trigger") + var triggers = _mapping.triggers.duplicate() + var copy = Utils.duplicate_if_inline(triggers[index]) + triggers.insert(index+1, copy) + + _undo_redo.add_do_property(_mapping, "triggers", triggers) + _undo_redo.add_undo_property(_mapping, "triggers", _mapping.triggers) + + _undo_redo.commit_action() + + + +func _on_modifier_delete_requested(index:int) -> void: + _undo_redo.create_action("Delete modifier") + var modifiers = _mapping.modifiers.duplicate() + modifiers.remove_at(index) + + _undo_redo.add_do_property(_mapping, "modifiers", modifiers) + _undo_redo.add_undo_property(_mapping, "modifiers", _mapping.modifiers) + + _undo_redo.commit_action() + + +func _on_trigger_delete_requested(index:int) -> void: + _undo_redo.create_action("Delete trigger") + var triggers = _mapping.triggers.duplicate() + triggers.remove_at(index) + + _undo_redo.add_do_property(_mapping, "triggers", triggers) + _undo_redo.add_undo_property(_mapping, "triggers", _mapping.triggers) + + _undo_redo.commit_action() + + +func _on_modifiers_clear_requested() -> void: + _undo_redo.create_action("Clear modifiers") + # if this is inlined into the do_property, then it doesn't work + # so lets keep it a local variable + var value:Array[GUIDEModifier] = [] + _undo_redo.add_do_property(_mapping, "modifiers", value) + _undo_redo.add_undo_property(_mapping, "modifiers", _mapping.modifiers) + + _undo_redo.commit_action() + + +func _on_triggers_clear_requested() -> void: + _undo_redo.create_action("Clear triggers") + # if this is inlined into the do_property, then it doesn't work + # so lets keep it a local variable + var value:Array[GUIDETrigger] = [] + _undo_redo.add_do_property(_mapping, "triggers", value) + _undo_redo.add_undo_property(_mapping, "triggers", _mapping.triggers) + + _undo_redo.commit_action() + + +func _on_modifiers_collapse_state_changed(new_state:bool): + _mapping.set_meta("_guide_modifiers_collapsed", new_state) + +func _on_triggers_collapse_state_changed(new_state:bool): + _mapping.set_meta("_guide_triggers_collapsed", new_state) + + +func _on_edit_input_mapping_button_pressed(): + EditorInterface.edit_resource(_mapping) diff --git a/addons/guide/editor/input_mapping_editor/input_mapping_editor.gd.uid b/addons/guide/editor/input_mapping_editor/input_mapping_editor.gd.uid new file mode 100644 index 0000000..2effa94 --- /dev/null +++ b/addons/guide/editor/input_mapping_editor/input_mapping_editor.gd.uid @@ -0,0 +1 @@ +uid://dsw33iehbw8q6 diff --git a/addons/guide/editor/input_mapping_editor/input_mapping_editor.tscn b/addons/guide/editor/input_mapping_editor/input_mapping_editor.tscn new file mode 100644 index 0000000..a70f142 --- /dev/null +++ b/addons/guide/editor/input_mapping_editor/input_mapping_editor.tscn @@ -0,0 +1,140 @@ +[gd_scene load_steps=9 format=3 uid="uid://c323mdijdhktg"] + +[ext_resource type="PackedScene" uid="uid://dsv7s6tfmnsrs" path="res://addons/guide/editor/input_display/input_display.tscn" id="1_pg8n3"] +[ext_resource type="Script" path="res://addons/guide/editor/input_mapping_editor/input_mapping_editor.gd" id="1_xsluc"] +[ext_resource type="PackedScene" uid="uid://ck5a30syo6bpo" path="res://addons/guide/editor/modifier_slot/modifier_slot.tscn" id="2_uhbrq"] +[ext_resource type="PackedScene" uid="uid://tk30wnstb0ku" path="res://addons/guide/editor/trigger_slot/trigger_slot.tscn" id="3_e0jys"] +[ext_resource type="PackedScene" uid="uid://dic27bm4pfw3q" path="res://addons/guide/editor/binding_dialog/binding_dialog.tscn" id="4_oepf3"] +[ext_resource type="PackedScene" uid="uid://cly0ff32fvpb2" path="res://addons/guide/editor/array_edit/array_edit.tscn" id="6_jekhk"] + +[sub_resource type="Image" id="Image_m1w1j"] +data = { +"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0), +"format": "RGBA8", +"height": 16, +"mipmaps": false, +"width": 16 +} + +[sub_resource type="ImageTexture" id="ImageTexture_y0eyy"] +image = SubResource("Image_m1w1j") + +[node name="InputMappingEditor" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 0 +script = ExtResource("1_xsluc") +modifier_slot_scene = ExtResource("2_uhbrq") +trigger_slot_scene = ExtResource("3_e0jys") +binding_dialog_scene = ExtResource("4_oepf3") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_vertical = 0 +theme_override_constants/separation = 8 + +[node name="MarginContainer" type="MarginContainer" parent="HBoxContainer"] +layout_mode = 2 +size_flags_vertical = 0 + +[node name="Panel" type="Panel" parent="HBoxContainer/MarginContainer"] +visible = false +layout_mode = 2 + +[node name="EditInputMappingButton" type="Button" parent="HBoxContainer/MarginContainer"] +unique_name_in_owner = true +layout_mode = 2 +tooltip_text = "Open input mapping in inspector" +icon = SubResource("ImageTexture_y0eyy") +flat = true + +[node name="MarginContainer1" type="MarginContainer" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Panel" type="Panel" parent="HBoxContainer/MarginContainer1"] +visible = false +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer/MarginContainer1"] +layout_mode = 2 + +[node name="InputDisplay" parent="HBoxContainer/MarginContainer1/HBoxContainer" instance=ExtResource("1_pg8n3")] +unique_name_in_owner = true +layout_mode = 2 +scroll_active = false + +[node name="EditInputButton" type="Button" parent="HBoxContainer/MarginContainer1/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 0 +tooltip_text = "Edit bound input..." +icon = SubResource("ImageTexture_y0eyy") +flat = true + +[node name="ClearInputButton" type="Button" parent="HBoxContainer/MarginContainer1/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 0 +tooltip_text = "Delete bound input" +icon = SubResource("ImageTexture_y0eyy") +flat = true + +[node name="MarginContainer2" type="MarginContainer" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 2.0 + +[node name="Panel" type="Panel" parent="HBoxContainer/MarginContainer2"] +visible = false +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer/MarginContainer2"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +size_flags_stretch_ratio = 2.0 + +[node name="Modifiers" parent="HBoxContainer/MarginContainer2/VBoxContainer" instance=ExtResource("6_jekhk")] +unique_name_in_owner = true +layout_mode = 2 +title = "Modifiers" +add_tooltip = "Add modifier..." +clear_tooltip = "Clear modifiers" + +[node name="AddModifierPopup" type="PopupMenu" parent="HBoxContainer/MarginContainer2/VBoxContainer"] +unique_name_in_owner = true + +[node name="MarginContainer3" type="MarginContainer" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 2.0 + +[node name="Panel" type="Panel" parent="HBoxContainer/MarginContainer3"] +visible = false +layout_mode = 2 + +[node name="VBoxContainer2" type="VBoxContainer" parent="HBoxContainer/MarginContainer3"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +size_flags_stretch_ratio = 2.0 + +[node name="Triggers" parent="HBoxContainer/MarginContainer3/VBoxContainer2" instance=ExtResource("6_jekhk")] +unique_name_in_owner = true +layout_mode = 2 +title = "Triggers" +add_tooltip = "Add trigger..." +clear_tooltip = "Clear triggers" + +[node name="AddTriggerPopup" type="PopupMenu" parent="HBoxContainer/MarginContainer3/VBoxContainer2"] +unique_name_in_owner = true + +[connection signal="pressed" from="HBoxContainer/MarginContainer/EditInputMappingButton" to="." method="_on_edit_input_mapping_button_pressed"] +[connection signal="pressed" from="HBoxContainer/MarginContainer1/HBoxContainer/EditInputButton" to="." method="_on_edit_input_button_pressed"] +[connection signal="pressed" from="HBoxContainer/MarginContainer1/HBoxContainer/ClearInputButton" to="." method="_on_clear_input_button_pressed"] +[connection signal="index_pressed" from="HBoxContainer/MarginContainer2/VBoxContainer/AddModifierPopup" to="." method="_on_add_modifier_popup_index_pressed"] +[connection signal="index_pressed" from="HBoxContainer/MarginContainer3/VBoxContainer2/AddTriggerPopup" to="." method="_on_add_trigger_popup_index_pressed"] diff --git a/addons/guide/editor/logo_editor_small.svg b/addons/guide/editor/logo_editor_small.svg new file mode 100644 index 0000000..38b6805 --- /dev/null +++ b/addons/guide/editor/logo_editor_small.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/guide/editor/logo_editor_small.svg.import b/addons/guide/editor/logo_editor_small.svg.import new file mode 100644 index 0000000..50a40ea --- /dev/null +++ b/addons/guide/editor/logo_editor_small.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cap7e0f05pj8j" +path="res://.godot/imported/logo_editor_small.svg-a18f1eaff840dcdf5215ef26c289caf9.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/editor/logo_editor_small.svg" +dest_files=["res://.godot/imported/logo_editor_small.svg-a18f1eaff840dcdf5215ef26c289caf9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=0.5 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/editor/mapping_context_editor/mapping_context_editor.gd b/addons/guide/editor/mapping_context_editor/mapping_context_editor.gd new file mode 100644 index 0000000..8f7882c --- /dev/null +++ b/addons/guide/editor/mapping_context_editor/mapping_context_editor.gd @@ -0,0 +1,159 @@ +@tool +extends MarginContainer + +const ClassScanner = preload("../class_scanner.gd") +const Utils = preload("../utils.gd") +const ArrayEdit = preload("../array_edit/array_edit.gd") + +@export var action_mapping_editor_scene:PackedScene + +@onready var _title_label:Label = %TitleLabel +@onready var _action_mappings:ArrayEdit = %ActionMappings +@onready var _editing_view:Control = %EditingView +@onready var _empty_view = %EmptyView + +var _plugin:EditorPlugin +var _current_context:GUIDEMappingContext +var _undo_redo:EditorUndoRedoManager +var _scanner:ClassScanner + + +func _ready(): + _title_label.add_theme_font_override("font", get_theme_font("title", "EditorFonts")) + _scanner = ClassScanner.new() + + _editing_view.visible = false + _empty_view.visible = true + + _action_mappings.add_requested.connect(_on_action_mappings_add_requested) + _action_mappings.move_requested.connect(_on_action_mappings_move_requested) + _action_mappings.delete_requested.connect(_on_action_mapping_delete_requested) + _action_mappings.clear_requested.connect(_on_action_mappings_clear_requested) + _action_mappings.duplicate_requested.connect(_on_action_mapping_duplicate_requested) + _action_mappings.collapse_state_changed.connect(_on_action_mappings_collapse_state_changed) + +func initialize(plugin:EditorPlugin) -> void: + _plugin = plugin + _undo_redo = plugin.get_undo_redo() + + +func edit(context:GUIDEMappingContext) -> void: + if is_instance_valid(_current_context): + _current_context.changed.disconnect(_refresh) + + _current_context = context + + if is_instance_valid(_current_context): + _current_context.changed.connect(_refresh) + + _refresh() + + +func _refresh(): + _editing_view.visible = is_instance_valid(_current_context) + _empty_view.visible = not is_instance_valid(_current_context) + + if not is_instance_valid(_current_context): + return + + _title_label.text = _current_context._editor_name() + _title_label.tooltip_text = _current_context.resource_path + + _action_mappings.clear() + + for i in _current_context.mappings.size(): + var mapping = _current_context.mappings[i] + + var mapping_editor = action_mapping_editor_scene.instantiate() + mapping_editor.initialize(_plugin, _scanner) + + _action_mappings.add_item(mapping_editor) + + mapping_editor.edit(mapping) + + _action_mappings.collapsed = _current_context.get_meta("_guide_action_mappings_collapsed", false) + +func _on_action_mappings_add_requested(): + var mappings = _current_context.mappings.duplicate() + var new_mapping := GUIDEActionMapping.new() + # don't set an action because they should come from the file system + mappings.append(new_mapping) + + _undo_redo.create_action("Add action mapping") + + _undo_redo.add_do_property(_current_context, "mappings", mappings) + _undo_redo.add_undo_property(_current_context, "mappings", _current_context.mappings) + + _undo_redo.commit_action() + + +func _on_action_mappings_move_requested(from:int, to:int): + var mappings = _current_context.mappings.duplicate() + var mapping = mappings[from] + mappings.remove_at(from) + if from < to: + to -= 1 + mappings.insert(to, mapping) + + _undo_redo.create_action("Move action mapping") + + _undo_redo.add_do_property(_current_context, "mappings", mappings) + _undo_redo.add_undo_property(_current_context, "mappings", _current_context.mappings) + + _undo_redo.commit_action() + + +func _on_action_mapping_delete_requested(index:int): + var mappings = _current_context.mappings.duplicate() + mappings.remove_at(index) + + _undo_redo.create_action("Delete action mapping") + + _undo_redo.add_do_property(_current_context, "mappings", mappings) + _undo_redo.add_undo_property(_current_context, "mappings", _current_context.mappings) + + _undo_redo.commit_action() + + +func _on_action_mappings_clear_requested(): + var mappings:Array[GUIDEActionMapping] = [] + + _undo_redo.create_action("Clear action mappings") + + _undo_redo.add_do_property(_current_context, "mappings", mappings) + _undo_redo.add_undo_property(_current_context, "mappings", _current_context.mappings) + + _undo_redo.commit_action() + +func _on_action_mapping_duplicate_requested(index:int): + var mappings = _current_context.mappings.duplicate() + var to_duplicate:GUIDEActionMapping = mappings[index] + + var copy = GUIDEActionMapping.new() + # don't set the action, because each mapping should have a unique mapping + for input_mapping:GUIDEInputMapping in to_duplicate.input_mappings: + var copied_input_mapping := GUIDEInputMapping.new() + copied_input_mapping.input = Utils.duplicate_if_inline(input_mapping.input) + for modifier in input_mapping.modifiers: + copied_input_mapping.modifiers.append(Utils.duplicate_if_inline(modifier)) + + for trigger in input_mapping.triggers: + copied_input_mapping.triggers.append(Utils.duplicate_if_inline(trigger)) + + copy.input_mappings.append(copied_input_mapping) + + # insert the copy after the copied mapping + mappings.insert(index+1, copy) + + + _undo_redo.create_action("Duplicate action mapping") + + _undo_redo.add_do_property(_current_context, "mappings", mappings) + _undo_redo.add_undo_property(_current_context, "mappings", _current_context.mappings) + + _undo_redo.commit_action() + +func _on_action_mappings_collapse_state_changed(new_state:bool): + _current_context.set_meta("_guide_action_mappings_collapsed", new_state) + + diff --git a/addons/guide/editor/mapping_context_editor/mapping_context_editor.gd.uid b/addons/guide/editor/mapping_context_editor/mapping_context_editor.gd.uid new file mode 100644 index 0000000..fc98c0d --- /dev/null +++ b/addons/guide/editor/mapping_context_editor/mapping_context_editor.gd.uid @@ -0,0 +1 @@ +uid://bpemf1ch2011g diff --git a/addons/guide/editor/mapping_context_editor/mapping_context_editor.tscn b/addons/guide/editor/mapping_context_editor/mapping_context_editor.tscn new file mode 100644 index 0000000..f28a17f --- /dev/null +++ b/addons/guide/editor/mapping_context_editor/mapping_context_editor.tscn @@ -0,0 +1,58 @@ +[gd_scene load_steps=4 format=3 uid="uid://dm3hott3tfvwe"] + +[ext_resource type="Script" path="res://addons/guide/editor/mapping_context_editor/mapping_context_editor.gd" id="1_vytdu"] +[ext_resource type="PackedScene" uid="uid://361aipcef24h" path="res://addons/guide/editor/action_mapping_editor/action_mapping_editor.tscn" id="2_qb3p8"] +[ext_resource type="PackedScene" uid="uid://cly0ff32fvpb2" path="res://addons/guide/editor/array_edit/array_edit.tscn" id="3_x7h5x"] + +[node name="MappingContextEditor" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 +script = ExtResource("1_vytdu") +action_mapping_editor_scene = ExtResource("2_qb3p8") + +[node name="EditingView" type="VBoxContainer" parent="."] +unique_name_in_owner = true +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="EditingView"] +layout_mode = 2 + +[node name="TitleLabel" type="Label" parent="EditingView/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 6 +text = "narf.tres" +horizontal_alignment = 1 + +[node name="MarginContainer" type="MarginContainer" parent="EditingView"] +layout_mode = 2 +theme_override_constants/margin_bottom = 5 + +[node name="ScrollContainer" type="ScrollContainer" parent="EditingView"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="ActionMappings" parent="EditingView/ScrollContainer" instance=ExtResource("3_x7h5x")] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +title = "Action mappings" +add_tooltip = "Add action mapping" +clear_tooltip = "Clear action mappings" + +[node name="EmptyView" type="CenterContainer" parent="."] +unique_name_in_owner = true +layout_mode = 2 + +[node name="Label" type="Label" parent="EmptyView"] +layout_mode = 2 +text = "Create and open a GUIDEMappingContext to get started." diff --git a/addons/guide/editor/modifier_slot/modifier_slot.gd b/addons/guide/editor/modifier_slot/modifier_slot.gd new file mode 100644 index 0000000..30dc53d --- /dev/null +++ b/addons/guide/editor/modifier_slot/modifier_slot.gd @@ -0,0 +1,14 @@ +@tool +extends "../resource_slot/resource_slot.gd" + +var modifier:GUIDEModifier: + set(value): + _value = value + get: + return _value + +func _accepts_drop_data(data:Resource) -> bool: + return data is GUIDEModifier + + + diff --git a/addons/guide/editor/modifier_slot/modifier_slot.gd.uid b/addons/guide/editor/modifier_slot/modifier_slot.gd.uid new file mode 100644 index 0000000..a575576 --- /dev/null +++ b/addons/guide/editor/modifier_slot/modifier_slot.gd.uid @@ -0,0 +1 @@ +uid://cmvfuu8u5ubkk diff --git a/addons/guide/editor/modifier_slot/modifier_slot.tscn b/addons/guide/editor/modifier_slot/modifier_slot.tscn new file mode 100644 index 0000000..6b2f91e --- /dev/null +++ b/addons/guide/editor/modifier_slot/modifier_slot.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=2 format=3 uid="uid://ck5a30syo6bpo"] + +[ext_resource type="Script" path="res://addons/guide/editor/modifier_slot/modifier_slot.gd" id="1_273m5"] + +[node name="LineEdit" type="LineEdit"] +offset_right = 1920.0 +offset_bottom = 31.0 +size_flags_horizontal = 3 +size_flags_vertical = 0 +text = "Name" +editable = false +context_menu_enabled = false +virtual_keyboard_enabled = false +shortcut_keys_enabled = false +middle_mouse_paste_enabled = false +selecting_enabled = false +drag_and_drop_selection_enabled = false +script = ExtResource("1_273m5") diff --git a/addons/guide/editor/resource_slot/resource_slot.gd b/addons/guide/editor/resource_slot/resource_slot.gd new file mode 100644 index 0000000..d54ec95 --- /dev/null +++ b/addons/guide/editor/resource_slot/resource_slot.gd @@ -0,0 +1,106 @@ +@tool +extends LineEdit + +signal changed() +const Utils = preload("../utils.gd") + +func _ready(): + editable = false + context_menu_enabled = false + virtual_keyboard_enabled = false + shortcut_keys_enabled = false + selecting_enabled = false + drag_and_drop_selection_enabled = false + middle_mouse_paste_enabled = false + +## The underlying resource. This is opened for editing when the user clicks on the control. Its also +## used when dragging from the control. +var _value:Resource = null: + set(value): + if _value == value: + return + + # stop tracking changes to the old resource (if any) + if is_instance_valid(_value): + _value.changed.disconnect(_update_from_value) + + _value = value + + # track changes to the resource itself + if is_instance_valid(_value): + _value.changed.connect(_update_from_value) + + _update_from_value() + changed.emit() + +func _update_from_value(): + if not is_instance_valid(_value): + text = "" + tooltip_text = "" + remove_theme_color_override("font_uneditable_color") + else: + text = _value._editor_name() + tooltip_text = _value.resource_path + # if the value is shared, we override the font color to indicate that + if not Utils.is_inline(_value): + add_theme_color_override("font_uneditable_color", get_theme_color("accent_color", "Editor")) + queue_redraw() + else: + remove_theme_color_override("font_uneditable_color") + +## Can be overridden to handle the drop data. This method is called when the user drops something on the control. +## If the value should be updated ,this method should set the _value property. +func _do_drop_data(data:Resource): + _value = data + + +## Whether this control can accept drop data. This method is called when the user drags something over the control. +func _accepts_drop_data(data:Resource) -> bool: + return false + +func _can_drop_data(at_position, data) -> bool: + if data is Resource: + return _accepts_drop_data(data) + + if not data is Dictionary: + return false + + if data.has("files"): + for file in data["files"]: + if _accepts_drop_data(ResourceLoader.load(file)): + return true + + return false + + +func _drop_data(at_position, data) -> void: + if data is Resource: + _do_drop_data(data) + return + + for file in data["files"]: + var item := ResourceLoader.load(file) + _do_drop_data(item) + + +func _get_drag_data(at_position: Vector2) -> Variant: + if is_instance_valid(_value): + var _preview := TextureRect.new() + _preview.texture = get_theme_icon("File", "EditorIcons") + set_drag_preview(_preview) + # if the value is shared, we just hand out the resource path + if not Utils.is_inline(_value): + return {"files": [_value.resource_path]} + else: + # otherwise we hand out a shallow copy + return _value.duplicate() + else: + return null + +func _gui_input(event): + if event is InputEventMouseButton: + if event.pressed and event.button_index == MOUSE_BUTTON_LEFT: + if is_instance_valid(_value): + EditorInterface.edit_resource(_value) + + diff --git a/addons/guide/editor/resource_slot/resource_slot.gd.uid b/addons/guide/editor/resource_slot/resource_slot.gd.uid new file mode 100644 index 0000000..d11247d --- /dev/null +++ b/addons/guide/editor/resource_slot/resource_slot.gd.uid @@ -0,0 +1 @@ +uid://b7cctlhen71jw diff --git a/addons/guide/editor/trigger_slot/trigger_slot.gd b/addons/guide/editor/trigger_slot/trigger_slot.gd new file mode 100644 index 0000000..70cb053 --- /dev/null +++ b/addons/guide/editor/trigger_slot/trigger_slot.gd @@ -0,0 +1,14 @@ +@tool +extends "../resource_slot/resource_slot.gd" + +var trigger:GUIDETrigger: + set(value): + _value = value + get: + return _value + +func _accepts_drop_data(data:Resource) -> bool: + return data is GUIDETrigger + + + diff --git a/addons/guide/editor/trigger_slot/trigger_slot.gd.uid b/addons/guide/editor/trigger_slot/trigger_slot.gd.uid new file mode 100644 index 0000000..4575b7f --- /dev/null +++ b/addons/guide/editor/trigger_slot/trigger_slot.gd.uid @@ -0,0 +1 @@ +uid://dk2lv53ohhes2 diff --git a/addons/guide/editor/trigger_slot/trigger_slot.tscn b/addons/guide/editor/trigger_slot/trigger_slot.tscn new file mode 100644 index 0000000..3d5e6d8 --- /dev/null +++ b/addons/guide/editor/trigger_slot/trigger_slot.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=2 format=3 uid="uid://tk30wnstb0ku"] + +[ext_resource type="Script" path="res://addons/guide/editor/trigger_slot/trigger_slot.gd" id="1_wxafc"] + +[node name="LineEdit" type="LineEdit"] +unique_name_in_owner = true +offset_right = 1920.0 +offset_bottom = 31.0 +size_flags_horizontal = 3 +size_flags_vertical = 0 +tooltip_text = "Delete trigger" +text = "Name" +editable = false +context_menu_enabled = false +virtual_keyboard_enabled = false +shortcut_keys_enabled = false +middle_mouse_paste_enabled = false +selecting_enabled = false +drag_and_drop_selection_enabled = false +script = ExtResource("1_wxafc") diff --git a/addons/guide/editor/utils.gd b/addons/guide/editor/utils.gd new file mode 100644 index 0000000..f3549af --- /dev/null +++ b/addons/guide/editor/utils.gd @@ -0,0 +1,22 @@ +## Removes and frees all children of a node. +static func clear(node:Node): + if not is_instance_valid(node): + return + for child in node.get_children(): + node.remove_child(child) + child.queue_free() + + +## Checks if the given resource is an inline resource. If so, returns a shallow copy, +## otherwise returns the resource. If the resource is null, returns null. +static func duplicate_if_inline(resource:Resource) -> Resource: + if is_inline(resource): + return resource.duplicate() + return resource + + +## Checks if the given resource is an inline resource. +static func is_inline(resource:Resource) -> bool: + if resource == null: + return false + return resource.resource_path.contains("::") or resource.resource_path == "" \ No newline at end of file diff --git a/addons/guide/editor/utils.gd.uid b/addons/guide/editor/utils.gd.uid new file mode 100644 index 0000000..db0f31f --- /dev/null +++ b/addons/guide/editor/utils.gd.uid @@ -0,0 +1 @@ +uid://c2jwjge0gqr1l diff --git a/addons/guide/guide.gd b/addons/guide/guide.gd new file mode 100644 index 0000000..c9aa8f1 --- /dev/null +++ b/addons/guide/guide.gd @@ -0,0 +1,387 @@ +extends Node + +const GUIDESet = preload("guide_set.gd") +const GUIDEReset = preload("guide_reset.gd") +const GUIDEInputTracker = preload("guide_input_tracker.gd") + +## This is emitted whenever input mappings change (either due to mapping +## contexts being enabled/disabled or remapping configs being re-applied or +## joystick devices being connected/disconnected). +## This is useful for updating UI prompts. +signal input_mappings_changed() + +## The currently active contexts. Key is the context, value is the priority +var _active_contexts:Dictionary = {} +## The currently active action mappings. +var _active_action_mappings:Array[GUIDEActionMapping] = [] + +## The currently active remapping config. +var _active_remapping_config:GUIDERemappingConfig + +## All currently active inputs as collected from the active input mappings +var _active_inputs:Array[GUIDEInput] = [] + +## A dictionary of actions sharing input. Key is the action, value +## is an array of lower-priority actions that share input with the +## key action. +var _actions_sharing_input:Dictionary = {} + +## A reference to the reset node which resets inputs that need a reset per frame +## This is an extra node because the reset should run at the end of the frame +## before new input is processed at the beginning of the frame. +var _reset_node:GUIDEReset + +## The current input state. This is used to track the state of the inputs +## and serves as a basis for the GUIDEInputs. +var _input_state:GUIDEInputState + + +func _ready(): + process_mode = Node.PROCESS_MODE_ALWAYS + _reset_node = GUIDEReset.new() + _input_state = GUIDEInputState.new() + add_child(_reset_node) + # attach to the current viewport to get input events + GUIDEInputTracker._instrument.call_deferred(get_viewport()) + + get_tree().node_added.connect(_on_node_added) + + # Emit a change of input mappings whenever a joystick was connected + # or disconnected. + Input.joy_connection_changed.connect(func(ig, ig2): input_mappings_changed.emit()) + + +## Called when a node is added to the tree. If the node is a window +## GUIDE will instrument it to get events when the window is focused. +func _on_node_added(node:Node) -> void: + if not node is Window: + return + + GUIDEInputTracker._instrument(node) + + +## Injects input into GUIDE. GUIDE will call this automatically but +## can also be used to manually inject input for GUIDE to handle +func inject_input(event:InputEvent) -> void: + if event is InputEventAction: + return # we don't react to Godot's built-in events + + # The input state is the sole consumer of input events. It will notify + # GUIDEInputs when relevant input events happen. This way we don't need + # to process input events multiple times and at the same time always have + # the full picture of the input state. + _input_state._input(event) + + +## Applies an input remapping config. This will override all input bindings in the +## currently loaded mapping contexts with the bindings from the configuration. +## Note that GUIDE will not track changes to the remapping config. If your remapping +## config changes, you will need to call this method again. +func set_remapping_config(config:GUIDERemappingConfig) -> void: + _active_remapping_config = config + _update_caches() + + +## Enables the given context with the given priority. Lower numbers have higher priority. If +## disable_others is set to true, all other currently enabled mapping contexts will be disabled. +func enable_mapping_context(context:GUIDEMappingContext, disable_others:bool = false, priority:int = 0): + if not is_instance_valid(context): + push_error("Null context given. Ignoring.") + return + + if disable_others: + _active_contexts.clear() + + _active_contexts[context] = priority + _update_caches() + + +## Disables the given mapping context. +func disable_mapping_context(context:GUIDEMappingContext): + if not is_instance_valid(context): + push_error("Null context given. Ignoring.") + return + + _active_contexts.erase(context) + _update_caches() + + +## Checks whether the given mapping context is currently enabled. +func is_mapping_context_enabled(context:GUIDEMappingContext) -> bool: + return _active_contexts.has(context) + + +## Returns the currently enabled mapping contexts +func get_enabled_mapping_contexts() -> Array[GUIDEMappingContext]: + var result:Array[GUIDEMappingContext] = [] + for key in _active_contexts.keys(): + result.append(key) + return result + + +## Processes all currently active actions +func _process(delta:float) -> void: + var blocked_actions:GUIDESet = GUIDESet.new() + + for action_mapping:GUIDEActionMapping in _active_action_mappings: + + var action:GUIDEAction = action_mapping.action + + # Walk over all input mappings for this action and consolidate state + # and result value. + var consolidated_value:Vector3 = Vector3.ZERO + var consolidated_trigger_state:GUIDETrigger.GUIDETriggerState + + for input_mapping:GUIDEInputMapping in action_mapping.input_mappings: + input_mapping._update_state(delta, action.action_value_type) + consolidated_value += input_mapping._value + consolidated_trigger_state = max(consolidated_trigger_state, input_mapping._state) + + # we do the blocking check only here because triggers may need to run anyways + # (e.g. to collect hold times). + if blocked_actions.has(action): + consolidated_trigger_state = GUIDETrigger.GUIDETriggerState.NONE + + if action.block_lower_priority_actions and \ + consolidated_trigger_state == GUIDETrigger.GUIDETriggerState.TRIGGERED and \ + _actions_sharing_input.has(action): + for blocked_action in _actions_sharing_input[action]: + blocked_actions.add(blocked_action) + + + # Now state change events. + match(action._last_state): + GUIDEAction.GUIDEActionState.TRIGGERED: + match(consolidated_trigger_state): + GUIDETrigger.GUIDETriggerState.NONE: + action._completed(consolidated_value) + GUIDETrigger.GUIDETriggerState.ONGOING: + action._ongoing(consolidated_value, delta) + GUIDETrigger.GUIDETriggerState.TRIGGERED: + action._triggered(consolidated_value, delta) + + GUIDEAction.GUIDEActionState.ONGOING: + match(consolidated_trigger_state): + GUIDETrigger.GUIDETriggerState.NONE: + action._cancelled(consolidated_value) + GUIDETrigger.GUIDETriggerState.ONGOING: + action._ongoing(consolidated_value, delta) + GUIDETrigger.GUIDETriggerState.TRIGGERED: + action._triggered(consolidated_value, delta) + + GUIDEAction.GUIDEActionState.COMPLETED: + match(consolidated_trigger_state): + GUIDETrigger.GUIDETriggerState.NONE: + # make sure the value updated but don't emit any other events + action._update_value(consolidated_value) + GUIDETrigger.GUIDETriggerState.ONGOING: + action._started(consolidated_value) + GUIDETrigger.GUIDETriggerState.TRIGGERED: + action._triggered(consolidated_value, delta) + +func _update_caches(): + # Notify existing inputs that they aren no longer required + for input:GUIDEInput in _active_inputs: + input._reset() + input._end_usage() + + # Cancel all actions, so they don't remain in weird states. + for mapping:GUIDEActionMapping in _active_action_mappings: + match mapping.action._last_state: + GUIDEAction.GUIDEActionState.ONGOING: + mapping.action._cancelled(Vector3.ZERO) + GUIDEAction.GUIDEActionState.TRIGGERED: + mapping.action._completed(Vector3.ZERO) + # notify all modifiers they are no longer in use + for input_mapping in mapping.input_mappings: + for modifier in input_mapping.modifiers: + modifier._end_usage() + + _active_inputs.clear() + _active_action_mappings.clear() + _actions_sharing_input.clear() + + var sorted_contexts:Array[Dictionary] = [] + + for context:GUIDEMappingContext in _active_contexts.keys(): + sorted_contexts.append({"context": context, "priority": _active_contexts[context]}) + + sorted_contexts.sort_custom( func(a,b): return a.priority < b.priority ) + + # The actions we already have processed. Same action may appear in different + # contexts, so if we find the same action twice, only the first instance wins. + var processed_actions:GUIDESet = GUIDESet.new() + var consolidated_inputs:GUIDESet = GUIDESet.new() + + for entry:Dictionary in sorted_contexts: + var context:GUIDEMappingContext = entry.context + var position:int = 0 + for action_mapping:GUIDEActionMapping in context.mappings: + position += 1 + var action := action_mapping.action + + # Mapping may be misconfigured, so we need to handle the case + # that the action is missing. + if action == null: + push_warning("Mapping at position %s in context %s has no action set. This mapping will be ignored." % [position, context.resource_path]) + continue + + # If the action was already configured in a higher priority context, + # we'll skip it. + if processed_actions.has(action): + # skip + continue + + processed_actions.add(action) + + # We consolidate the inputs here, so we'll internally build a new + # action mapping that uses consolidated inputs rather than the + # original ones. This achieves multiple things: + # - if two actions check for the same input, we only need to + # process the input once instead of twice. + # - it allows us to prioritize input, if two actions check for + # the same input. This way the first action can consume the + # input and not have it affect further actions. + # - we make sure nobody shares triggers as they are stateful and + # should not be shared. + + var effective_mapping = GUIDEActionMapping.new() + effective_mapping.action = action + + # now update the input mappings + for index in action_mapping.input_mappings.size(): + var bound_input:GUIDEInput = action_mapping.input_mappings[index].input + + # if the mapping has an override for the input, apply it. + if _active_remapping_config != null and \ + _active_remapping_config._has(context, action, index): + bound_input = _active_remapping_config._get_bound_input_or_null(context, action, index) + + # make a new input mapping + var new_input_mapping := GUIDEInputMapping.new() + + # can be null for combo mappings, so check that + if bound_input != null: + # check if we already have this kind of input + var existing = consolidated_inputs.first_match(func(it:GUIDEInput): return it.is_same_as(bound_input)) + if existing != null: + # if we have this already, use the instance we have + bound_input = existing + else: + # otherwise register this input into the consolidated input + consolidated_inputs.add(bound_input) + + new_input_mapping.input = bound_input + # modifiers cannot be re-bound so we can just use the one + # from the original configuration. this is also needed for shared + # modifiers to work. + new_input_mapping.modifiers = action_mapping.input_mappings[index].modifiers + # triggers also cannot be re-bound but we still make a copy + # to ensure that no shared triggers exist. + new_input_mapping.triggers = [] + + for trigger in action_mapping.input_mappings[index].triggers: + new_input_mapping.triggers.append(trigger.duplicate()) + + new_input_mapping._initialize() + + # and add it to the new mapping + effective_mapping.input_mappings.append(new_input_mapping) + + + # if any binding remains, add the mapping to the list of active + # action mappings + if not effective_mapping.input_mappings.is_empty(): + _active_action_mappings.append(effective_mapping) + + # INVARIANT: all _active_action_mappings now have actions. + + # now we have a new set of active inputs + for input:GUIDEInput in consolidated_inputs.values(): + _active_inputs.append(input) + + # prepare the action input share lookup table + for i:int in _active_action_mappings.size(): + + var mapping = _active_action_mappings[i] + + if mapping.action.block_lower_priority_actions: + # first find out if the action uses any chorded actions and + # collect all inputs that this action uses + var chorded_actions:GUIDESet = GUIDESet.new() + var inputs:GUIDESet = GUIDESet.new() + var blocked_actions:GUIDESet = GUIDESet.new() + for input_mapping:GUIDEInputMapping in mapping.input_mappings: + if input_mapping.input != null: + inputs.add(input_mapping.input) + + for trigger:GUIDETrigger in input_mapping.triggers: + if trigger is GUIDETriggerChordedAction and trigger.action != null: + chorded_actions.add(trigger.action) + + # Now the action that has a chorded action (A) needs to make sure that + # the chorded action it depends upon (B) is not blocked (otherwise A would + # never trigger) and if that chorded action (B) in turn depends on chorded actions. So + # if chorded actions build a chain, we need to keep the full + # chain unblocked. In addition we need to add the inputs of all + # these chorded actions to the list of blocked inputs. + for j:int in range(i+1, _active_action_mappings.size()): + var inner_mapping = _active_action_mappings[j] + # this is a chorded action that is used by one other action + # in the chain. + if chorded_actions.has(inner_mapping.action): + for input_mapping:GUIDEInputMapping in inner_mapping.input_mappings: + # put all of its inputs into the list of blocked inputs + if input_mapping.input != null: + inputs.add(input_mapping.input) + + # also if this mapping in turn again depends on a chorded + # action, ad this one to the list of chorded actions + for trigger:GUIDETrigger in input_mapping.triggers: + if trigger is GUIDETriggerChordedAction and trigger.action != null: + chorded_actions.add(trigger.action) + + # now find lower priority actions that share input + for j:int in range(i+1, _active_action_mappings.size()): + var inner_mapping = _active_action_mappings[j] + if chorded_actions.has(inner_mapping.action): + continue + + for input_mapping:GUIDEInputMapping in inner_mapping.input_mappings: + if input_mapping.input == null: + continue + + # because we consolidated input, we can now do an == comparison + # to find equal input. + if inputs.has(input_mapping.input): + blocked_actions.add(inner_mapping.action) + # we can continue to the next action + break + + if not blocked_actions.is_empty(): + _actions_sharing_input[mapping.action] = blocked_actions.values() + + _reset_node._inputs_to_reset.clear() + for input:GUIDEInput in _active_inputs: + # finally collect which inputs we need to reset per frame + if input._needs_reset(): + _reset_node._inputs_to_reset.append(input) + + # Give the state to the input + input._state = _input_state + # Notify inputs that GUIDE is about to use them + input._begin_usage() + + for mapping in _active_action_mappings: + for input_mapping in mapping.input_mappings: + # notify modifiers they will be used. + for modifier in input_mapping.modifiers: + modifier._begin_usage() + + # and copy over the hold time threshold from the mapping + mapping.action._trigger_hold_threshold = input_mapping._trigger_hold_threshold + + # and notify interested parties that the input mappings have changed + input_mappings_changed.emit() + + diff --git a/addons/guide/guide.gd.uid b/addons/guide/guide.gd.uid new file mode 100644 index 0000000..6e0cdad --- /dev/null +++ b/addons/guide/guide.gd.uid @@ -0,0 +1 @@ +uid://p2jwrgjcbexr diff --git a/addons/guide/guide_action.gd b/addons/guide/guide_action.gd new file mode 100644 index 0000000..a92ef64 --- /dev/null +++ b/addons/guide/guide_action.gd @@ -0,0 +1,254 @@ +@tool +@icon("res://addons/guide/guide_action.svg") +class_name GUIDEAction +extends Resource + +enum GUIDEActionValueType { + BOOL = 0, + AXIS_1D = 1, + AXIS_2D = 2, + AXIS_3D = 3 +} + +enum GUIDEActionState { + TRIGGERED, + ONGOING, + COMPLETED +} + +## The name of this action. Required when this action should be used as +## Godot action. Also displayed in the debugger. +@export var name:StringName: + set(value): + if name == value: + return + name = value + emit_changed() + + +## The action value type. +@export var action_value_type: GUIDEActionValueType = GUIDEActionValueType.BOOL: + set(value): + if action_value_type == value: + return + action_value_type = value + emit_changed() + +## If this action triggers, lower-priority actions cannot trigger +## if they share input with this action unless these actions are +## chorded with this action. +@export var block_lower_priority_actions:bool = true: + set(value): + if block_lower_priority_actions == value: + return + block_lower_priority_actions = value + emit_changed() + + +@export_category("Godot Actions") +## If true, then this action will be emitted into Godot's +## built-in action system. This can be helpful to interact with +## code using this system, like Godot's UI system. Actions +## will be emitted on trigger and completion (e.g. button down +## and button up). +@export var emit_as_godot_actions:bool = false: + set(value): + if emit_as_godot_actions == value: + return + emit_as_godot_actions = value + emit_changed() + + +@export_category("Action Remapping") + +## If true, players can remap this action. To be remappable, make sure +## that a name and the action type are properly set. +@export var is_remappable:bool: + set(value): + if is_remappable == value: + return + is_remappable = value + emit_changed() + +## The display name of the action shown to the player. +@export var display_name:String: + set(value): + if display_name == value: + return + display_name = value + emit_changed() + +## The display category of the action shown to the player. +@export var display_category:String: + set(value): + if display_category == value: + return + display_category = value + emit_changed() + +## Emitted every frame while the action is triggered. +signal triggered() + +## Emitted when the action started evaluating. +signal started() + +## Emitted every frame while the action is still evaluating. +signal ongoing() + +## Emitted when the action finished evaluating. +signal completed() + +## Emitted when the action was cancelled. +signal cancelled() + +var _last_state:GUIDEActionState = GUIDEActionState.COMPLETED + +var _value_bool:bool +## Returns the value of this action as bool. +var value_bool:bool: + get: return _value_bool + +## Returns the value of this action as float. +var value_axis_1d:float: + get: return _value.x + +var _value_axis_2d:Vector2 = Vector2.ZERO +## Returns the value of this action as Vector2. +var value_axis_2d:Vector2: + get: return _value_axis_2d + +var _value:Vector3 = Vector3.ZERO +## Returns the value of this action as Vector3. +var value_axis_3d:Vector3: + get: return _value + + +var _elapsed_seconds:float +## The amount of seconds elapsed since the action started evaluating. +var elapsed_seconds:float: + get: return _elapsed_seconds + +var _elapsed_ratio:float +## The ratio of the elapsed time to the hold time. This is a percentage +## of the hold time that has passed. If the action has no hold time, this will +## be 0 when the action is not triggered and 1 when the action is triggered. +## Otherwise, this will be a value between 0 and 1. +var elapsed_ratio:float: + get: return _elapsed_ratio + +var _triggered_seconds:float +## The amount of seconds elapsed since the action triggered. +var triggered_seconds:float: + get: return _triggered_seconds + + +## This is a hint for how long the input must remain actuated (in seconds) before the action triggers. +## It depends on the mapping in which this action is used. If the mapping has no hold trigger it will be -1. +## In general, you should not access this variable directly, but rather the `elapsed_ratio` property of the action +## which is a percentage of the hold time that has passed. +var _trigger_hold_threshold:float = -1.0 + +func _triggered(value:Vector3, delta:float) -> void: + _triggered_seconds += delta + _elapsed_ratio = 1.0 + _update_value(value) + _last_state = GUIDEActionState.TRIGGERED + triggered.emit() + _emit_godot_action_maybe(true) + +func _started(value:Vector3) -> void: + _elapsed_ratio = 0.0 + _update_value(value) + _last_state = GUIDEActionState.ONGOING + started.emit() + ongoing.emit() + +func _ongoing(value:Vector3, delta:float) -> void: + _elapsed_seconds += delta + if _trigger_hold_threshold > 0: + _elapsed_ratio = _elapsed_seconds / _trigger_hold_threshold + _update_value(value) + var was_triggered:bool = _last_state == GUIDEActionState.TRIGGERED + _last_state = GUIDEActionState.ONGOING + ongoing.emit() + # if the action reverts from triggered to ongoing, this counts as + # releasing the action for the godot action system. + if was_triggered: + _emit_godot_action_maybe(false) + + +func _cancelled(value:Vector3) -> void: + _elapsed_seconds = 0 + _elapsed_ratio = 0 + _update_value(value) + _last_state = GUIDEActionState.COMPLETED + cancelled.emit() + completed.emit() + +func _completed(value:Vector3) -> void: + _elapsed_seconds = 0 + _elapsed_ratio = 0 + _triggered_seconds = 0 + _update_value(value) + _last_state = GUIDEActionState.COMPLETED + completed.emit() + _emit_godot_action_maybe(false) + +func _emit_godot_action_maybe(pressed:bool) -> void: + if not emit_as_godot_actions: + return + + if name.is_empty(): + push_error("Cannot emit action into Godot's system because name is empty.") + return + + var godot_action = InputEventAction.new() + godot_action.action = name + godot_action.strength = _value.x + godot_action.pressed = pressed + Input.parse_input_event(godot_action) + +func _update_value(value:Vector3): + match action_value_type: + GUIDEActionValueType.BOOL, GUIDEActionValueType.AXIS_1D: + _value_bool = abs(value.x) > 0 + _value_axis_2d = Vector2(abs(value.x), 0) + _value = Vector3(value.x, 0, 0) + GUIDEActionValueType.AXIS_2D: + _value_bool = abs(value.x) > 0 + _value_axis_2d = Vector2(value.x, value.y) + _value = Vector3(value.x, value.y, 0) + GUIDEActionValueType.AXIS_3D: + _value_bool = abs(value.x) > 0 + _value_axis_2d = Vector2(value.x, value.y) + _value = value + +## Returns whether the action is currently triggered. Can be used for a +## polling style input. +func is_triggered() -> bool: + return _last_state == GUIDEActionState.TRIGGERED + + +## Returns whether the action is currently completed. Can be used for a +## polling style input. +func is_completed() -> bool: + return _last_state == GUIDEActionState.COMPLETED + + +## Returns whether the action is currently completed. Can be used for a +## polling style input. +func is_ongoing() -> bool: + return _last_state == GUIDEActionState.ONGOING + + +func _editor_name() -> String: + # Try to give the most user friendly name + if display_name != "": + return display_name + + if name != "": + return name + + return resource_path.get_file().replace(".tres", "") + + diff --git a/addons/guide/guide_action.gd.uid b/addons/guide/guide_action.gd.uid new file mode 100644 index 0000000..6a4397c --- /dev/null +++ b/addons/guide/guide_action.gd.uid @@ -0,0 +1 @@ +uid://cluhc11vixkf1 diff --git a/addons/guide/guide_action.svg b/addons/guide/guide_action.svg new file mode 100644 index 0000000..b39120c --- /dev/null +++ b/addons/guide/guide_action.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/addons/guide/guide_action.svg.import b/addons/guide/guide_action.svg.import new file mode 100644 index 0000000..a55db27 --- /dev/null +++ b/addons/guide/guide_action.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bei7cw115tks0" +path="res://.godot/imported/guide_action.svg-4d1dfb47183d95c4796078798ce2d0ab.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/guide_action.svg" +dest_files=["res://.godot/imported/guide_action.svg-4d1dfb47183d95c4796078798ce2d0ab.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=0.5 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/guide_action_mapping.gd b/addons/guide/guide_action_mapping.gd new file mode 100644 index 0000000..f965b9f --- /dev/null +++ b/addons/guide/guide_action_mapping.gd @@ -0,0 +1,21 @@ +@icon("res://addons/guide/guide_internal.svg") +@tool +## An action to input mapping +class_name GUIDEActionMapping +extends Resource + +## The action to be mapped +@export var action:GUIDEAction: + set(value): + if value == action: + return + action = value + emit_changed() + +## A set of input mappings that can trigger the action +@export var input_mappings:Array[GUIDEInputMapping] = []: + set(value): + if value == input_mappings: + return + input_mappings = value + emit_changed() diff --git a/addons/guide/guide_action_mapping.gd.uid b/addons/guide/guide_action_mapping.gd.uid new file mode 100644 index 0000000..d0c1f54 --- /dev/null +++ b/addons/guide/guide_action_mapping.gd.uid @@ -0,0 +1 @@ +uid://cpplm41b5bt6m diff --git a/addons/guide/guide_input_mapping.gd b/addons/guide/guide_input_mapping.gd new file mode 100644 index 0000000..62d4dd9 --- /dev/null +++ b/addons/guide/guide_input_mapping.gd @@ -0,0 +1,177 @@ +@icon("res://addons/guide/guide_internal.svg") +@tool +## A mapping from actuated input to a trigger result +class_name GUIDEInputMapping +extends Resource + +## Whether the remapping configuration in this input mapping +## should override the configuration of the bound action. Enable +## this, to give a key a custom name or category for remapping. +@export var override_action_settings:bool = false: + set(value): + if override_action_settings == value: + return + override_action_settings = value + emit_changed() + +## If true, players can remap this input mapping. Note that the +## action to which this input is bound also needs to be remappable +## for this setting to have an effect. +@export var is_remappable:bool = false: + set(value): + if is_remappable == value: + return + is_remappable = value + emit_changed() + +## The display name of the input mapping shown to the player. If empty, +## the display name of the action is used. +@export var display_name:String = "": + set(value): + if display_name == value: + return + display_name = value + emit_changed() + +## The display category of the input mapping. If empty, the display name of the +## action is used. +@export var display_category:String = "": + set(value): + if display_category == value: + return + display_category = value + emit_changed() + + +@export_group("Mappings") +## The input to be actuated +@export var input:GUIDEInput: + set(value): + if value == input: + return + input = value + emit_changed() + + +## A list of modifiers that preprocess the actuated input before +## it is fed to the triggers. +@export var modifiers:Array[GUIDEModifier] = []: + set(value): + if value == modifiers: + return + modifiers = value + emit_changed() + + +## A list of triggers that could trigger the mapped action. +@export var triggers:Array[GUIDETrigger] = []: + set(value): + if value == triggers: + return + triggers = value + emit_changed() + +## Hint for how long the input must remain actuated (in seconds) before the mapping triggers. +## If the mapping has no hold trigger it will be -1. If it has multiple hold triggers +## the shortest hold time will be used. +var _trigger_hold_threshold:float = -1.0 + +var _state:GUIDETrigger.GUIDETriggerState = GUIDETrigger.GUIDETriggerState.NONE +var _value:Vector3 = Vector3.ZERO + +var _trigger_list:Array[GUIDETrigger] = [] +var _implicit_count:int = 0 +var _explicit_count:int = 0 + +## Called when the mapping is started to be used by GUIDE. Calculates +## the number of implicit and explicit triggers so we don't need to do this +## per frame. Also creates a default trigger when none is set. +func _initialize() -> void : + _trigger_list.clear() + + _implicit_count = 0 + _explicit_count = 0 + _trigger_hold_threshold = -1.0 + + if triggers.is_empty(): + # make a default trigger and use that + var default_trigger = GUIDETriggerDown.new() + default_trigger.actuation_threshold = 0 + _explicit_count = 1 + _trigger_list.append(default_trigger) + return + + for trigger in triggers: + match trigger._get_trigger_type(): + GUIDETrigger.GUIDETriggerType.EXPLICIT: + _explicit_count += 1 + GUIDETrigger.GUIDETriggerType.IMPLICIT: + _implicit_count += 1 + _trigger_list.append(trigger) + + # collect the hold threshold for hinting the UI about how long + # the input must be held down. This is only relevant for hold triggers + if trigger is GUIDETriggerHold: + if _trigger_hold_threshold == -1: + _trigger_hold_threshold = trigger.hold_treshold + else: + _trigger_hold_threshold = min(_trigger_hold_threshold, trigger.hold_treshold) + + + +func _update_state(delta:float, value_type:GUIDEAction.GUIDEActionValueType): + # Collect the current input value + var input_value:Vector3 = input._value if input != null else Vector3.ZERO + + # Run it through all modifiers + for modifier:GUIDEModifier in modifiers: + input_value = modifier._modify_input(input_value, delta, value_type) + + _value = input_value + + var triggered_implicits:int = 0 + var triggered_explicits:int = 0 + var triggered_blocked:int = 0 + + # Run over all triggers + var result:int = GUIDETrigger.GUIDETriggerState.NONE + for trigger:GUIDETrigger in _trigger_list: + var trigger_result:GUIDETrigger.GUIDETriggerState = trigger._update_state(_value, delta, value_type) + trigger._last_value = _value + + var trigger_type = trigger._get_trigger_type() + if trigger_result == GUIDETrigger.GUIDETriggerState.TRIGGERED: + match trigger_type: + GUIDETrigger.GUIDETriggerType.EXPLICIT: + triggered_explicits += 1 + GUIDETrigger.GUIDETriggerType.IMPLICIT: + triggered_implicits += 1 + GUIDETrigger.GUIDETriggerType.BLOCKING: + triggered_blocked += 1 + + # we only care about the nuances of explicit triggers. implicits and blocking + # can only really return yes or no, so they have no nuance + if trigger_type == GUIDETrigger.GUIDETriggerType.EXPLICIT: + # Higher value results take precedence over lower value results + result = max(result, trigger_result) + + # final collection + if triggered_blocked > 0: + # some blocker triggered which means that this cannot succeed + _state = GUIDETrigger.GUIDETriggerState.NONE + return + + if triggered_implicits < _implicit_count: + # not all implicits triggered, which also fails this binding + _state = GUIDETrigger.GUIDETriggerState.NONE + return + + if _explicit_count == 0 and _implicit_count > 0: + # if no explicits exist, its enough when all implicits trigger + _state = GUIDETrigger.GUIDETriggerState.TRIGGERED + return + + # return the best result + _state = result + + diff --git a/addons/guide/guide_input_mapping.gd.uid b/addons/guide/guide_input_mapping.gd.uid new file mode 100644 index 0000000..647d216 --- /dev/null +++ b/addons/guide/guide_input_mapping.gd.uid @@ -0,0 +1 @@ +uid://mtx1unc2aqn7 diff --git a/addons/guide/guide_input_tracker.gd b/addons/guide/guide_input_tracker.gd new file mode 100644 index 0000000..6dd7ef1 --- /dev/null +++ b/addons/guide/guide_input_tracker.gd @@ -0,0 +1,26 @@ +## Tracker that tracks input for a window and injects it into GUIDE. +## Will automatically keep track of sub-windows. +extends Node + +## Instruments a sub-window so it forwards input events to GUIDE. +static func _instrument(viewport:Viewport): + if viewport.has_meta("x-guide-instrumented"): + return + + var tracker = preload("guide_input_tracker.gd").new() + tracker.process_mode = Node.PROCESS_MODE_ALWAYS + viewport.add_child(tracker, false, Node.INTERNAL_MODE_BACK) + viewport.gui_focus_changed.connect(tracker._control_focused) + +## Catches unhandled input and forwards it to GUIDE +func _unhandled_input(event:InputEvent): + GUIDE.inject_input(event) + +## Some ... creative code ... to catch events from popup windows +## that are spawned by Godot's control nodes. +func _control_focused(control:Control): + if control is OptionButton or control is ColorPickerButton \ + or control is MenuButton or control is TabContainer: + _instrument(control.get_popup()) + + diff --git a/addons/guide/guide_input_tracker.gd.uid b/addons/guide/guide_input_tracker.gd.uid new file mode 100644 index 0000000..e8cd90d --- /dev/null +++ b/addons/guide/guide_input_tracker.gd.uid @@ -0,0 +1 @@ +uid://d2elu0augsms diff --git a/addons/guide/guide_internal.svg b/addons/guide/guide_internal.svg new file mode 100644 index 0000000..78d42de --- /dev/null +++ b/addons/guide/guide_internal.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/addons/guide/guide_internal.svg.import b/addons/guide/guide_internal.svg.import new file mode 100644 index 0000000..f235301 --- /dev/null +++ b/addons/guide/guide_internal.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ddkj7kntb4fit" +path="res://.godot/imported/guide_internal.svg-560a143a1e289215e72d8844f5173844.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/guide_internal.svg" +dest_files=["res://.godot/imported/guide_internal.svg-560a143a1e289215e72d8844f5173844.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=0.5 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/guide_mapping_context.gd b/addons/guide/guide_mapping_context.gd new file mode 100644 index 0000000..097205b --- /dev/null +++ b/addons/guide/guide_mapping_context.gd @@ -0,0 +1,30 @@ +@tool +@icon("res://addons/guide/guide_mapping_context.svg") +class_name GUIDEMappingContext +extends Resource + +const GUIDESet = preload("guide_set.gd") + +## The display name for this mapping context during action remapping +@export var display_name:String: + set(value): + if value == display_name: + return + display_name = value + emit_changed() + +## The mappings. Do yourself a favour and use the G.U.I.D.E panel +## to edit these. +@export var mappings:Array[GUIDEActionMapping] = []: + set(value): + if value == mappings: + return + mappings = value + emit_changed() + + +func _editor_name() -> String: + if display_name.is_empty(): + return resource_path.get_file() + else: + return display_name diff --git a/addons/guide/guide_mapping_context.gd.uid b/addons/guide/guide_mapping_context.gd.uid new file mode 100644 index 0000000..8b58985 --- /dev/null +++ b/addons/guide/guide_mapping_context.gd.uid @@ -0,0 +1 @@ +uid://dsa1dnifd6w32 diff --git a/addons/guide/guide_mapping_context.svg b/addons/guide/guide_mapping_context.svg new file mode 100644 index 0000000..eaa1abf --- /dev/null +++ b/addons/guide/guide_mapping_context.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/addons/guide/guide_mapping_context.svg.import b/addons/guide/guide_mapping_context.svg.import new file mode 100644 index 0000000..6f740b7 --- /dev/null +++ b/addons/guide/guide_mapping_context.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bcwpqc8016n7b" +path="res://.godot/imported/guide_mapping_context.svg-025f10fbbdb2bb11a96754ab9b725bea.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/guide_mapping_context.svg" +dest_files=["res://.godot/imported/guide_mapping_context.svg-025f10fbbdb2bb11a96754ab9b725bea.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=0.5 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/guide_reset.gd b/addons/guide/guide_reset.gd new file mode 100644 index 0000000..de09896 --- /dev/null +++ b/addons/guide/guide_reset.gd @@ -0,0 +1,15 @@ +extends Node + + +var _inputs_to_reset:Array[GUIDEInput] = [] + +func _enter_tree() -> void: + # this should run at the end of the frame, so we put in a low priority (= high number) + process_priority = 10000000 + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + for input:GUIDEInput in _inputs_to_reset: + input._reset() + + GUIDE._input_state._reset() diff --git a/addons/guide/guide_reset.gd.uid b/addons/guide/guide_reset.gd.uid new file mode 100644 index 0000000..62ba7f9 --- /dev/null +++ b/addons/guide/guide_reset.gd.uid @@ -0,0 +1 @@ +uid://cgr8gmw4k8j5x diff --git a/addons/guide/guide_set.gd b/addons/guide/guide_set.gd new file mode 100644 index 0000000..d439c91 --- /dev/null +++ b/addons/guide/guide_set.gd @@ -0,0 +1,40 @@ +## Helper class for modelling sets +var _values:Dictionary = {} + +func add(value:Variant) -> void: + _values[value] = value + + +func remove(value:Variant) -> void: + _values.erase(value) + + +func clear() -> void: + _values.clear() + +func is_empty() -> bool: + return _values.is_empty() + + +func pull() -> Variant: + if is_empty(): + return null + + var key = _values.keys()[0] + remove(key) + return key + + +func has(value:Variant) -> bool: + return _values.has(value) + +## Returns the first item for which the given matcher function returns +## a true value. +func first_match(matcher:Callable) -> Variant: + for key in _values.keys(): + if matcher.call(key): + return key + return null + +func values() -> Array: + return _values.keys() diff --git a/addons/guide/guide_set.gd.uid b/addons/guide/guide_set.gd.uid new file mode 100644 index 0000000..3c66856 --- /dev/null +++ b/addons/guide/guide_set.gd.uid @@ -0,0 +1 @@ +uid://ctvyc3kv17qad diff --git a/addons/guide/inputs/guide_input.gd b/addons/guide/inputs/guide_input.gd new file mode 100644 index 0000000..49877cc --- /dev/null +++ b/addons/guide/inputs/guide_input.gd @@ -0,0 +1,49 @@ +@tool +@icon("res://addons/guide/inputs/guide_input.svg") +## A class representing some actuated input. +class_name GUIDEInput +extends Resource + +## The current valueo f this input. Depending on the input type only parts of the +## returned vector may be relevant. +var _value:Vector3 = Vector3.ZERO + +## The current input state. This will be set by GUIDE when the input is used. +var _state:GUIDEInputState = null + +## Whether this input needs a reset per frame. _input is only called when +## there is input happening, but some GUIDE inputs may need to be reset +## in the absence of input. +func _needs_reset() -> bool: + return false + +## Resets the input value to the default value. Is called once per frame if +## _needs_reset returns true. +func _reset() -> void: + _value = Vector3.ZERO + +## Returns whether this input is the same input as the other input. +func is_same_as(other:GUIDEInput) -> bool: + return false + +## Called when the input is started to be used by GUIDE. Can be used to perform +## initializations. The state object can be used to subscribe to input events +## and to get the current input state. +func _begin_usage() -> void : + pass + +## Called, when the input is no longer used by GUIDE. Can be used to perform +## cleanup. +func _end_usage() -> void: + pass + + +func _editor_name() -> String: + return "" + +func _editor_description() -> String: + return "" + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return -1 diff --git a/addons/guide/inputs/guide_input.gd.uid b/addons/guide/inputs/guide_input.gd.uid new file mode 100644 index 0000000..b40cfd9 --- /dev/null +++ b/addons/guide/inputs/guide_input.gd.uid @@ -0,0 +1 @@ +uid://ccvqqvfooyvn0 diff --git a/addons/guide/inputs/guide_input.svg b/addons/guide/inputs/guide_input.svg new file mode 100644 index 0000000..7e2314f --- /dev/null +++ b/addons/guide/inputs/guide_input.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/addons/guide/inputs/guide_input.svg.import b/addons/guide/inputs/guide_input.svg.import new file mode 100644 index 0000000..458a207 --- /dev/null +++ b/addons/guide/inputs/guide_input.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://oku7f5t0ox3r" +path="res://.godot/imported/guide_input.svg-d7e8ae255db039e6a02cccc3f844cc0e.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/inputs/guide_input.svg" +dest_files=["res://.godot/imported/guide_input.svg-d7e8ae255db039e6a02cccc3f844cc0e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=0.5 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/inputs/guide_input_action.gd b/addons/guide/inputs/guide_input_action.gd new file mode 100644 index 0000000..3c677a0 --- /dev/null +++ b/addons/guide/inputs/guide_input_action.gd @@ -0,0 +1,59 @@ +## An input that mirrors the action's value while the action is triggered. +@tool +class_name GUIDEInputAction +extends GUIDEInput + +## The action that this input should mirror. This is live tracked, so any change in +## the action will update the input. +@export var action:GUIDEAction: + set(value): + if value == action: + return + action = value + emit_changed() + +func _begin_usage(): + if is_instance_valid(action): + action.triggered.connect(_on) + action.completed.connect(_off) + action.ongoing.connect(_off) + if action.is_triggered(): + _on() + return + # not triggered or no action. + _off() + + +func _end_usage(): + if is_instance_valid(action): + action.triggered.disconnect(_on) + action.completed.disconnect(_off) + action.ongoing.disconnect(_off) + + +func _on() -> void: + # on is only called when the action is actually existing, so this is + # always not-null here + _value = action.value_axis_3d + +func _off() -> void: + _value = Vector3.ZERO + + +func is_same_as(other:GUIDEInput) -> bool: + return other is GUIDEInputAction and other.action == action + + +func _to_string(): + return "(GUIDEInputAction: " + str(action) + ")" + +func _editor_name() -> String: + return "Action" + + +func _editor_description() -> String: + return "An input that mirrors the action's value while the action is triggered." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_3D diff --git a/addons/guide/inputs/guide_input_action.gd.uid b/addons/guide/inputs/guide_input_action.gd.uid new file mode 100644 index 0000000..279176d --- /dev/null +++ b/addons/guide/inputs/guide_input_action.gd.uid @@ -0,0 +1 @@ +uid://mc0mxjvhanrx diff --git a/addons/guide/inputs/guide_input_any.gd b/addons/guide/inputs/guide_input_any.gd new file mode 100644 index 0000000..fed74ee --- /dev/null +++ b/addons/guide/inputs/guide_input_any.gd @@ -0,0 +1,150 @@ +## Input that triggers if any input from the given device class +## is given. +@tool +class_name GUIDEInputAny +extends GUIDEInput + + +## Should input from mouse buttons be considered? Deprecated, use +## mouse_buttons instead. +## @deprecated +var mouse:bool: + get: return mouse_buttons + set(value): mouse_buttons = value + +## Should input from joy buttons be considered. Deprecated, use +## joy_buttons instead. +## @deprecated +var joy:bool: + get: return joy_buttons + set(value): joy_buttons = value + +## Should input from mouse buttons be considered? +@export var mouse_buttons:bool = false + +## Should input from mouse movement be considered? +@export var mouse_movement:bool = false + +## Minimum movement distance of the mouse before it is considered +## moving. +@export var minimum_mouse_movement_distance:float = 1.0 + +## Should input from gamepad/joystick buttons be considered? +@export var joy_buttons:bool = false + +## Should input from gamepad/joystick axes be considered? +@export var joy_axes:bool = false + +## Minimum strength of a single joy axis actuation before it is considered +## as actuated. +@export var minimum_joy_axis_actuation_strength:float = 0.2 + +## Should input from the keyboard be considered? +@export var keyboard:bool = false + +## Should input from touch be considered? +@export var touch:bool = false + + +func _needs_reset() -> bool: + # Needs reset because we cannot detect the absence of input. + return true + +func _begin_usage() -> void: + # subscribe to relevant input events + if mouse_movement: + _state.mouse_position_changed.connect(_refresh) + if mouse_buttons: + _state.mouse_button_state_changed.connect(_refresh) + if keyboard: + _state.keyboard_state_changed.connect(_refresh) + if joy_buttons: + _state.joy_button_state_changed.connect(_refresh) + if joy_axes: + _state.joy_axis_state_changed.connect(_refresh) + if touch: + _state.touch_state_changed.connect(_refresh) + + _refresh() + +func _end_usage() -> void: + # unsubscribe from input events + if mouse_movement: + _state.mouse_position_changed.disconnect(_refresh) + if mouse_buttons: + _state.mouse_button_state_changed.disconnect(_refresh) + if keyboard: + _state.keyboard_state_changed.disconnect(_refresh) + if joy_buttons: + _state.joy_button_state_changed.disconnect(_refresh) + if joy_axes: + _state.joy_axis_state_changed.disconnect(_refresh) + if touch: + _state.touch_state_changed.disconnect(_refresh) + +func _refresh() -> void: + # if the input was already actuated this frame, remain + # actuated, even if more input events come in. Input will + # reset at the end of the frame. + if not _value.is_zero_approx(): + return + + if keyboard and _state.is_any_key_pressed(): + _value = Vector3.RIGHT + return + + if mouse_buttons and _state.is_any_mouse_button_pressed(): + _value = Vector3.RIGHT + return + + if mouse_movement and _state.get_mouse_delta_since_last_frame().length() >= minimum_mouse_movement_distance: + _value = Vector3.RIGHT + return + + if joy_buttons and _state.is_any_joy_button_pressed(): + _value = Vector3.RIGHT + return + + if joy_axes and _state.is_any_joy_axis_actuated(minimum_joy_axis_actuation_strength): + _value = Vector3.RIGHT + return + + if touch and _state.is_any_finger_down(): + _value = Vector3.RIGHT + return + + _value = Vector3.ZERO + + +func is_same_as(other:GUIDEInput) -> bool: + return other is GUIDEInputAny and \ + other.mouse == mouse and \ + other.joy == joy and \ + other.keyboard == keyboard + +func _editor_name() -> String: + return "Any Input" + + +func _editor_description() -> String: + return "Input that triggers if any input from the given device class is given." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.BOOL + +# support for legacy properties +func _get_property_list(): + return [ + { + "name": "mouse", + "type": TYPE_BOOL, + "usage": PROPERTY_USAGE_NO_EDITOR + }, + { + "name": "joy", + "type": TYPE_BOOL, + "usage": PROPERTY_USAGE_NO_EDITOR + } + ] + diff --git a/addons/guide/inputs/guide_input_any.gd.uid b/addons/guide/inputs/guide_input_any.gd.uid new file mode 100644 index 0000000..8842c0e --- /dev/null +++ b/addons/guide/inputs/guide_input_any.gd.uid @@ -0,0 +1 @@ +uid://w3fbpe7r01n8 diff --git a/addons/guide/inputs/guide_input_joy_axis_1d.gd b/addons/guide/inputs/guide_input_joy_axis_1d.gd new file mode 100644 index 0000000..16ff7fc --- /dev/null +++ b/addons/guide/inputs/guide_input_joy_axis_1d.gd @@ -0,0 +1,40 @@ +## Input from a single joy axis. +@tool +class_name GUIDEInputJoyAxis1D +extends GUIDEInputJoyBase + +## The joy axis to sample +@export var axis:JoyAxis = JOY_AXIS_LEFT_X: + set(value): + if value == axis: + return + axis = value + emit_changed() + +func _begin_usage() -> void: + _state.joy_axis_state_changed.connect(_refresh) + +func _end_usage() -> void: + _state.joy_axis_state_changed.disconnect(_refresh) + +func _refresh() -> void: + _value.x = _state.get_joy_axis_value(joy_index, axis) + + +func is_same_as(other:GUIDEInput) -> bool: + return other is GUIDEInputJoyAxis1D and \ + other.axis == axis and \ + other.joy_index == joy_index + +func _to_string(): + return "(GUIDEInputJoyAxis1D: axis=" + str(axis) + ", joy_index=" + str(joy_index) + ")" + +func _editor_name() -> String: + return "Joy Axis 1D" + +func _editor_description() -> String: + return "The input from a single joy axis." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_1D diff --git a/addons/guide/inputs/guide_input_joy_axis_1d.gd.uid b/addons/guide/inputs/guide_input_joy_axis_1d.gd.uid new file mode 100644 index 0000000..60f719e --- /dev/null +++ b/addons/guide/inputs/guide_input_joy_axis_1d.gd.uid @@ -0,0 +1 @@ +uid://bbhoxsiqwo07l diff --git a/addons/guide/inputs/guide_input_joy_axis_2d.gd b/addons/guide/inputs/guide_input_joy_axis_2d.gd new file mode 100644 index 0000000..c8b0099 --- /dev/null +++ b/addons/guide/inputs/guide_input_joy_axis_2d.gd @@ -0,0 +1,53 @@ +## Input from two joy axes. +class_name GUIDEInputJoyAxis2D +extends GUIDEInputJoyBase + +## The joy axis to sample for x input. +@export var x:JoyAxis = JOY_AXIS_LEFT_X: + set(value): + if value == x: + return + x = value + emit_changed() + + +## The joy axis to sample for y input. +@export var y:JoyAxis = JOY_AXIS_LEFT_Y: + set(value): + if value == y: + return + y = value + emit_changed() + +func _begin_usage() -> void: + _state.joy_axis_state_changed.connect(_refresh) + _refresh() + +func _end_usage() -> void: + _state.joy_axis_state_changed.disconnect(_refresh) + + +func _refresh(): + _value.x = _state.get_joy_axis_value(joy_index, x) + _value.y = _state.get_joy_axis_value(joy_index, y) + + +func is_same_as(other:GUIDEInput) -> bool: + return other is GUIDEInputJoyAxis2D and \ + other.x == x and \ + other.y == y and \ + other.joy_index == joy_index + +func _to_string(): + return "(GUIDEInputJoyAxis2D: x=" + str(x) + ", y=" + str(y) + ", joy_index=" + str(joy_index) + ")" + + +func _editor_name() -> String: + return "Joy Axis 2D" + +func _editor_description() -> String: + return "The input from two Joy axes. Usually from a stick." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_2D diff --git a/addons/guide/inputs/guide_input_joy_axis_2d.gd.uid b/addons/guide/inputs/guide_input_joy_axis_2d.gd.uid new file mode 100644 index 0000000..e88d711 --- /dev/null +++ b/addons/guide/inputs/guide_input_joy_axis_2d.gd.uid @@ -0,0 +1 @@ +uid://doauobik3xyea diff --git a/addons/guide/inputs/guide_input_joy_base.gd b/addons/guide/inputs/guide_input_joy_base.gd new file mode 100644 index 0000000..5f1eddc --- /dev/null +++ b/addons/guide/inputs/guide_input_joy_base.gd @@ -0,0 +1,13 @@ +## Base class for joystick inputs. +@tool +class_name GUIDEInputJoyBase +extends GUIDEInput + +## The index of the connected joy pad to check. If -1 checks all joypads. +@export var joy_index:int = -1: + set(value): + if value == joy_index: + return + joy_index = value + emit_changed() + diff --git a/addons/guide/inputs/guide_input_joy_base.gd.uid b/addons/guide/inputs/guide_input_joy_base.gd.uid new file mode 100644 index 0000000..e66454d --- /dev/null +++ b/addons/guide/inputs/guide_input_joy_base.gd.uid @@ -0,0 +1 @@ +uid://cnqnbdsw3lw12 diff --git a/addons/guide/inputs/guide_input_joy_button.gd b/addons/guide/inputs/guide_input_joy_button.gd new file mode 100644 index 0000000..c74a9d6 --- /dev/null +++ b/addons/guide/inputs/guide_input_joy_button.gd @@ -0,0 +1,41 @@ +@tool +class_name GUIDEInputJoyButton +extends GUIDEInputJoyBase + +@export var button:JoyButton = JOY_BUTTON_A: + set(value): + if value == button: + return + button = value + emit_changed() + +func _begin_usage() -> void: + _state.joy_button_state_changed.connect(_refresh) + _refresh() + +func _end_usage() -> void: + _state.joy_button_state_changed.disconnect(_refresh) + +func _refresh(): + _value.x = 1.0 if _state.is_joy_button_pressed(joy_index, button) else 0.0 + + +func is_same_as(other:GUIDEInput) -> bool: + return other is GUIDEInputJoyButton and \ + other.button == button and \ + other.joy_index == joy_index + + +func _to_string(): + return "(GUIDEInputJoyButton: button=" + str(button) + ", joy_index=" + str(joy_index) + ")" + + +func _editor_name() -> String: + return "Joy Button" + +func _editor_description() -> String: + return "A button press from a joy button." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.BOOL diff --git a/addons/guide/inputs/guide_input_joy_button.gd.uid b/addons/guide/inputs/guide_input_joy_button.gd.uid new file mode 100644 index 0000000..b52b7fe --- /dev/null +++ b/addons/guide/inputs/guide_input_joy_button.gd.uid @@ -0,0 +1 @@ +uid://rvttn472ix6v diff --git a/addons/guide/inputs/guide_input_key.gd b/addons/guide/inputs/guide_input_key.gd new file mode 100644 index 0000000..36d73e5 --- /dev/null +++ b/addons/guide/inputs/guide_input_key.gd @@ -0,0 +1,126 @@ +@tool +class_name GUIDEInputKey +extends GUIDEInput + +## The physical keycode of the key. +@export var key:Key: + set(value): + if value == key: + return + key = value + emit_changed() + + +@export_group("Modifiers") +## Whether shift must be pressed. +@export var shift:bool = false: + set(value): + if value == shift: + return + shift = value + emit_changed() + +## Whether control must be pressed. +@export var control:bool = false: + set(value): + if value == control: + return + control = value + emit_changed() + +## Whether alt must be pressed. +@export var alt:bool = false: + set(value): + if value == alt: + return + alt = value + emit_changed() + + +## Whether meta/win/cmd must be pressed. +@export var meta:bool = false: + set(value): + if value == meta: + return + meta = value + emit_changed() + +## Whether this input should fire if additional +## modifier keys are currently pressed. +@export var allow_additional_modifiers:bool = true: + set(value): + if value == allow_additional_modifiers: + return + allow_additional_modifiers = value + emit_changed() + +## Helper array. All keys that must be pressed for this input to considered actuated. +var _must_be_pressed:Array[Key] = [] +## Helper array. All keys that must not be pressed for this input to considered actuated. +var _must_not_be_pressed:Array[Key] = [] + +func _begin_usage() -> void: + _must_be_pressed = [key] + + # also add the modifiers to the list of keys that must be pressed + if shift: + _must_be_pressed.append(KEY_SHIFT) + if control: + _must_be_pressed.append(KEY_CTRL) + if alt: + _must_be_pressed.append(KEY_ALT) + if meta: + _must_be_pressed.append(KEY_META) + + _must_not_be_pressed = [] + # now unless additional modifiers are allowed, add all modifiers + # that are not required to the list of keys that must not be pressed + # except if the bound key is actually the modifier itself + if not allow_additional_modifiers: + if not shift and key != KEY_SHIFT: + _must_not_be_pressed.append(KEY_SHIFT) + if not control and key != KEY_CTRL: + _must_not_be_pressed.append(KEY_CTRL) + if not alt and key != KEY_ALT: + _must_not_be_pressed.append(KEY_ALT) + if not meta and key != KEY_META: + _must_not_be_pressed.append(KEY_META) + + # subscribe to input events + _state.keyboard_state_changed.connect(_refresh) + _refresh() + +func _end_usage() -> void: + # unsubscribe from input events + _state.keyboard_state_changed.disconnect(_refresh) + + +func _refresh(): + # We are actuated if all keys that must be pressed are pressed and none of the keys that must not be pressed + # are pressed. + var is_actuated:bool = _state.are_all_keys_pressed(_must_be_pressed) and not _state.is_at_least_one_key_pressed(_must_not_be_pressed) + _value.x = 1.0 if is_actuated else 0.0 + + +func is_same_as(other:GUIDEInput) -> bool: + return other is GUIDEInputKey \ + and other.key == key \ + and other.shift == shift \ + and other.control == control \ + and other.alt == alt \ + and other.meta == meta \ + and other.allow_additional_modifiers == allow_additional_modifiers + +func _to_string(): + return "(GUIDEInputKey: key=" + str(key) + ", shift=" + str(shift) + ", alt=" + str(alt) + ", control=" + str(control) + ", meta="+ str(meta) + ")" + + +func _editor_name() -> String: + return "Key" + +func _editor_description() -> String: + return "A button press on the keyboard." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.BOOL diff --git a/addons/guide/inputs/guide_input_key.gd.uid b/addons/guide/inputs/guide_input_key.gd.uid new file mode 100644 index 0000000..584ef99 --- /dev/null +++ b/addons/guide/inputs/guide_input_key.gd.uid @@ -0,0 +1 @@ +uid://cw71o87tvdx3q diff --git a/addons/guide/inputs/guide_input_mouse_axis_1d.gd b/addons/guide/inputs/guide_input_mouse_axis_1d.gd new file mode 100644 index 0000000..cd437d7 --- /dev/null +++ b/addons/guide/inputs/guide_input_mouse_axis_1d.gd @@ -0,0 +1,57 @@ +@tool +class_name GUIDEInputMouseAxis1D +extends GUIDEInput + +enum GUIDEInputMouseAxis { + X, + Y +} + +@export var axis:GUIDEInputMouseAxis: + set(value): + if value == axis: + return + axis = value + emit_changed() + +# we don't get mouse updates when the mouse is not moving, so this needs to be +# reset every frame +func _needs_reset() -> bool: + return true + + +func _begin_usage() -> void: + # subscribe to mouse movement events + _state.mouse_position_changed.connect(_refresh) + _refresh() + +func _end_usage() -> void: + # unsubscribe from mouse movement events + _state.mouse_position_changed.disconnect(_refresh) + +func _refresh() -> void: + var delta:Vector2 = _state.get_mouse_delta_since_last_frame() + match axis: + GUIDEInputMouseAxis.X: + _value.x = delta.x + GUIDEInputMouseAxis.Y: + _value.x = delta.y + + +func is_same_as(other:GUIDEInput): + return other is GUIDEInputMouseAxis1D and other.axis == axis + +func _to_string(): + return "(GUIDEInputMouseAxis1D: axis=" + str(axis) + ")" + + +func _editor_name() -> String: + return "Mouse Axis 1D" + + +func _editor_description() -> String: + return "Relative mouse movement on a single axis." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_1D diff --git a/addons/guide/inputs/guide_input_mouse_axis_1d.gd.uid b/addons/guide/inputs/guide_input_mouse_axis_1d.gd.uid new file mode 100644 index 0000000..8dd27d8 --- /dev/null +++ b/addons/guide/inputs/guide_input_mouse_axis_1d.gd.uid @@ -0,0 +1 @@ +uid://b6bwb7ie85kl1 diff --git a/addons/guide/inputs/guide_input_mouse_axis_2d.gd b/addons/guide/inputs/guide_input_mouse_axis_2d.gd new file mode 100644 index 0000000..718ebf4 --- /dev/null +++ b/addons/guide/inputs/guide_input_mouse_axis_2d.gd @@ -0,0 +1,42 @@ +@tool +class_name GUIDEInputMouseAxis2D +extends GUIDEInput + + +# we don't get mouse updates when the mouse is not moving, so this needs to be +# reset every frame +func _needs_reset() -> bool: + return true + +func _begin_usage() -> void: + # subscribe to mouse movement events + _state.mouse_position_changed.connect(_refresh) + _refresh() + +func _end_usage() -> void: + # unsubscribe from mouse movement events + _state.mouse_position_changed.disconnect(_refresh) + +func _refresh() -> void: + var delta:Vector2 = _state.get_mouse_delta_since_last_frame() + _value.x = delta.x + _value.y = delta.y + +func is_same_as(other:GUIDEInput): + return other is GUIDEInputMouseAxis2D + + +func _to_string(): + return "(GUIDEInputMouseAxis2D)" + + +func _editor_name() -> String: + return "Mouse Axis 2D" + + +func _editor_description() -> String: + return "Relative mouse movement on 2 axes." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_2D diff --git a/addons/guide/inputs/guide_input_mouse_axis_2d.gd.uid b/addons/guide/inputs/guide_input_mouse_axis_2d.gd.uid new file mode 100644 index 0000000..0ef3f26 --- /dev/null +++ b/addons/guide/inputs/guide_input_mouse_axis_2d.gd.uid @@ -0,0 +1 @@ +uid://dh0hf08e0yit5 diff --git a/addons/guide/inputs/guide_input_mouse_button.gd b/addons/guide/inputs/guide_input_mouse_button.gd new file mode 100644 index 0000000..9fe0540 --- /dev/null +++ b/addons/guide/inputs/guide_input_mouse_button.gd @@ -0,0 +1,74 @@ +@tool +class_name GUIDEInputMouseButton +extends GUIDEInput + +@export var button: MouseButton = MOUSE_BUTTON_LEFT: + set(value): + if value == button: + return + button = value + emit_changed() + +# The value that this input will be reset to at the end of the frame. +var _reset_to: Vector3 +var _was_pressed_this_frame: bool + + +func _needs_reset() -> bool: + # mouse wheel up and down can potentially send multiple inputs within a single frame + # so we need to smooth this out a bit. + return button == MOUSE_BUTTON_WHEEL_UP or button == MOUSE_BUTTON_WHEEL_DOWN + + +func _reset() -> void: + _was_pressed_this_frame = false + _value = _reset_to + + +func _begin_usage() -> void: + # subscribe to mouse button events + _state.mouse_button_state_changed.connect(_refresh) + _refresh() + + +func _end_usage() -> void: + # unsubscribe from mouse button events + _state.mouse_button_state_changed.disconnect(_refresh) + + +func _refresh() -> void: + var is_pressed: bool = _state.is_mouse_button_pressed(button) + + if _needs_reset(): + # we always reset to the last event we received in a frame + # so after the frame is over we're still in sync. + _reset_to.x = 1.0 if is_pressed else 0.0 + + if is_pressed: + _was_pressed_this_frame = true + + if not is_pressed and _was_pressed_this_frame: + # keep pressed state for this frame + return + + _value.x = 1.0 if is_pressed else 0.0 + + +func is_same_as(other: GUIDEInput) -> bool: + return other is GUIDEInputMouseButton and other.button == button + + +func _to_string(): + return "(GUIDEInputMouseButton: button=" + str(button) + ")" + + +func _editor_name() -> String: + return "Mouse Button" + + +func _editor_description() -> String: + return "A press of a mouse button. The mouse wheel is also a button." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.BOOL diff --git a/addons/guide/inputs/guide_input_mouse_button.gd.uid b/addons/guide/inputs/guide_input_mouse_button.gd.uid new file mode 100644 index 0000000..f21212d --- /dev/null +++ b/addons/guide/inputs/guide_input_mouse_button.gd.uid @@ -0,0 +1 @@ +uid://vgjlx6p007lp diff --git a/addons/guide/inputs/guide_input_mouse_position.gd b/addons/guide/inputs/guide_input_mouse_position.gd new file mode 100644 index 0000000..8b21d61 --- /dev/null +++ b/addons/guide/inputs/guide_input_mouse_position.gd @@ -0,0 +1,39 @@ +@tool +class_name GUIDEInputMousePosition +extends GUIDEInput + + +func _begin_usage() -> void : + # subscribe to mouse movement events + _state.mouse_position_changed.connect(_refresh) + _refresh() + +func _end_usage() -> void: + # unsubscribe from mouse movement events + _state.mouse_position_changed.disconnect(_refresh) + +func _refresh(): + var position:Vector2 = _state.get_mouse_position() + + _value.x = position.x + _value.y = position.y + + +func is_same_as(other:GUIDEInput): + return other is GUIDEInputMousePosition + + +func _to_string(): + return "(GUIDEInputMousePosition)" + + +func _editor_name() -> String: + return "Mouse Position" + + +func _editor_description() -> String: + return "Position of the mouse in the main viewport." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_2D diff --git a/addons/guide/inputs/guide_input_mouse_position.gd.uid b/addons/guide/inputs/guide_input_mouse_position.gd.uid new file mode 100644 index 0000000..d03116b --- /dev/null +++ b/addons/guide/inputs/guide_input_mouse_position.gd.uid @@ -0,0 +1 @@ +uid://deeru16npi81q diff --git a/addons/guide/inputs/guide_input_state.gd b/addons/guide/inputs/guide_input_state.gd new file mode 100644 index 0000000..7b6ba6a --- /dev/null +++ b/addons/guide/inputs/guide_input_state.gd @@ -0,0 +1,327 @@ +## The GUIDEInputState holds the current state of all input. It is basically a wrapper around Godot's Input +## class that provides some additional functionality like getting the information if any key or mouse button +## is currently pressed. It also is the single entry point for all input events from Godot, so we don't have +## process them in every GUIDEInput object and duplicate input handling code everywere. This also improves performance. +## +class_name GUIDEInputState + +## Device ID for a virtual joystick that means "any joystick". +## This relies on the fact that Godot's device IDs for joysticks are always >= 0. +## https://github.com/godotengine/godot/blob/80a3d205f1ad22e779a64921fb56d62b893881ae/core/input/input.cpp#L1821 +const ANY_JOY_DEVICE_ID: int = -1 + +## Signalled, when the keyboard state has changed. +signal keyboard_state_changed() +## Signalled, when the mouse motion state has changed. +signal mouse_position_changed() +## Signalled, when the mouse button state has changed. +signal mouse_button_state_changed() +## Signalled, when the joy button state has changed. +signal joy_button_state_changed() +## Signalled, when the joy axis state has changed. +signal joy_axis_state_changed() +## Signalled, when the touch state has changed. +signal touch_state_changed() + +# Keys that are currently pressed. Key is the key index, value is not important. The presence of a key in the dictionary +# indicates that the key is currently pressed. +var _keys: Dictionary = {} +# Fingers that are currently touching the screen. Key is the finger index, value is the position (Vector2). +var _finger_positions: Dictionary = {} +# The mouse movement since the last frame. +var _mouse_movement: Vector2 = Vector2.ZERO +# Mouse buttons that are currently pressed. Key is the button index, value is not important. The presence of a key +# in the dictionary indicates that the button is currently pressed. +var _mouse_buttons: Dictionary = {} +# Joy buttons that are currently pressed. Key is device id, value is a dictionary with the button index as key. The +# value of the inner dictionary is not important. The presence of a key in the inner dictionary indicates that the button +# is currently pressed. +var _joy_buttons: Dictionary = {} +# Current values of joy axes. Key is device id, value is a dictionary with the axis index as key. +# The value of the inner dictionary is the axis value. Once an axis is actuated, it will be added to the dictionary. +# We will not remove it anymore after that. +var _joy_axes: Dictionary = {} + +# The current mapping of joy index to device id. This is used to map the joy index to the device id. A joy index +# if -1 means "any device id". +var _joy_index_to_device_id: Dictionary = {} + +func _init(): + Input.joy_connection_changed.connect(_refresh_joy_device_ids) + _clear() + +# Used by the automated tests to make sure we don't have any leftovers from the +# last test. +func _clear(): + _keys.clear() + _finger_positions.clear() + _mouse_movement = Vector2.ZERO + _mouse_buttons.clear() + _joy_buttons.clear() + _joy_axes.clear() + + _refresh_joy_device_ids(0, 0) + + # ensure we have an entry for the virtual "any device id" + _joy_buttons[ANY_JOY_DEVICE_ID] = {} + _joy_axes[ANY_JOY_DEVICE_ID] = {} + + +# Called when any joy device is connected or disconnected. This will refresh the joy device ids and clear out any +# joy state which is not valid anymore. Will also notify relevant inputs. +func _refresh_joy_device_ids(_ignore1, _ignore2): + # refresh the joy device ids + _joy_index_to_device_id.clear() + var connected_joys:Array[int] = Input.get_connected_joypads() + for i in connected_joys.size(): + var device_id:int = connected_joys[i] + _joy_index_to_device_id[i] = device_id + # ensure we have an inner dictionary for the device id + # by setting this here, we don't need to check for the device id + # on every input event + if not _joy_buttons.has(device_id): + _joy_buttons[device_id] = {} + if not _joy_axes.has(device_id): + _joy_axes[device_id] = {} + + # add a virtual device id for the "any device id" case + _joy_index_to_device_id[-1] = ANY_JOY_DEVICE_ID + + var dirty: bool = false + + # clear out any joy state which is not valid anymore + for device_id in _joy_buttons.keys(): + if device_id != ANY_JOY_DEVICE_ID and not connected_joys.has(device_id): + dirty = true + _joy_buttons.erase(device_id) + + if dirty: + # notify all inputs that the joy state has changed + joy_button_state_changed.emit() + + dirty = false + for device_id in _joy_axes.keys(): + if device_id != ANY_JOY_DEVICE_ID and not connected_joys.has(device_id): + dirty = true + _joy_axes.erase(device_id) + + if dirty: + # notify all inputs that the joy state has changed + joy_axis_state_changed.emit() + +## Called at the end of the frame to reset the state before the next frame. +func _reset() -> void: + _mouse_movement = Vector2.ZERO + + +## Processes an input event and updates the state. +func _input(event: InputEvent) -> void: + # ----------------------- KEYBOARD ----------------------------- + if event is InputEventKey: + var index: int = event.physical_keycode + + if event.pressed: + _keys[index] = true + else: + _keys.erase(index) + + # Emit the keyboard state changed signal + keyboard_state_changed.emit() + return + + # ----------------------- MOUSE MOVEMENT ----------------------- + if event is InputEventMouseMotion: + # Emit the mouse moved signal with the distance moved + _mouse_movement += event.relative + mouse_position_changed.emit() + return + + # ----------------------- MOUSE BUTTONS ----------------------- + if event is InputEventMouseButton: + var index: int = event.button_index + + if event.pressed: + _mouse_buttons[index] = true + else: + _mouse_buttons.erase(index) + + # Emit the mouse button state changed signal + mouse_button_state_changed.emit() + return + + # ----------------------- JOYSTICK BUTTONS ----------------------- + if event is InputEventJoypadButton: + var device_id: int = event.device + var button: int = event.button_index + + if event.pressed: + # _refresh_joy_device_ids ensures we have an inner dictionary for the device id + # so we don't need to check for it here + _joy_buttons[device_id][button] = true + else: + _joy_buttons[device_id].erase(button) + + # finally set the ANY_JOY_DEVICE_ID state based on what we know + var any_value: bool = false + for inner in _joy_buttons.keys(): + if inner != ANY_JOY_DEVICE_ID and _joy_buttons[inner].has(button): + any_value = true + break + + if any_value: + _joy_buttons[ANY_JOY_DEVICE_ID][button] = true + else: + _joy_buttons[ANY_JOY_DEVICE_ID].erase(button) + + # Emit the joy button state changed signal + joy_button_state_changed.emit() + return + + # ----------------------- JOYSTICK AXES ----------------------- + if event is InputEventJoypadMotion: + var device_id: int = event.device + var axis: int = event.axis + + # update the axis value + _joy_axes[device_id][axis] = event.axis_value + + # for the ANY_JOY_DEVICE_ID, we apply the maximum actuation of all devices (in any direction) + var any_value: float = 0.0 + var maximum_actuation: float = 0.0 + for inner in _joy_axes.keys(): + if inner != ANY_JOY_DEVICE_ID and _joy_axes[inner].has(axis): + var strength: float = abs(_joy_axes[inner][axis]) + if strength > maximum_actuation: + maximum_actuation = strength + any_value = _joy_axes[inner][axis] + + _joy_axes[ANY_JOY_DEVICE_ID][axis] = any_value + + # Emit the joy axis state changed signal + joy_axis_state_changed.emit() + return + + # ----------------------- TOUCH INPUT ----------------------- + + if event is InputEventScreenTouch: + if event.pressed: + _finger_positions[event.index] = event.position + else: + _finger_positions.erase(event.index) + + touch_state_changed.emit() + return + + + if event is InputEventScreenDrag: + _finger_positions[event.index] = event.position + + touch_state_changed.emit() + return + + +## Returns true if the key with the given index is currently pressed. +func is_key_pressed(key: Key) -> bool: + return _keys.has(key) + +# Returns true if at least one key in the given array is currently pressed. +func is_at_least_one_key_pressed(keys:Array[Key]) -> bool: + for key in keys: + if _keys.has(key): + return true + return false + +# Returns true if all keys in the given array are currently pressed. +func are_all_keys_pressed(keys:Array[Key]) -> bool: + return _keys.has_all(keys) + +## Returns true if currently any key is pressed. +func is_any_key_pressed() -> bool: + return not _keys.is_empty() + +## Gets the mouse movement since the last frame. +## If no movement has been detected, returns Vector2.ZERO. +func get_mouse_delta_since_last_frame() -> Vector2: + return _mouse_movement + +## Returns the current mouse position in the root viewport. +func get_mouse_position() -> Vector2: + return Engine.get_main_loop().root.get_mouse_position() + + +## Returns true if the mouse button with the given index is currently pressed. +func is_mouse_button_pressed(button_index: MouseButton) -> bool: + return _mouse_buttons.has(button_index) + +## Returns true if currently any mouse button is pressed. +func is_any_mouse_button_pressed() -> bool: + return not _mouse_buttons.is_empty() + +## Returns the current value of the given joy axis on the device with the given index. If no +## such device or axis exists, returns 0.0. +func get_joy_axis_value(index:int, axis:JoyAxis) -> float: + var device_id: int = _joy_index_to_device_id.get(index, -9999) + # unknown device + if device_id == -9999: + return 0.0 + if _joy_axes.has(device_id): + var inner = _joy_axes[device_id] + return inner.get(axis, 0.0) + return 0.0 + +## Returns true, if the given joy button is currentely pressed on the device with the given index. +func is_joy_button_pressed(index:int, button:JoyButton) -> bool: + var device_id: int = _joy_index_to_device_id.get(index, -9999) + # unknown device + if device_id == -9999: + return false + if _joy_buttons.has(device_id): + return _joy_buttons[device_id].has(button) + return false + +## Returns true, if currently any joy button is pressed on any device. +func is_any_joy_button_pressed() -> bool: + for inner in _joy_buttons.values(): + if not inner.is_empty(): + return true + return false + +## Returns true if currently any joy axis is actuated with at least the given strength. +func is_any_joy_axis_actuated(minimum_strength: float) -> bool: + for inner in _joy_axes.values(): + for value in inner.values(): + if abs(value) >= minimum_strength: + return true + return false + +## Gets the finger position of the finger at the given index. +## If finger_index is < 0, returns the average of all finger positions. +## Will only return a position if the amount of fingers +## currently touching matches finger_count. +## +## If no finger position can be determined, returns Vector2.INF. +func get_finger_position(finger_index: int, finger_count: int) -> Vector2: + # if we have no finger positions right now, we can cut it short here + if _finger_positions.is_empty(): + return Vector2.INF + + # If the finger count doesn't match we have no position right now + if _finger_positions.size() != finger_count: + return Vector2.INF + + # if a finger index is set, use this fingers position, if available + if finger_index > -1: + return _finger_positions.get(finger_index, Vector2.INF) + + var result: Vector2 = Vector2.ZERO + for value in _finger_positions.values(): + result += value + + result /= float(finger_count) + return result + +## Returns true, if currently any finger is touching the screen. +func is_any_finger_down() -> bool: + return not _finger_positions.is_empty() + + diff --git a/addons/guide/inputs/guide_input_state.gd.uid b/addons/guide/inputs/guide_input_state.gd.uid new file mode 100644 index 0000000..09e5386 --- /dev/null +++ b/addons/guide/inputs/guide_input_state.gd.uid @@ -0,0 +1 @@ +uid://c11q8ft87iu87 diff --git a/addons/guide/inputs/guide_input_touch_angle.gd b/addons/guide/inputs/guide_input_touch_angle.gd new file mode 100644 index 0000000..dfcbf99 --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_angle.gd @@ -0,0 +1,91 @@ +## Input representing angle changes between two fingers. +@tool +class_name GUIDEInputTouchAngle +extends GUIDEInput + +## Unit in which the angle should be provided +enum AngleUnit { + ## Angle is provided in radians + RADIANS = 0, + ## Angle is provided in degrees. + DEGREES = 1 +} + +## The unit in which the angle should be provided +@export var unit:AngleUnit = AngleUnit.RADIANS + +var _initial_angle:float = INF + +# We use the reset call to calculate the angle for this frame +# so it can serve as reference for the next frame +func _needs_reset() -> bool: + return true + +func _reset(): + var angle = _calculate_angle() + # update initial angle when input is actuated or stops being actuated + if is_finite(_initial_angle) != is_finite(angle): + _initial_angle = angle + +func _begin_usage() -> void: + # subscribe to relevant input events + _state.touch_state_changed.connect(_refresh) + _refresh() + +func _end_usage() -> void: + # unsubscribe from input events + _state.touch_state_changed.disconnect(_refresh) + +func _refresh(): + var angle := _calculate_angle() + # if either current angle or initial angle is not set, + # we are zero + if not is_finite(angle) or not is_finite(_initial_angle): + _value = Vector3.ZERO + return + + # we assume that _initial_distance is never 0 because + # you cannot have two fingers physically at the same place + # on a touch screen (unless you're a ghost, which raises + # the question how you are using a touch screen in the first place) + var final_angle:float = angle - _initial_angle + if unit == AngleUnit.DEGREES: + final_angle = rad_to_deg(final_angle) + + _value = Vector3(final_angle, 0, 0) + + +func _calculate_angle() -> float: + var pos1:Vector2 = _state.get_finger_position(0, 2) + # if we have no position for first finger, we can immediately abort + if not pos1.is_finite(): + return INF + + var pos2:Vector2 = _state.get_finger_position(1, 2) + # if there is no second finger, we can abort as well + if not pos2.is_finite(): + return INF + + # calculate distance for the fingers + return -pos1.angle_to_point(pos2) + + +func is_same_as(other:GUIDEInput): + return other is GUIDEInputTouchAngle and \ + other.unit == unit + + +func _to_string(): + return "(GUIDEInputTouchAngle unit=" + ("radians" if unit == AngleUnit.RADIANS else "degrees") + ")" + + +func _editor_name() -> String: + return "Touch Angle" + + +func _editor_description() -> String: + return "Angle changes of two touching fingers." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_1D diff --git a/addons/guide/inputs/guide_input_touch_angle.gd.uid b/addons/guide/inputs/guide_input_touch_angle.gd.uid new file mode 100644 index 0000000..7599a31 --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_angle.gd.uid @@ -0,0 +1 @@ +uid://b3sxmqknm7ljs diff --git a/addons/guide/inputs/guide_input_touch_axis_1d.gd b/addons/guide/inputs/guide_input_touch_axis_1d.gd new file mode 100644 index 0000000..3615efa --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_axis_1d.gd @@ -0,0 +1,44 @@ +@tool +class_name GUIDEInputTouchAxis1D +extends GUIDEInputTouchAxisBase + +enum GUIDEInputTouchAxis { + X, + Y +} + +@export var axis:GUIDEInputTouchAxis: + set(value): + if value == axis: + return + axis = value + emit_changed() + +func is_same_as(other:GUIDEInput): + return other is GUIDEInputTouchAxis1D and \ + other.finger_count == finger_count and \ + other.finger_index == finger_index and \ + other.axis == axis + +func _apply_value(value:Vector2): + match axis: + GUIDEInputTouchAxis.X: + _value = Vector3(value.x, 0, 0) + GUIDEInputTouchAxis.Y: + _value = Vector3(value.y, 0, 0) + +func _to_string(): + return "(GUIDEInputTouchAxis1D finger_count=" + str(finger_count) + \ + " finger_index=" + str(finger_index) +" axis=" + ("X" if axis == GUIDEInputTouchAxis.X else "Y") + ")" + + +func _editor_name() -> String: + return "Touch Axis1D" + + +func _editor_description() -> String: + return "Relative movement of a touching finger on a single axis." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_1D diff --git a/addons/guide/inputs/guide_input_touch_axis_1d.gd.uid b/addons/guide/inputs/guide_input_touch_axis_1d.gd.uid new file mode 100644 index 0000000..e925cd0 --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_axis_1d.gd.uid @@ -0,0 +1 @@ +uid://idi72xetfe0s diff --git a/addons/guide/inputs/guide_input_touch_axis_2d.gd b/addons/guide/inputs/guide_input_touch_axis_2d.gd new file mode 100644 index 0000000..13b79d7 --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_axis_2d.gd @@ -0,0 +1,27 @@ +@tool +class_name GUIDEInputTouchAxis2D +extends GUIDEInputTouchAxisBase + +func _apply_value(value:Vector2): + _value = Vector3(value.x, value.y, 0) + +func is_same_as(other:GUIDEInput): + return other is GUIDEInputTouchAxis2D and \ + other.finger_count == finger_count and \ + other.finger_index == finger_index + + +func _to_string(): + return "(GUIDEInputTouchAxis2D finger_count=" + str(finger_count) + \ + " finger_index=" + str(finger_index) +")" + + +func _editor_name() -> String: + return "Touch Axis2D" + + +func _editor_description() -> String: + return "2D relative movement of a touching finger." + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_2D diff --git a/addons/guide/inputs/guide_input_touch_axis_2d.gd.uid b/addons/guide/inputs/guide_input_touch_axis_2d.gd.uid new file mode 100644 index 0000000..d3e9254 --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_axis_2d.gd.uid @@ -0,0 +1 @@ +uid://83ggp3br4dqv diff --git a/addons/guide/inputs/guide_input_touch_axis_base.gd b/addons/guide/inputs/guide_input_touch_axis_base.gd new file mode 100644 index 0000000..638abad --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_axis_base.gd @@ -0,0 +1,49 @@ +## Base class for axis-like touch input. +@tool +class_name GUIDEInputTouchAxisBase +extends GUIDEInputTouchBase + +var _last_position:Vector2 = Vector2.INF + +# We use the reset call to calculate the position for this frame +# so it can serve as reference for the next frame +func _needs_reset() -> bool: + return true + +func _reset() -> void: + _last_position = _state.get_finger_position(finger_index, finger_count) + _apply_value(_calculate_value(_last_position)) + +func _begin_usage() -> void: + # subscribe to relevant input events + _state.touch_state_changed.connect(_refresh) + _refresh() + +func _end_usage() -> void: + # unsubscribe from input events + _state.touch_state_changed.disconnect(_refresh) + +func _refresh() -> void: + # calculate live position from the cache + var new_position:Vector2 = _state.get_finger_position(finger_index, finger_count) + + _apply_value(_calculate_value(new_position)) + +func _apply_value(value:Vector2): + pass + +func _calculate_value(new_position:Vector2) -> Vector2: + # if we cannot calculate a delta because old or new position + # are undefined, we say the delta is zero + if not _last_position.is_finite() or not new_position.is_finite(): + return Vector2.ZERO + + return new_position - _last_position + + +func is_same_as(other:GUIDEInput): + return other is GUIDEInputTouchAxis2D and \ + other.finger_count == finger_count and \ + other.finger_index == finger_index + + diff --git a/addons/guide/inputs/guide_input_touch_axis_base.gd.uid b/addons/guide/inputs/guide_input_touch_axis_base.gd.uid new file mode 100644 index 0000000..682ab7b --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_axis_base.gd.uid @@ -0,0 +1 @@ +uid://c32np6tk2l12 diff --git a/addons/guide/inputs/guide_input_touch_base.gd b/addons/guide/inputs/guide_input_touch_base.gd new file mode 100644 index 0000000..7f9aa0b --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_base.gd @@ -0,0 +1,22 @@ +## Base class for generic touch input +@tool +class_name GUIDEInputTouchBase +extends GUIDEInput + +## The number of fingers to be tracked. +@export_range(1, 5, 1, "or_greater") var finger_count:int = 1: + set(value): + if value < 1: + value = 1 + finger_count = value + emit_changed() + +## The index of the finger for which the position/delta should be reported +## (0 = first finger, 1 = second finger, etc.). If -1, reports the average position/delta for +## all fingers currently touching. +@export_range(-1, 4, 1, "or_greater") var finger_index:int = 0: + set(value): + if value < -1: + value = -1 + finger_index = value + emit_changed() diff --git a/addons/guide/inputs/guide_input_touch_base.gd.uid b/addons/guide/inputs/guide_input_touch_base.gd.uid new file mode 100644 index 0000000..05c2aba --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_base.gd.uid @@ -0,0 +1 @@ +uid://dfmq3cijb3ju3 diff --git a/addons/guide/inputs/guide_input_touch_distance.gd b/addons/guide/inputs/guide_input_touch_distance.gd new file mode 100644 index 0000000..c14fb1d --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_distance.gd @@ -0,0 +1,76 @@ +## Input representing the distance changes between two fingers. +@tool +class_name GUIDEInputTouchDistance +extends GUIDEInput + +var _initial_distance:float = INF + +# We use the reset call to calculate the distance for this frame +# so it can serve as reference for the next frame +func _needs_reset() -> bool: + return true + +func _reset(): + var distance = _calculate_distance() + # update initial distance when input is actuated or stops being actuated + if is_finite(_initial_distance) != is_finite(distance): + _initial_distance = distance + + +func _begin_usage() -> void: + # subscribe to relevant input events + _state.touch_state_changed.connect(_refresh) + _refresh() + +func _end_usage() -> void: + # unsubscribe from input events + _state.touch_state_changed.disconnect(_refresh) + + +func _refresh() -> void: + var distance := _calculate_distance() + # if either current distance or initial distance is not set, + # we are zero + if not is_finite(distance) or not is_finite(_initial_distance): + _value = Vector3.ZERO + return + + # we assume that _initial_distance is never 0 because + # you cannot have two fingers physically at the same place + # on a touch screen + _value = Vector3(distance / _initial_distance, 0, 0) + + +func _calculate_distance() -> float: + var pos1:Vector2 = _state.get_finger_position(0, 2) + # if we have no position for first finger, we can immediately abort + if not pos1.is_finite(): + return INF + + var pos2:Vector2 = _state.get_finger_position(1, 2) + # if there is no second finger, we can abort as well + if not pos2.is_finite(): + return INF + + # calculate distance for the fingers + return pos1.distance_to(pos2) + + +func is_same_as(other:GUIDEInput): + return other is GUIDEInputTouchDistance + + +func _to_string(): + return "(GUIDEInputTouchDistance)" + + +func _editor_name() -> String: + return "Touch Distance" + + +func _editor_description() -> String: + return "Distance of two touching fingers." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_1D diff --git a/addons/guide/inputs/guide_input_touch_distance.gd.uid b/addons/guide/inputs/guide_input_touch_distance.gd.uid new file mode 100644 index 0000000..a8b80d6 --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_distance.gd.uid @@ -0,0 +1 @@ +uid://hjbdbq1wud8h diff --git a/addons/guide/inputs/guide_input_touch_position.gd b/addons/guide/inputs/guide_input_touch_position.gd new file mode 100644 index 0000000..5b62e89 --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_position.gd @@ -0,0 +1,45 @@ +@tool +class_name GUIDEInputTouchPosition +extends GUIDEInputTouchBase + + +func _begin_usage(): + # subscribe to touch events + _state.touch_state_changed.connect(_refresh) + _refresh() + +func _end_usage(): + # unsubscribe from touch events + _state.touch_state_changed.disconnect(_refresh) + +func _refresh() -> void: + # update finger position + var position:Vector2 = _state.get_finger_position(finger_index, finger_count) + if not position.is_finite(): + _value = Vector3.INF + return + + _value = Vector3(position.x, position.y, 0) + + +func is_same_as(other:GUIDEInput): + return other is GUIDEInputTouchPosition and \ + other.finger_count == finger_count and \ + other.finger_index == finger_index + + +func _to_string(): + return "(GUIDEInputTouchPosition finger_count=" + str(finger_count) + \ + " finger_index=" + str(finger_index) +")" + + +func _editor_name() -> String: + return "Touch Position" + + +func _editor_description() -> String: + return "Position of a touching finger." + + +func _native_value_type() -> GUIDEAction.GUIDEActionValueType: + return GUIDEAction.GUIDEActionValueType.AXIS_2D diff --git a/addons/guide/inputs/guide_input_touch_position.gd.uid b/addons/guide/inputs/guide_input_touch_position.gd.uid new file mode 100644 index 0000000..2324ae9 --- /dev/null +++ b/addons/guide/inputs/guide_input_touch_position.gd.uid @@ -0,0 +1 @@ +uid://c2bvqibcqlmv5 diff --git a/addons/guide/inputs/guide_touch_state.gd.uid b/addons/guide/inputs/guide_touch_state.gd.uid new file mode 100644 index 0000000..2dd6e7e --- /dev/null +++ b/addons/guide/inputs/guide_touch_state.gd.uid @@ -0,0 +1 @@ +uid://duw4xaip8onca diff --git a/addons/guide/modifiers/guide_modifier.gd b/addons/guide/modifiers/guide_modifier.gd new file mode 100644 index 0000000..6253480 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier.gd @@ -0,0 +1,23 @@ +@tool +@icon("res://addons/guide/modifiers/guide_modifier.svg") +class_name GUIDEModifier +extends Resource + +## Called when the modifier is started to be used by GUIDE. Can be used to perform +## initializations. +func _begin_usage() -> void : + pass + +## Called, when the modifier is no longer used by GUIDE. Can be used to perform +## cleanup. +func _end_usage() -> void: + pass + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + return input + +func _editor_name() -> String: + return "" + +func _editor_description() -> String: + return "" diff --git a/addons/guide/modifiers/guide_modifier.gd.uid b/addons/guide/modifiers/guide_modifier.gd.uid new file mode 100644 index 0000000..97af6a3 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier.gd.uid @@ -0,0 +1 @@ +uid://bl8rjl4oaldje diff --git a/addons/guide/modifiers/guide_modifier.svg b/addons/guide/modifiers/guide_modifier.svg new file mode 100644 index 0000000..e51d736 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/addons/guide/modifiers/guide_modifier.svg.import b/addons/guide/modifiers/guide_modifier.svg.import new file mode 100644 index 0000000..3d85142 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://j64d8n4am2uh" +path="res://.godot/imported/guide_modifier.svg-8cf939ca3244410aba00f7b558561d72.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/modifiers/guide_modifier.svg" +dest_files=["res://.godot/imported/guide_modifier.svg-8cf939ca3244410aba00f7b558561d72.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=0.5 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/modifiers/guide_modifier_3d_coordinates.gd b/addons/guide/modifiers/guide_modifier_3d_coordinates.gd new file mode 100644 index 0000000..21abb90 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_3d_coordinates.gd @@ -0,0 +1,53 @@ +## Converts a position input in viewport coordinates (e.g. from the mouse position input) +## into 3D coordinates (e.g. 3D world coordinates). Useful to get a 3D 'world' position. +## Returns a Vector3.INF if no 3D world coordinates can be determined. +@tool +class_name GUIDEModifier3DCoordinates +extends GUIDEModifier + +## The maximum depth of the ray cast used to detect the 3D position. +@export var max_depth:float = 1000.0 + +## Whether the rays cast should collide with areas. +@export var collide_with_areas:bool = false + +## Collision mask to use for the ray cast. +@export_flags_3d_physics var collision_mask:int + + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + # if we collide with nothing, no need to even try + if collision_mask == 0: + return Vector3.INF + + if not input.is_finite(): + return Vector3.INF + + var viewport = Engine.get_main_loop().root + var camera:Camera3D = viewport.get_camera_3d() + if camera == null: + return Vector3.INF + + + var input_position:Vector2 = Vector2(input.x, input.y) + + var from:Vector3 = camera.project_ray_origin(input_position) + var to:Vector3 = from + camera.project_ray_normal(input_position) * max_depth + var query:= PhysicsRayQueryParameters3D.create(from, to, collision_mask) + query.collide_with_areas = collide_with_areas + + var result = viewport.world_3d.direct_space_state.intersect_ray(query) + if result.has("position"): + return result.position + + return Vector3.INF + + + +func _editor_name() -> String: + return "3D coordinates" + + +func _editor_description() -> String: + return "Converts a position input in viewport coordinates (e.g. from the mouse position input)\n" + \ + "into 3D coordinates (e.g. 3D world coordinates). Useful to get a 3D 'world' position." diff --git a/addons/guide/modifiers/guide_modifier_3d_coordinates.gd.uid b/addons/guide/modifiers/guide_modifier_3d_coordinates.gd.uid new file mode 100644 index 0000000..211fd4a --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_3d_coordinates.gd.uid @@ -0,0 +1 @@ +uid://cw8qjwdktercg diff --git a/addons/guide/modifiers/guide_modifier_8_way_direction.gd b/addons/guide/modifiers/guide_modifier_8_way_direction.gd new file mode 100644 index 0000000..8ae2954 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_8_way_direction.gd @@ -0,0 +1,47 @@ +@tool +## A filter that converts a 2D input into a boolean that is true when the +## input direction matches the selected direction. Note, that north is negative Y, +## because in Godot negative Y is up. +class_name GUIDEModifier8WayDirection +extends GUIDEModifier + +enum GUIDEDirection { + EAST = 0, + NORTH_EAST = 1, + NORTH = 2, + NORTH_WEST = 3, + WEST = 4, + SOUTH_WEST = 5, + SOUTH = 6, + SOUTH_EAST = 7 +} + +## The direction in which the input should point. +@export var direction:GUIDEDirection = GUIDEDirection.EAST + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if not input.is_finite(): + return Vector3.INF + + if input.is_zero_approx(): + return Vector3.ZERO + + + + # get the angle in which the direction is pointing in radians. + var angle_radians = atan2( -input.y, input.x ); + var octant = roundi( 8 * angle_radians / TAU + 8 ) % 8; + if octant == direction: + return Vector3.RIGHT # (1, 0, 0) indicating boolean true + else: + return Vector3.ZERO + + +func _editor_name() -> String: + return "8-way direction" + + +func _editor_description() -> String: + return "Converts a 2D input into a boolean that is true when the\n" + \ + "input direction matches the selected direction. Note, that north is negative Y,\n" + \ + "because in Godot negative Y is up." diff --git a/addons/guide/modifiers/guide_modifier_8_way_direction.gd.uid b/addons/guide/modifiers/guide_modifier_8_way_direction.gd.uid new file mode 100644 index 0000000..3e3dc98 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_8_way_direction.gd.uid @@ -0,0 +1 @@ +uid://cmjelxqb3e7n6 diff --git a/addons/guide/modifiers/guide_modifier_canvas_coordinates.gd b/addons/guide/modifiers/guide_modifier_canvas_coordinates.gd new file mode 100644 index 0000000..23a5938 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_canvas_coordinates.gd @@ -0,0 +1,35 @@ +## Converts a position input in viewport coordinates (e.g. from the mouse position input) +## into canvas coordinates (e.g. 2D world coordinates). Useful to get a 2D 'world' position. +@tool +class_name GUIDEModifierCanvasCoordinates +extends GUIDEModifier + +## If checked, the input will be treated as relative input (position change) +## rather than absolute input (position). +@export var relative_input:bool: + set(value): + relative_input = value + emit_changed() + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if not input.is_finite(): + return Vector3.INF + + var viewport = Engine.get_main_loop().root + var transform = viewport.canvas_transform.affine_inverse() + var coordinates = transform * Vector2(input.x, input.y) + + if relative_input: + var origin = transform * Vector2.ZERO + coordinates -= origin + + return Vector3(coordinates.x, coordinates.y, input.z) + + +func _editor_name() -> String: + return "Canvas coordinates" + + +func _editor_description() -> String: + return "Converts a position input in viewport coordinates (e.g. from the mouse position input)\n" + \ + "into canvas coordinates (e.g. 2D world coordinates). Useful to get a 2D 'world' position." diff --git a/addons/guide/modifiers/guide_modifier_canvas_coordinates.gd.uid b/addons/guide/modifiers/guide_modifier_canvas_coordinates.gd.uid new file mode 100644 index 0000000..e93e75c --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_canvas_coordinates.gd.uid @@ -0,0 +1 @@ +uid://vho2v7ax07ef diff --git a/addons/guide/modifiers/guide_modifier_curve.gd b/addons/guide/modifiers/guide_modifier_curve.gd new file mode 100644 index 0000000..bb55b11 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_curve.gd @@ -0,0 +1,51 @@ +@tool +## Applies a separate curve to each input axis. +class_name GUIDEModifierCurve +extends GUIDEModifier + + +## The curve to apply to the x axis +@export var curve: Curve = default_curve() + +## Apply modifier to X axis +@export var x: bool = true + +## Apply modifier to Y axis +@export var y: bool = true + +## Apply modifier to Z axis +@export var z: bool = true + + +## Create default curve resource with a smoothstep, 0.0 - 1.0 input/output range +static func default_curve() -> Curve: + var curve = Curve.new() + curve.add_point(Vector2(0.0, 0.0)) + curve.add_point(Vector2(1.0, 1.0)) + + return curve + + +func _modify_input(input: Vector3, delta: float, value_type: GUIDEAction.GUIDEActionValueType) -> Vector3: + # Curve should never be null + if curve == null: + push_error("No curve added to Curve modifier.") + return input + + if not input.is_finite(): + return Vector3.INF + + # Return vector with enabled axes modified, others remain unchanged. + return Vector3( + curve.sample(input.x) if x else input.x, + curve.sample(input.y) if y else input.y, + curve.sample(input.z) if z else input.z + ) + + +func _editor_name() -> String: + return "Curve" + + +func _editor_description() -> String: + return "Applies a curve to each input axis." diff --git a/addons/guide/modifiers/guide_modifier_curve.gd.uid b/addons/guide/modifiers/guide_modifier_curve.gd.uid new file mode 100644 index 0000000..8b18651 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_curve.gd.uid @@ -0,0 +1 @@ +uid://trjb6t778n84 diff --git a/addons/guide/modifiers/guide_modifier_deadzone.gd b/addons/guide/modifiers/guide_modifier_deadzone.gd new file mode 100644 index 0000000..b40a00c --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_deadzone.gd @@ -0,0 +1,63 @@ +@tool +## Inputs between the lower and upper threshold are mapped 0 -> 1. +## Values outside the thresholds are clamped. +class_name GUIDEModifierDeadzone +extends GUIDEModifier + +## Lower threshold for the deadzone. +@export_range(0,1) var lower_threshold:float = 0.2: + set(value): + if value > upper_threshold: + lower_threshold = upper_threshold + else: + lower_threshold = value + emit_changed() + + +## Upper threshold for the deadzone. +@export_range(0,1) var upper_threshold:float = 1.0: + set(value): + if value < lower_threshold: + upper_threshold = lower_threshold + else: + upper_threshold = value + emit_changed() + + +func _rescale(value:float) -> float: + return min(1.0, (max(0.0, abs(value) - lower_threshold) / (upper_threshold - lower_threshold))) * sign(value) + + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if upper_threshold <= lower_threshold: + return input + + if not input.is_finite(): + return Vector3.INF + + match value_type: + GUIDEAction.GUIDEActionValueType.BOOL, GUIDEAction.GUIDEActionValueType.AXIS_1D: + return Vector3(_rescale(input.x), input.y, input.z) + + GUIDEAction.GUIDEActionValueType.AXIS_2D: + var v2d = Vector2(input.x, input.y) + if v2d.is_zero_approx(): + return Vector3(0, 0, input.z) + v2d = v2d.normalized() * _rescale(v2d.length()) + return Vector3(v2d.x, v2d.y, input.z) + + GUIDEAction.GUIDEActionValueType.AXIS_3D: + if input.is_zero_approx(): + return Vector3.ZERO + return input.normalized() * _rescale(input.length()) + _: + push_error("Unsupported value type. This is a bug. Please report it.") + return input + + +func _editor_name() -> String: + return "Deadzone" + +func _editor_description() -> String: + return "Inputs between the lower and upper threshold are mapped 0 -> 1.\n" + \ + "Values outside the thresholds are clamped." diff --git a/addons/guide/modifiers/guide_modifier_deadzone.gd.uid b/addons/guide/modifiers/guide_modifier_deadzone.gd.uid new file mode 100644 index 0000000..152bb06 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_deadzone.gd.uid @@ -0,0 +1 @@ +uid://c47lkb48itd6l diff --git a/addons/guide/modifiers/guide_modifier_input_swizzle.gd b/addons/guide/modifiers/guide_modifier_input_swizzle.gd new file mode 100644 index 0000000..115a50f --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_input_swizzle.gd @@ -0,0 +1,43 @@ +## Swizzle the input vector components. Useful to map 1D input to 2D or vice versa. +@tool +class_name GUIDEModifierInputSwizzle +extends GUIDEModifier + +enum GUIDEInputSwizzleOperation { + ## Swap X and Y axes. + YXZ, + ## Swap X and Z axes. + ZYX, + ## Swap Y and Z axes. + XZY, + ## Y to X, Z to Y, X to Z. + YZX, + ## Y to Z, Z to X, X to Y. + ZXY +} + +## The new order into which the input should be brought. +@export var order:GUIDEInputSwizzleOperation = GUIDEInputSwizzleOperation.YXZ + + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + match order: + GUIDEInputSwizzleOperation.YXZ: + return Vector3(input.y, input.x, input.z) + GUIDEInputSwizzleOperation.ZYX: + return Vector3(input.z, input.y, input.x) + GUIDEInputSwizzleOperation.XZY: + return Vector3(input.x, input.z, input.y) + GUIDEInputSwizzleOperation.YZX: + return Vector3(input.y, input.z, input.x) + GUIDEInputSwizzleOperation.ZXY: + return Vector3(input.z, input.x, input.y) + _: + push_error("Unknown order ", order , " this is most likely a bug, please report it.") + return input + +func _editor_name() -> String: + return "Input Swizzle" + +func _editor_description() -> String: + return "Swizzle the input vector components. Useful to map 1D input to 2D or vice versa." diff --git a/addons/guide/modifiers/guide_modifier_input_swizzle.gd.uid b/addons/guide/modifiers/guide_modifier_input_swizzle.gd.uid new file mode 100644 index 0000000..71f872d --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_input_swizzle.gd.uid @@ -0,0 +1 @@ +uid://bm5gjgadon6hb diff --git a/addons/guide/modifiers/guide_modifier_map_range.gd b/addons/guide/modifiers/guide_modifier_map_range.gd new file mode 100644 index 0000000..65f2275 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_map_range.gd @@ -0,0 +1,67 @@ +@tool +## Maps an input range to an output range and optionally clamps the output. +class_name GUIDEModifierMapRange +extends GUIDEModifier + +## Should the output be clamped to the range? +@export var apply_clamp:bool = true + +## The minimum input value +@export var input_min:float = 0.0 + +## The maximum input value +@export var input_max:float = 1.0 + +## The minimum output value +@export var output_min:float = 0.0 + +## The maximum output value +@export var output_max:float = 1.0 + +## Apply modifier to X axis +@export var x:bool = true + +## Apply modifier to Y axis +@export var y:bool = true + +## Apply modifier to Z axis +@export var z:bool = true + +var _omin:float +var _omax:float + +func _begin_usage(): + # we calculate the min and max of the output range here, so we can use them later and don't have to + # recalculate them every time the modifier is used + _omin = min(output_min, output_max) + _omax = max(output_min, output_max) + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if not input.is_finite(): + return Vector3.INF + + var x_value:float = remap(input.x, input_min, input_max, output_min, output_max) + var y_value:float = remap(input.y, input_min, input_max, output_min, output_max) + var z_value:float = remap(input.z, input_min, input_max, output_min, output_max) + + if apply_clamp: + # clamp doesn't handle reverse ranges, so we need to use our calculated normalized output range + # to clamp the output values + x_value = clamp(x_value, _omin, _omax) + y_value = clamp(y_value, _omin, _omax) + z_value = clamp(z_value, _omin, _omax) + + # Return vector with enabled axes set, others unchanged + return Vector3( + x_value if x else input.x, + y_value if y else input.y, + z_value if z else input.z, + ) + + +func _editor_name() -> String: + return "Map Range" + + +func _editor_description() -> String: + return "Maps an input range to an output range and optionally clamps the output" diff --git a/addons/guide/modifiers/guide_modifier_map_range.gd.uid b/addons/guide/modifiers/guide_modifier_map_range.gd.uid new file mode 100644 index 0000000..9cdcf40 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_map_range.gd.uid @@ -0,0 +1 @@ +uid://cs70d8i3sqe7p diff --git a/addons/guide/modifiers/guide_modifier_negate.gd b/addons/guide/modifiers/guide_modifier_negate.gd new file mode 100644 index 0000000..895d1ef --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_negate.gd @@ -0,0 +1,52 @@ +## Inverts input per axis. +@tool +class_name GUIDEModifierNegate +extends GUIDEModifier + +## Whether the X axis should be inverted. +@export var x:bool = true: + set(value): + if x == value: + return + x = value + _update_caches() + emit_changed() + +## Whether the Y axis should be inverted. +@export var y:bool = true: + set(value): + if y == value: + return + y = value + _update_caches() + emit_changed() + +## Whether the Z axis should be inverted. +@export var z:bool = true: + set(value): + if z == value: + return + z = value + _update_caches() + emit_changed() + +var _multiplier:Vector3 = Vector3.ONE * -1 + +func _update_caches(): + _multiplier.x = -1 if x else 1 + _multiplier.y = -1 if y else 1 + _multiplier.z = -1 if z else 1 + + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if not input.is_finite(): + return Vector3.INF + + return input * _multiplier + +func _editor_name() -> String: + return "Negate" + + +func _editor_description() -> String: + return "Inverts input per axis." diff --git a/addons/guide/modifiers/guide_modifier_negate.gd.uid b/addons/guide/modifiers/guide_modifier_negate.gd.uid new file mode 100644 index 0000000..5aefba2 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_negate.gd.uid @@ -0,0 +1 @@ +uid://ckggy40lm0vjc diff --git a/addons/guide/modifiers/guide_modifier_normalize.gd b/addons/guide/modifiers/guide_modifier_normalize.gd new file mode 100644 index 0000000..7b10f52 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_normalize.gd @@ -0,0 +1,17 @@ +## Normalizes the input vector. +@tool +class_name GUIDEModifierNormalize +extends GUIDEModifier + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if not input.is_finite(): + return Vector3.INF + + return input.normalized() + +func _editor_name() -> String: + return "Normalize" + + +func _editor_description() -> String: + return "Normalizes the input vector." diff --git a/addons/guide/modifiers/guide_modifier_normalize.gd.uid b/addons/guide/modifiers/guide_modifier_normalize.gd.uid new file mode 100644 index 0000000..e6762fd --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_normalize.gd.uid @@ -0,0 +1 @@ +uid://bs86pentlbwbi diff --git a/addons/guide/modifiers/guide_modifier_positive_negative.gd b/addons/guide/modifiers/guide_modifier_positive_negative.gd new file mode 100644 index 0000000..1f0ce35 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_positive_negative.gd @@ -0,0 +1,65 @@ +## Limits inputs to positive or negative values. +@tool +class_name GUIDEModifierPositiveNegative +extends GUIDEModifier + +enum LimitRange { + POSITIVE = 1, + NEGATIVE = 2 +} + +## The range of numbers to which the input should be limited +@export var range:LimitRange = LimitRange.POSITIVE + +## Whether the X axis should be affected. +@export var x:bool = true: + set(value): + if x == value: + return + x = value + emit_changed() + +## Whether the Y axis should be affected. +@export var y:bool = true: + set(value): + if y == value: + return + y = value + emit_changed() + +## Whether the Z axis should be affected. +@export var z:bool = true: + set(value): + if z == value: + return + z = value + emit_changed() + + + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if not input.is_finite(): + return Vector3.INF + + match range: + LimitRange.POSITIVE: + return Vector3( + max(0, input.x) if x else input.x, \ + max(0, input.y) if y else input.y, \ + max(0, input.z) if z else input.z \ + ) + LimitRange.NEGATIVE: + return Vector3( + min(0, input.x) if x else input.x, \ + min(0, input.y) if y else input.y, \ + min(0, input.z) if z else input.z \ + ) + # should never happen + return input + +func _editor_name() -> String: + return "Positive/Negative" + + +func _editor_description() -> String: + return "Clamps the input to positive or negative values." diff --git a/addons/guide/modifiers/guide_modifier_positive_negative.gd.uid b/addons/guide/modifiers/guide_modifier_positive_negative.gd.uid new file mode 100644 index 0000000..d145bf8 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_positive_negative.gd.uid @@ -0,0 +1 @@ +uid://cbe2gpphnd1fg diff --git a/addons/guide/modifiers/guide_modifier_scale.gd b/addons/guide/modifiers/guide_modifier_scale.gd new file mode 100644 index 0000000..68e0564 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_scale.gd @@ -0,0 +1,35 @@ +@tool +## Scales the input by the given value and optionally, delta time. +class_name GUIDEModifierScale +extends GUIDEModifier + +## The scale by which the input should be scaled. +@export var scale:Vector3 = Vector3.ONE: + set(value): + scale = value + emit_changed() + + +## If true, delta time will be multiplied in addition to the scale. +@export var apply_delta_time:bool = false: + set(value): + apply_delta_time = value + emit_changed() + + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if not input.is_finite(): + return Vector3.INF + + if apply_delta_time: + return input * scale * delta + else: + return input * scale + + +func _editor_name() -> String: + return "Scale" + + +func _editor_description() -> String: + return "Scales the input by the given value and optionally, delta time." diff --git a/addons/guide/modifiers/guide_modifier_scale.gd.uid b/addons/guide/modifiers/guide_modifier_scale.gd.uid new file mode 100644 index 0000000..d15aa20 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_scale.gd.uid @@ -0,0 +1 @@ +uid://bjm4myqxg4phm diff --git a/addons/guide/modifiers/guide_modifier_virtual_cursor.gd b/addons/guide/modifiers/guide_modifier_virtual_cursor.gd new file mode 100644 index 0000000..79ada82 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_virtual_cursor.gd @@ -0,0 +1,105 @@ +## Stateful modifier which provides a virtual "mouse" cursor driven by input. The modifier +## returns the current cursor position in pixels releative to the origin of the currently +## active window. +@tool +class_name GUIDEModifierVirtualCursor +extends GUIDEModifier + +enum ScreenScale { + ## Input is not scaled with input screen size. This means that the cursor will + ## visually move slower on higher resolutions. + NONE = 0, + ## Input is scaled with the longer axis of the screen size (e.g. width in + ## landscape mode, height in portrait mode). The cursor will move with + ## the same visual speed on all resolutions. + LONGER_AXIS = 1, + ## Input is scaled with the shorter axis of the screen size (e.g. height in + ## landscape mode, width in portrait mode). The cursor will move with the + ## same visual speed on all resolutions. + SHORTER_AXIS = 2 +} + +## The initial position of the virtual cursor (given in screen relative coordinates) +@export var initial_position:Vector2 = Vector2(0.5, 0.5): + set(value): + initial_position = value.clamp(Vector2.ZERO, Vector2.ONE) + +## The cursor movement speed in pixels. +@export var speed:Vector3 = Vector3.ONE + +## Screen scaling to be applied to the cursor movement. This controls +## whether the cursor movement speed is resolution dependent or not. +## If set to anything but [code]None[/code] then the input value will +## be multiplied with the window width/height depending on the setting. +@export var screen_scale:ScreenScale = ScreenScale.LONGER_AXIS + +## The scale by which the input should be scaled. +## @deprecated: use [member speed] instead. +var scale:Vector3: + get: return speed + set(value): speed = value + +## If true, the cursor movement speed is in pixels per second, otherwise it is in pixels +## per frame. +@export var apply_delta_time:bool = true + + +## Cursor offset in pixels. +var _offset:Vector3 = Vector3.ZERO + +## Returns the scaled screen size. This takes Godot's scaling factor for windows into account. +func _get_scaled_screen_size(): + # Get window size, including scaling factor + var window = Engine.get_main_loop().get_root() + return window.get_screen_transform().affine_inverse() * Vector2(window.size) + +func _begin_usage(): + var window_size = _get_scaled_screen_size() + _offset = Vector3(window_size.x * initial_position.x, window_size.y * initial_position.y, 0) + + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if not input.is_finite(): + # input is invalid, so just return current cursor position + return _offset + + var window_size = _get_scaled_screen_size() + input *= speed + + if apply_delta_time: + input *= delta + + var screen_scale_factor:float = 1.0 + match screen_scale: + ScreenScale.LONGER_AXIS: + screen_scale_factor = max(window_size.x, window_size.y) + ScreenScale.SHORTER_AXIS: + screen_scale_factor = min(window_size.x, window_size.y) + + input *= screen_scale_factor + + # apply input and clamp to window size + _offset = (_offset + input).clamp(Vector3.ZERO, Vector3(window_size.x, window_size.y, 0)) + + return _offset + +func _editor_name() -> String: + return "Virtual Cursor" + + +func _editor_description() -> String: + return "Stateful modifier which provides a virtual \"mouse\" cursor driven by input. The modifier\n" + \ + "returns the current cursor position in pixels releative to the origin of the currently \n" + \ + "active window." + + +# support for legacy properties +func _get_property_list(): + return [ + { + "name": "scale", + "type": TYPE_VECTOR3, + "usage": PROPERTY_USAGE_NO_EDITOR + } + ] + diff --git a/addons/guide/modifiers/guide_modifier_virtual_cursor.gd.uid b/addons/guide/modifiers/guide_modifier_virtual_cursor.gd.uid new file mode 100644 index 0000000..6692a53 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_virtual_cursor.gd.uid @@ -0,0 +1 @@ +uid://0ubnfkes0d4r diff --git a/addons/guide/modifiers/guide_modifier_window_relative.gd b/addons/guide/modifiers/guide_modifier_window_relative.gd new file mode 100644 index 0000000..66c88d7 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_window_relative.gd @@ -0,0 +1,26 @@ +## Converts the value of the input into window-relative units between 0 and 1. +## E.g. if a mouse cursor moves half a screen to the right and down, then +## this modifier will return (0.5, 0.5). +@tool +class_name GUIDEModifierWindowRelative +extends GUIDEModifier + + +func _modify_input(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> Vector3: + if not input.is_finite(): + return Vector3.INF + + var window = Engine.get_main_loop().get_root() + # We want real pixels, so we need to factor in any scaling that the window does. + var window_size:Vector2 = window.get_screen_transform().affine_inverse() * Vector2(window.size) + return Vector3(input.x / window_size.x, input.y / window_size.y, input.z) + + +func _editor_name() -> String: + return "Window relative" + + +func _editor_description() -> String: + return "Converts the value of the input into window-relative units between 0 and 1.\n" + \ + "E.g. if a mouse cursor moves half a screen to the right and down, then \n" + \ + "this modifier will return (0.5, 0.5)." diff --git a/addons/guide/modifiers/guide_modifier_window_relative.gd.uid b/addons/guide/modifiers/guide_modifier_window_relative.gd.uid new file mode 100644 index 0000000..19646a7 --- /dev/null +++ b/addons/guide/modifiers/guide_modifier_window_relative.gd.uid @@ -0,0 +1 @@ +uid://cgy4anjdob2tp diff --git a/addons/guide/plugin.cfg b/addons/guide/plugin.cfg new file mode 100644 index 0000000..ae7473d --- /dev/null +++ b/addons/guide/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Godot Unified Input Detection Engine (G.U.I.D.E)" +description="" +author="Jan Thomä" +version="0.6.3" +script="plugin.gd" diff --git a/addons/guide/plugin.gd b/addons/guide/plugin.gd new file mode 100644 index 0000000..cb5410b --- /dev/null +++ b/addons/guide/plugin.gd @@ -0,0 +1,45 @@ +@tool +extends EditorPlugin +const MainPanel = preload("editor/mapping_context_editor/mapping_context_editor.tscn") + +var _main_panel:Control + + +func _enable_plugin(): + add_autoload_singleton("GUIDE", "res://addons/guide/guide.gd") + +func _enter_tree() -> void: + _main_panel = MainPanel.instantiate() + _main_panel.initialize(self) + EditorInterface.get_editor_main_screen().add_child(_main_panel) + # Hide the main panel. Very much required. + _make_visible(false) + +func _exit_tree() -> void: + if is_instance_valid(_main_panel): + _main_panel.queue_free() + GUIDEInputFormatter.cleanup() + +func _disable_plugin(): + remove_autoload_singleton("GUIDE") + + +func _edit(object): + if object is GUIDEMappingContext: + _main_panel.edit(object) + +func _get_plugin_name() -> String: + return "G.U.I.D.E" + +func _get_plugin_icon() -> Texture2D: + return preload("res://addons/guide/editor/logo_editor_small.svg") + +func _has_main_screen() -> bool: + return true + +func _handles(object:Variant) -> bool: + return object is GUIDEMappingContext + +func _make_visible(visible): + if is_instance_valid(_main_panel): + _main_panel.visible = visible diff --git a/addons/guide/plugin.gd.uid b/addons/guide/plugin.gd.uid new file mode 100644 index 0000000..d144701 --- /dev/null +++ b/addons/guide/plugin.gd.uid @@ -0,0 +1 @@ +uid://wstfxvdc0ol0 diff --git a/addons/guide/remapping/guide_input_detector.gd b/addons/guide/remapping/guide_input_detector.gd new file mode 100644 index 0000000..9276cbe --- /dev/null +++ b/addons/guide/remapping/guide_input_detector.gd @@ -0,0 +1,376 @@ +@tool +## Helper node for detecting inputs. Detects the next input matching a specification and +## emits a signal with the detected input. +class_name GUIDEInputDetector +extends Node + +## The device type for which the input should be filtered. +enum DeviceType { + ## Only detect input from keyboard. + KEYBOARD = 1, + ## Only detect input from the mouse. + MOUSE = 2, + ## Only detect input from joysticks/gamepads. + JOY = 4 + # touch doesn't make a lot of sense as this is usually + # not remappable. +} + +## Which joy index should be used for detected joy events +enum JoyIndex { + # Use -1, so the detected input will match any joystick + ANY = 0, + # Use the actual index of the detected joystick. + DETECTED = 1 +} + +enum DetectionState { + # The detector is currently idle. + IDLE = 0, + # The detector is currently counting down before starting the detection. + COUNTDOWN = 3, + # The detector is currently detecting input. + DETECTING = 1, + # The detector has finished detecting but is waiting for input to be released. + WAITING_FOR_INPUT_CLEAR = 2, +} + +## A countdown between initiating a dection and the actual start of the +## detection. This is useful because when the user clicks a button to +## start a detection, we want to make sure that the player is actually +## ready (and not accidentally moves anything). If set to 0, no countdown +## will be started. +@export_range(0, 2, 0.1, "or_greater") var detection_countdown_seconds:float = 0.5 + +## Minimum amplitude to detect any axis. +@export_range(0, 1, 0.1, "or_greater") var minimum_axis_amplitude:float = 0.2 + +## If any of these inputs is encountered, the detector will +## treat this as "abort detection". +@export var abort_detection_on:Array[GUIDEInput] = [] + +## Which joy index should be returned for detected joy events. +@export var use_joy_index:JoyIndex = JoyIndex.ANY + +## Whether trigger buttons on controllers should be detected when +## then action value type is limited to boolean. +@export var allow_triggers_for_boolean_actions:bool = true + +## Emitted when the detection has started (e.g. countdown has elapsed). +## Can be used to signal this to the player. +signal detection_started() + +## Emitted when the input detector detects an input of the given type. +## If detection was aborted the given input is null. +signal input_detected(input:GUIDEInput) + +# The timer for the detection countdown. +var _timer:Timer + +# Our copy of the input state +var _input_state:GUIDEInputState +# The current state of the detection. +var _status:DetectionState = DetectionState.IDLE +# Mapping contexts that were active when the detection started. We need to restore these once the detection is +# finished or aborted. +var _saved_mapping_contexts:Array[GUIDEMappingContext] = [] + +# The last detected input. +var _last_detected_input:GUIDEInput = null + +func _ready(): + # don't run the process function if we are not detecting to not waste resources + set_process(false) + _timer = Timer.new() + _input_state = GUIDEInputState.new() + _timer.one_shot = true + add_child(_timer, false, Node.INTERNAL_MODE_FRONT) + _timer.timeout.connect(_begin_detection) + + +## Whether the input detector is currently detecting input. +var is_detecting:bool: + get: return _status != DetectionState.IDLE + +var _value_type:GUIDEAction.GUIDEActionValueType +var _device_types:Array[DeviceType] = [] + +## Detects a boolean input type. +func detect_bool(device_types:Array[DeviceType] = []) -> void: + detect(GUIDEAction.GUIDEActionValueType.BOOL, device_types) + + +## Detects a 1D axis input type. +func detect_axis_1d(device_types:Array[DeviceType] = []) -> void: + detect(GUIDEAction.GUIDEActionValueType.AXIS_1D, device_types) + + +## Detects a 2D axis input type. +func detect_axis_2d(device_types:Array[DeviceType] = []) -> void: + detect(GUIDEAction.GUIDEActionValueType.AXIS_2D, device_types) + + +## Detects a 3D axis input type. +func detect_axis_3d(device_types:Array[DeviceType] = []) -> void: + detect(GUIDEAction.GUIDEActionValueType.AXIS_3D, device_types) + + +## Detects the given input type. If device types are given +## will only detect inputs from the given device types. +## Otherwise will detect inputs from all supported device types. +func detect(value_type:GUIDEAction.GUIDEActionValueType, + device_types:Array[DeviceType] = []) -> void: + if device_types == null: + push_error("Device types must not be null. Supply an empty array if you want to detect input from all devices.") + return + + + # If we are already detecting, abort this. + if _status == DetectionState.DETECTING or _status == DetectionState.WAITING_FOR_INPUT_CLEAR: + for input in abort_detection_on: + input._end_usage() + + # and start a new detection. + _status = DetectionState.COUNTDOWN + + _value_type = value_type + _device_types = device_types + _timer.stop() + _timer.start(detection_countdown_seconds) + +## This is called by the timer when the countdown has elapsed. +func _begin_detection(): + # set status to detecting + _status = DetectionState.DETECTING + # reset and clear the input state + _input_state._clear() + _input_state._reset() + + # enable all abort detection inputs + for input in abort_detection_on: + input._state = _input_state + input._begin_usage() + + # we also use this inside the editor where the GUIDE + # singleton is not active. Here we don't need to enable + # and disable the mapping contexts. + if not Engine.is_editor_hint(): + # save currently active mapping contexts + _saved_mapping_contexts = GUIDE.get_enabled_mapping_contexts() + + # disable all mapping contexts + for context in _saved_mapping_contexts: + GUIDE.disable_mapping_context(context) + + detection_started.emit() + + +## Aborts a running detection. If no detection currently runs +## does nothing. +func abort_detection() -> void: + _timer.stop() + # if we are currently detecting, deliver the null result + # which will gracefully shut down everything + if _status == DetectionState.DETECTING: + _deliver(null) + + # in any other state we don't need to do anything + +## This is called while we are waiting for input to be released. +func _process(delta: float) -> void: + # if we are not detecting, we don't need to do anything + if _status != DetectionState.WAITING_FOR_INPUT_CLEAR: + set_process(false) + return + + # check if the input is still actuated. We do this to avoid the problem + # of this input accidentally triggering something in the mapping contexts + # when we enable them again. + for input in abort_detection_on: + if input._value.is_finite() and input._value.length() > 0: + # we still have input, so we are still waiting + # retry next frame + return + + # if we are here, the input is no longer actuated + + # tear down the inputs + for input in abort_detection_on: + input._end_usage() + + # restore the mapping contexts + # but only when not running in the editor + if not Engine.is_editor_hint(): + for context in _saved_mapping_contexts: + GUIDE.enable_mapping_context(context) + + # set status to idle + _status = DetectionState.IDLE + # and deliver the detected input + input_detected.emit(_last_detected_input) + +## This is called in any state when input is received. +func _input(event:InputEvent) -> void: + if _status == DetectionState.IDLE: + return + + # feed the event into the state + _input_state._input(event) + + # while detecting, we're the only ones consuming input and we eat this input + # to not accidentally trigger built-in Godot mappings (e.g. UI stuff) + get_viewport().set_input_as_handled() + # but we still feed it into GUIDE's global state so this state stays + # up to date. This should have no effect because we disabled all mapping + # contexts. + if not Engine.is_editor_hint(): + GUIDE.inject_input(event) + + if _status == DetectionState.DETECTING: + # check if any abort input will trigger + for input in abort_detection_on: + # if it triggers, we abort + if input._value.is_finite() and input._value.length() > 0: + abort_detection() + return + + # check if the event matches the device type we are + # looking for + if not _matches_device_types(event): + return + + # then check if it can be mapped to the desired + # value type + match _value_type: + GUIDEAction.GUIDEActionValueType.BOOL: + _try_detect_bool(event) + GUIDEAction.GUIDEActionValueType.AXIS_1D: + _try_detect_axis_1d(event) + GUIDEAction.GUIDEActionValueType.AXIS_2D: + _try_detect_axis_2d(event) + GUIDEAction.GUIDEActionValueType.AXIS_3D: + _try_detect_axis_3d(event) + + +func _matches_device_types(event:InputEvent) -> bool: + if _device_types.is_empty(): + return true + + if event is InputEventKey: + return _device_types.has(DeviceType.KEYBOARD) + + if event is InputEventMouse: + return _device_types.has(DeviceType.MOUSE) + + if event is InputEventJoypadButton or event is InputEventJoypadMotion: + return _device_types.has(DeviceType.JOY) + + return false + + +func _try_detect_bool(event:InputEvent) -> void: + if event is InputEventKey and event.is_released(): + var result := GUIDEInputKey.new() + result.key = event.physical_keycode + result.shift = event.shift_pressed + result.control = event.ctrl_pressed + result.meta = event.meta_pressed + result.alt = event.alt_pressed + _deliver(result) + return + + if event is InputEventMouseButton and event.is_released(): + var result := GUIDEInputMouseButton.new() + result.button = event.button_index + _deliver(result) + return + + if event is InputEventJoypadButton and event.is_released(): + var result := GUIDEInputJoyButton.new() + result.button = event.button_index + result.joy_index = _find_joy_index(event.device) + _deliver(result) + + if allow_triggers_for_boolean_actions: + # only allow joypad trigger buttons + if not (event is InputEventJoypadMotion): + return + if event.axis != JOY_AXIS_TRIGGER_LEFT and \ + event.axis != JOY_AXIS_TRIGGER_RIGHT: + return + + var result := GUIDEInputJoyAxis1D.new() + result.axis = event.axis + result.joy_index = _find_joy_index(event.device) + _deliver(result) + + + +func _try_detect_axis_1d(event:InputEvent) -> void: + if event is InputEventMouseMotion: + var result := GUIDEInputMouseAxis1D.new() + # Pick the direction in which the mouse was moved more. + if abs(event.relative.x) > abs(event.relative.y): + result.axis = GUIDEInputMouseAxis1D.GUIDEInputMouseAxis.X + else: + result.axis = GUIDEInputMouseAxis1D.GUIDEInputMouseAxis.Y + _deliver(result) + return + + if event is InputEventJoypadMotion: + if abs(event.axis_value) < minimum_axis_amplitude: + return + + var result := GUIDEInputJoyAxis1D.new() + result.axis = event.axis + result.joy_index = _find_joy_index(event.device) + _deliver(result) + + +func _try_detect_axis_2d(event:InputEvent) -> void: + if event is InputEventMouseMotion: + var result := GUIDEInputMouseAxis2D.new() + _deliver(result) + return + + if event is InputEventJoypadMotion: + if event.axis_value < minimum_axis_amplitude: + return + + var result := GUIDEInputJoyAxis2D.new() + match event.axis: + JOY_AXIS_LEFT_X, JOY_AXIS_LEFT_Y: + result.x = JOY_AXIS_LEFT_X + result.y = JOY_AXIS_LEFT_Y + JOY_AXIS_RIGHT_X, JOY_AXIS_RIGHT_Y: + result.x = JOY_AXIS_RIGHT_X + result.y = JOY_AXIS_RIGHT_Y + _: + # not supported for detection + return + result.joy_index = _find_joy_index(event.device) + _deliver(result) + return + + +func _try_detect_axis_3d(event:InputEvent) -> void: + # currently no input for 3D + pass + + +func _find_joy_index(device_id:int) -> int: + if use_joy_index == JoyIndex.ANY: + return -1 + + var pads := Input.get_connected_joypads() + for i in pads.size(): + if pads[i] == device_id: + return i + + return -1 + +func _deliver(input:GUIDEInput) -> void: + _last_detected_input = input + _status = DetectionState.WAITING_FOR_INPUT_CLEAR + # enable processing so we can check if the input is released before we re-enable GUIDE's mapping contexts + set_process(true) diff --git a/addons/guide/remapping/guide_input_detector.gd.uid b/addons/guide/remapping/guide_input_detector.gd.uid new file mode 100644 index 0000000..d6ed3bf --- /dev/null +++ b/addons/guide/remapping/guide_input_detector.gd.uid @@ -0,0 +1 @@ +uid://db27ccgomq455 diff --git a/addons/guide/remapping/guide_remapper.gd b/addons/guide/remapping/guide_remapper.gd new file mode 100644 index 0000000..4037819 --- /dev/null +++ b/addons/guide/remapping/guide_remapper.gd @@ -0,0 +1,307 @@ +class_name GUIDERemapper + +## Emitted when the bound input of an item changes. +signal item_changed(item:ConfigItem, input:GUIDEInput) + +var _remapping_config:GUIDERemappingConfig = GUIDERemappingConfig.new() +var _mapping_contexts:Array[GUIDEMappingContext] = [] + +const GUIDESet = preload("../guide_set.gd") + +## Loads the default bindings as they are currently configured in the mapping contexts and a mapping +## config for editing. Note that the given mapping config will not be modified, so editing can be +## cancelled. Call get_mapping_config to get the modified mapping config. +func initialize(mapping_contexts:Array[GUIDEMappingContext], remapping_config:GUIDERemappingConfig): + _remapping_config = remapping_config.duplicate() if remapping_config != null else GUIDERemappingConfig.new() + + _mapping_contexts.clear() + + for mapping_context in mapping_contexts: + if not is_instance_valid(mapping_context): + push_error("Cannot add null mapping context. Ignoring.") + return + _mapping_contexts.append(mapping_context) + + +## Returns the mapping config with all modifications applied. +func get_mapping_config() -> GUIDERemappingConfig: + return _remapping_config.duplicate() + + +func set_custom_data(key:Variant, value:Variant): + _remapping_config.custom_data[key] = value + + +func get_custom_data(key:Variant, default:Variant = null) -> Variant: + return _remapping_config.custom_data.get(key, default) + + +func remove_custom_data(key:Variant) -> void: + _remapping_config.custom_data.erase(key) + + +## Returns all remappable items. Can be filtered by context, display category or +## action. +func get_remappable_items(context:GUIDEMappingContext = null, + display_category:String = "", + action:GUIDEAction = null) -> Array[ConfigItem]: + + if action != null and not action.is_remappable: + push_warning("Action filter was set but filtered action is not remappable.") + return [] + + + var result:Array[ConfigItem] = [] + for a_context:GUIDEMappingContext in _mapping_contexts: + if context != null and context != a_context: + continue + for action_mapping:GUIDEActionMapping in a_context.mappings: + var mapped_action:GUIDEAction = action_mapping.action + # filter non-remappable actions + if not mapped_action.is_remappable: + continue + + # if action filter is set, only pick mappings for this action + if action != null and action != mapped_action: + continue + + # make config items + for index:int in action_mapping.input_mappings.size(): + var input_mapping:GUIDEInputMapping = action_mapping.input_mappings[index] + if input_mapping.override_action_settings and not input_mapping.is_remappable: + # skip non-remappable items + continue + + # Calculate effective display category + var effective_display_category:String = \ + _get_effective_display_category(mapped_action, input_mapping) + + # if display category filter is set, only pick mappings + # in this category + if display_category.length() > 0 and effective_display_category != display_category: + continue + + var item = ConfigItem.new(a_context, action_mapping.action, index, input_mapping) + item_changed.connect(item._item_changed) + result.append(item) + + return result + + +static func _get_effective_display_category(action:GUIDEAction, input_mapping:GUIDEInputMapping) -> String: + var result:String = "" + if input_mapping.override_action_settings: + result = input_mapping.display_category + + if result.is_empty(): + result = action.display_category + + return result + + +static func _get_effective_display_name(action:GUIDEAction, input_mapping:GUIDEInputMapping) -> String: + var result:String = "" + if input_mapping.override_action_settings: + result = input_mapping.display_name + + if result.is_empty(): + result = action.display_name + + return result + +static func _is_effectively_remappable(action:GUIDEAction, input_mapping:GUIDEInputMapping) -> bool: + return action.is_remappable and ((not input_mapping.override_action_settings) or input_mapping.is_remappable) + + +static func _get_effective_value_type(action:GUIDEAction, input_mapping:GUIDEInputMapping) -> GUIDEAction.GUIDEActionValueType: + if input_mapping.override_action_settings and input_mapping.input != null: + return input_mapping.input._native_value_type() + + return action.action_value_type + + +## Returns a list of all collisions in all contexts when this new input would be applied to the config item. +func get_input_collisions(item:ConfigItem, input:GUIDEInput) -> Array[ConfigItem]: + if not _check_item(item): + return [] + var result:Array[ConfigItem] = [] + + if input == null: + # no item collides with absent input + return result + + # walk over all known contexts and find any mappings. + for context:GUIDEMappingContext in _mapping_contexts: + for action_mapping:GUIDEActionMapping in context.mappings: + for index:int in action_mapping.input_mappings.size(): + var action := action_mapping.action + if context == item.context and action == item.action and index == item.index: + # collisions with self are allowed + continue + + var input_mapping:GUIDEInputMapping = action_mapping.input_mappings[index] + var bound_input:GUIDEInput = input_mapping.input + # check if this is currently overridden + if _remapping_config._has(context, action, index): + bound_input = _remapping_config._get_bound_input_or_null(context, action, index) + + # We have a collision + if bound_input != null and bound_input.is_same_as(input): + var collision_item := ConfigItem.new(context, action, index, input_mapping) + item_changed.connect(collision_item._item_changed) + result.append(collision_item) + + return result + + +## Gets the input currently bound to the action in the given context. Can be null if the input +## is currently not bound. +func get_bound_input_or_null(item:ConfigItem) -> GUIDEInput: + if not _check_item(item): + return null + + # If the remapping config has a binding for this, this binding wins. + if _remapping_config._has(item.context, item.action, item.index): + return _remapping_config._get_bound_input_or_null(item.context, item.action, item.index) + + # otherwise return the default binding for this action in the context + for action_mapping:GUIDEActionMapping in item.context.mappings: + if action_mapping.action == item.action: + if action_mapping.input_mappings.size() > item.index: + return action_mapping.input_mappings[item.index].input + else: + push_error("Action mapping does not have an index of ", item.index , ".") + + return null + +## Sets the bound input to the new value for the given config item. Ignores collisions +## because collision resolution is highly game specific. Use get_input_collisions to find +## potential collisions and then resolve them in a way that suits the game. Note that +## bound input can be set to null, which deliberately unbinds the input. If you want +## to restore the defaults, call restore_default instead. +func set_bound_input(item:ConfigItem, input:GUIDEInput) -> void: + if not _check_item(item): + return + + # first remove any custom binding we have + _remapping_config._clear(item.context, item.action, item.index) + + # Now check if the input is the same as the default + var bound_input:GUIDEInput = get_bound_input_or_null(item) + + if bound_input == null and input == null: + item_changed.emit(item, input) + return # nothing to do + + if bound_input == null: + _remapping_config._bind(item.context, item.action, input, item.index) + item_changed.emit(item, input) + return + + if bound_input != null and input != null and bound_input.is_same_as(input): + item_changed.emit(item, input) + return # nothing to do + + _remapping_config._bind(item.context, item.action, input, item.index) + item_changed.emit(item, input) + + +## Returns the default binding for the given config item. +func get_default_input(item:ConfigItem) -> GUIDEInput: + if not _check_item(item): + return null + + for mapping:GUIDEActionMapping in item.context.mappings: + if mapping.action == item.action: + # _check_item verifies the index exists, so no need to check here. + return mapping.input_mappings[item.index].input + + return null + + +## Restores the default binding for the given config item. Note that this may +## introduce a conflict if other bindings have bound conflicting input. You can +## call get_default_input for the given item to get the default input and then +## call get_input_collisions for that to find out whether you would get a collision. +func restore_default_for(item:ConfigItem) -> void: + if not _check_item(item): + return + + _remapping_config._clear(item.context, item.action, item.index) + item_changed.emit(item, get_bound_input_or_null(item)) + + + +## Verifies that the given item is valid. +func _check_item(item:ConfigItem) -> bool: + if not _mapping_contexts.has(item.context): + push_error("Given context is not known to this mapper. Did you call initialize()?") + return false + + var action_found := false + var size_ok := false + for mapping in item.context.mappings: + if mapping.action == item.action: + action_found = true + if mapping.input_mappings.size() > item.index and item.index >= 0: + size_ok = true + break + + if not action_found: + push_error("Given action does not belong to the given context.") + return false + + if not size_ok: + push_error("Given index does not exist for the given action's input binding.") + + + if not item.action.is_remappable: + push_error("Given action is not remappable.") + return false + + return true + + +class ConfigItem: + ## Emitted when the input to this item has changed. + signal changed(input:GUIDEInput) + + var _input_mapping:GUIDEInputMapping + + ## The display category for this config item + var display_category:String: + get: return GUIDERemapper._get_effective_display_category(action, _input_mapping) + + ## The display name for this config item. + var display_name:String: + get: return GUIDERemapper._get_effective_display_name(action, _input_mapping) + + ## Whether this item is remappable. + var is_remappable:bool: + get: return GUIDERemapper._is_effectively_remappable(action, _input_mapping) + + ## The value type for this config item. + var value_type:GUIDEAction.GUIDEActionValueType: + get: return GUIDERemapper._get_effective_value_type(action, _input_mapping) + + var context:GUIDEMappingContext + var action:GUIDEAction + var index:int + + func _init(context:GUIDEMappingContext, action:GUIDEAction, index:int, input_mapping:GUIDEInputMapping): + self.context = context + self.action = action + self.index = index + _input_mapping = input_mapping + + ## Checks whether this config item is the same as some other + ## e.g. refers to the same input mapping. + func is_same_as(other:ConfigItem) -> bool: + return context == other.context and \ + action == other.action and \ + index == other.index + + func _item_changed(item:ConfigItem, input:GUIDEInput): + if item.is_same_as(self): + changed.emit(input) + diff --git a/addons/guide/remapping/guide_remapper.gd.uid b/addons/guide/remapping/guide_remapper.gd.uid new file mode 100644 index 0000000..ff84866 --- /dev/null +++ b/addons/guide/remapping/guide_remapper.gd.uid @@ -0,0 +1 @@ +uid://nh78h8tprhwn diff --git a/addons/guide/remapping/guide_remapping_config.gd b/addons/guide/remapping/guide_remapping_config.gd new file mode 100644 index 0000000..7bd6453 --- /dev/null +++ b/addons/guide/remapping/guide_remapping_config.gd @@ -0,0 +1,85 @@ +@icon("res://addons/guide/guide_internal.svg") +## A remapping configuration. This only holds changes to the context mapping, +## so to get the full input map you need to apply this on top of one or more +## mapping contexts. The settings from this config take precedence over the +## settings from the mapping contexts. +class_name GUIDERemappingConfig +extends Resource + +## Dictionary with remapped inputs. Structure is: +## { +## mapping_context : { +## action : { +## index : bound input +## ... +## }, ... +## } +## The bound input can be NULL which means that this was deliberately unbound. +@export var remapped_inputs:Dictionary = {} + +## Dictionary for additional custom data to store (e.g. modifier settings, etc.) +## Note that this data is completely under application control and it's the responsibility +## of the application to ensure that this data is serializable and gets applied at +## the necessary point in time. +@export var custom_data:Dictionary = {} + +## Binds the given input to the given action. Index can be given to have +## alternative bindings for the same action. +func _bind(mapping_context:GUIDEMappingContext, action:GUIDEAction, input:GUIDEInput, index:int = 0) -> void: + if not remapped_inputs.has(mapping_context): + remapped_inputs[mapping_context] = {} + + if not remapped_inputs[mapping_context].has(action): + remapped_inputs[mapping_context][action] = {} + + remapped_inputs[mapping_context][action][index] = input + + +## Unbinds the given input from the given action. This is a deliberate unbind +## which means that the action should not be triggerable by the input anymore. It +## its not the same as _clear. +func _unbind(mapping_context:GUIDEMappingContext, action:GUIDEAction, index:int = 0) -> void: + _bind(mapping_context, action, null, index) + + +## Removes the given input action binding from this configuration. The action will +## now have the default input that it has in the mapping_context. This is not the +## same as _unbind. +func _clear(mapping_context:GUIDEMappingContext, action:GUIDEAction, index:int = 0) -> void: + if not remapped_inputs.has(mapping_context): + return + + if not remapped_inputs[mapping_context].has(action): + return + + remapped_inputs[mapping_context][action].erase(index) + + if remapped_inputs[mapping_context][action].is_empty(): + remapped_inputs[mapping_context].erase(action) + + if remapped_inputs[mapping_context].is_empty(): + remapped_inputs.erase(mapping_context) + + +## Returns the bound input for the given action name and index. Returns null +## if there is matching binding. +func _get_bound_input_or_null(mapping_context:GUIDEMappingContext, action:GUIDEAction, index:int = 0) -> GUIDEInput: + if not remapped_inputs.has(mapping_context): + return null + + if not remapped_inputs[mapping_context].has(action): + return null + + return remapped_inputs[mapping_context][action].get(index, null) + + +## Returns whether or not this mapping has a configuration for the given combination (even if the +## combination is set to null). +func _has(mapping_context:GUIDEMappingContext, action:GUIDEAction, index:int = 0) -> bool: + if not remapped_inputs.has(mapping_context): + return false + + if not remapped_inputs[mapping_context].has(action): + return false + + return remapped_inputs[mapping_context][action].has(index) diff --git a/addons/guide/remapping/guide_remapping_config.gd.uid b/addons/guide/remapping/guide_remapping_config.gd.uid new file mode 100644 index 0000000..137332f --- /dev/null +++ b/addons/guide/remapping/guide_remapping_config.gd.uid @@ -0,0 +1 @@ +uid://bjnghv2v2qu6w diff --git a/addons/guide/triggers/guide_trigger.gd b/addons/guide/triggers/guide_trigger.gd new file mode 100644 index 0000000..d158ece --- /dev/null +++ b/addons/guide/triggers/guide_trigger.gd @@ -0,0 +1,65 @@ +@tool +@icon("res://addons/guide/triggers/guide_trigger.svg") +class_name GUIDETrigger +extends Resource + +enum GUIDETriggerState { + ## The trigger did not fire. + NONE, + ## The trigger's conditions are partially met + ONGOING, + ## The trigger has fired. + TRIGGERED +} + +enum GUIDETriggerType { + # If there are more than one explicit triggers at least one must trigger + # for the action to trigger. + EXPLICIT = 1, + # All implicit triggers must trigger for the action to trigger. + IMPLICIT = 2, + # All blocking triggers prevent the action from triggering. + BLOCKING = 3 +} + + +@export var actuation_threshold:float = 0.5 +var _last_value:Vector3 + +## Returns the trigger type of this trigger. +func _get_trigger_type() -> GUIDETriggerType: + return GUIDETriggerType.EXPLICIT + + +func _update_state(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + return GUIDETriggerState.NONE + + +func _is_actuated(input:Vector3, value_type:GUIDEAction.GUIDEActionValueType) -> bool: + match value_type: + GUIDEAction.GUIDEActionValueType.AXIS_1D, GUIDEAction.GUIDEActionValueType.BOOL: + return _is_axis1d_actuated(input) + GUIDEAction.GUIDEActionValueType.AXIS_2D: + return _is_axis2d_actuated(input) + GUIDEAction.GUIDEActionValueType.AXIS_3D: + return _is_axis3d_actuated(input) + + return false + +## Checks if a 1D input is actuated. +func _is_axis1d_actuated(input:Vector3) -> bool: + return is_finite(input.x) and abs(input.x) > actuation_threshold + +## Checks if a 2D input is actuated. +func _is_axis2d_actuated(input:Vector3) -> bool: + return is_finite(input.x) and is_finite(input.y) and Vector2(input.x, input.y).length_squared() > actuation_threshold * actuation_threshold + +## Checks if a 3D input is actuated. +func _is_axis3d_actuated(input:Vector3) -> bool: + return input.is_finite() and input.length_squared() > actuation_threshold * actuation_threshold + +func _editor_name() -> String: + return "GUIDETrigger" + +func _editor_description() -> String: + return "" diff --git a/addons/guide/triggers/guide_trigger.gd.uid b/addons/guide/triggers/guide_trigger.gd.uid new file mode 100644 index 0000000..eed577d --- /dev/null +++ b/addons/guide/triggers/guide_trigger.gd.uid @@ -0,0 +1 @@ +uid://x74mnwgr08a7 diff --git a/addons/guide/triggers/guide_trigger.svg b/addons/guide/triggers/guide_trigger.svg new file mode 100644 index 0000000..48f8822 --- /dev/null +++ b/addons/guide/triggers/guide_trigger.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/addons/guide/triggers/guide_trigger.svg.import b/addons/guide/triggers/guide_trigger.svg.import new file mode 100644 index 0000000..e63657a --- /dev/null +++ b/addons/guide/triggers/guide_trigger.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ca1eiagyinhl7" +path="res://.godot/imported/guide_trigger.svg-cd87acbd491929cf49a255f8481b0b63.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/triggers/guide_trigger.svg" +dest_files=["res://.godot/imported/guide_trigger.svg-cd87acbd491929cf49a255f8481b0b63.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=0.5 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/triggers/guide_trigger_chorded_action.gd b/addons/guide/triggers/guide_trigger_chorded_action.gd new file mode 100644 index 0000000..2b06f8c --- /dev/null +++ b/addons/guide/triggers/guide_trigger_chorded_action.gd @@ -0,0 +1,28 @@ +## Fires, when the given action is currently triggering. This trigger is implicit, +## so it will prevent the action from triggering even if other triggers are successful. +@tool +class_name GUIDETriggerChordedAction +extends GUIDETrigger + +@export var action:GUIDEAction + + +func _get_trigger_type() -> GUIDETriggerType: + return GUIDETriggerType.IMPLICIT + +func _update_state(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + if action == null: + push_warning("Chorded trigger without action will never trigger.") + return GUIDETriggerState.NONE + + if action.is_triggered(): + return GUIDETriggerState.TRIGGERED + return GUIDETriggerState.NONE + + +func _editor_name() -> String: + return "Chorded Action" + +func _editor_description() -> String: + return "Fires, when the given action is currently triggering. This trigger is implicit,\n" + \ + "so it will prevent the action from triggering even if other triggers are successful." diff --git a/addons/guide/triggers/guide_trigger_chorded_action.gd.uid b/addons/guide/triggers/guide_trigger_chorded_action.gd.uid new file mode 100644 index 0000000..b9ba49b --- /dev/null +++ b/addons/guide/triggers/guide_trigger_chorded_action.gd.uid @@ -0,0 +1 @@ +uid://brsxcrai2te83 diff --git a/addons/guide/triggers/guide_trigger_combo.gd b/addons/guide/triggers/guide_trigger_combo.gd new file mode 100644 index 0000000..2464e65 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_combo.gd @@ -0,0 +1,117 @@ +@tool +class_name GUIDETriggerCombo +extends GUIDETrigger + +enum ActionEventType { + TRIGGERED = 1, + STARTED = 2, + ONGOING = 4, + CANCELLED = 8, + COMPLETED = 16 +} + +## If set to true, the combo trigger will print information +## about state changes to the debug log. +@export var enable_debug_print:bool = false +@export var steps:Array[GUIDETriggerComboStep] = [] +@export var cancellation_actions:Array[GUIDETriggerComboCancelAction] = [] + +var _current_step:int = -1 +var _remaining_time:float = 0 + +func _update_state(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + if steps.is_empty(): + push_warning("Combo with no steps will never fire.") + return GUIDETriggerState.NONE + + # initial setup + if _current_step == -1: + for step in steps: + step._prepare() + for action in cancellation_actions: + action._prepare() + _reset() + + + var current_action := steps[_current_step].action + if current_action == null: + push_warning("Step ", _current_step , " has no action ", resource_path) + return GUIDETriggerState.NONE + + # check if any of our cancellation actions fired + for action in cancellation_actions: + # if the action is the current action we don't count its firing as cancellation + if action.action == current_action: + continue + + if action._has_fired: + if enable_debug_print: + print("Combo cancelled by action '", action.action._editor_name(), "'.") + _reset() + return GUIDETriggerState.NONE + + # check if any of the steps has fired out of order + for step in steps: + if step.action == current_action: + continue + + if step._has_fired: + if enable_debug_print: + print("Combo out of order step by action '", step.action._editor_name(), "'.") + _reset() + return GUIDETriggerState.NONE + + # check if we took too long (unless we're in the first step) + if _current_step > 0: + _remaining_time -= delta + if _remaining_time <= 0.0: + if enable_debug_print: + print("Step time for step ", _current_step , " exceeded.") + _reset() + return GUIDETriggerState.NONE + + # if the current action was fired, if so advance to the next + if steps[_current_step]._has_fired: + # reset this step, so it will not count as misfired next round + steps[_current_step]._has_fired = false + if _current_step + 1 >= steps.size(): + # we finished the combo + if enable_debug_print: + print("Combo fired.") + _reset() + return GUIDETriggerState.TRIGGERED + + # otherwise, pick the next step + _current_step += 1 + if enable_debug_print: + print("Combo advanced to step " , _current_step, ".") + _remaining_time = steps[_current_step].time_to_actuate + + # Reset all steps and cancellation actions to "not fired" in + # case they were triggered by this action. Otherwise a double-tap + # would immediately fire for both taps once the first is through + for step in steps: + step._has_fired = false + for action in cancellation_actions: + action._has_fired = false + + # and in any case we're still processing. + return GUIDETriggerState.ONGOING + + +func _reset(): + if enable_debug_print: + print("Combo reset.") + _current_step = 0 + _remaining_time = steps[0].time_to_actuate + for step in steps: + step._has_fired = false + for action in cancellation_actions: + action._has_fired = false + +func _editor_name() -> String: + return "Combo" + +func _editor_description() -> String: + return "Fires, when the input exceeds the actuation threshold." + diff --git a/addons/guide/triggers/guide_trigger_combo.gd.uid b/addons/guide/triggers/guide_trigger_combo.gd.uid new file mode 100644 index 0000000..6a9db7e --- /dev/null +++ b/addons/guide/triggers/guide_trigger_combo.gd.uid @@ -0,0 +1 @@ +uid://biioody2ca0e7 diff --git a/addons/guide/triggers/guide_trigger_combo_cancel_action.gd b/addons/guide/triggers/guide_trigger_combo_cancel_action.gd new file mode 100644 index 0000000..10a0e83 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_combo_cancel_action.gd @@ -0,0 +1,27 @@ +@icon("res://addons/guide/guide_internal.svg") +class_name GUIDETriggerComboCancelAction +extends Resource + +@export var action:GUIDEAction +@export_flags("Triggered:1", "Started:2", "Ongoing:4", "Cancelled:8","Completed:16") +var completion_events:int = GUIDETriggerCombo.ActionEventType.TRIGGERED + +var _has_fired:bool = false + +func _prepare(): + if completion_events & GUIDETriggerCombo.ActionEventType.TRIGGERED: + action.triggered.connect(_fired) + if completion_events & GUIDETriggerCombo.ActionEventType.STARTED: + action.started.connect(_fired) + if completion_events & GUIDETriggerCombo.ActionEventType.ONGOING: + action.ongoing.connect(_fired) + if completion_events & GUIDETriggerCombo.ActionEventType.CANCELLED: + action.cancelled.connect(_fired) + if completion_events & GUIDETriggerCombo.ActionEventType.COMPLETED: + action.completed.connect(_fired) + _has_fired = false + + +func _fired(): + _has_fired = true + diff --git a/addons/guide/triggers/guide_trigger_combo_cancel_action.gd.uid b/addons/guide/triggers/guide_trigger_combo_cancel_action.gd.uid new file mode 100644 index 0000000..9bbbdc5 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_combo_cancel_action.gd.uid @@ -0,0 +1 @@ +uid://ddgp5tashyo8o diff --git a/addons/guide/triggers/guide_trigger_combo_step.gd b/addons/guide/triggers/guide_trigger_combo_step.gd new file mode 100644 index 0000000..4e22bf7 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_combo_step.gd @@ -0,0 +1,29 @@ +@icon("res://addons/guide/guide_internal.svg") +class_name GUIDETriggerComboStep +extends Resource + +@export var action:GUIDEAction +@export_flags("Triggered:1", "Started:2", "Ongoing:4", "Cancelled:8","Completed:16") +var completion_events:int = GUIDETriggerCombo.ActionEventType.TRIGGERED +@export var time_to_actuate:float = 0.5 + + +var _has_fired:bool = false + +func _prepare(): + if completion_events & GUIDETriggerCombo.ActionEventType.TRIGGERED: + action.triggered.connect(_fired) + if completion_events & GUIDETriggerCombo.ActionEventType.STARTED: + action.started.connect(_fired) + if completion_events & GUIDETriggerCombo.ActionEventType.ONGOING: + action.ongoing.connect(_fired) + if completion_events & GUIDETriggerCombo.ActionEventType.CANCELLED: + action.cancelled.connect(_fired) + if completion_events & GUIDETriggerCombo.ActionEventType.COMPLETED: + action.completed.connect(_fired) + _has_fired = false + + +func _fired(): + _has_fired = true + diff --git a/addons/guide/triggers/guide_trigger_combo_step.gd.uid b/addons/guide/triggers/guide_trigger_combo_step.gd.uid new file mode 100644 index 0000000..a864287 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_combo_step.gd.uid @@ -0,0 +1 @@ +uid://be47edmg8hwpo diff --git a/addons/guide/triggers/guide_trigger_down.gd b/addons/guide/triggers/guide_trigger_down.gd new file mode 100644 index 0000000..5327d62 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_down.gd @@ -0,0 +1,20 @@ +## Fires, when the input exceeds the actuation threshold. This is +## the default trigger when no trigger is specified. +@tool +class_name GUIDETriggerDown +extends GUIDETrigger + +func _update_state(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + # if the input is actuated, then the trigger is triggered. + if _is_actuated(input, value_type): + return GUIDETriggerState.TRIGGERED + # otherwise, the trigger is not triggered. + return GUIDETriggerState.NONE + + +func _editor_name() -> String: + return "Down" + +func _editor_description() -> String: + return "Fires, when the input exceeds the actuation threshold. This is\n" +\ + "the default trigger when no trigger is specified." diff --git a/addons/guide/triggers/guide_trigger_down.gd.uid b/addons/guide/triggers/guide_trigger_down.gd.uid new file mode 100644 index 0000000..fd07aaf --- /dev/null +++ b/addons/guide/triggers/guide_trigger_down.gd.uid @@ -0,0 +1 @@ +uid://b4cdrn4paoj3i diff --git a/addons/guide/triggers/guide_trigger_hold.gd b/addons/guide/triggers/guide_trigger_hold.gd new file mode 100644 index 0000000..8ad5bb2 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_hold.gd @@ -0,0 +1,43 @@ +@tool +## A trigger that activates when the input is held down for a certain amount of time. +class_name GUIDETriggerHold +extends GUIDETrigger + +## The time for how long the input must be held. +@export var hold_treshold:float = 1.0 +## If true, the trigger will only fire once until the input is released. Otherwise the trigger will fire every frame. +@export var is_one_shot:bool = false + +var _accumulated_time:float = 0 +var _did_shoot:bool = false + +func _update_state(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + # if the input is actuated, accumulate time and check if the hold threshold has been reached + if _is_actuated(input, value_type): + _accumulated_time += delta + + if _accumulated_time >= hold_treshold: + # if the trigger is one shot and we already shot, then we will not trigger again. + if is_one_shot and _did_shoot: + return GUIDETriggerState.NONE + else: + # otherwise, we will just trigger. + _did_shoot = true + return GUIDETriggerState.TRIGGERED + else: + # if the hold threshold has not been reached, then the trigger is ongoing. + return GUIDETriggerState.ONGOING + else: + # if the input is not actuated, then the trigger is not triggered and we reset the accumulated time. + # and our one shot flag. + _accumulated_time = 0 + _did_shoot = false + return GUIDETriggerState.NONE + + +func _editor_name() -> String: + return "Hold" + +func _editor_description() -> String: + return "Fires, once the input has remained actuated for hold_threshold seconds.\n" + \ + "My fire once or repeatedly." diff --git a/addons/guide/triggers/guide_trigger_hold.gd.uid b/addons/guide/triggers/guide_trigger_hold.gd.uid new file mode 100644 index 0000000..d835396 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_hold.gd.uid @@ -0,0 +1 @@ +uid://cfvgpvihp74si diff --git a/addons/guide/triggers/guide_trigger_pressed.gd b/addons/guide/triggers/guide_trigger_pressed.gd new file mode 100644 index 0000000..97fd0e1 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_pressed.gd @@ -0,0 +1,22 @@ +@tool +## A trigger that activates when the input is pushed down. Will only emit a +## trigger event once. Holding the input will not trigger further events. +class_name GUIDETriggerPressed +extends GUIDETrigger + + +func _update_state(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + if _is_actuated(input, value_type): + if not _is_actuated(_last_value, value_type): + return GUIDETriggerState.TRIGGERED + + return GUIDETriggerState.NONE + + +func _editor_name() -> String: + return "Pressed" + + +func _editor_description() -> String: + return "Fires once, when the input exceeds actuation threshold. Holding the input\n" + \ + "will not fire additional triggers." diff --git a/addons/guide/triggers/guide_trigger_pressed.gd.uid b/addons/guide/triggers/guide_trigger_pressed.gd.uid new file mode 100644 index 0000000..9148235 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_pressed.gd.uid @@ -0,0 +1 @@ +uid://b52rqq28tuqpg diff --git a/addons/guide/triggers/guide_trigger_pulse.gd b/addons/guide/triggers/guide_trigger_pulse.gd new file mode 100644 index 0000000..61ee88c --- /dev/null +++ b/addons/guide/triggers/guide_trigger_pulse.gd @@ -0,0 +1,86 @@ +@tool +## A trigger that activates when the input is pushed down and then repeatedly sends trigger events at a fixed interval. +## Note: the trigger will be either triggering or ongoing until the input is released. +## Note: at most one pulse will be emitted per frame. +class_name GUIDETriggerPulse +extends GUIDETrigger + +## If true, the trigger will trigger immediately when the input is actuated. Otherwise, the trigger will wait for the initial delay. +@export var trigger_on_start:bool = true +## The delay after the initial actuation before pulsing begins. +@export var initial_delay:float = 0.3: + set(value): + initial_delay = max(0, value) + +## The interval between pulses. Set to 0 to pulse every frame. +@export var pulse_interval:float = 0.1: + set(value): + pulse_interval = max(0, value) + +## Maximum number of pulses. If <= 0, the trigger will pulse indefinitely. +@export var max_pulses:int = 0 + +var _delay_until_next_pulse:float = 0 +var _emitted_pulses:int = 0 + +func _update_state(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + if _is_actuated(input, value_type): + if not _is_actuated(_last_value, value_type): + # we went from "not actuated" to actuated, pulsing starts + _delay_until_next_pulse = initial_delay + if trigger_on_start: + return GUIDETriggerState.TRIGGERED + else: + return GUIDETriggerState.ONGOING + + # if we already are pulsing and have exceeded the maximum number of pulses, we will not pulse anymore. + if max_pulses > 0 and _emitted_pulses >= max_pulses: + return GUIDETriggerState.NONE + + # subtract the delta from the delay until the next pulse + _delay_until_next_pulse -= delta + + if _delay_until_next_pulse > 0: + # we are still waiting for the next pulse, nothing to do. + return GUIDETriggerState.ONGOING + + # now delta could be larger than our pulse, in which case we loose a few pulses. + # as we can pulse at most once per frame. + + # in case someone sets the pulse interval to 0, we will pulse every frame. + if is_equal_approx(pulse_interval, 0): + _delay_until_next_pulse = 0 + if max_pulses > 0: + _emitted_pulses += 1 + return GUIDETriggerState.TRIGGERED + + # Now add the delay until the next pulse + _delay_until_next_pulse += pulse_interval + + # If the interval is really small, we can potentially have skipped some pulses + if _delay_until_next_pulse <= 0: + # we have skipped some pulses + var skipped_pulses:int = int(-_delay_until_next_pulse / pulse_interval) + _delay_until_next_pulse += skipped_pulses * pulse_interval + if max_pulses > 0: + _emitted_pulses += skipped_pulses + if _emitted_pulses >= max_pulses: + return GUIDETriggerState.NONE + + # Record a pulse and return triggered + if max_pulses > 0: + _emitted_pulses += 1 + return GUIDETriggerState.TRIGGERED + + # if the input is not actuated, then the trigger is not triggered. + _emitted_pulses = 0 + _delay_until_next_pulse = 0 + return GUIDETriggerState.NONE + + +func _editor_name() -> String: + return "Pulse" + + +func _editor_description() -> String: + return "Fires at an interval while the input is actuated." diff --git a/addons/guide/triggers/guide_trigger_pulse.gd.uid b/addons/guide/triggers/guide_trigger_pulse.gd.uid new file mode 100644 index 0000000..77b958f --- /dev/null +++ b/addons/guide/triggers/guide_trigger_pulse.gd.uid @@ -0,0 +1 @@ +uid://dna8tkcuk528v diff --git a/addons/guide/triggers/guide_trigger_released.gd b/addons/guide/triggers/guide_trigger_released.gd new file mode 100644 index 0000000..d1509e9 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_released.gd @@ -0,0 +1,21 @@ +@tool +## A trigger that activates when the input is released down. Will only emit a +## trigger event once. +class_name GUIDETriggerReleased +extends GUIDETrigger + + +func _update_state(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + if not _is_actuated(input, value_type): + if _is_actuated(_last_value, value_type): + return GUIDETriggerState.TRIGGERED + + return GUIDETriggerState.NONE + + +func _editor_name() -> String: + return "Released" + + +func _editor_description() -> String: + return "Fires once, when the input goes from actuated to not actuated. The opposite of the Pressed trigger." diff --git a/addons/guide/triggers/guide_trigger_released.gd.uid b/addons/guide/triggers/guide_trigger_released.gd.uid new file mode 100644 index 0000000..168b74b --- /dev/null +++ b/addons/guide/triggers/guide_trigger_released.gd.uid @@ -0,0 +1 @@ +uid://biiggjw6tv4uq diff --git a/addons/guide/triggers/guide_trigger_stability.gd b/addons/guide/triggers/guide_trigger_stability.gd new file mode 100644 index 0000000..cfe01f9 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_stability.gd @@ -0,0 +1,72 @@ +@tool +## Triggers depending on whether the input changes while actuated. This trigger is +## is implicit, so it must succeed for all other triggers to succeed. +class_name GUIDETriggerStability +extends GUIDETrigger + +enum TriggerWhen { + ## Input must be stable + INPUT_IS_STABLE, + ## Input must change + INPUT_CHANGES +} + + +## The maximum amount that the input can change after actuation before it is +## considered "changed". +@export var max_deviation:float = 1 + +## When should the trigger trigger? +@export var trigger_when:TriggerWhen = TriggerWhen.INPUT_IS_STABLE + + +var _initial_value:Vector3 +var _deviated:bool = false + + +func _get_trigger_type() -> GUIDETriggerType: + return GUIDETriggerType.IMPLICIT + + +func _update_state(input:Vector3, delta:float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + if _is_actuated(input, value_type): + if _deviated: + if trigger_when == TriggerWhen.INPUT_IS_STABLE: + return GUIDETriggerState.NONE + return GUIDETriggerState.TRIGGERED + + + if not _is_actuated(_last_value, value_type): + # we went from "not actuated" to actuated, start + _initial_value = input + if trigger_when == TriggerWhen.INPUT_IS_STABLE: + return GUIDETriggerState.TRIGGERED + else: + return GUIDETriggerState.ONGOING + + # calculate how far the input is from the initial value + if _initial_value.distance_squared_to(input) > (max_deviation * max_deviation): + _deviated = true + if trigger_when == TriggerWhen.INPUT_IS_STABLE: + return GUIDETriggerState.NONE + return GUIDETriggerState.TRIGGERED + + if trigger_when == TriggerWhen.INPUT_IS_STABLE: + return GUIDETriggerState.TRIGGERED + + return GUIDETriggerState.ONGOING + + # if the input is not actuated + _deviated = false + return GUIDETriggerState.NONE + + + + +func _editor_name() -> String: + return "Stability" + + +func _editor_description() -> String: + return "Triggers depending on whether the input changes while actuated. This trigger\n" +\ + "is implicit, so it must succeed for all other triggers to succeed." diff --git a/addons/guide/triggers/guide_trigger_stability.gd.uid b/addons/guide/triggers/guide_trigger_stability.gd.uid new file mode 100644 index 0000000..41a665d --- /dev/null +++ b/addons/guide/triggers/guide_trigger_stability.gd.uid @@ -0,0 +1 @@ +uid://deoksgw6vfo5v diff --git a/addons/guide/triggers/guide_trigger_tap.gd b/addons/guide/triggers/guide_trigger_tap.gd new file mode 100644 index 0000000..a0d0c26 --- /dev/null +++ b/addons/guide/triggers/guide_trigger_tap.gd @@ -0,0 +1,48 @@ +@tool +## A trigger that activates when the input is tapped and released before the time threshold is reached. +class_name GUIDETriggerTap +extends GUIDETrigger + +## The time threshold for the tap to be considered a tap. +@export var tap_threshold: float = 0.2 + +var _accumulated_time: float = 0 + + +func _update_state(input: Vector3, delta: float, value_type:GUIDEAction.GUIDEActionValueType) -> GUIDETriggerState: + if _is_actuated(input, value_type): + # if the input was actuated before, and the tap threshold has been exceeded, the trigger is locked down + # until the input is released and we can exit out early + if _is_actuated(_last_value, value_type) and _accumulated_time > tap_threshold: + return GUIDETriggerState.NONE + + # accumulate time + _accumulated_time += delta + + if _accumulated_time < tap_threshold: + return GUIDETriggerState.ONGOING + else: + # we have exceeded the tap threshold, so the tap is not triggered. + return GUIDETriggerState.NONE + + else: # not actuated right now + # if the input was actuated before... + if _is_actuated(_last_value, value_type): + # ... and the accumulated time is less than the threshold, then the tap is triggered. + if _accumulated_time < tap_threshold: + _accumulated_time = 0 + return GUIDETriggerState.TRIGGERED + + # Otherwise, the tap is not triggered, but we reset the accumulated time + # so the trigger is now again ready to be triggered. + _accumulated_time = 0 + + # in either case, the trigger is not triggered. + return GUIDETriggerState.NONE + +func _editor_name() -> String: + return "Tap" + + +func _editor_description() -> String: + return "Fires when the input is actuated and released within the given timeframe." diff --git a/addons/guide/triggers/guide_trigger_tap.gd.uid b/addons/guide/triggers/guide_trigger_tap.gd.uid new file mode 100644 index 0000000..9b92bed --- /dev/null +++ b/addons/guide/triggers/guide_trigger_tap.gd.uid @@ -0,0 +1 @@ +uid://c76fmncyucwqc diff --git a/addons/guide/ui/guide_icon_renderer.gd b/addons/guide/ui/guide_icon_renderer.gd new file mode 100644 index 0000000..558303e --- /dev/null +++ b/addons/guide/ui/guide_icon_renderer.gd @@ -0,0 +1,30 @@ +## Base class for icon renderers. Note that all icon renderers must be tool +## scripts. +@tool +class_name GUIDEIconRenderer +extends Control + +## The priority of this icon renderer. Built-in renderers use priority 0. Built-in +## fallback renderer uses priority 100. The smaller the number the higher the priority. +@export var priority:int = 0 + +## Whether or not this renderer can render an icon for this input. +func supports(input:GUIDEInput) -> bool: + return false + +## Set up the scene so that the given input can be rendered. This will +## only be called for input where `supports` has returned true. +func render(input:GUIDEInput) -> void: + pass + + +## A cache key for the given input. This should be unique for this renderer +## and the given input. The same input should yield the same cache key for +## each renderer. +func cache_key(input:GUIDEInput) -> String: + push_error("Custom renderers must override the cache_key function to ensure proper caching.") + return "i-forgot-the-cache-key" + +func _ready(): + process_mode = Node.PROCESS_MODE_ALWAYS + diff --git a/addons/guide/ui/guide_icon_renderer.gd.uid b/addons/guide/ui/guide_icon_renderer.gd.uid new file mode 100644 index 0000000..388cb65 --- /dev/null +++ b/addons/guide/ui/guide_icon_renderer.gd.uid @@ -0,0 +1 @@ +uid://c25x75clb4fgl diff --git a/addons/guide/ui/guide_input_formatter.gd b/addons/guide/ui/guide_input_formatter.gd new file mode 100644 index 0000000..1fd670c --- /dev/null +++ b/addons/guide/ui/guide_input_formatter.gd @@ -0,0 +1,358 @@ +@tool +## Helper class for formatting GUIDE input for the UI. +class_name GUIDEInputFormatter + +const IconMaker = preload("icon_maker/icon_maker.gd") +const KeyRenderer = preload("renderers/keyboard/key_renderer.tscn") +const MouseRenderer = preload("renderers/mouse/mouse_renderer.tscn") +const TouchRenderer = preload("renderers/touch/touch_renderer.tscn") +const JoyRenderer = preload("renderers/joy/joy_renderer.tscn") +const XboxRenderer = preload("renderers/controllers/xbox/xbox_controller_renderer.tscn") +const PlayStationRenderer = preload("renderers/controllers/playstation/playstation_controller_renderer.tscn") +const SwitchRenderer = preload("renderers/controllers/switch/switch_controller_renderer.tscn") +const ActionRenderer = preload("renderers/misc/action_renderer.tscn") +const FallbackRenderer = preload("renderers/misc/fallback_renderer.tscn") +const DefaultTextProvider = preload("text_providers/default_text_provider.gd") +const XboxTextProvider = preload("text_providers/controllers/xbox/xbox_controller_text_provider.gd") +const PlayStationTextProvider = preload("text_providers/controllers/playstation/playstation_controller_text_provider.gd") +const SwitchTextProvider = preload("text_providers/controllers/switch/switch_controller_text_provider.gd") + +# These are shared across all instances +static var _icon_maker:IconMaker +static var _icon_renderers:Array[GUIDEIconRenderer] = [] +static var _text_providers:Array[GUIDETextProvider] = [] +static var _is_ready:bool = false + +## Separator to separate mixed input. +static var mixed_input_separator:String = ", " +## Separator to separate chorded input. +static var chorded_input_separator:String = " + " +## Separator to separate combo input. +static var combo_input_separator:String = " > " + +# These are per-instance +var _action_resolver:Callable +var _icon_size:int + +static func _ensure_readiness(): + if _is_ready: + return + + # reconnect to an icon maker that might be there + var root = Engine.get_main_loop().root + for child in root.get_children(): + if child is IconMaker: + _icon_maker = child + + if _icon_maker == null: + _icon_maker = preload("icon_maker/icon_maker.tscn").instantiate() + root.add_child.call_deferred(_icon_maker) + + add_icon_renderer(KeyRenderer.instantiate()) + add_icon_renderer(MouseRenderer.instantiate()) + add_icon_renderer(TouchRenderer.instantiate()) + add_icon_renderer(ActionRenderer.instantiate()) + add_icon_renderer(JoyRenderer.instantiate()) + add_icon_renderer(XboxRenderer.instantiate()) + add_icon_renderer(PlayStationRenderer.instantiate()) + add_icon_renderer(SwitchRenderer.instantiate()) + add_icon_renderer(FallbackRenderer.instantiate()) + + add_text_provider(DefaultTextProvider.new()) + add_text_provider(XboxTextProvider.new()) + add_text_provider(PlayStationTextProvider.new()) + add_text_provider(SwitchTextProvider.new()) + + _is_ready = true + + +## This will clean up the rendering infrastructure used for generating +## icons. Note that in a normal game you will have no need to call this +## as the infrastructure is needed throughout the run of your game. +## It might be useful in tests though, to get rid of spurious warnings +## about orphaned nodes. +static func cleanup(): + _is_ready = false + + # free all the nodes to avoid memory leaks + for renderer in _icon_renderers: + renderer.queue_free() + + _icon_renderers.clear() + + _text_providers.clear() + if is_instance_valid(_icon_maker): + _icon_maker.queue_free() + + +func _init(icon_size:int = 32, resolver:Callable = func(action) -> GUIDEActionMapping: return null ): + _icon_size = icon_size + _action_resolver = resolver + + +## Adds an icon renderer for rendering icons. +static func add_icon_renderer(renderer:GUIDEIconRenderer) -> void: + _icon_renderers.append(renderer) + _icon_renderers.sort_custom(func(r1, r2): return r1.priority < r2.priority) + +## Removes an icon renderer. +static func remove_icon_renderer(renderer:GUIDEIconRenderer) -> void: + _icon_renderers.erase(renderer) + +## Adds a text provider for rendering text. +static func add_text_provider(provider:GUIDETextProvider) -> void: + _text_providers.append(provider) + _text_providers.sort_custom(func(r1, r2): return r1.priority < r2.priority) + + +## Removes a text provider +static func remove_text_provider(provider:GUIDETextProvider) -> void: + _text_providers.erase(provider) + + +## Returns an input formatter that can format actions using the currently active inputs. +static func for_active_contexts(icon_size:int = 32) -> GUIDEInputFormatter: + var resolver = func(action:GUIDEAction) -> GUIDEActionMapping: + for mapping in GUIDE._active_action_mappings: + if mapping.action == action: + return mapping + return null + return GUIDEInputFormatter.new(icon_size, resolver) + + +## Returns an input formatter that can format actions using the given context. +static func for_context(context:GUIDEMappingContext, icon_size:int = 32) -> GUIDEInputFormatter: + var resolver:Callable = func(action:GUIDEAction) -> GUIDEActionMapping: + for mapping in context.mappings: + if mapping.action == action: + return mapping + return null + + return GUIDEInputFormatter.new(icon_size, resolver) + + +## Formats the action input as richtext with icons suitable for a RichTextLabel. This function +## is async as icons may need to be rendered in the background which can take a few frames, so +## you will need to await on it. +func action_as_richtext_async(action:GUIDEAction) -> String: + return await _materialized_as_richtext_async(_materialize_action_input(action)) + + +## Formats the action input as plain text which can be used in any UI component. This is a bit +## more light-weight than formatting as icons and returns immediately. +func action_as_text(action:GUIDEAction) -> String: + return _materialized_as_text(_materialize_action_input(action)) + +## Formats the input as richtext with icons suitable for a RichTextLabel. This function +## is async as icons may need to be rendered in the background which can take a few frames, so +## you will need to await on it. +func input_as_richtext_async(input:GUIDEInput, materialize_actions:bool = true) -> String: + return await _materialized_as_richtext_async(_materialize_input(input, materialize_actions)) + + +## Formats the input as plain text which can be used in any UI component. This is a bit +## more light-weight than formatting as icons and returns immediately. +func input_as_text(input:GUIDEInput, materialize_actions:bool = true) -> String: + return _materialized_as_text(_materialize_input(input, materialize_actions)) + + +## Renders materialized input as text. +func _materialized_as_text(input:MaterializedInput) -> String: + _ensure_readiness() + if input is MaterializedSimpleInput: + var text:String = "" + for provider in _text_providers: + if provider.supports(input.input): + text = provider.get_text(input.input) + # first provider wins + break + if text == "": + pass + ## push_warning("No formatter found for input ", input) + return text + + var separator = _separator_for_input(input) + if separator == "" or input.parts.is_empty(): + return "" + + var parts:Array[String] = [] + for part in input.parts: + parts.append(_materialized_as_text(part)) + + return separator.join(parts) + +## Renders materialized input as rich text. +func _materialized_as_richtext_async(input:MaterializedInput) -> String: + _ensure_readiness() + if input is MaterializedSimpleInput: + var icon:Texture2D = null + for renderer in _icon_renderers: + if renderer.supports(input.input): + icon = await _icon_maker.make_icon(input.input, renderer, _icon_size) + # first renderer wins + break + if icon == null: + push_warning("No renderer found for input ", input) + return "" + + return "[img]%s[/img]" % [icon.resource_path] + + + var separator = _separator_for_input(input) + if separator == "" or input.parts.is_empty(): + return "" + + var parts:Array[String] = [] + for part in input.parts: + parts.append(await _materialized_as_richtext_async(part)) + + return separator.join(parts) + + +func _separator_for_input(input:MaterializedInput) -> String: + if input is MaterializedMixedInput: + return mixed_input_separator + elif input is MaterializedComboInput: + return combo_input_separator + elif input is MaterializedChordedInput: + return chorded_input_separator + + push_error("Unknown materialized input type") + return "" + + +## Materializes action input. +func _materialize_action_input(action:GUIDEAction) -> MaterializedInput: + var result := MaterializedMixedInput.new() + if action == null: + push_warning("Trying to get inputs for a null action.") + return result + + # get the mapping for this action + var mapping:GUIDEActionMapping = _action_resolver.call(action) + + # if we have no mapping, well that's it, return an empty mixed input + if mapping == null: + return result + + # collect input mappings + for input_mapping in mapping.input_mappings: + var chorded_actions:Array[MaterializedInput] = [] + var combos:Array[MaterializedInput] = [] + + for trigger in input_mapping.triggers: + # if we have a combo trigger, materialize its input. + if trigger is GUIDETriggerCombo: + var combo := MaterializedComboInput.new() + for step:GUIDETriggerComboStep in trigger.steps: + combo.parts.append(_materialize_action_input(step.action)) + combos.append(combo) + + # if we have a chorded action, materialize its input + if trigger is GUIDETriggerChordedAction: + chorded_actions.append(_materialize_action_input(trigger.action)) + + if not chorded_actions.is_empty(): + # if we have chorded action then the whole mapping is chorded. + var chord := MaterializedChordedInput.new() + for chorded_action in chorded_actions: + chord.parts.append(chorded_action) + for combo in combos: + chord.parts.append(combo) + if combos.is_empty(): + if input_mapping.input != null: + chord.parts.append(_materialize_input(input_mapping.input)) + result.parts.append(chord) + else: + for combo in combos: + result.parts.append(combo) + if combos.is_empty(): + if input_mapping.input != null: + result.parts.append(_materialize_input(input_mapping.input)) + return result + +## Materializes direct input. +func _materialize_input(input:GUIDEInput, materialize_actions:bool = true) -> MaterializedInput: + if input == null: + push_warning("Trying to materialize a null input.") + return MaterializedMixedInput.new() + + # if its an action input, get its parts + if input is GUIDEInputAction: + if materialize_actions: + return _materialize_action_input(input.action) + else: + return MaterializedSimpleInput.new(input) + + # if its a key input, split out the modifiers + if input is GUIDEInputKey: + var chord := MaterializedChordedInput.new() + if input.control: + var ctrl = GUIDEInputKey.new() + ctrl.key = KEY_CTRL + chord.parts.append(MaterializedSimpleInput.new(ctrl)) + if input.alt: + var alt = GUIDEInputKey.new() + alt.key = KEY_ALT + chord.parts.append(MaterializedSimpleInput.new(alt)) + if input.shift: + var shift = GUIDEInputKey.new() + shift.key = KEY_SHIFT + chord.parts.append(MaterializedSimpleInput.new(shift)) + if input.meta: + var meta = GUIDEInputKey.new() + meta.key = KEY_META + chord.parts.append(MaterializedSimpleInput.new(meta)) + + # got no modifiers? + if chord.parts.is_empty(): + return MaterializedSimpleInput.new(input) + + chord.parts.append(MaterializedSimpleInput.new(input)) + return chord + + # everything else is just a simple input + return MaterializedSimpleInput.new(input) + +class MaterializedInput: + pass + +class MaterializedSimpleInput: + extends MaterializedInput + var input:GUIDEInput + + func _init(input:GUIDEInput): + self.input = input + +class MaterializedMixedInput: + extends MaterializedInput + var parts:Array[MaterializedInput] = [] + +class MaterializedChordedInput: + extends MaterializedInput + var parts:Array[MaterializedInput] = [] + +class MaterializedComboInput: + extends MaterializedInput + var parts:Array[MaterializedInput] = [] + + +## Returns the name of the associated joystick/pad of the given input. +## If the input is no joy input or the device name cannot be determined +## returns an empty string. +static func _joy_name_for_input(input:GUIDEInput) -> String: + if not input is GUIDEInputJoyBase: + return "" + + var joypads:Array[int] = Input.get_connected_joypads() + var joy_index = input.joy_index + if joy_index < 0: + # pick the first one + joy_index = 0 + + # We don't have such a controller, so bail out. + if joypads.size() <= joy_index: + return "" + + var id = joypads[joy_index] + return Input.get_joy_name(id) diff --git a/addons/guide/ui/guide_input_formatter.gd.uid b/addons/guide/ui/guide_input_formatter.gd.uid new file mode 100644 index 0000000..0ffe62a --- /dev/null +++ b/addons/guide/ui/guide_input_formatter.gd.uid @@ -0,0 +1 @@ +uid://duisgvlqywtbn diff --git a/addons/guide/ui/guide_text_provider.gd b/addons/guide/ui/guide_text_provider.gd new file mode 100644 index 0000000..2f84075 --- /dev/null +++ b/addons/guide/ui/guide_text_provider.gd @@ -0,0 +1,22 @@ +## Base class for text providers. A text provider provides a textual representation +## of an input which is displayed to the user. +## scripts. +@tool +class_name GUIDETextProvider + +## The priority of this text provider. The built-in text provider uses priority 0. +## The smaller the number the higher the priority. +@export var priority:int = 0 + +## Whether or not this provider can provide a text for this input. +func supports(input:GUIDEInput) -> bool: + return false + +## Provides the text for the given input. Will only be called when the +## input is supported by this text provider. Note that for key input +## this is not supposed to look at the modifiers. This function will +## be called separately for each modifier. +func get_text(input:GUIDEInput) -> String: + return "not implemented" + + diff --git a/addons/guide/ui/guide_text_provider.gd.uid b/addons/guide/ui/guide_text_provider.gd.uid new file mode 100644 index 0000000..1e9c968 --- /dev/null +++ b/addons/guide/ui/guide_text_provider.gd.uid @@ -0,0 +1 @@ +uid://di8xw2ysyq483 diff --git a/addons/guide/ui/icon_maker/icon_maker.gd b/addons/guide/ui/icon_maker/icon_maker.gd new file mode 100644 index 0000000..1a03a0d --- /dev/null +++ b/addons/guide/ui/icon_maker/icon_maker.gd @@ -0,0 +1,103 @@ +@tool +extends Node + +const CACHE_DIR:String = "user://_guide_cache" + +@onready var _sub_viewport:SubViewport = %SubViewport +@onready var _root:Node2D = %Root +@onready var _scene_holder = %SceneHolder + +var _pending_requests:Array[Job] = [] +var _current_request:Job = null +var _fetch_image:bool = false + +func _ready(): + # keep working when game is paused + process_mode = Node.PROCESS_MODE_ALWAYS + # don't needlessly eat performance + if _pending_requests.is_empty(): + set_process(false) + + +func clear_cache(): + var files = DirAccess.get_files_at(CACHE_DIR) + for file in files: + DirAccess.remove_absolute(CACHE_DIR + "/" + file) + +## Makes an icon for the given input and returns a Texture2D with the icon. Icons +## are cached on disk so subsequent calls for the same input will be faster. +func make_icon(input:GUIDEInput, renderer:GUIDEIconRenderer, height_px:int) -> Texture2D: + DirAccess.make_dir_recursive_absolute(CACHE_DIR) + var cache_key = (str(height_px) + renderer.cache_key(input)).sha256_text() + var cache_path = "user://_guide_cache/" + cache_key + ".res" + if ResourceLoader.exists(cache_path): + return ResourceLoader.load(cache_path, "Texture2D") + + var job = Job.new() + job.height = height_px + job.input = input + job.renderer = renderer + _pending_requests.append(job) + set_process(true) + + await job.done + + var image_texture = ImageTexture.create_from_image(job.result) + ResourceSaver.save(image_texture, cache_path) + image_texture.take_over_path(cache_path) + + return image_texture + + + +func _process(delta): + if _current_request == null and _pending_requests.is_empty(): + # nothing more to do.. + set_process(false) + return + + # nothing in progress, so pick the next request + if _current_request == null: + _current_request = _pending_requests.pop_front() + var renderer = _current_request.renderer + _root.add_child(renderer) + + renderer.render(_current_request.input) + await get_tree().process_frame + + var actual_size = renderer.get_rect().size + var scale = float(_current_request.height) / float(actual_size.y) + _root.scale = Vector2.ONE * scale + _sub_viewport.size = actual_size * scale + + _sub_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS + + # give the renderer some time to update itself. 3 frames seem + # to work nicely and keep things speedy. + await get_tree().process_frame + await get_tree().process_frame + await get_tree().process_frame + + _fetch_image = true + return + + # fetch the image after the renderer is done + if _fetch_image: + # we're done. make a copy of the viewport texture + var image:Image = _scene_holder.texture.get_image() + _current_request.result = image + _current_request.done.emit() + _current_request = null + # remove the renderer + _root.remove_child(_root.get_child(0)) + _sub_viewport.render_target_update_mode = SubViewport.UPDATE_DISABLED + _fetch_image = false + +class Job: + signal done() + var height:int + var input:GUIDEInput + var renderer:GUIDEIconRenderer + var result:Image + + diff --git a/addons/guide/ui/icon_maker/icon_maker.gd.uid b/addons/guide/ui/icon_maker/icon_maker.gd.uid new file mode 100644 index 0000000..bd0b53d --- /dev/null +++ b/addons/guide/ui/icon_maker/icon_maker.gd.uid @@ -0,0 +1 @@ +uid://dq6cdbdturmel diff --git a/addons/guide/ui/icon_maker/icon_maker.tscn b/addons/guide/ui/icon_maker/icon_maker.tscn new file mode 100644 index 0000000..662d2ce --- /dev/null +++ b/addons/guide/ui/icon_maker/icon_maker.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=3 format=3 uid="uid://8thurteeibtu"] + +[ext_resource type="Script" path="res://addons/guide/ui/icon_maker/icon_maker.gd" id="1_hdbjk"] + +[sub_resource type="ViewportTexture" id="ViewportTexture_kra7t"] +viewport_path = NodePath("SubViewport") + +[node name="GUIDEIconMaker" type="Node2D"] +script = ExtResource("1_hdbjk") + +[node name="SubViewport" type="SubViewport" parent="."] +unique_name_in_owner = true +transparent_bg = true +gui_disable_input = true +gui_snap_controls_to_pixels = false + +[node name="Root" type="Node2D" parent="SubViewport"] +unique_name_in_owner = true +scale = Vector2(0.1, 0.1) + +[node name="SceneHolder" type="Sprite2D" parent="."] +unique_name_in_owner = true +visible = false +texture = SubResource("ViewportTexture_kra7t") diff --git a/addons/guide/ui/renderers/controllers/controller_renderer.gd b/addons/guide/ui/renderers/controllers/controller_renderer.gd new file mode 100644 index 0000000..96b6fdc --- /dev/null +++ b/addons/guide/ui/renderers/controllers/controller_renderer.gd @@ -0,0 +1,171 @@ +@tool +extends GUIDEIconRenderer + +@export var controller_name_matches:Array[String] = [] +@export var a_button:Texture2D +@export var b_button:Texture2D +@export var x_button:Texture2D +@export var y_button:Texture2D +@export var left_stick:Texture2D +@export var left_stick_click:Texture2D +@export var right_stick:Texture2D +@export var right_stick_click:Texture2D +@export var left_bumper:Texture2D +@export var right_bumper:Texture2D +@export var left_trigger:Texture2D +@export var right_trigger:Texture2D +@export var dpad_up:Texture2D +@export var dpad_left:Texture2D +@export var dpad_right:Texture2D +@export var dpad_down:Texture2D +@export var start:Texture2D +@export var misc1:Texture2D +@export var back:Texture2D + + +@onready var _a_button:TextureRect = %AButton +@onready var _b_button:TextureRect = %BButton +@onready var _x_button:TextureRect = %XButton +@onready var _y_button:TextureRect = %YButton +@onready var _left_stick:TextureRect = %LeftStick +@onready var _left_stick_click:TextureRect = %LeftStickClick +@onready var _right_stick:TextureRect = %RightStick +@onready var _right_stick_click:TextureRect = %RightStickClick +@onready var _left_bumper:Control = %LeftBumper +@onready var _right_bumper:Control = %RightBumper +@onready var _left_trigger:Control = %LeftTrigger +@onready var _right_trigger:TextureRect = %RightTrigger +@onready var _dpad_up:TextureRect = %DpadUp +@onready var _dpad_left:TextureRect = %DpadLeft +@onready var _dpad_right:TextureRect = %DpadRight +@onready var _dpad_down:TextureRect = %DpadDown +@onready var _start:TextureRect = %Start +@onready var _misc1:TextureRect = %Misc1 +@onready var _back:TextureRect = %Back +@onready var _left_right:Control = %LeftRight +@onready var _up_down:Control = %UpDown +@onready var _controls:Control = %Controls +@onready var _directions:Control = %Directions + + +func _ready(): + super() + _a_button.texture = a_button + _b_button.texture = b_button + _x_button.texture = x_button + _y_button.texture = y_button + _left_stick.texture = left_stick + _left_stick_click.texture = left_stick_click + _right_stick.texture = right_stick + _right_stick_click.texture = right_stick_click + _left_bumper.texture = left_bumper + _right_bumper.texture = right_bumper + _left_trigger.texture = left_trigger + _right_trigger.texture = right_trigger + _dpad_up.texture = dpad_up + _dpad_left.texture = dpad_left + _dpad_right.texture = dpad_right + _dpad_down.texture = dpad_down + _start.texture = start + _misc1.texture = misc1 + _back.texture = back + +func supports(input:GUIDEInput) -> bool: + var joy_name = GUIDEInputFormatter._joy_name_for_input(input) + if joy_name == "": + return false + + # Look if the controller name matches one of the supported ones + var haystack = joy_name.to_lower() + for needle in controller_name_matches: + if haystack.contains(needle.to_lower()): + return true + + return false + +func render(input:GUIDEInput) -> void: + for control in _controls.get_children(): + control.visible = false + for direction in _directions.get_children(): + direction.visible = false + _directions.visible = false + + + if input is GUIDEInputJoyAxis1D: + match input.axis: + JOY_AXIS_LEFT_X: + _left_stick.visible = true + _show_left_right() + JOY_AXIS_LEFT_Y: + _left_stick.visible = true + _show_up_down() + JOY_AXIS_RIGHT_X: + _right_stick.visible = true + _show_left_right() + JOY_AXIS_RIGHT_Y: + _right_stick.visible = true + _show_up_down() + JOY_AXIS_TRIGGER_LEFT: + _left_trigger.visible = true + JOY_AXIS_TRIGGER_RIGHT: + _right_trigger.visible = true + + if input is GUIDEInputJoyAxis2D: + # We assume that there is no input mixing horizontal and vertical + # from different sticks into a 2D axis as this would confuse the + # players. + match input.x: + JOY_AXIS_LEFT_X, JOY_AXIS_LEFT_Y: + _left_stick.visible = true + JOY_AXIS_RIGHT_X, JOY_AXIS_RIGHT_Y: + _right_stick.visible = true + + if input is GUIDEInputJoyButton: + match input.button: + JOY_BUTTON_A: + _a_button.visible = true + JOY_BUTTON_B: + _b_button.visible = true + JOY_BUTTON_X: + _x_button.visible = true + JOY_BUTTON_Y: + _y_button.visible = true + JOY_BUTTON_DPAD_LEFT: + _dpad_left.visible = true + JOY_BUTTON_DPAD_RIGHT: + _dpad_right.visible = true + JOY_BUTTON_DPAD_UP: + _dpad_up.visible = true + JOY_BUTTON_DPAD_DOWN: + _dpad_down.visible = true + JOY_BUTTON_LEFT_SHOULDER: + _left_bumper.visible = true + JOY_BUTTON_RIGHT_SHOULDER: + _right_bumper.visible = true + JOY_BUTTON_LEFT_STICK: + _left_stick_click.visible = true + JOY_BUTTON_RIGHT_STICK: + _right_stick_click.visible = true + JOY_BUTTON_RIGHT_STICK: + _right_stick_click.visible = true + JOY_BUTTON_START: + _start.visible = true + JOY_BUTTON_BACK: + _back.visible = true + JOY_BUTTON_MISC1: + _misc1.visible = true + + call("queue_sort") + + +func _show_left_right(): + _directions.visible = true + _left_right.visible = true + +func _show_up_down(): + _directions.visible = true + _up_down.visible = true + + +func cache_key(input:GUIDEInput) -> String: + return "7581f483-bc68-411f-98ad-dc246fd2593a" + input.to_string() + GUIDEInputFormatter._joy_name_for_input(input) diff --git a/addons/guide/ui/renderers/controllers/controller_renderer.gd.uid b/addons/guide/ui/renderers/controllers/controller_renderer.gd.uid new file mode 100644 index 0000000..0b051f6 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/controller_renderer.gd.uid @@ -0,0 +1 @@ +uid://cj5qd3pot17v3 diff --git a/addons/guide/ui/renderers/controllers/controller_renderer.tscn b/addons/guide/ui/renderers/controllers/controller_renderer.tscn new file mode 100644 index 0000000..9ab0538 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/controller_renderer.tscn @@ -0,0 +1,135 @@ +[gd_scene load_steps=4 format=3 uid="uid://bsaylcb5ixjxk"] + +[ext_resource type="Script" path="res://addons/guide/ui/renderers/controllers/controller_renderer.gd" id="1_yt13e"] +[ext_resource type="Texture2D" uid="uid://bmgxqbypegjxh" path="res://addons/guide/ui/renderers/textures/arrow_horizontal.svg" id="2_nv2ob"] +[ext_resource type="Texture2D" uid="uid://bu5nlug6uf03w" path="res://addons/guide/ui/renderers/textures/arrow_vertical.svg" id="3_ejti1"] + +[node name="ControllerRenderer" type="MarginContainer"] +offset_right = 100.0 +offset_bottom = 100.0 +size_flags_horizontal = 0 +script = ExtResource("1_yt13e") +priority = -1 + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_horizontal = 0 + +[node name="Controls" type="MarginContainer" parent="HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(100, 100) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="AButton" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="BButton" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="XButton" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="YButton" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="LeftStick" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="LeftStickClick" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="RightStick" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="RightStickClick" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="LeftBumper" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="RightBumper" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="LeftTrigger" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="RightTrigger" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="DpadUp" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="DpadLeft" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="DpadRight" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="DpadDown" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="Start" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="Misc1" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="Back" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +stretch_mode = 5 + +[node name="Directions" type="MarginContainer" parent="HBoxContainer"] +unique_name_in_owner = true +visible = false +custom_minimum_size = Vector2(100, 100) +layout_mode = 2 + +[node name="LeftRight" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("2_nv2ob") +stretch_mode = 5 + +[node name="UpDown" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("3_ejti1") +stretch_mode = 5 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Circle.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Circle.png new file mode 100644 index 0000000..05a89a9 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Circle.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Circle.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Circle.png.import new file mode 100644 index 0000000..9aa8906 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Circle.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://civpcnwgbu5ky" +path="res://.godot/imported/PS5_Circle.png-991ec3d8ff387e8a1997f29928333c68.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Circle.png" +dest_files=["res://.godot/imported/PS5_Circle.png-991ec3d8ff387e8a1997f29928333c68.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Cross.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Cross.png new file mode 100644 index 0000000..395a898 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Cross.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Cross.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Cross.png.import new file mode 100644 index 0000000..f0a694d --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Cross.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cfy1rx4d4wjdh" +path="res://.godot/imported/PS5_Cross.png-94e7143faf483eb3d6ca6505fc615cd3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Cross.png" +dest_files=["res://.godot/imported/PS5_Cross.png-94e7143faf483eb3d6ca6505fc615cd3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad.png new file mode 100644 index 0000000..49e6405 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad.png.import new file mode 100644 index 0000000..ed99363 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ubnurptd6ee2" +path="res://.godot/imported/PS5_Dpad.png-ef26d9f78f150d4ab2b9e6bbe325f986.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad.png" +dest_files=["res://.godot/imported/PS5_Dpad.png-ef26d9f78f150d4ab2b9e6bbe325f986.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Down.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Down.png new file mode 100644 index 0000000..a8f893a Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Down.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Down.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Down.png.import new file mode 100644 index 0000000..26ef580 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Down.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vk1vje3280tk" +path="res://.godot/imported/PS5_Dpad_Down.png-ba21ca6e311100c142d2b003152ea1d2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Down.png" +dest_files=["res://.godot/imported/PS5_Dpad_Down.png-ba21ca6e311100c142d2b003152ea1d2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Left.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Left.png new file mode 100644 index 0000000..2bdc048 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Left.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Left.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Left.png.import new file mode 100644 index 0000000..9a31227 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Left.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bkpw61ctv0fbg" +path="res://.godot/imported/PS5_Dpad_Left.png-bd78cf7c0092facc48bbf8fd7816f7a2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Left.png" +dest_files=["res://.godot/imported/PS5_Dpad_Left.png-bd78cf7c0092facc48bbf8fd7816f7a2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Right.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Right.png new file mode 100644 index 0000000..b7cd568 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Right.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Right.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Right.png.import new file mode 100644 index 0000000..257b99c --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Right.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dybnayy8y7rxe" +path="res://.godot/imported/PS5_Dpad_Right.png-064b9c5c42d22a9c2be3902ca2e33638.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Right.png" +dest_files=["res://.godot/imported/PS5_Dpad_Right.png-064b9c5c42d22a9c2be3902ca2e33638.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Up.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Up.png new file mode 100644 index 0000000..99180d2 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Up.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Up.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Up.png.import new file mode 100644 index 0000000..bfa2c71 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Up.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bvbd876sy2430" +path="res://.godot/imported/PS5_Dpad_Up.png-b8fc9319fe2231915e5e8e21174b1c1c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Up.png" +dest_files=["res://.godot/imported/PS5_Dpad_Up.png-b8fc9319fe2231915e5e8e21174b1c1c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L1.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L1.png new file mode 100644 index 0000000..07e505a Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L1.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L1.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L1.png.import new file mode 100644 index 0000000..dd46c43 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L1.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqgpumb0tf5xr" +path="res://.godot/imported/PS5_L1.png-daedbc1549c79d92cbcf68661193a3b8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_L1.png" +dest_files=["res://.godot/imported/PS5_L1.png-daedbc1549c79d92cbcf68661193a3b8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L2.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L2.png new file mode 100644 index 0000000..05f3dd2 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L2.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L2.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L2.png.import new file mode 100644 index 0000000..376d592 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_L2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bhoi6nfung5ye" +path="res://.godot/imported/PS5_L2.png-2ad86a3ad9afd70333db64063ae812ae.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_L2.png" +dest_files=["res://.godot/imported/PS5_L2.png-2ad86a3ad9afd70333db64063ae812ae.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick.png new file mode 100644 index 0000000..0245ff8 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick.png.import new file mode 100644 index 0000000..55a4f30 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c3qet180o0dn6" +path="res://.godot/imported/PS5_Left_Stick.png-472622a0a1752a811747d3e6c02f5438.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick.png" +dest_files=["res://.godot/imported/PS5_Left_Stick.png-472622a0a1752a811747d3e6c02f5438.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick_Click.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick_Click.png new file mode 100644 index 0000000..66e5271 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick_Click.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick_Click.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick_Click.png.import new file mode 100644 index 0000000..84fe65f --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick_Click.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c0b1sdadfcnbk" +path="res://.godot/imported/PS5_Left_Stick_Click.png-f837f37222a7c945cd4b672d0d7e3ba1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick_Click.png" +dest_files=["res://.godot/imported/PS5_Left_Stick_Click.png-f837f37222a7c945cd4b672d0d7e3ba1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Microphone.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Microphone.png new file mode 100644 index 0000000..bb0f331 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Microphone.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Microphone.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Microphone.png.import new file mode 100644 index 0000000..6199d2d --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Microphone.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://eljpu2rrb3k4" +path="res://.godot/imported/PS5_Microphone.png-3a2db423599523aa5c1b828df7d224bc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Microphone.png" +dest_files=["res://.godot/imported/PS5_Microphone.png-3a2db423599523aa5c1b828df7d224bc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options.png new file mode 100644 index 0000000..3e56fe2 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options.png.import new file mode 100644 index 0000000..b464245 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bkttgyeuecjw" +path="res://.godot/imported/PS5_Options.png-4bd9928e2e3aca6fb17663799d26e7a5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options.png" +dest_files=["res://.godot/imported/PS5_Options.png-4bd9928e2e3aca6fb17663799d26e7a5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options_Alt.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options_Alt.png new file mode 100644 index 0000000..ca28364 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options_Alt.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options_Alt.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options_Alt.png.import new file mode 100644 index 0000000..cb2f529 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options_Alt.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://byed3fsjbp82u" +path="res://.godot/imported/PS5_Options_Alt.png-4b64997ac577d658c383b1e727319cf5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options_Alt.png" +dest_files=["res://.godot/imported/PS5_Options_Alt.png-4b64997ac577d658c383b1e727319cf5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R1.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R1.png new file mode 100644 index 0000000..2cff97a Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R1.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R1.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R1.png.import new file mode 100644 index 0000000..3cb7aec --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R1.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://rwgkfm18pk3l" +path="res://.godot/imported/PS5_R1.png-2f57506c67c952763f228117ce37754b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_R1.png" +dest_files=["res://.godot/imported/PS5_R1.png-2f57506c67c952763f228117ce37754b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R2.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R2.png new file mode 100644 index 0000000..a13f17f Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R2.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R2.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R2.png.import new file mode 100644 index 0000000..533cfd7 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_R2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://u6ba23igjbj5" +path="res://.godot/imported/PS5_R2.png-9671164f26e8ed5c0f2352c255960e7c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_R2.png" +dest_files=["res://.godot/imported/PS5_R2.png-9671164f26e8ed5c0f2352c255960e7c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick.png new file mode 100644 index 0000000..85c1556 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick.png.import new file mode 100644 index 0000000..555e054 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bukgaq1m26bw3" +path="res://.godot/imported/PS5_Right_Stick.png-884107fa82c161e8696ba874c711b8d7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick.png" +dest_files=["res://.godot/imported/PS5_Right_Stick.png-884107fa82c161e8696ba874c711b8d7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick_Click.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick_Click.png new file mode 100644 index 0000000..eecd4e8 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick_Click.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick_Click.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick_Click.png.import new file mode 100644 index 0000000..90f3926 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick_Click.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c4krmros0va1i" +path="res://.godot/imported/PS5_Right_Stick_Click.png-b097f7eaaf3fdd2f3db31ab4d9ef06b4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick_Click.png" +dest_files=["res://.godot/imported/PS5_Right_Stick_Click.png-b097f7eaaf3fdd2f3db31ab4d9ef06b4.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share.png new file mode 100644 index 0000000..d96e698 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share.png.import new file mode 100644 index 0000000..018c729 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bw2h7xxdtp31i" +path="res://.godot/imported/PS5_Share.png-ecf2ad701cb784ee9e69b7052bffc94f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share.png" +dest_files=["res://.godot/imported/PS5_Share.png-ecf2ad701cb784ee9e69b7052bffc94f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share_Alt.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share_Alt.png new file mode 100644 index 0000000..10941aa Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share_Alt.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share_Alt.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share_Alt.png.import new file mode 100644 index 0000000..5bf9adc --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share_Alt.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bwje5248woygn" +path="res://.godot/imported/PS5_Share_Alt.png-f38d2e9e85009e094eb2254e0d890a1d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share_Alt.png" +dest_files=["res://.godot/imported/PS5_Share_Alt.png-f38d2e9e85009e094eb2254e0d890a1d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Square.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Square.png new file mode 100644 index 0000000..20f6065 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Square.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Square.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Square.png.import new file mode 100644 index 0000000..501b7da --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Square.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dm6vfcwtodame" +path="res://.godot/imported/PS5_Square.png-c0fff0babe3326f24867d317d430c13a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Square.png" +dest_files=["res://.godot/imported/PS5_Square.png-c0fff0babe3326f24867d317d430c13a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Touch_Pad.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Touch_Pad.png new file mode 100644 index 0000000..1a77d0c Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Touch_Pad.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Touch_Pad.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Touch_Pad.png.import new file mode 100644 index 0000000..025c11c --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Touch_Pad.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bxxkjsl2u83mp" +path="res://.godot/imported/PS5_Touch_Pad.png-b3baca99700ac1cd505b545f684de924.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Touch_Pad.png" +dest_files=["res://.godot/imported/PS5_Touch_Pad.png-b3baca99700ac1cd505b545f684de924.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Triangle.png b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Triangle.png new file mode 100644 index 0000000..4950d17 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Triangle.png differ diff --git a/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Triangle.png.import b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Triangle.png.import new file mode 100644 index 0000000..0aa199d --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/icons/PS5_Triangle.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bjjj12v4g82g4" +path="res://.godot/imported/PS5_Triangle.png-6cfcb99a3dd2daba1763b52afa5e6f91.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Triangle.png" +dest_files=["res://.godot/imported/PS5_Triangle.png-6cfcb99a3dd2daba1763b52afa5e6f91.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/playstation/playstation_controller_renderer.tscn b/addons/guide/ui/renderers/controllers/playstation/playstation_controller_renderer.tscn new file mode 100644 index 0000000..d4809e0 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/playstation/playstation_controller_renderer.tscn @@ -0,0 +1,101 @@ +[gd_scene load_steps=21 format=3 uid="uid://bwv1638hcrfni"] + +[ext_resource type="PackedScene" uid="uid://bsaylcb5ixjxk" path="res://addons/guide/ui/renderers/controllers/controller_renderer.tscn" id="1_bq6gh"] +[ext_resource type="Texture2D" uid="uid://cfy1rx4d4wjdh" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Cross.png" id="2_oqi6t"] +[ext_resource type="Texture2D" uid="uid://civpcnwgbu5ky" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Circle.png" id="3_m332j"] +[ext_resource type="Texture2D" uid="uid://dm6vfcwtodame" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Square.png" id="4_dqhg4"] +[ext_resource type="Texture2D" uid="uid://bjjj12v4g82g4" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Triangle.png" id="5_42ocy"] +[ext_resource type="Texture2D" uid="uid://c3qet180o0dn6" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick.png" id="6_wwoxb"] +[ext_resource type="Texture2D" uid="uid://c0b1sdadfcnbk" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Left_Stick_Click.png" id="7_gethe"] +[ext_resource type="Texture2D" uid="uid://bukgaq1m26bw3" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick.png" id="8_u2725"] +[ext_resource type="Texture2D" uid="uid://c4krmros0va1i" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Right_Stick_Click.png" id="9_wfckm"] +[ext_resource type="Texture2D" uid="uid://cqgpumb0tf5xr" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_L1.png" id="10_34ib6"] +[ext_resource type="Texture2D" uid="uid://rwgkfm18pk3l" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_R1.png" id="11_53ury"] +[ext_resource type="Texture2D" uid="uid://bhoi6nfung5ye" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_L2.png" id="12_tyubh"] +[ext_resource type="Texture2D" uid="uid://u6ba23igjbj5" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_R2.png" id="13_pr5lk"] +[ext_resource type="Texture2D" uid="uid://bvbd876sy2430" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Up.png" id="14_h0miw"] +[ext_resource type="Texture2D" uid="uid://bkpw61ctv0fbg" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Left.png" id="15_q5yu5"] +[ext_resource type="Texture2D" uid="uid://dybnayy8y7rxe" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Right.png" id="16_ulk14"] +[ext_resource type="Texture2D" uid="uid://vk1vje3280tk" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Dpad_Down.png" id="17_wm4fj"] +[ext_resource type="Texture2D" uid="uid://bkttgyeuecjw" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Options.png" id="18_eabm3"] +[ext_resource type="Texture2D" uid="uid://eljpu2rrb3k4" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Microphone.png" id="19_oj5w7"] +[ext_resource type="Texture2D" uid="uid://bw2h7xxdtp31i" path="res://addons/guide/ui/renderers/controllers/playstation/icons/PS5_Share.png" id="20_p3s2m"] + +[node name="ControllerRenderer" instance=ExtResource("1_bq6gh")] +controller_name_matches = Array[String](["DualSense", "DualShock", "PlayStation", "PS3", "PS4", "PS5"]) +a_button = ExtResource("2_oqi6t") +b_button = ExtResource("3_m332j") +x_button = ExtResource("4_dqhg4") +y_button = ExtResource("5_42ocy") +left_stick = ExtResource("6_wwoxb") +left_stick_click = ExtResource("7_gethe") +right_stick = ExtResource("8_u2725") +right_stick_click = ExtResource("9_wfckm") +left_bumper = ExtResource("10_34ib6") +right_bumper = ExtResource("11_53ury") +left_trigger = ExtResource("12_tyubh") +right_trigger = ExtResource("13_pr5lk") +dpad_up = ExtResource("14_h0miw") +dpad_left = ExtResource("15_q5yu5") +dpad_right = ExtResource("16_ulk14") +dpad_down = ExtResource("17_wm4fj") +start = ExtResource("18_eabm3") +misc1 = ExtResource("19_oj5w7") +back = ExtResource("20_p3s2m") + +[node name="AButton" parent="HBoxContainer/Controls" index="0"] +texture = ExtResource("2_oqi6t") + +[node name="BButton" parent="HBoxContainer/Controls" index="1"] +texture = ExtResource("3_m332j") + +[node name="XButton" parent="HBoxContainer/Controls" index="2"] +texture = ExtResource("4_dqhg4") + +[node name="YButton" parent="HBoxContainer/Controls" index="3"] +texture = ExtResource("5_42ocy") + +[node name="LeftStick" parent="HBoxContainer/Controls" index="4"] +texture = ExtResource("6_wwoxb") + +[node name="LeftStickClick" parent="HBoxContainer/Controls" index="5"] +texture = ExtResource("7_gethe") + +[node name="RightStick" parent="HBoxContainer/Controls" index="6"] +texture = ExtResource("8_u2725") + +[node name="RightStickClick" parent="HBoxContainer/Controls" index="7"] +texture = ExtResource("9_wfckm") + +[node name="LeftBumper" parent="HBoxContainer/Controls" index="8"] +texture = ExtResource("10_34ib6") + +[node name="RightBumper" parent="HBoxContainer/Controls" index="9"] +texture = ExtResource("11_53ury") + +[node name="LeftTrigger" parent="HBoxContainer/Controls" index="10"] +texture = ExtResource("12_tyubh") + +[node name="RightTrigger" parent="HBoxContainer/Controls" index="11"] +texture = ExtResource("13_pr5lk") + +[node name="DpadUp" parent="HBoxContainer/Controls" index="12"] +texture = ExtResource("14_h0miw") + +[node name="DpadLeft" parent="HBoxContainer/Controls" index="13"] +texture = ExtResource("15_q5yu5") + +[node name="DpadRight" parent="HBoxContainer/Controls" index="14"] +texture = ExtResource("16_ulk14") + +[node name="DpadDown" parent="HBoxContainer/Controls" index="15"] +texture = ExtResource("17_wm4fj") + +[node name="Start" parent="HBoxContainer/Controls" index="16"] +texture = ExtResource("18_eabm3") + +[node name="Misc1" parent="HBoxContainer/Controls" index="17"] +texture = ExtResource("19_oj5w7") + +[node name="Back" parent="HBoxContainer/Controls" index="18"] +texture = ExtResource("20_p3s2m") diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_A.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_A.png new file mode 100644 index 0000000..df756ef Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_A.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_A.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_A.png.import new file mode 100644 index 0000000..309879f --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_A.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cl75ptbm7sfi5" +path="res://.godot/imported/Switch_A.png-f1d58b04f27891568073a11e43627862.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_A.png" +dest_files=["res://.godot/imported/Switch_A.png-f1d58b04f27891568073a11e43627862.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_B.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_B.png new file mode 100644 index 0000000..ea7e743 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_B.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_B.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_B.png.import new file mode 100644 index 0000000..a6de4c9 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_B.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bptn4jygg3p8q" +path="res://.godot/imported/Switch_B.png-fbb8f305e166298807aa18fab0c22a62.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_B.png" +dest_files=["res://.godot/imported/Switch_B.png-fbb8f305e166298807aa18fab0c22a62.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Left.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Left.png new file mode 100644 index 0000000..f90a244 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Left.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Left.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Left.png.import new file mode 100644 index 0000000..4d4974c --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Left.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b0ha1pv08n3fn" +path="res://.godot/imported/Switch_Controller_Left.png-832f94a111c828ab506576e8c22b3c3a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Left.png" +dest_files=["res://.godot/imported/Switch_Controller_Left.png-832f94a111c828ab506576e8c22b3c3a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Right.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Right.png new file mode 100644 index 0000000..873da7e Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Right.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Right.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Right.png.import new file mode 100644 index 0000000..c3d22d6 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Right.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://qv33ijfxtj1x" +path="res://.godot/imported/Switch_Controller_Right.png-0738167dcf8a308918a4e0351ec370a7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Controller_Right.png" +dest_files=["res://.godot/imported/Switch_Controller_Right.png-0738167dcf8a308918a4e0351ec370a7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers.png new file mode 100644 index 0000000..b6ee54d Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers.png.import new file mode 100644 index 0000000..f4751a8 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dqfhfnjqwcjpk" +path="res://.godot/imported/Switch_Controllers.png-0ab7b7957a575a33aec8f6138ec1b468.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers.png" +dest_files=["res://.godot/imported/Switch_Controllers.png-0ab7b7957a575a33aec8f6138ec1b468.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers_Separate.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers_Separate.png new file mode 100644 index 0000000..0c019da Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers_Separate.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers_Separate.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers_Separate.png.import new file mode 100644 index 0000000..88af5e1 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers_Separate.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://8lsr71y25n8q" +path="res://.godot/imported/Switch_Controllers_Separate.png-8b202bd393de46b2f97712ac19581121.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Controllers_Separate.png" +dest_files=["res://.godot/imported/Switch_Controllers_Separate.png-8b202bd393de46b2f97712ac19581121.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Down.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Down.png new file mode 100644 index 0000000..7b7b2b2 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Down.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Down.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Down.png.import new file mode 100644 index 0000000..77b7d18 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Down.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://qt8r1byskjmu" +path="res://.godot/imported/Switch_Down.png-a8bebe4deb11df0456c90115a2306f62.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Down.png" +dest_files=["res://.godot/imported/Switch_Down.png-a8bebe4deb11df0456c90115a2306f62.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad.png new file mode 100644 index 0000000..12f01eb Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad.png.import new file mode 100644 index 0000000..9d3db24 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bxvp4elmagomg" +path="res://.godot/imported/Switch_Dpad.png-9f1893107a829bf94f95a8bcfa879f1c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad.png" +dest_files=["res://.godot/imported/Switch_Dpad.png-9f1893107a829bf94f95a8bcfa879f1c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Down.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Down.png new file mode 100644 index 0000000..37f6d5b Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Down.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Down.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Down.png.import new file mode 100644 index 0000000..8a8f63f --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Down.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dq2ypo4cx3ucs" +path="res://.godot/imported/Switch_Dpad_Down.png-fda4a0d96c9c1d604adf4addc863361f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Down.png" +dest_files=["res://.godot/imported/Switch_Dpad_Down.png-fda4a0d96c9c1d604adf4addc863361f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Left.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Left.png new file mode 100644 index 0000000..8efd7a4 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Left.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Left.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Left.png.import new file mode 100644 index 0000000..e6468b6 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Left.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://rcrsxqeu6mns" +path="res://.godot/imported/Switch_Dpad_Left.png-7d4e2c9108e5188065fbd9645e1af97e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Left.png" +dest_files=["res://.godot/imported/Switch_Dpad_Left.png-7d4e2c9108e5188065fbd9645e1af97e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Right.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Right.png new file mode 100644 index 0000000..8b5411d Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Right.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Right.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Right.png.import new file mode 100644 index 0000000..41f76e4 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Right.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dubah62ttpnc0" +path="res://.godot/imported/Switch_Dpad_Right.png-74599bcfe029ca89e967999e956aa664.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Right.png" +dest_files=["res://.godot/imported/Switch_Dpad_Right.png-74599bcfe029ca89e967999e956aa664.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Up.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Up.png new file mode 100644 index 0000000..700a8ba Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Up.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Up.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Up.png.import new file mode 100644 index 0000000..5609977 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Up.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://u6uclokrrbaq" +path="res://.godot/imported/Switch_Dpad_Up.png-38cc365cd950cad00eb7342f63b614a5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Dpad_Up.png" +dest_files=["res://.godot/imported/Switch_Dpad_Up.png-38cc365cd950cad00eb7342f63b614a5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Home.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Home.png new file mode 100644 index 0000000..9b6733c Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Home.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Home.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Home.png.import new file mode 100644 index 0000000..29e9d4d --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Home.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://uf6oq3wbq11f" +path="res://.godot/imported/Switch_Home.png-31680591ab356324906bfaaeace20e43.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Home.png" +dest_files=["res://.godot/imported/Switch_Home.png-31680591ab356324906bfaaeace20e43.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_LB.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_LB.png new file mode 100644 index 0000000..ddfa3b9 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_LB.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_LB.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_LB.png.import new file mode 100644 index 0000000..f004694 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_LB.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cb6gvej03avm3" +path="res://.godot/imported/Switch_LB.png-fc77289764fd409ac6c0408486b0c16b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_LB.png" +dest_files=["res://.godot/imported/Switch_LB.png-fc77289764fd409ac6c0408486b0c16b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_LT.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_LT.png new file mode 100644 index 0000000..6942e1f Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_LT.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_LT.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_LT.png.import new file mode 100644 index 0000000..3badb9f --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_LT.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://savy2mhybmun" +path="res://.godot/imported/Switch_LT.png-b154a02af7bcd266253a208d8d610852.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_LT.png" +dest_files=["res://.godot/imported/Switch_LT.png-b154a02af7bcd266253a208d8d610852.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left.png new file mode 100644 index 0000000..fd58439 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left.png.import new file mode 100644 index 0000000..20957cb --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cyjwul8mif4s2" +path="res://.godot/imported/Switch_Left.png-cc76cc1aa00b43ca3e312439715d169a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Left.png" +dest_files=["res://.godot/imported/Switch_Left.png-cc76cc1aa00b43ca3e312439715d169a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick.png new file mode 100644 index 0000000..d861ca5 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick.png.import new file mode 100644 index 0000000..2a5be36 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cha2jimmsyrsg" +path="res://.godot/imported/Switch_Left_Stick.png-1cc52d3c1e1f259e0115217e02740b99.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick.png" +dest_files=["res://.godot/imported/Switch_Left_Stick.png-1cc52d3c1e1f259e0115217e02740b99.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick_Click.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick_Click.png new file mode 100644 index 0000000..66e5271 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick_Click.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick_Click.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick_Click.png.import new file mode 100644 index 0000000..fc56eb6 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick_Click.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://by1vmleujtq1i" +path="res://.godot/imported/Switch_Left_Stick_Click.png-7992de9526c87e19b6a04a21954e96af.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick_Click.png" +dest_files=["res://.godot/imported/Switch_Left_Stick_Click.png-7992de9526c87e19b6a04a21954e96af.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Minus.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Minus.png new file mode 100644 index 0000000..d32608e Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Minus.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Minus.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Minus.png.import new file mode 100644 index 0000000..9a4233c --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Minus.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bdydqv6vi48ix" +path="res://.godot/imported/Switch_Minus.png-b6cd3147393308196e49ab3a608d1c8a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Minus.png" +dest_files=["res://.godot/imported/Switch_Minus.png-b6cd3147393308196e49ab3a608d1c8a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Plus.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Plus.png new file mode 100644 index 0000000..f1b0dc4 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Plus.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Plus.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Plus.png.import new file mode 100644 index 0000000..4d470fe --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Plus.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://j3wpcxyxsy2r" +path="res://.godot/imported/Switch_Plus.png-75c2cf5b7056a47425c210b1f60dcdc2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Plus.png" +dest_files=["res://.godot/imported/Switch_Plus.png-75c2cf5b7056a47425c210b1f60dcdc2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_RB.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_RB.png new file mode 100644 index 0000000..01f137a Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_RB.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_RB.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_RB.png.import new file mode 100644 index 0000000..1c7a578 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_RB.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://s2xm61tj0mfy" +path="res://.godot/imported/Switch_RB.png-3d9fbc66dcc67aee9a5716cef6ece679.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_RB.png" +dest_files=["res://.godot/imported/Switch_RB.png-3d9fbc66dcc67aee9a5716cef6ece679.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_RT.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_RT.png new file mode 100644 index 0000000..6aef3cb Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_RT.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_RT.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_RT.png.import new file mode 100644 index 0000000..2109b91 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_RT.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cccvjq78xw3n4" +path="res://.godot/imported/Switch_RT.png-521dbc557ae52cbe19429b25fbf68d18.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_RT.png" +dest_files=["res://.godot/imported/Switch_RT.png-521dbc557ae52cbe19429b25fbf68d18.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right.png new file mode 100644 index 0000000..f524c6c Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right.png.import new file mode 100644 index 0000000..094f135 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b3os8st4cai36" +path="res://.godot/imported/Switch_Right.png-cd6972267e466e454282edcdee867c3a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Right.png" +dest_files=["res://.godot/imported/Switch_Right.png-cd6972267e466e454282edcdee867c3a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick.png new file mode 100644 index 0000000..f2c605b Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick.png.import new file mode 100644 index 0000000..5b96fa4 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1jqxuup5llkb" +path="res://.godot/imported/Switch_Right_Stick.png-9a091e8f8aab1b8517e0e63458ce9648.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick.png" +dest_files=["res://.godot/imported/Switch_Right_Stick.png-9a091e8f8aab1b8517e0e63458ce9648.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick_Click.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick_Click.png new file mode 100644 index 0000000..eecd4e8 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick_Click.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick_Click.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick_Click.png.import new file mode 100644 index 0000000..d9492b0 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick_Click.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://denpxaxemjpg3" +path="res://.godot/imported/Switch_Right_Stick_Click.png-73f9b93cd8d68f031b93843441f5ac52.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick_Click.png" +dest_files=["res://.godot/imported/Switch_Right_Stick_Click.png-73f9b93cd8d68f031b93843441f5ac52.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Square.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Square.png new file mode 100644 index 0000000..d0fd432 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Square.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Square.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Square.png.import new file mode 100644 index 0000000..1da9b49 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Square.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cl0owijnhu5pc" +path="res://.godot/imported/Switch_Square.png-e3ed4021db85fe9e3827c68afd31c3ac.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Square.png" +dest_files=["res://.godot/imported/Switch_Square.png-e3ed4021db85fe9e3827c68afd31c3ac.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Up.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Up.png new file mode 100644 index 0000000..352f890 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Up.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Up.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Up.png.import new file mode 100644 index 0000000..e6fe688 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Up.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dxmy0dvee663b" +path="res://.godot/imported/Switch_Up.png-d9db5e9a6fb52c3f8674741ac7a63c50.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Up.png" +dest_files=["res://.godot/imported/Switch_Up.png-d9db5e9a6fb52c3f8674741ac7a63c50.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_X.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_X.png new file mode 100644 index 0000000..bdf86ba Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_X.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_X.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_X.png.import new file mode 100644 index 0000000..eeee651 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_X.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://7c6ie8ef23ox" +path="res://.godot/imported/Switch_X.png-8ff15c2bb86e671b78d91e2041718b60.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_X.png" +dest_files=["res://.godot/imported/Switch_X.png-8ff15c2bb86e671b78d91e2041718b60.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Y.png b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Y.png new file mode 100644 index 0000000..46ac216 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Y.png differ diff --git a/addons/guide/ui/renderers/controllers/switch/icons/Switch_Y.png.import b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Y.png.import new file mode 100644 index 0000000..0ace6f9 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/icons/Switch_Y.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bru7lpc778npo" +path="res://.godot/imported/Switch_Y.png-f47eae5d6991151df29244754a422398.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Y.png" +dest_files=["res://.godot/imported/Switch_Y.png-f47eae5d6991151df29244754a422398.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/switch/switch_controller_renderer.tscn b/addons/guide/ui/renderers/controllers/switch/switch_controller_renderer.tscn new file mode 100644 index 0000000..98bc510 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/switch/switch_controller_renderer.tscn @@ -0,0 +1,101 @@ +[gd_scene load_steps=21 format=3 uid="uid://dlhmh4o43l7pp"] + +[ext_resource type="PackedScene" uid="uid://bsaylcb5ixjxk" path="res://addons/guide/ui/renderers/controllers/controller_renderer.tscn" id="1_mxg2g"] +[ext_resource type="Texture2D" uid="uid://bptn4jygg3p8q" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_B.png" id="2_hj4a5"] +[ext_resource type="Texture2D" uid="uid://cl75ptbm7sfi5" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_A.png" id="3_0hjly"] +[ext_resource type="Texture2D" uid="uid://bru7lpc778npo" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Y.png" id="4_b8ldp"] +[ext_resource type="Texture2D" uid="uid://7c6ie8ef23ox" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_X.png" id="5_qpo6l"] +[ext_resource type="Texture2D" uid="uid://cha2jimmsyrsg" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick.png" id="6_o36fw"] +[ext_resource type="Texture2D" uid="uid://by1vmleujtq1i" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Left_Stick_Click.png" id="7_tn44v"] +[ext_resource type="Texture2D" uid="uid://d1jqxuup5llkb" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick.png" id="8_gfspk"] +[ext_resource type="Texture2D" uid="uid://denpxaxemjpg3" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Right_Stick_Click.png" id="9_ktbic"] +[ext_resource type="Texture2D" uid="uid://cb6gvej03avm3" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_LB.png" id="10_6uo88"] +[ext_resource type="Texture2D" uid="uid://s2xm61tj0mfy" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_RB.png" id="11_xm8m7"] +[ext_resource type="Texture2D" uid="uid://savy2mhybmun" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_LT.png" id="12_y225d"] +[ext_resource type="Texture2D" uid="uid://cccvjq78xw3n4" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_RT.png" id="13_xpnov"] +[ext_resource type="Texture2D" uid="uid://dxmy0dvee663b" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Up.png" id="14_ujug8"] +[ext_resource type="Texture2D" uid="uid://cyjwul8mif4s2" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Left.png" id="15_2efb3"] +[ext_resource type="Texture2D" uid="uid://b3os8st4cai36" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Right.png" id="16_yqxw1"] +[ext_resource type="Texture2D" uid="uid://qt8r1byskjmu" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Down.png" id="17_gfqch"] +[ext_resource type="Texture2D" uid="uid://j3wpcxyxsy2r" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Plus.png" id="18_s5cn6"] +[ext_resource type="Texture2D" uid="uid://cl0owijnhu5pc" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Square.png" id="19_iegd6"] +[ext_resource type="Texture2D" uid="uid://bdydqv6vi48ix" path="res://addons/guide/ui/renderers/controllers/switch/icons/Switch_Minus.png" id="20_kalbc"] + +[node name="ControllerRenderer" instance=ExtResource("1_mxg2g")] +controller_name_matches = Array[String](["Nintendo Switch"]) +a_button = ExtResource("2_hj4a5") +b_button = ExtResource("3_0hjly") +x_button = ExtResource("4_b8ldp") +y_button = ExtResource("5_qpo6l") +left_stick = ExtResource("6_o36fw") +left_stick_click = ExtResource("7_tn44v") +right_stick = ExtResource("8_gfspk") +right_stick_click = ExtResource("9_ktbic") +left_bumper = ExtResource("10_6uo88") +right_bumper = ExtResource("11_xm8m7") +left_trigger = ExtResource("12_y225d") +right_trigger = ExtResource("13_xpnov") +dpad_up = ExtResource("14_ujug8") +dpad_left = ExtResource("15_2efb3") +dpad_right = ExtResource("16_yqxw1") +dpad_down = ExtResource("17_gfqch") +start = ExtResource("18_s5cn6") +misc1 = ExtResource("19_iegd6") +back = ExtResource("20_kalbc") + +[node name="AButton" parent="HBoxContainer/Controls" index="0"] +texture = ExtResource("2_hj4a5") + +[node name="BButton" parent="HBoxContainer/Controls" index="1"] +texture = ExtResource("3_0hjly") + +[node name="XButton" parent="HBoxContainer/Controls" index="2"] +texture = ExtResource("4_b8ldp") + +[node name="YButton" parent="HBoxContainer/Controls" index="3"] +texture = ExtResource("5_qpo6l") + +[node name="LeftStick" parent="HBoxContainer/Controls" index="4"] +texture = ExtResource("6_o36fw") + +[node name="LeftStickClick" parent="HBoxContainer/Controls" index="5"] +texture = ExtResource("7_tn44v") + +[node name="RightStick" parent="HBoxContainer/Controls" index="6"] +texture = ExtResource("8_gfspk") + +[node name="RightStickClick" parent="HBoxContainer/Controls" index="7"] +texture = ExtResource("9_ktbic") + +[node name="LeftBumper" parent="HBoxContainer/Controls" index="8"] +texture = ExtResource("10_6uo88") + +[node name="RightBumper" parent="HBoxContainer/Controls" index="9"] +texture = ExtResource("11_xm8m7") + +[node name="LeftTrigger" parent="HBoxContainer/Controls" index="10"] +texture = ExtResource("12_y225d") + +[node name="RightTrigger" parent="HBoxContainer/Controls" index="11"] +texture = ExtResource("13_xpnov") + +[node name="DpadUp" parent="HBoxContainer/Controls" index="12"] +texture = ExtResource("14_ujug8") + +[node name="DpadLeft" parent="HBoxContainer/Controls" index="13"] +texture = ExtResource("15_2efb3") + +[node name="DpadRight" parent="HBoxContainer/Controls" index="14"] +texture = ExtResource("16_yqxw1") + +[node name="DpadDown" parent="HBoxContainer/Controls" index="15"] +texture = ExtResource("17_gfqch") + +[node name="Start" parent="HBoxContainer/Controls" index="16"] +texture = ExtResource("18_s5cn6") + +[node name="Misc1" parent="HBoxContainer/Controls" index="17"] +texture = ExtResource("19_iegd6") + +[node name="Back" parent="HBoxContainer/Controls" index="18"] +texture = ExtResource("20_kalbc") diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_A.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_A.png new file mode 100644 index 0000000..e22bb29 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_A.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_A.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_A.png.import new file mode 100644 index 0000000..271ef8d --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_A.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cujvw3m7aghgh" +path="res://.godot/imported/XboxSeriesX_A.png-6e6e4943fb226932d525ee72e98fb8ef.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_A.png" +dest_files=["res://.godot/imported/XboxSeriesX_A.png-6e6e4943fb226932d525ee72e98fb8ef.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_B.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_B.png new file mode 100644 index 0000000..9312c26 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_B.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_B.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_B.png.import new file mode 100644 index 0000000..4eb3b2b --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_B.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://brgqhp87g40l5" +path="res://.godot/imported/XboxSeriesX_B.png-78255eca5094e7bc4b681e33187791ff.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_B.png" +dest_files=["res://.godot/imported/XboxSeriesX_B.png-78255eca5094e7bc4b681e33187791ff.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad.png new file mode 100644 index 0000000..d66bd81 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad.png.import new file mode 100644 index 0000000..177a232 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://j5kp5tnwtysq" +path="res://.godot/imported/XboxSeriesX_Dpad.png-4bf4aa5e92bab139204438b5ac2b303d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad.png" +dest_files=["res://.godot/imported/XboxSeriesX_Dpad.png-4bf4aa5e92bab139204438b5ac2b303d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Down.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Down.png new file mode 100644 index 0000000..93478ee Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Down.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Down.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Down.png.import new file mode 100644 index 0000000..33030ff --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Down.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1fgf8ia7q4vo" +path="res://.godot/imported/XboxSeriesX_Dpad_Down.png-04b87c5546afa2b93f9116f73733624b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Down.png" +dest_files=["res://.godot/imported/XboxSeriesX_Dpad_Down.png-04b87c5546afa2b93f9116f73733624b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Left.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Left.png new file mode 100644 index 0000000..e1e3dfd Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Left.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Left.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Left.png.import new file mode 100644 index 0000000..4a746df --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Left.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bqtskbk6l8v7w" +path="res://.godot/imported/XboxSeriesX_Dpad_Left.png-8d74fbe74c1e93968cbcbaa007feb182.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Left.png" +dest_files=["res://.godot/imported/XboxSeriesX_Dpad_Left.png-8d74fbe74c1e93968cbcbaa007feb182.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Right.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Right.png new file mode 100644 index 0000000..2cabaef Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Right.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Right.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Right.png.import new file mode 100644 index 0000000..4dc009f --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Right.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://gsilbr1bntic" +path="res://.godot/imported/XboxSeriesX_Dpad_Right.png-e6fc74a1f6107eff3516a80369cf5807.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Right.png" +dest_files=["res://.godot/imported/XboxSeriesX_Dpad_Right.png-e6fc74a1f6107eff3516a80369cf5807.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Up.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Up.png new file mode 100644 index 0000000..a466bad Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Up.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Up.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Up.png.import new file mode 100644 index 0000000..a3ae1e8 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Up.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://boc4an5lj12lp" +path="res://.godot/imported/XboxSeriesX_Dpad_Up.png-d339224a22eaf2e00e885d73c907a138.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Up.png" +dest_files=["res://.godot/imported/XboxSeriesX_Dpad_Up.png-d339224a22eaf2e00e885d73c907a138.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LB.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LB.png new file mode 100644 index 0000000..f6c414b Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LB.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LB.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LB.png.import new file mode 100644 index 0000000..99b6409 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LB.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://uwqbgrkqv7qc" +path="res://.godot/imported/XboxSeriesX_LB.png-50df36f6ecf745654f01aae04e5a8a67.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LB.png" +dest_files=["res://.godot/imported/XboxSeriesX_LB.png-50df36f6ecf745654f01aae04e5a8a67.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LT.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LT.png new file mode 100644 index 0000000..526816c Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LT.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LT.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LT.png.import new file mode 100644 index 0000000..7b6737d --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LT.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c1rw1hnlt3dlt" +path="res://.godot/imported/XboxSeriesX_LT.png-4c80e87d7c8bd0e2d11025799541d6ae.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LT.png" +dest_files=["res://.godot/imported/XboxSeriesX_LT.png-4c80e87d7c8bd0e2d11025799541d6ae.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick.png new file mode 100644 index 0000000..de49dc6 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick.png.import new file mode 100644 index 0000000..66a1fbd --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://wol4p4f32lfr" +path="res://.godot/imported/XboxSeriesX_Left_Stick.png-c81470e6e08de714ca5029e194422ef3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick.png" +dest_files=["res://.godot/imported/XboxSeriesX_Left_Stick.png-c81470e6e08de714ca5029e194422ef3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick_Click.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick_Click.png new file mode 100644 index 0000000..ad0428f Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick_Click.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick_Click.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick_Click.png.import new file mode 100644 index 0000000..bc1a37b --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick_Click.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c0xpc73ovry50" +path="res://.godot/imported/XboxSeriesX_Left_Stick_Click.png-583c878cd8832ec16d9d309381418b44.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick_Click.png" +dest_files=["res://.godot/imported/XboxSeriesX_Left_Stick_Click.png-583c878cd8832ec16d9d309381418b44.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Menu.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Menu.png new file mode 100644 index 0000000..190780e Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Menu.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Menu.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Menu.png.import new file mode 100644 index 0000000..6ff0007 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Menu.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://y70m84f40jkk" +path="res://.godot/imported/XboxSeriesX_Menu.png-b5260eb2af6d939947fd11289117ab1c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Menu.png" +dest_files=["res://.godot/imported/XboxSeriesX_Menu.png-b5260eb2af6d939947fd11289117ab1c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RB.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RB.png new file mode 100644 index 0000000..5dcfc6d Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RB.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RB.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RB.png.import new file mode 100644 index 0000000..44914e1 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RB.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://5j0mm7ydxc5b" +path="res://.godot/imported/XboxSeriesX_RB.png-8b5fe7ad52beb7dc8003e7331b18e18b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RB.png" +dest_files=["res://.godot/imported/XboxSeriesX_RB.png-8b5fe7ad52beb7dc8003e7331b18e18b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RT.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RT.png new file mode 100644 index 0000000..8004286 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RT.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RT.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RT.png.import new file mode 100644 index 0000000..8f521dc --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RT.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dvsukgwjjn78x" +path="res://.godot/imported/XboxSeriesX_RT.png-e4f797c7b4ec150868ad67aaecd7e6bc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RT.png" +dest_files=["res://.godot/imported/XboxSeriesX_RT.png-e4f797c7b4ec150868ad67aaecd7e6bc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick.png new file mode 100644 index 0000000..866be1c Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick.png.import new file mode 100644 index 0000000..8da437a --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c1p7p5qpqxqfn" +path="res://.godot/imported/XboxSeriesX_Right_Stick.png-9c5f7904babde376c469263f16a00eac.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick.png" +dest_files=["res://.godot/imported/XboxSeriesX_Right_Stick.png-9c5f7904babde376c469263f16a00eac.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick_Click.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick_Click.png new file mode 100644 index 0000000..de08508 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick_Click.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick_Click.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick_Click.png.import new file mode 100644 index 0000000..cf66afe --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick_Click.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://pmymadotp1l0" +path="res://.godot/imported/XboxSeriesX_Right_Stick_Click.png-7cd7984c348fb4db2998472d7b950c6a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick_Click.png" +dest_files=["res://.godot/imported/XboxSeriesX_Right_Stick_Click.png-7cd7984c348fb4db2998472d7b950c6a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Share.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Share.png new file mode 100644 index 0000000..66d9f95 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Share.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Share.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Share.png.import new file mode 100644 index 0000000..cf906c6 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Share.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b8b2oomlnf5tt" +path="res://.godot/imported/XboxSeriesX_Share.png-39f960085afed02792af365e2b9c52a6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Share.png" +dest_files=["res://.godot/imported/XboxSeriesX_Share.png-39f960085afed02792af365e2b9c52a6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_View.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_View.png new file mode 100644 index 0000000..066086a Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_View.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_View.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_View.png.import new file mode 100644 index 0000000..b2f81ab --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_View.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b5wc83dex8igr" +path="res://.godot/imported/XboxSeriesX_View.png-4584623e9f69c92b5f7aa502e1647455.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_View.png" +dest_files=["res://.godot/imported/XboxSeriesX_View.png-4584623e9f69c92b5f7aa502e1647455.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_X.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_X.png new file mode 100644 index 0000000..e944b3e Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_X.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_X.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_X.png.import new file mode 100644 index 0000000..b461388 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_X.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dqnryo1s6qi45" +path="res://.godot/imported/XboxSeriesX_X.png-5f1df66dbbce24929b4c3ab5307e19e3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_X.png" +dest_files=["res://.godot/imported/XboxSeriesX_X.png-5f1df66dbbce24929b4c3ab5307e19e3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Y.png b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Y.png new file mode 100644 index 0000000..cf4a997 Binary files /dev/null and b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Y.png differ diff --git a/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Y.png.import b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Y.png.import new file mode 100644 index 0000000..b0c08db --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Y.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bx76tv1exmv0p" +path="res://.godot/imported/XboxSeriesX_Y.png-a7cca5057748346da0259b111678f72f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Y.png" +dest_files=["res://.godot/imported/XboxSeriesX_Y.png-a7cca5057748346da0259b111678f72f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/controllers/xbox/xbox_controller_renderer.tscn b/addons/guide/ui/renderers/controllers/xbox/xbox_controller_renderer.tscn new file mode 100644 index 0000000..d27adc9 --- /dev/null +++ b/addons/guide/ui/renderers/controllers/xbox/xbox_controller_renderer.tscn @@ -0,0 +1,101 @@ +[gd_scene load_steps=21 format=3 uid="uid://b0dr5w7b7spvo"] + +[ext_resource type="PackedScene" uid="uid://bsaylcb5ixjxk" path="res://addons/guide/ui/renderers/controllers/controller_renderer.tscn" id="1_5pcnq"] +[ext_resource type="Texture2D" uid="uid://cujvw3m7aghgh" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_A.png" id="2_kd0r1"] +[ext_resource type="Texture2D" uid="uid://brgqhp87g40l5" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_B.png" id="3_oebii"] +[ext_resource type="Texture2D" uid="uid://dqnryo1s6qi45" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_X.png" id="4_dgucg"] +[ext_resource type="Texture2D" uid="uid://bx76tv1exmv0p" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Y.png" id="5_nbb1e"] +[ext_resource type="Texture2D" uid="uid://wol4p4f32lfr" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick.png" id="6_wb84l"] +[ext_resource type="Texture2D" uid="uid://c0xpc73ovry50" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Left_Stick_Click.png" id="7_en4bp"] +[ext_resource type="Texture2D" uid="uid://c1p7p5qpqxqfn" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick.png" id="8_3a0jg"] +[ext_resource type="Texture2D" uid="uid://pmymadotp1l0" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Right_Stick_Click.png" id="9_vu674"] +[ext_resource type="Texture2D" uid="uid://uwqbgrkqv7qc" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LB.png" id="10_4dsgt"] +[ext_resource type="Texture2D" uid="uid://5j0mm7ydxc5b" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RB.png" id="11_3efc4"] +[ext_resource type="Texture2D" uid="uid://c1rw1hnlt3dlt" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_LT.png" id="12_bylwu"] +[ext_resource type="Texture2D" uid="uid://dvsukgwjjn78x" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_RT.png" id="13_viufm"] +[ext_resource type="Texture2D" uid="uid://boc4an5lj12lp" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Up.png" id="14_2uufq"] +[ext_resource type="Texture2D" uid="uid://bqtskbk6l8v7w" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Left.png" id="15_52cih"] +[ext_resource type="Texture2D" uid="uid://gsilbr1bntic" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Right.png" id="16_j6krd"] +[ext_resource type="Texture2D" uid="uid://d1fgf8ia7q4vo" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Dpad_Down.png" id="17_03a3w"] +[ext_resource type="Texture2D" uid="uid://y70m84f40jkk" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Menu.png" id="18_qlpxc"] +[ext_resource type="Texture2D" uid="uid://b8b2oomlnf5tt" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_Share.png" id="19_24yjp"] +[ext_resource type="Texture2D" uid="uid://b5wc83dex8igr" path="res://addons/guide/ui/renderers/controllers/xbox/icons/XboxSeriesX_View.png" id="20_0bc5x"] + +[node name="ControllerRenderer" instance=ExtResource("1_5pcnq")] +controller_name_matches = Array[String](["xbox", "xinput"]) +a_button = ExtResource("2_kd0r1") +b_button = ExtResource("3_oebii") +x_button = ExtResource("4_dgucg") +y_button = ExtResource("5_nbb1e") +left_stick = ExtResource("6_wb84l") +left_stick_click = ExtResource("7_en4bp") +right_stick = ExtResource("8_3a0jg") +right_stick_click = ExtResource("9_vu674") +left_bumper = ExtResource("10_4dsgt") +right_bumper = ExtResource("11_3efc4") +left_trigger = ExtResource("12_bylwu") +right_trigger = ExtResource("13_viufm") +dpad_up = ExtResource("14_2uufq") +dpad_left = ExtResource("15_52cih") +dpad_right = ExtResource("16_j6krd") +dpad_down = ExtResource("17_03a3w") +start = ExtResource("18_qlpxc") +misc1 = ExtResource("19_24yjp") +back = ExtResource("20_0bc5x") + +[node name="AButton" parent="HBoxContainer/Controls" index="0"] +texture = ExtResource("2_kd0r1") + +[node name="BButton" parent="HBoxContainer/Controls" index="1"] +texture = ExtResource("3_oebii") + +[node name="XButton" parent="HBoxContainer/Controls" index="2"] +texture = ExtResource("4_dgucg") + +[node name="YButton" parent="HBoxContainer/Controls" index="3"] +texture = ExtResource("5_nbb1e") + +[node name="LeftStick" parent="HBoxContainer/Controls" index="4"] +texture = ExtResource("6_wb84l") + +[node name="LeftStickClick" parent="HBoxContainer/Controls" index="5"] +texture = ExtResource("7_en4bp") + +[node name="RightStick" parent="HBoxContainer/Controls" index="6"] +texture = ExtResource("8_3a0jg") + +[node name="RightStickClick" parent="HBoxContainer/Controls" index="7"] +texture = ExtResource("9_vu674") + +[node name="LeftBumper" parent="HBoxContainer/Controls" index="8"] +texture = ExtResource("10_4dsgt") + +[node name="RightBumper" parent="HBoxContainer/Controls" index="9"] +texture = ExtResource("11_3efc4") + +[node name="LeftTrigger" parent="HBoxContainer/Controls" index="10"] +texture = ExtResource("12_bylwu") + +[node name="RightTrigger" parent="HBoxContainer/Controls" index="11"] +texture = ExtResource("13_viufm") + +[node name="DpadUp" parent="HBoxContainer/Controls" index="12"] +texture = ExtResource("14_2uufq") + +[node name="DpadLeft" parent="HBoxContainer/Controls" index="13"] +texture = ExtResource("15_52cih") + +[node name="DpadRight" parent="HBoxContainer/Controls" index="14"] +texture = ExtResource("16_j6krd") + +[node name="DpadDown" parent="HBoxContainer/Controls" index="15"] +texture = ExtResource("17_03a3w") + +[node name="Start" parent="HBoxContainer/Controls" index="16"] +texture = ExtResource("18_qlpxc") + +[node name="Misc1" parent="HBoxContainer/Controls" index="17"] +texture = ExtResource("19_24yjp") + +[node name="Back" parent="HBoxContainer/Controls" index="18"] +texture = ExtResource("20_0bc5x") diff --git a/addons/guide/ui/renderers/joy/icons/button_empty.png b/addons/guide/ui/renderers/joy/icons/button_empty.png new file mode 100644 index 0000000..800bee0 Binary files /dev/null and b/addons/guide/ui/renderers/joy/icons/button_empty.png differ diff --git a/addons/guide/ui/renderers/joy/icons/button_empty.png.import b/addons/guide/ui/renderers/joy/icons/button_empty.png.import new file mode 100644 index 0000000..e2bc208 --- /dev/null +++ b/addons/guide/ui/renderers/joy/icons/button_empty.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://veqjcwokdukw" +path="res://.godot/imported/button_empty.png-123d9e156dcc9c2e5ff33e4ffbcd7884.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/joy/icons/button_empty.png" +dest_files=["res://.godot/imported/button_empty.png-123d9e156dcc9c2e5ff33e4ffbcd7884.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/joy/icons/stick_empty.png b/addons/guide/ui/renderers/joy/icons/stick_empty.png new file mode 100644 index 0000000..ae363d2 Binary files /dev/null and b/addons/guide/ui/renderers/joy/icons/stick_empty.png differ diff --git a/addons/guide/ui/renderers/joy/icons/stick_empty.png.import b/addons/guide/ui/renderers/joy/icons/stick_empty.png.import new file mode 100644 index 0000000..8d805df --- /dev/null +++ b/addons/guide/ui/renderers/joy/icons/stick_empty.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://do001o6aysaxo" +path="res://.godot/imported/stick_empty.png-10fa96eb31f6946670d6998f8648c1db.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/joy/icons/stick_empty.png" +dest_files=["res://.godot/imported/stick_empty.png-10fa96eb31f6946670d6998f8648c1db.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/joy/joy_renderer.gd b/addons/guide/ui/renderers/joy/joy_renderer.gd new file mode 100644 index 0000000..92bdec1 --- /dev/null +++ b/addons/guide/ui/renderers/joy/joy_renderer.gd @@ -0,0 +1,69 @@ +@tool +extends GUIDEIconRenderer + +@onready var _stick:Control = %Stick +@onready var _button:Control = %Button +@onready var _text:Control = %Text +@onready var _directions:Control = %Directions +@onready var _horizontal:Control = %Horizontal +@onready var _vertical:Control = %Vertical + + + +func supports(input:GUIDEInput) -> bool: + return input is GUIDEInputJoyBase + +func render(input:GUIDEInput) -> void: + _stick.visible = false + _button.visible = false + _directions.visible = false + _horizontal.visible = false + _vertical.visible = false + _text.text = "" + + + if input is GUIDEInputJoyAxis1D: + _stick.visible = true + match input.axis: + JOY_AXIS_LEFT_X: + _directions.visible = true + _text.text = "1" + _horizontal.visible = true + JOY_AXIS_RIGHT_X: + _directions.visible = true + _text.text = "2" + _horizontal.visible = true + JOY_AXIS_LEFT_Y: + _directions.visible = true + _text.text = "1" + _vertical.visible = true + JOY_AXIS_RIGHT_Y: + _directions.visible = true + _text.text = "2" + _vertical.visible = true + JOY_AXIS_TRIGGER_LEFT: + _text.text = "3" + JOY_AXIS_TRIGGER_RIGHT: + _text.text = "4" + + + + if input is GUIDEInputJoyAxis2D: + _stick.visible = true + match input.x: + JOY_AXIS_LEFT_X, JOY_AXIS_LEFT_Y: + _text.text = "1" + JOY_AXIS_RIGHT_X, JOY_AXIS_RIGHT_Y: + _text.text = "2" + _: + # well we don't know really what this is but what can we do. + _text.text = str(input.x + input.y) + + if input is GUIDEInputJoyButton: + _button.visible = true + _text.text = str(input.button) + + call("queue_sort") + +func cache_key(input:GUIDEInput) -> String: + return "a9ced629-de65-4c31-9de0-8e4cbf88a2e0" + input.to_string() diff --git a/addons/guide/ui/renderers/joy/joy_renderer.gd.uid b/addons/guide/ui/renderers/joy/joy_renderer.gd.uid new file mode 100644 index 0000000..a0ab334 --- /dev/null +++ b/addons/guide/ui/renderers/joy/joy_renderer.gd.uid @@ -0,0 +1 @@ +uid://bnk4uahoa45vc diff --git a/addons/guide/ui/renderers/joy/joy_renderer.tscn b/addons/guide/ui/renderers/joy/joy_renderer.tscn new file mode 100644 index 0000000..a1dd98e --- /dev/null +++ b/addons/guide/ui/renderers/joy/joy_renderer.tscn @@ -0,0 +1,63 @@ +[gd_scene load_steps=7 format=3 uid="uid://c6sqf8rur1wss"] + +[ext_resource type="Script" path="res://addons/guide/ui/renderers/joy/joy_renderer.gd" id="1_u7brn"] +[ext_resource type="Texture2D" uid="uid://do001o6aysaxo" path="res://addons/guide/ui/renderers/joy/icons/stick_empty.png" id="2_23u2k"] +[ext_resource type="Texture2D" uid="uid://veqjcwokdukw" path="res://addons/guide/ui/renderers/joy/icons/button_empty.png" id="3_7qfbp"] +[ext_resource type="FontFile" uid="uid://cu8bvod6tnnwr" path="res://addons/guide/ui/renderers/keyboard/Lato-Black.ttf" id="4_otp86"] +[ext_resource type="Texture2D" uid="uid://bmgxqbypegjxh" path="res://addons/guide/ui/renderers/textures/arrow_horizontal.svg" id="5_81uyo"] +[ext_resource type="Texture2D" uid="uid://bu5nlug6uf03w" path="res://addons/guide/ui/renderers/textures/arrow_vertical.svg" id="6_syx8c"] + +[node name="JoyRenderer" type="MarginContainer"] +offset_right = 100.0 +offset_bottom = 100.0 +size_flags_horizontal = 0 +script = ExtResource("1_u7brn") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="Controls" type="MarginContainer" parent="HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(100, 100) +layout_mode = 2 + +[node name="Stick" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("2_23u2k") +stretch_mode = 4 + +[node name="Button" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("3_7qfbp") +stretch_mode = 4 + +[node name="Text" type="Label" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_colors/font_color = Color(0.843137, 0.843137, 0.843137, 1) +theme_override_fonts/font = ExtResource("4_otp86") +theme_override_font_sizes/font_size = 50 +text = "1" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="Directions" type="MarginContainer" parent="HBoxContainer"] +unique_name_in_owner = true +visible = false +custom_minimum_size = Vector2(100, 100) +layout_mode = 2 + +[node name="Horizontal" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("5_81uyo") +stretch_mode = 4 + +[node name="Vertical" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("6_syx8c") +stretch_mode = 4 diff --git a/addons/guide/ui/renderers/keyboard/Lato-Black.ttf b/addons/guide/ui/renderers/keyboard/Lato-Black.ttf new file mode 100644 index 0000000..4340502 Binary files /dev/null and b/addons/guide/ui/renderers/keyboard/Lato-Black.ttf differ diff --git a/addons/guide/ui/renderers/keyboard/Lato-Black.ttf.import b/addons/guide/ui/renderers/keyboard/Lato-Black.ttf.import new file mode 100644 index 0000000..c7bb2da --- /dev/null +++ b/addons/guide/ui/renderers/keyboard/Lato-Black.ttf.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://cu8bvod6tnnwr" +path="res://.godot/imported/Lato-Black.ttf-dd70fb4540a062e6fd25f6b3cb73f785.fontdata" + +[deps] + +source_file="res://addons/guide/ui/renderers/keyboard/Lato-Black.ttf" +dest_files=["res://.godot/imported/Lato-Black.ttf-dd70fb4540a062e6fd25f6b3cb73f785.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/addons/guide/ui/renderers/keyboard/icons/Blank_White_Normal.png b/addons/guide/ui/renderers/keyboard/icons/Blank_White_Normal.png new file mode 100644 index 0000000..beee975 Binary files /dev/null and b/addons/guide/ui/renderers/keyboard/icons/Blank_White_Normal.png differ diff --git a/addons/guide/ui/renderers/keyboard/icons/Blank_White_Normal.png.import b/addons/guide/ui/renderers/keyboard/icons/Blank_White_Normal.png.import new file mode 100644 index 0000000..99d4b10 --- /dev/null +++ b/addons/guide/ui/renderers/keyboard/icons/Blank_White_Normal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b3x586os8uuwb" +path="res://.godot/imported/Blank_White_Normal.png-71b5933a92dfdd83fd323e35be33b3b2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/keyboard/icons/Blank_White_Normal.png" +dest_files=["res://.godot/imported/Blank_White_Normal.png-71b5933a92dfdd83fd323e35be33b3b2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/keyboard/key_renderer.gd b/addons/guide/ui/renderers/keyboard/key_renderer.gd new file mode 100644 index 0000000..3facf61 --- /dev/null +++ b/addons/guide/ui/renderers/keyboard/key_renderer.gd @@ -0,0 +1,17 @@ +@tool +extends GUIDEIconRenderer + +@onready var _label:Label = %Label + +func supports(input:GUIDEInput) -> bool: + return input is GUIDEInputKey + +func render(input:GUIDEInput) -> void: + var key:Key = input.key + var label_key:Key = DisplayServer.keyboard_get_label_from_physical(key) + _label.text = OS.get_keycode_string(label_key).strip_edges() + size = Vector2.ZERO + call("queue_sort") + +func cache_key(input:GUIDEInput) -> String: + return "ed6923d5-4115-44bd-b35e-2c4102ffc83e" + input.to_string() diff --git a/addons/guide/ui/renderers/keyboard/key_renderer.gd.uid b/addons/guide/ui/renderers/keyboard/key_renderer.gd.uid new file mode 100644 index 0000000..65ec674 --- /dev/null +++ b/addons/guide/ui/renderers/keyboard/key_renderer.gd.uid @@ -0,0 +1 @@ +uid://cd4r6x5q0mkhp diff --git a/addons/guide/ui/renderers/keyboard/key_renderer.tscn b/addons/guide/ui/renderers/keyboard/key_renderer.tscn new file mode 100644 index 0000000..eacb5b9 --- /dev/null +++ b/addons/guide/ui/renderers/keyboard/key_renderer.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=4 format=3 uid="uid://toty2e3yx26l"] + +[ext_resource type="Script" path="res://addons/guide/ui/renderers/keyboard/key_renderer.gd" id="1_tm2sd"] +[ext_resource type="Texture2D" uid="uid://b3x586os8uuwb" path="res://addons/guide/ui/renderers/keyboard/icons/Blank_White_Normal.png" id="2_myc15"] +[ext_resource type="FontFile" uid="uid://cu8bvod6tnnwr" path="res://addons/guide/ui/renderers/keyboard/Lato-Black.ttf" id="3_d3uds"] + +[node name="KeyRenderer" type="MarginContainer"] +custom_minimum_size = Vector2(100, 100) +offset_right = 267.0 +offset_bottom = 100.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +script = ExtResource("1_tm2sd") + +[node name="NinePatchRect" type="NinePatchRect" parent="."] +layout_mode = 2 +texture = ExtResource("2_myc15") +region_rect = Rect2(10, 10, 80, 80) +patch_margin_left = 29 +patch_margin_top = 30 +patch_margin_right = 29 +patch_margin_bottom = 29 + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_left = 30 +theme_override_constants/margin_right = 30 + +[node name="Label" type="Label" parent="MarginContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_colors/font_color = Color(0.25098, 0.25098, 0.25098, 1) +theme_override_fonts/font = ExtResource("3_d3uds") +theme_override_font_sizes/font_size = 45 +text = "Long Long Long" +horizontal_alignment = 1 diff --git a/addons/guide/ui/renderers/misc/action_renderer.gd b/addons/guide/ui/renderers/misc/action_renderer.gd new file mode 100644 index 0000000..c39f8a6 --- /dev/null +++ b/addons/guide/ui/renderers/misc/action_renderer.gd @@ -0,0 +1,11 @@ +@tool +extends GUIDEIconRenderer + +func supports(input:GUIDEInput) -> bool: + return input is GUIDEInputAction + +func render(input:GUIDEInput) -> void: + pass + +func cache_key(input:GUIDEInput) -> String: + return "0ecd6608-ba3c-4fc2-83f7-ad61736f1106" # we only have one output, so same cache key diff --git a/addons/guide/ui/renderers/misc/action_renderer.gd.uid b/addons/guide/ui/renderers/misc/action_renderer.gd.uid new file mode 100644 index 0000000..baefc8a --- /dev/null +++ b/addons/guide/ui/renderers/misc/action_renderer.gd.uid @@ -0,0 +1 @@ +uid://bdrygt8mymguu diff --git a/addons/guide/ui/renderers/misc/action_renderer.tscn b/addons/guide/ui/renderers/misc/action_renderer.tscn new file mode 100644 index 0000000..88cb452 --- /dev/null +++ b/addons/guide/ui/renderers/misc/action_renderer.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=3 format=3 uid="uid://ortn6jb3wljf"] + +[ext_resource type="Script" path="res://addons/guide/ui/renderers/misc/action_renderer.gd" id="1_140q4"] +[ext_resource type="Texture2D" uid="uid://diwkvjkss2ie" path="res://addons/guide/ui/renderers/textures/action.svg" id="2_uqvia"] + +[node name="ActionRenderer" type="MarginContainer"] +offset_right = 512.0 +offset_bottom = 512.0 +size_flags_horizontal = 0 +script = ExtResource("1_140q4") + +[node name="Action" type="TextureRect" parent="."] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("2_uqvia") +stretch_mode = 4 diff --git a/addons/guide/ui/renderers/misc/fallback_renderer.gd b/addons/guide/ui/renderers/misc/fallback_renderer.gd new file mode 100644 index 0000000..4fa78e1 --- /dev/null +++ b/addons/guide/ui/renderers/misc/fallback_renderer.gd @@ -0,0 +1,11 @@ +@tool +extends GUIDEIconRenderer + +func supports(input:GUIDEInput) -> bool: + return true + +func render(input:GUIDEInput) -> void: + pass + +func cache_key(input:GUIDEInput) -> String: + return "2e130e8b-d5b3-478c-af65-53415adfd6bb" # we only have one output, so same cache key diff --git a/addons/guide/ui/renderers/misc/fallback_renderer.gd.uid b/addons/guide/ui/renderers/misc/fallback_renderer.gd.uid new file mode 100644 index 0000000..36a7db9 --- /dev/null +++ b/addons/guide/ui/renderers/misc/fallback_renderer.gd.uid @@ -0,0 +1 @@ +uid://dah64oq8ican diff --git a/addons/guide/ui/renderers/misc/fallback_renderer.tscn b/addons/guide/ui/renderers/misc/fallback_renderer.tscn new file mode 100644 index 0000000..106c8d8 --- /dev/null +++ b/addons/guide/ui/renderers/misc/fallback_renderer.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=3 format=3 uid="uid://bqf4yoind3a82"] + +[ext_resource type="Script" path="res://addons/guide/ui/renderers/misc/fallback_renderer.gd" id="1_mgm3k"] +[ext_resource type="FontFile" uid="uid://cu8bvod6tnnwr" path="res://addons/guide/ui/renderers/keyboard/Lato-Black.ttf" id="2_5hk8u"] + +[node name="FallbackRenderer" type="MarginContainer"] +offset_right = 512.0 +offset_bottom = 512.0 +size_flags_horizontal = 0 +script = ExtResource("1_mgm3k") +priority = 100 + +[node name="Label" type="Label" parent="."] +custom_minimum_size = Vector2(512, 512) +layout_mode = 2 +theme_override_fonts/font = ExtResource("2_5hk8u") +theme_override_font_sizes/font_size = 350 +text = "?" +horizontal_alignment = 1 +vertical_alignment = 1 diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Cursor.png b/addons/guide/ui/renderers/mouse/icons/Mouse_Cursor.png new file mode 100644 index 0000000..8d52353 Binary files /dev/null and b/addons/guide/ui/renderers/mouse/icons/Mouse_Cursor.png differ diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Cursor.png.import b/addons/guide/ui/renderers/mouse/icons/Mouse_Cursor.png.import new file mode 100644 index 0000000..21c5623 --- /dev/null +++ b/addons/guide/ui/renderers/mouse/icons/Mouse_Cursor.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ci7icm3q4l1sg" +path="res://.godot/imported/Mouse_Cursor.png-d260e60db8690d81bb10201ace09e70f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/mouse/icons/Mouse_Cursor.png" +dest_files=["res://.godot/imported/Mouse_Cursor.png-d260e60db8690d81bb10201ace09e70f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Left_Key_Light.png b/addons/guide/ui/renderers/mouse/icons/Mouse_Left_Key_Light.png new file mode 100644 index 0000000..22983fa Binary files /dev/null and b/addons/guide/ui/renderers/mouse/icons/Mouse_Left_Key_Light.png differ diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Left_Key_Light.png.import b/addons/guide/ui/renderers/mouse/icons/Mouse_Left_Key_Light.png.import new file mode 100644 index 0000000..e6fb06e --- /dev/null +++ b/addons/guide/ui/renderers/mouse/icons/Mouse_Left_Key_Light.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vvgpheda22ew" +path="res://.godot/imported/Mouse_Left_Key_Light.png-8c9c47fe23d850a53ee5b259032ff1e7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/mouse/icons/Mouse_Left_Key_Light.png" +dest_files=["res://.godot/imported/Mouse_Left_Key_Light.png-8c9c47fe23d850a53ee5b259032ff1e7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Middle_Key_Light.png b/addons/guide/ui/renderers/mouse/icons/Mouse_Middle_Key_Light.png new file mode 100644 index 0000000..d3298c1 Binary files /dev/null and b/addons/guide/ui/renderers/mouse/icons/Mouse_Middle_Key_Light.png differ diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Middle_Key_Light.png.import b/addons/guide/ui/renderers/mouse/icons/Mouse_Middle_Key_Light.png.import new file mode 100644 index 0000000..74951c7 --- /dev/null +++ b/addons/guide/ui/renderers/mouse/icons/Mouse_Middle_Key_Light.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bmj244x0jn7v2" +path="res://.godot/imported/Mouse_Middle_Key_Light.png-d1b621d65964bf35e881bf5a749d0470.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/mouse/icons/Mouse_Middle_Key_Light.png" +dest_files=["res://.godot/imported/Mouse_Middle_Key_Light.png-d1b621d65964bf35e881bf5a749d0470.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Right_Key_Light.png b/addons/guide/ui/renderers/mouse/icons/Mouse_Right_Key_Light.png new file mode 100644 index 0000000..8106df7 Binary files /dev/null and b/addons/guide/ui/renderers/mouse/icons/Mouse_Right_Key_Light.png differ diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Right_Key_Light.png.import b/addons/guide/ui/renderers/mouse/icons/Mouse_Right_Key_Light.png.import new file mode 100644 index 0000000..f44ea7f --- /dev/null +++ b/addons/guide/ui/renderers/mouse/icons/Mouse_Right_Key_Light.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b8bsyguf4qw6f" +path="res://.godot/imported/Mouse_Right_Key_Light.png-f1130bc98a1b33064099609790f7efff.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/mouse/icons/Mouse_Right_Key_Light.png" +dest_files=["res://.godot/imported/Mouse_Right_Key_Light.png-f1130bc98a1b33064099609790f7efff.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_1_Light.png b/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_1_Light.png new file mode 100644 index 0000000..a2fd2a0 Binary files /dev/null and b/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_1_Light.png differ diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_1_Light.png.import b/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_1_Light.png.import new file mode 100644 index 0000000..b41bb91 --- /dev/null +++ b/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_1_Light.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://je8rm7jk2nxd" +path="res://.godot/imported/Mouse_Side_Key_1_Light.png-1e0810994bec8c12ac686f4c33006236.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_1_Light.png" +dest_files=["res://.godot/imported/Mouse_Side_Key_1_Light.png-1e0810994bec8c12ac686f4c33006236.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_2_Light.png b/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_2_Light.png new file mode 100644 index 0000000..2011ef0 Binary files /dev/null and b/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_2_Light.png differ diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_2_Light.png.import b/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_2_Light.png.import new file mode 100644 index 0000000..8696fa5 --- /dev/null +++ b/addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_2_Light.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bqxly0g8pftxa" +path="res://.godot/imported/Mouse_Side_Key_2_Light.png-3a47028a83b486166e55c8b465b98934.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_2_Light.png" +dest_files=["res://.godot/imported/Mouse_Side_Key_2_Light.png-3a47028a83b486166e55c8b465b98934.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Simple_Key_Light.png b/addons/guide/ui/renderers/mouse/icons/Mouse_Simple_Key_Light.png new file mode 100644 index 0000000..7891ea4 Binary files /dev/null and b/addons/guide/ui/renderers/mouse/icons/Mouse_Simple_Key_Light.png differ diff --git a/addons/guide/ui/renderers/mouse/icons/Mouse_Simple_Key_Light.png.import b/addons/guide/ui/renderers/mouse/icons/Mouse_Simple_Key_Light.png.import new file mode 100644 index 0000000..4799ca4 --- /dev/null +++ b/addons/guide/ui/renderers/mouse/icons/Mouse_Simple_Key_Light.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b3uxk5agbpmab" +path="res://.godot/imported/Mouse_Simple_Key_Light.png-0d9fe3a005ffb8a731da9e9c204556cb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/mouse/icons/Mouse_Simple_Key_Light.png" +dest_files=["res://.godot/imported/Mouse_Simple_Key_Light.png-0d9fe3a005ffb8a731da9e9c204556cb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/mouse/mouse_renderer.gd b/addons/guide/ui/renderers/mouse/mouse_renderer.gd new file mode 100644 index 0000000..2671a99 --- /dev/null +++ b/addons/guide/ui/renderers/mouse/mouse_renderer.gd @@ -0,0 +1,87 @@ +@tool +extends GUIDEIconRenderer + +@onready var _controls:Control = %Controls +@onready var _mouse_left:Control = %MouseLeft +@onready var _mouse_right:Control = %MouseRight +@onready var _mouse_middle:Control = %MouseMiddle +@onready var _mouse_side_a:Control = %MouseSideA +@onready var _mouse_side_b:Control = %MouseSideB +@onready var _mouse_blank:Control = %MouseBlank +@onready var _mouse_cursor:Control = %MouseCursor + + +@onready var _directions:Control = %Directions +@onready var _left:Control = %Left +@onready var _right:Control = %Right +@onready var _up:Control = %Up +@onready var _down:Control = %Down +@onready var _horizontal:Control = %Horizontal +@onready var _vertical:Control = %Vertical + + + +func supports(input:GUIDEInput) -> bool: + return input is GUIDEInputMouseButton or \ + input is GUIDEInputMouseAxis1D or \ + input is GUIDEInputMouseAxis2D or \ + input is GUIDEInputMousePosition + + +func render(input:GUIDEInput) -> void: + for child in _controls.get_children(): + child.visible = false + for child in _directions.get_children(): + child.visible = false + + _directions.visible = false + + if input is GUIDEInputMouseButton: + match input.button: + MOUSE_BUTTON_LEFT: + _mouse_left.visible = true + MOUSE_BUTTON_RIGHT: + _mouse_right.visible = true + MOUSE_BUTTON_MIDDLE: + _mouse_middle.visible = true + MOUSE_BUTTON_WHEEL_UP: + _directions.visible = true + _up.visible = true + _mouse_middle.visible = true + MOUSE_BUTTON_WHEEL_DOWN: + _directions.visible = true + _down.visible = true + _mouse_middle.visible = true + MOUSE_BUTTON_WHEEL_LEFT: + _directions.visible = true + _left.visible = true + _mouse_middle.visible = true + MOUSE_BUTTON_WHEEL_RIGHT: + _directions.visible = true + _right.visible = true + _mouse_middle.visible = true + MOUSE_BUTTON_XBUTTON1: + _mouse_side_a.visible = true + MOUSE_BUTTON_XBUTTON2: + _mouse_side_b.visible = true + + if input is GUIDEInputMouseAxis1D: + if input.axis == GUIDEInputMouseAxis1D.GUIDEInputMouseAxis.X: + _mouse_blank.visible = true + _directions.visible = true + _horizontal.visible = true + else: + _mouse_blank.visible = true + _directions.visible = true + _vertical.visible = true + + if input is GUIDEInputMouseAxis2D: + _mouse_blank.visible = true + + if input is GUIDEInputMousePosition: + _mouse_cursor.visible = true + + call("queue_sort") + +func cache_key(input:GUIDEInput) -> String: + return "7e27520a-b6d8-4451-858d-e94330c82e85" + input.to_string() diff --git a/addons/guide/ui/renderers/mouse/mouse_renderer.gd.uid b/addons/guide/ui/renderers/mouse/mouse_renderer.gd.uid new file mode 100644 index 0000000..26c3497 --- /dev/null +++ b/addons/guide/ui/renderers/mouse/mouse_renderer.gd.uid @@ -0,0 +1 @@ +uid://dh2deng2bk2eo diff --git a/addons/guide/ui/renderers/mouse/mouse_renderer.tscn b/addons/guide/ui/renderers/mouse/mouse_renderer.tscn new file mode 100644 index 0000000..01d8eb9 --- /dev/null +++ b/addons/guide/ui/renderers/mouse/mouse_renderer.tscn @@ -0,0 +1,125 @@ +[gd_scene load_steps=15 format=3 uid="uid://bfl6dbw21xqs1"] + +[ext_resource type="Script" path="res://addons/guide/ui/renderers/mouse/mouse_renderer.gd" id="1_amutf"] +[ext_resource type="Texture2D" uid="uid://vvgpheda22ew" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Left_Key_Light.png" id="2_6vk7n"] +[ext_resource type="Texture2D" uid="uid://b8bsyguf4qw6f" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Right_Key_Light.png" id="3_aaqrj"] +[ext_resource type="Texture2D" uid="uid://bmj244x0jn7v2" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Middle_Key_Light.png" id="4_gprek"] +[ext_resource type="Texture2D" uid="uid://bqxly0g8pftxa" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_2_Light.png" id="6_adi64"] +[ext_resource type="Texture2D" uid="uid://1swh072gtbb4" path="res://addons/guide/ui/renderers/textures/arrow_left.svg" id="6_fo4h0"] +[ext_resource type="Texture2D" uid="uid://je8rm7jk2nxd" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Side_Key_1_Light.png" id="7_bbgo7"] +[ext_resource type="Texture2D" uid="uid://cjvs04qsrj8ap" path="res://addons/guide/ui/renderers/textures/arrow_right.svg" id="7_t242p"] +[ext_resource type="Texture2D" uid="uid://ni6lsbx1d2hf" path="res://addons/guide/ui/renderers/textures/arrow_up.svg" id="8_a7prs"] +[ext_resource type="Texture2D" uid="uid://ci7icm3q4l1sg" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Cursor.png" id="8_g4vq6"] +[ext_resource type="Texture2D" uid="uid://oq2vvwgbdsh7" path="res://addons/guide/ui/renderers/textures/arrow_down.svg" id="9_dfyjd"] +[ext_resource type="Texture2D" uid="uid://bmgxqbypegjxh" path="res://addons/guide/ui/renderers/textures/arrow_horizontal.svg" id="12_xdqh7"] +[ext_resource type="Texture2D" uid="uid://b3uxk5agbpmab" path="res://addons/guide/ui/renderers/mouse/icons/Mouse_Simple_Key_Light.png" id="13_1bw2l"] +[ext_resource type="Texture2D" uid="uid://bu5nlug6uf03w" path="res://addons/guide/ui/renderers/textures/arrow_vertical.svg" id="13_yoogt"] + +[node name="MouseRenderer" type="MarginContainer"] +process_mode = 3 +offset_right = 100.0 +offset_bottom = 100.0 +size_flags_horizontal = 0 +script = ExtResource("1_amutf") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_horizontal = 0 + +[node name="Controls" type="MarginContainer" parent="HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(100, 100) +layout_mode = 2 + +[node name="MouseBlank" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("13_1bw2l") +stretch_mode = 4 + +[node name="MouseLeft" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("2_6vk7n") +stretch_mode = 4 + +[node name="MouseRight" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("3_aaqrj") +stretch_mode = 4 + +[node name="MouseMiddle" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("4_gprek") +stretch_mode = 4 + +[node name="MouseSideA" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("7_bbgo7") +stretch_mode = 4 + +[node name="MouseSideB" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("6_adi64") +stretch_mode = 4 + +[node name="MouseCursor" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("8_g4vq6") +stretch_mode = 4 + +[node name="Directions" type="MarginContainer" parent="HBoxContainer"] +unique_name_in_owner = true +visible = false +custom_minimum_size = Vector2(100, 100) +layout_mode = 2 + +[node name="Left" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("6_fo4h0") +stretch_mode = 4 + +[node name="Right" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("7_t242p") +stretch_mode = 4 + +[node name="Up" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("8_a7prs") +stretch_mode = 4 + +[node name="Down" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("9_dfyjd") +stretch_mode = 4 + +[node name="Horizontal" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("12_xdqh7") +stretch_mode = 4 + +[node name="Vertical" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("13_yoogt") +stretch_mode = 4 diff --git a/addons/guide/ui/renderers/textures/action.svg b/addons/guide/ui/renderers/textures/action.svg new file mode 100644 index 0000000..1da724c --- /dev/null +++ b/addons/guide/ui/renderers/textures/action.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/addons/guide/ui/renderers/textures/action.svg.import b/addons/guide/ui/renderers/textures/action.svg.import new file mode 100644 index 0000000..7c0aa8d --- /dev/null +++ b/addons/guide/ui/renderers/textures/action.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://diwkvjkss2ie" +path="res://.godot/imported/action.svg-6100da2ab8ea5d289c6e91ccdfb53aca.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/textures/action.svg" +dest_files=["res://.godot/imported/action.svg-6100da2ab8ea5d289c6e91ccdfb53aca.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/ui/renderers/textures/arrow_all_directions.svg b/addons/guide/ui/renderers/textures/arrow_all_directions.svg new file mode 100644 index 0000000..c0053b6 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_all_directions.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/addons/guide/ui/renderers/textures/arrow_all_directions.svg.import b/addons/guide/ui/renderers/textures/arrow_all_directions.svg.import new file mode 100644 index 0000000..20bd950 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_all_directions.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dwb1h8sfsccyy" +path="res://.godot/imported/arrow_all_directions.svg-c87a4938e66e69435ad57c677b38771f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/textures/arrow_all_directions.svg" +dest_files=["res://.godot/imported/arrow_all_directions.svg-c87a4938e66e69435ad57c677b38771f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/ui/renderers/textures/arrow_down.svg b/addons/guide/ui/renderers/textures/arrow_down.svg new file mode 100644 index 0000000..b1a193a --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_down.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/addons/guide/ui/renderers/textures/arrow_down.svg.import b/addons/guide/ui/renderers/textures/arrow_down.svg.import new file mode 100644 index 0000000..f624ed8 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_down.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://oq2vvwgbdsh7" +path="res://.godot/imported/arrow_down.svg-88a3b47c68c37638cef21944ad9cda50.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/textures/arrow_down.svg" +dest_files=["res://.godot/imported/arrow_down.svg-88a3b47c68c37638cef21944ad9cda50.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/ui/renderers/textures/arrow_horizontal.svg b/addons/guide/ui/renderers/textures/arrow_horizontal.svg new file mode 100644 index 0000000..ae0146f --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_horizontal.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/addons/guide/ui/renderers/textures/arrow_horizontal.svg.import b/addons/guide/ui/renderers/textures/arrow_horizontal.svg.import new file mode 100644 index 0000000..8975345 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_horizontal.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bmgxqbypegjxh" +path="res://.godot/imported/arrow_horizontal.svg-5fd469f78a3e46cba20723a7b243bca1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/textures/arrow_horizontal.svg" +dest_files=["res://.godot/imported/arrow_horizontal.svg-5fd469f78a3e46cba20723a7b243bca1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/ui/renderers/textures/arrow_left.svg b/addons/guide/ui/renderers/textures/arrow_left.svg new file mode 100644 index 0000000..9f94969 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_left.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/addons/guide/ui/renderers/textures/arrow_left.svg.import b/addons/guide/ui/renderers/textures/arrow_left.svg.import new file mode 100644 index 0000000..2b22128 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_left.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://1swh072gtbb4" +path="res://.godot/imported/arrow_left.svg-2a189e6eec3713a64220cf9427e1f45c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/textures/arrow_left.svg" +dest_files=["res://.godot/imported/arrow_left.svg-2a189e6eec3713a64220cf9427e1f45c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/ui/renderers/textures/arrow_right.svg b/addons/guide/ui/renderers/textures/arrow_right.svg new file mode 100644 index 0000000..7516511 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_right.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/addons/guide/ui/renderers/textures/arrow_right.svg.import b/addons/guide/ui/renderers/textures/arrow_right.svg.import new file mode 100644 index 0000000..2b784e3 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_right.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cjvs04qsrj8ap" +path="res://.godot/imported/arrow_right.svg-83b2fe427227f253ed212a8b1c56acb4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/textures/arrow_right.svg" +dest_files=["res://.godot/imported/arrow_right.svg-83b2fe427227f253ed212a8b1c56acb4.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/ui/renderers/textures/arrow_up.svg b/addons/guide/ui/renderers/textures/arrow_up.svg new file mode 100644 index 0000000..8b37520 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_up.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/addons/guide/ui/renderers/textures/arrow_up.svg.import b/addons/guide/ui/renderers/textures/arrow_up.svg.import new file mode 100644 index 0000000..83e63ee --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_up.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ni6lsbx1d2hf" +path="res://.godot/imported/arrow_up.svg-56e16fd95d307eb9666c8ac4e78e2b97.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/textures/arrow_up.svg" +dest_files=["res://.godot/imported/arrow_up.svg-56e16fd95d307eb9666c8ac4e78e2b97.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/ui/renderers/textures/arrow_vertical.svg b/addons/guide/ui/renderers/textures/arrow_vertical.svg new file mode 100644 index 0000000..2bf3493 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_vertical.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/addons/guide/ui/renderers/textures/arrow_vertical.svg.import b/addons/guide/ui/renderers/textures/arrow_vertical.svg.import new file mode 100644 index 0000000..7d87170 --- /dev/null +++ b/addons/guide/ui/renderers/textures/arrow_vertical.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bu5nlug6uf03w" +path="res://.godot/imported/arrow_vertical.svg-17983361d36ac9313b8d80f7240cf6aa.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/textures/arrow_vertical.svg" +dest_files=["res://.godot/imported/arrow_vertical.svg-17983361d36ac9313b8d80f7240cf6aa.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/guide/ui/renderers/touch/icons/touch_1_finger.png b/addons/guide/ui/renderers/touch/icons/touch_1_finger.png new file mode 100644 index 0000000..86ef0be Binary files /dev/null and b/addons/guide/ui/renderers/touch/icons/touch_1_finger.png differ diff --git a/addons/guide/ui/renderers/touch/icons/touch_1_finger.png.import b/addons/guide/ui/renderers/touch/icons/touch_1_finger.png.import new file mode 100644 index 0000000..15f71ab --- /dev/null +++ b/addons/guide/ui/renderers/touch/icons/touch_1_finger.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c5nwnp5cjny7m" +path="res://.godot/imported/touch_1_finger.png-c21ed1a6c694f6c9460ef451efcf36e2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/touch/icons/touch_1_finger.png" +dest_files=["res://.godot/imported/touch_1_finger.png-c21ed1a6c694f6c9460ef451efcf36e2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/touch/icons/touch_2_fingers.png b/addons/guide/ui/renderers/touch/icons/touch_2_fingers.png new file mode 100644 index 0000000..354ff8d Binary files /dev/null and b/addons/guide/ui/renderers/touch/icons/touch_2_fingers.png differ diff --git a/addons/guide/ui/renderers/touch/icons/touch_2_fingers.png.import b/addons/guide/ui/renderers/touch/icons/touch_2_fingers.png.import new file mode 100644 index 0000000..5e7dfd6 --- /dev/null +++ b/addons/guide/ui/renderers/touch/icons/touch_2_fingers.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bllhe78a1yo6" +path="res://.godot/imported/touch_2_fingers.png-f5e5340b938b807b9249837228cb3c96.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/touch/icons/touch_2_fingers.png" +dest_files=["res://.godot/imported/touch_2_fingers.png-f5e5340b938b807b9249837228cb3c96.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/touch/icons/touch_3_fingers.png b/addons/guide/ui/renderers/touch/icons/touch_3_fingers.png new file mode 100644 index 0000000..09a07d9 Binary files /dev/null and b/addons/guide/ui/renderers/touch/icons/touch_3_fingers.png differ diff --git a/addons/guide/ui/renderers/touch/icons/touch_3_fingers.png.import b/addons/guide/ui/renderers/touch/icons/touch_3_fingers.png.import new file mode 100644 index 0000000..180b468 --- /dev/null +++ b/addons/guide/ui/renderers/touch/icons/touch_3_fingers.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bwhqf2nmm5q1w" +path="res://.godot/imported/touch_3_fingers.png-1b0a5171a90b9f0d4adf18b2d204fed6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/touch/icons/touch_3_fingers.png" +dest_files=["res://.godot/imported/touch_3_fingers.png-1b0a5171a90b9f0d4adf18b2d204fed6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/touch/icons/touch_4_fingers.png b/addons/guide/ui/renderers/touch/icons/touch_4_fingers.png new file mode 100644 index 0000000..288c40c Binary files /dev/null and b/addons/guide/ui/renderers/touch/icons/touch_4_fingers.png differ diff --git a/addons/guide/ui/renderers/touch/icons/touch_4_fingers.png.import b/addons/guide/ui/renderers/touch/icons/touch_4_fingers.png.import new file mode 100644 index 0000000..02e6cd4 --- /dev/null +++ b/addons/guide/ui/renderers/touch/icons/touch_4_fingers.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cjw5m42gufghr" +path="res://.godot/imported/touch_4_fingers.png-feb0257c01dc7e2234eb7bd7feabd57d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/touch/icons/touch_4_fingers.png" +dest_files=["res://.godot/imported/touch_4_fingers.png-feb0257c01dc7e2234eb7bd7feabd57d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/touch/icons/touch_rotate.png b/addons/guide/ui/renderers/touch/icons/touch_rotate.png new file mode 100644 index 0000000..6c1af5b Binary files /dev/null and b/addons/guide/ui/renderers/touch/icons/touch_rotate.png differ diff --git a/addons/guide/ui/renderers/touch/icons/touch_rotate.png.import b/addons/guide/ui/renderers/touch/icons/touch_rotate.png.import new file mode 100644 index 0000000..0975cd0 --- /dev/null +++ b/addons/guide/ui/renderers/touch/icons/touch_rotate.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bxj4t5vjx7o3w" +path="res://.godot/imported/touch_rotate.png-22fc9d2b74759b3c29981107fa4d935b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/touch/icons/touch_rotate.png" +dest_files=["res://.godot/imported/touch_rotate.png-22fc9d2b74759b3c29981107fa4d935b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/touch/icons/touch_zoom.png b/addons/guide/ui/renderers/touch/icons/touch_zoom.png new file mode 100644 index 0000000..37e0cb8 Binary files /dev/null and b/addons/guide/ui/renderers/touch/icons/touch_zoom.png differ diff --git a/addons/guide/ui/renderers/touch/icons/touch_zoom.png.import b/addons/guide/ui/renderers/touch/icons/touch_zoom.png.import new file mode 100644 index 0000000..73bc5e3 --- /dev/null +++ b/addons/guide/ui/renderers/touch/icons/touch_zoom.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cutplj0nhphk" +path="res://.godot/imported/touch_zoom.png-6fb619cb5fcce5feede2a4a5f40428ee.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/guide/ui/renderers/touch/icons/touch_zoom.png" +dest_files=["res://.godot/imported/touch_zoom.png-6fb619cb5fcce5feede2a4a5f40428ee.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/guide/ui/renderers/touch/touch_renderer.gd b/addons/guide/ui/renderers/touch/touch_renderer.gd new file mode 100644 index 0000000..ad2284e --- /dev/null +++ b/addons/guide/ui/renderers/touch/touch_renderer.gd @@ -0,0 +1,73 @@ +@tool +extends GUIDEIconRenderer + +const GUIDEInputTouchBase = preload("../../../inputs/guide_input_touch_base.gd") + +@onready var _controls:Control = %Controls +@onready var _1_finger:Control = %T1Finger +@onready var _2_finger:Control = %T2Fingers +@onready var _3_finger:Control = %T3Fingers +@onready var _4_finger:Control = %T4Fingers +@onready var _rotate:Control = %Rotate +@onready var _zoom:Control = %Zoom + + +@onready var _directions:Control = %Directions +@onready var _horizontal:Control = %Horizontal +@onready var _vertical:Control = %Vertical +@onready var _axis2d:Control = %Axis2D + + + +func supports(input:GUIDEInput) -> bool: + return input is GUIDEInputTouchAxis1D or \ + input is GUIDEInputTouchAxis2D or \ + input is GUIDEInputTouchPosition or \ + input is GUIDEInputTouchAngle or \ + input is GUIDEInputTouchDistance + + + +func render(input:GUIDEInput) -> void: + for child in _controls.get_children(): + child.visible = false + for child in _directions.get_children(): + child.visible = false + + _directions.visible = false + + if input is GUIDEInputTouchBase: + match input.finger_count: + 2: + _2_finger.visible = true + 3: + _3_finger.visible = true + 4: + _4_finger.visible = true + _: + # we have no icons for more than 4 fingers, so everything else gets + # the 1 finger icon + _1_finger.visible = true + + if input is GUIDEInputTouchAxis2D: + _directions.visible = true + _axis2d.visible = true + + if input is GUIDEInputTouchAxis1D: + _directions.visible = true + match input.axis: + GUIDEInputTouchAxis1D.GUIDEInputTouchAxis.X: + _horizontal.visible = true + GUIDEInputTouchAxis1D.GUIDEInputTouchAxis.X: + _vertical.visible = true + + if input is GUIDEInputTouchDistance: + _zoom.visible = true + + if input is GUIDEInputTouchAngle: + _rotate.visible = true + + call("queue_sort") + +func cache_key(input:GUIDEInput) -> String: + return "1f4c5082-d419-465f-aba8-f889caaff335" + input.to_string() diff --git a/addons/guide/ui/renderers/touch/touch_renderer.gd.uid b/addons/guide/ui/renderers/touch/touch_renderer.gd.uid new file mode 100644 index 0000000..b3ee4a7 --- /dev/null +++ b/addons/guide/ui/renderers/touch/touch_renderer.gd.uid @@ -0,0 +1 @@ +uid://birg7gy0a8mom diff --git a/addons/guide/ui/renderers/touch/touch_renderer.tscn b/addons/guide/ui/renderers/touch/touch_renderer.tscn new file mode 100644 index 0000000..b54a0e8 --- /dev/null +++ b/addons/guide/ui/renderers/touch/touch_renderer.tscn @@ -0,0 +1,93 @@ +[gd_scene load_steps=11 format=3 uid="uid://ykuou1deo5ub"] + +[ext_resource type="Script" path="res://addons/guide/ui/renderers/touch/touch_renderer.gd" id="1_heixj"] +[ext_resource type="Texture2D" uid="uid://c5nwnp5cjny7m" path="res://addons/guide/ui/renderers/touch/icons/touch_1_finger.png" id="2_4mplc"] +[ext_resource type="Texture2D" uid="uid://bllhe78a1yo6" path="res://addons/guide/ui/renderers/touch/icons/touch_2_fingers.png" id="3_0dcqu"] +[ext_resource type="Texture2D" uid="uid://bwhqf2nmm5q1w" path="res://addons/guide/ui/renderers/touch/icons/touch_3_fingers.png" id="4_mgq0v"] +[ext_resource type="Texture2D" uid="uid://cjw5m42gufghr" path="res://addons/guide/ui/renderers/touch/icons/touch_4_fingers.png" id="5_qoicp"] +[ext_resource type="Texture2D" uid="uid://bxj4t5vjx7o3w" path="res://addons/guide/ui/renderers/touch/icons/touch_rotate.png" id="6_4jaqi"] +[ext_resource type="Texture2D" uid="uid://cutplj0nhphk" path="res://addons/guide/ui/renderers/touch/icons/touch_zoom.png" id="7_gvy7l"] +[ext_resource type="Texture2D" uid="uid://bmgxqbypegjxh" path="res://addons/guide/ui/renderers/textures/arrow_horizontal.svg" id="8_m5om5"] +[ext_resource type="Texture2D" uid="uid://dwb1h8sfsccyy" path="res://addons/guide/ui/renderers/textures/arrow_all_directions.svg" id="9_5gr2q"] +[ext_resource type="Texture2D" uid="uid://bu5nlug6uf03w" path="res://addons/guide/ui/renderers/textures/arrow_vertical.svg" id="10_4vghq"] + +[node name="TouchRenderer" type="MarginContainer"] +offset_right = 100.0 +offset_bottom = 100.0 +size_flags_horizontal = 0 +script = ExtResource("1_heixj") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_horizontal = 0 + +[node name="Controls" type="MarginContainer" parent="HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(100, 100) +layout_mode = 2 + +[node name="T1Finger" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("2_4mplc") +stretch_mode = 4 + +[node name="T2Fingers" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("3_0dcqu") +stretch_mode = 4 + +[node name="T3Fingers" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("4_mgq0v") +stretch_mode = 4 + +[node name="T4Fingers" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("5_qoicp") +stretch_mode = 4 + +[node name="Rotate" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("6_4jaqi") +stretch_mode = 4 + +[node name="Zoom" type="TextureRect" parent="HBoxContainer/Controls"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +texture = ExtResource("7_gvy7l") +stretch_mode = 4 + +[node name="Directions" type="MarginContainer" parent="HBoxContainer"] +unique_name_in_owner = true +visible = false +custom_minimum_size = Vector2(100, 100) +layout_mode = 2 + +[node name="Horizontal" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("8_m5om5") +stretch_mode = 4 + +[node name="Vertical" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("10_4vghq") +stretch_mode = 4 + +[node name="Axis2D" type="TextureRect" parent="HBoxContainer/Directions"] +unique_name_in_owner = true +layout_mode = 2 +texture = ExtResource("9_5gr2q") +stretch_mode = 4 diff --git a/addons/guide/ui/text_providers/controllers/controller_text_provider.gd b/addons/guide/ui/text_providers/controllers/controller_text_provider.gd new file mode 100644 index 0000000..3a569ee --- /dev/null +++ b/addons/guide/ui/text_providers/controllers/controller_text_provider.gd @@ -0,0 +1,115 @@ +extends GUIDETextProvider + +func _init(): + priority = -1 + +func _controller_names() -> Array[String]: + return [] + +func _a_button_name() -> String: + return "A" + +func _b_button_name() -> String: + return "B" + +func _x_button_name() -> String: + return "X" + +func _y_button_name() -> String: + return "Y" + +func _left_bumper_name() -> String: + return "LB" + +func _right_bumper_name() -> String: + return "RB" + +func _left_trigger_name() -> String: + return "LT" + +func _right_trigger_name() -> String: + return "RT" + +func _back_button_name() -> String: + return "Back" + +func _misc_1_button_name() -> String: + return "Misc 1" + +func _start_button_name() -> String: + return "Start" + + +func supports(input:GUIDEInput) -> bool: + var controller_name = GUIDEInputFormatter._joy_name_for_input(input) + if controller_name == "": + return false + + var haystack = controller_name.to_lower() + for needle in _controller_names(): + if haystack.contains(needle.to_lower()): + return true + + return false + +func _format(input:String) -> String: + return "[%s]" % [input] + + +func get_text(input:GUIDEInput) -> String: + if input is GUIDEInputJoyAxis1D: + match input.axis: + JOY_AXIS_LEFT_X: + return _format(tr("Left Stick Horizontal")) + JOY_AXIS_LEFT_Y: + return _format(tr("Left Stick Vertical")) + JOY_AXIS_RIGHT_X: + return _format(tr("Right Stick Horizontal")) + JOY_AXIS_RIGHT_Y: + return _format(tr("Right Stick Vertical")) + JOY_AXIS_TRIGGER_LEFT: + return _format(tr(_left_trigger_name())) + JOY_AXIS_TRIGGER_RIGHT: + return _format(tr(_right_trigger_name())) + + if input is GUIDEInputJoyAxis2D: + match input.x: + JOY_AXIS_LEFT_X, JOY_AXIS_LEFT_Y: + return _format(tr("Left Stick")) + JOY_AXIS_RIGHT_X, JOY_AXIS_RIGHT_Y: + return _format(tr("Right Stick")) + + if input is GUIDEInputJoyButton: + match input.button: + JOY_BUTTON_A: + return _format(tr(_a_button_name())) + JOY_BUTTON_B: + return _format(tr(_b_button_name())) + JOY_BUTTON_X: + return _format(tr(_x_button_name())) + JOY_BUTTON_Y: + return _format(tr(_y_button_name())) + JOY_BUTTON_DPAD_LEFT: + return _format(tr("DPAD Left")) + JOY_BUTTON_DPAD_RIGHT: + return _format(tr("DPAD Right")) + JOY_BUTTON_DPAD_UP: + return _format(tr("DPAD Up")) + JOY_BUTTON_DPAD_DOWN: + return _format(tr("DPAD Down")) + JOY_BUTTON_LEFT_SHOULDER: + return _format(tr(_left_bumper_name())) + JOY_BUTTON_RIGHT_SHOULDER: + return _format(tr(_right_bumper_name())) + JOY_BUTTON_LEFT_STICK: + return _format(tr("Left Stick")) + JOY_BUTTON_RIGHT_STICK: + return _format(tr("Right Stick")) + JOY_BUTTON_BACK: + return _format(tr(_back_button_name())) + JOY_BUTTON_MISC1: + return _format(tr(_misc_1_button_name())) + JOY_BUTTON_START: + return _format(tr(_start_button_name())) + + return _format("??") diff --git a/addons/guide/ui/text_providers/controllers/controller_text_provider.gd.uid b/addons/guide/ui/text_providers/controllers/controller_text_provider.gd.uid new file mode 100644 index 0000000..1088756 --- /dev/null +++ b/addons/guide/ui/text_providers/controllers/controller_text_provider.gd.uid @@ -0,0 +1 @@ +uid://drnn2tb5xp5li diff --git a/addons/guide/ui/text_providers/controllers/playstation/playstation_controller_text_provider.gd b/addons/guide/ui/text_providers/controllers/playstation/playstation_controller_text_provider.gd new file mode 100644 index 0000000..786f145 --- /dev/null +++ b/addons/guide/ui/text_providers/controllers/playstation/playstation_controller_text_provider.gd @@ -0,0 +1,37 @@ +extends "res://addons/guide/ui/text_providers/controllers/controller_text_provider.gd" + +func _controller_names() -> Array[String]: + return ["DualSense", "DualShock", "Playstation", "PS3", "PS4", "PS5"] + +func _a_button_name() -> String: + return "Cross" + +func _b_button_name() -> String: + return "Circle" + +func _x_button_name() -> String: + return "Square" + +func _y_button_name() -> String: + return "Triangle" + +func _left_bumper_name() -> String: + return "L1" + +func _right_bumper_name() -> String: + return "R1" + +func _left_trigger_name() -> String: + return "L2" + +func _right_trigger_name() -> String: + return "R2" + +func _back_button_name() -> String: + return "Share" + +func _misc_1_button_name() -> String: + return "Microphone" + +func _start_button_name() -> String: + return "Options" diff --git a/addons/guide/ui/text_providers/controllers/playstation/playstation_controller_text_provider.gd.uid b/addons/guide/ui/text_providers/controllers/playstation/playstation_controller_text_provider.gd.uid new file mode 100644 index 0000000..35984e4 --- /dev/null +++ b/addons/guide/ui/text_providers/controllers/playstation/playstation_controller_text_provider.gd.uid @@ -0,0 +1 @@ +uid://cbsxonq3kwsx3 diff --git a/addons/guide/ui/text_providers/controllers/switch/switch_controller_text_provider.gd b/addons/guide/ui/text_providers/controllers/switch/switch_controller_text_provider.gd new file mode 100644 index 0000000..97fbe5d --- /dev/null +++ b/addons/guide/ui/text_providers/controllers/switch/switch_controller_text_provider.gd @@ -0,0 +1,37 @@ +extends "res://addons/guide/ui/text_providers/controllers/controller_text_provider.gd" + +func _controller_names() -> Array[String]: + return ["Nintendo Switch"] + +func _a_button_name() -> String: + return "B" + +func _b_button_name() -> String: + return "A" + +func _x_button_name() -> String: + return "Y" + +func _y_button_name() -> String: + return "X" + +func _left_bumper_name() -> String: + return "L" + +func _right_bumper_name() -> String: + return "R" + +func _left_trigger_name() -> String: + return "ZL" + +func _right_trigger_name() -> String: + return "ZR" + +func _back_button_name() -> String: + return "-" + +func _misc_1_button_name() -> String: + return "Square" + +func _start_button_name() -> String: + return "+" diff --git a/addons/guide/ui/text_providers/controllers/switch/switch_controller_text_provider.gd.uid b/addons/guide/ui/text_providers/controllers/switch/switch_controller_text_provider.gd.uid new file mode 100644 index 0000000..24fa650 --- /dev/null +++ b/addons/guide/ui/text_providers/controllers/switch/switch_controller_text_provider.gd.uid @@ -0,0 +1 @@ +uid://cjlop0xk86bnt diff --git a/addons/guide/ui/text_providers/controllers/xbox/xbox_controller_text_provider.gd b/addons/guide/ui/text_providers/controllers/xbox/xbox_controller_text_provider.gd new file mode 100644 index 0000000..1d044d7 --- /dev/null +++ b/addons/guide/ui/text_providers/controllers/xbox/xbox_controller_text_provider.gd @@ -0,0 +1,37 @@ +extends "res://addons/guide/ui/text_providers/controllers/controller_text_provider.gd" + +func _controller_names() -> Array[String]: + return ["XInput", "XBox"] + +func _a_button_name() -> String: + return "A" + +func _b_button_name() -> String: + return "B" + +func _x_button_name() -> String: + return "X" + +func _y_button_name() -> String: + return "Y" + +func _left_bumper_name() -> String: + return "LB" + +func _right_bumper_name() -> String: + return "RB" + +func _left_trigger_name() -> String: + return "LT" + +func _right_trigger_name() -> String: + return "RT" + +func _back_button_name() -> String: + return "View" + +func _misc_1_button_name() -> String: + return "Share" + +func _start_button_name() -> String: + return "Menu" diff --git a/addons/guide/ui/text_providers/controllers/xbox/xbox_controller_text_provider.gd.uid b/addons/guide/ui/text_providers/controllers/xbox/xbox_controller_text_provider.gd.uid new file mode 100644 index 0000000..0df0965 --- /dev/null +++ b/addons/guide/ui/text_providers/controllers/xbox/xbox_controller_text_provider.gd.uid @@ -0,0 +1 @@ +uid://d04a556ciqq35 diff --git a/addons/guide/ui/text_providers/default_text_provider.gd b/addons/guide/ui/text_providers/default_text_provider.gd new file mode 100644 index 0000000..c9ce6af --- /dev/null +++ b/addons/guide/ui/text_providers/default_text_provider.gd @@ -0,0 +1,141 @@ +extends GUIDETextProvider + +var _is_on_desktop:bool = false + +func _init(): + priority = 0 + _is_on_desktop = OS.has_feature("linuxbsd") or OS.has_feature("macos") or OS.has_feature("windows") + +func supports(input:GUIDEInput) -> bool: + return true + + +func _format(input:String) -> String: + return "[%s]" % [input] + + +func get_text(input:GUIDEInput) -> String: + if input is GUIDEInputKey: + var result:PackedStringArray = [] + if input.control: + var ctrl = GUIDEInputKey.new() + ctrl.key = KEY_CTRL + result.append(get_text(ctrl)) + if input.alt: + var alt = GUIDEInputKey.new() + alt.key = KEY_ALT + result.append(get_text(alt)) + if input.shift: + var shift = GUIDEInputKey.new() + shift.key = KEY_SHIFT + result.append(get_text(shift)) + if input.meta: + var meta = GUIDEInputKey.new() + meta.key = KEY_META + result.append(get_text(meta)) + + var the_key = input.key + + # if we are on desktop, translate the physical keycode into the actual label + # this is not supported on mobile, so we have to check + if _is_on_desktop: + the_key = DisplayServer.keyboard_get_label_from_physical(input.key) + + + result.append(_format(OS.get_keycode_string(the_key))) + return "+".join(result) + + if input is GUIDEInputMouseAxis1D: + match input.axis: + GUIDEInputMouseAxis1D.GUIDEInputMouseAxis.X: + return _format(tr("Mouse Left/Right")) + GUIDEInputMouseAxis1D.GUIDEInputMouseAxis.Y: + return _format(tr("Mouse Up/Down")) + + if input is GUIDEInputMouseAxis2D: + return _format(tr("Mouse")) + + if input is GUIDEInputMouseButton: + match input.button: + MOUSE_BUTTON_LEFT: + return _format(tr("Left Mouse Button")) + MOUSE_BUTTON_RIGHT: + return _format(tr("Right Mouse Button")) + MOUSE_BUTTON_MIDDLE: + return _format(tr("Middle Mouse Button")) + MOUSE_BUTTON_WHEEL_UP: + return _format(tr("Mouse Wheel Up")) + MOUSE_BUTTON_WHEEL_DOWN: + return _format(tr("Mouse Wheel Down")) + MOUSE_BUTTON_WHEEL_LEFT: + return _format(tr("Mouse Wheel Left")) + MOUSE_BUTTON_WHEEL_RIGHT: + return _format(tr("Mouse Wheel Right")) + MOUSE_BUTTON_XBUTTON1: + return _format(tr("Mouse Side 1")) + MOUSE_BUTTON_XBUTTON2: + return _format(tr("Mouse Side 2")) + + if input is GUIDEInputJoyAxis1D: + match input.axis: + JOY_AXIS_LEFT_X: + return _format(tr("Stick 1 Horizontal")) + JOY_AXIS_LEFT_Y: + return _format(tr("Stick 1 Vertical")) + JOY_AXIS_RIGHT_X: + return _format(tr("Stick 2 Horizontal")) + JOY_AXIS_RIGHT_Y: + return _format(tr("Stick 2 Vertical")) + JOY_AXIS_TRIGGER_LEFT: + return _format(tr("Axis 3")) + JOY_AXIS_TRIGGER_RIGHT: + return _format(tr("Axis 4")) + + if input is GUIDEInputJoyAxis2D: + match input.x: + JOY_AXIS_LEFT_X, JOY_AXIS_LEFT_Y: + return _format(tr("Stick 1")) + JOY_AXIS_RIGHT_X, JOY_AXIS_RIGHT_Y: + return _format(tr("Stick 2")) + + if input is GUIDEInputJoyButton: + return _format(tr("Joy %s") % [input.button]) + + + if input is GUIDEInputAction: + return _format(tr("Action %s") % ["?" if input.action == null else input.action._editor_name()]) + + if input is GUIDEInputAny: + var parts:Array[String] = [] + if input.joy: + parts.append(tr("Joy Button")) + if input.mouse: + parts.append(tr("Mouse Button")) + if input.keyboard: + parts.append(tr("Key")) + + return _format(tr("Any %s") % [ "/".join(parts) ] ) + + if input is GUIDEInputMousePosition: + return _format(tr("Mouse Position")) + + if input is GUIDEInputTouchPosition: + return _format(tr("Touch Position %s") % [input.finger_index if input.finger_index >= 0 else "Average"]) + + if input is GUIDEInputTouchAngle: + return _format(tr("Touch Angle")) + + if input is GUIDEInputTouchDistance: + return _format(tr("Touch Distance")) + + if input is GUIDEInputTouchAxis1D: + match input.axis: + GUIDEInputTouchAxis1D.GUIDEInputTouchAxis.X: + _format(tr("Touch Left/Right %s") % [input.finger_index if input.finger_index >= 0 else "Average"]) + GUIDEInputTouchAxis1D.GUIDEInputTouchAxis.Y: + _format(tr("Touch Up/Down %s") % [input.finger_index if input.finger_index >= 0 else "Average"]) + + if input is GUIDEInputTouchAxis2D: + return _format(tr("Touch Axis 2D %s") % [input.finger_index if input.finger_index >= 0 else "Average"]) + + return _format("??") diff --git a/addons/guide/ui/text_providers/default_text_provider.gd.uid b/addons/guide/ui/text_providers/default_text_provider.gd.uid new file mode 100644 index 0000000..ab6759d --- /dev/null +++ b/addons/guide/ui/text_providers/default_text_provider.gd.uid @@ -0,0 +1 @@ +uid://cpsrogavf5hy7 diff --git a/guide_examples/2d_axis_mapping/2d_axis_mapping.gd b/guide_examples/2d_axis_mapping/2d_axis_mapping.gd new file mode 100644 index 0000000..40a6fba --- /dev/null +++ b/guide_examples/2d_axis_mapping/2d_axis_mapping.gd @@ -0,0 +1,6 @@ +extends Node + +@export var mapping_context:GUIDEMappingContext + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) diff --git a/guide_examples/2d_axis_mapping/2d_axis_mapping.gd.uid b/guide_examples/2d_axis_mapping/2d_axis_mapping.gd.uid new file mode 100644 index 0000000..d9aef0e --- /dev/null +++ b/guide_examples/2d_axis_mapping/2d_axis_mapping.gd.uid @@ -0,0 +1 @@ +uid://cl57fk6xess4f diff --git a/guide_examples/2d_axis_mapping/2d_axis_mapping.tscn b/guide_examples/2d_axis_mapping/2d_axis_mapping.tscn new file mode 100644 index 0000000..bd60dd3 --- /dev/null +++ b/guide_examples/2d_axis_mapping/2d_axis_mapping.tscn @@ -0,0 +1,42 @@ +[gd_scene load_steps=9 format=3 uid="uid://dvbxt8jyo8okq"] + +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="1_4tef3"] +[ext_resource type="Script" path="res://guide_examples/2d_axis_mapping/2d_axis_mapping.gd" id="1_vdstu"] +[ext_resource type="Script" path="res://guide_examples/2d_axis_mapping/player.gd" id="2_54pxx"] +[ext_resource type="Resource" uid="uid://2hl7iqpondhi" path="res://guide_examples/input_scheme_switching/mapping_contexts/keyboard_scheme.tres" id="2_jtcd0"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="5_ewox0"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="5_h0lne"] +[ext_resource type="Resource" uid="uid://cxn2ibe1mn3sb" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/move.tres" id="8_581qd"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="8_p4vbo"] + +[node name="2DAxisMapping" type="Node"] +script = ExtResource("1_vdstu") +mapping_context = ExtResource("2_jtcd0") + +[node name="Player" type="Sprite2D" parent="."] +position = Vector2(546, 317) +texture = ExtResource("1_4tef3") +script = ExtResource("2_54pxx") +move_action = ExtResource("8_581qd") + +[node name="UI Layer" type="CanvasLayer" parent="."] + +[node name="Instructions Label" type="RichTextLabel" parent="UI Layer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -286.0 +offset_top = 24.0 +offset_right = -39.0 +offset_bottom = 47.0 +grow_horizontal = 0 +theme = ExtResource("8_p4vbo") +script = ExtResource("5_h0lne") +instructions_text = "Use %s to move the player." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("8_581qd")]) + +[node name="Debug Layer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="Debug Layer" instance=ExtResource("5_ewox0")] +theme = ExtResource("8_p4vbo") +metadata/_edit_lock_ = true diff --git a/guide_examples/2d_axis_mapping/mapping_contexts/2d_axis_mapping.tres b/guide_examples/2d_axis_mapping/mapping_contexts/2d_axis_mapping.tres new file mode 100644 index 0000000..c4830a2 --- /dev/null +++ b/guide_examples/2d_axis_mapping/mapping_contexts/2d_axis_mapping.tres @@ -0,0 +1,115 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=21 format=3 uid="uid://2hl7iqpondhj"] + +[ext_resource type="Resource" uid="uid://cxn2ibe1mn3sb" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/move.tres" id="1_5vw7l"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_0yrlp"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_ad6sj"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="3_nlxx1"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="4_16vkk"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_input_swizzle.gd" id="5_qr6a5"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="8_r1avn"] + +[sub_resource type="Resource" id="Resource_t51n6"] +script = ExtResource("2_0yrlp") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_ct0te"] +script = ExtResource("3_nlxx1") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_qm6gq"] +script = ExtResource("5_qr6a5") +order = 0 + +[sub_resource type="Resource" id="Resource_yewp7"] +script = ExtResource("3_ad6sj") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_t51n6") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_ct0te"), SubResource("Resource_qm6gq")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_c40re"] +script = ExtResource("2_0yrlp") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_rkxfa"] +script = ExtResource("3_nlxx1") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_6qgwf"] +script = ExtResource("3_ad6sj") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_c40re") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_rkxfa")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_2t3ts"] +script = ExtResource("2_0yrlp") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_eoiu5"] +script = ExtResource("5_qr6a5") +order = 0 + +[sub_resource type="Resource" id="Resource_bilhe"] +script = ExtResource("3_ad6sj") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_2t3ts") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_eoiu5")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_lften"] +script = ExtResource("2_0yrlp") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_v2qov"] +script = ExtResource("3_ad6sj") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_lften") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_u0xy6"] +script = ExtResource("4_16vkk") +action = ExtResource("1_5vw7l") +input_mappings = Array[ExtResource("3_ad6sj")]([SubResource("Resource_yewp7"), SubResource("Resource_6qgwf"), SubResource("Resource_bilhe"), SubResource("Resource_v2qov")]) + +[resource] +script = ExtResource("8_r1avn") +display_name = "" +mappings = Array[ExtResource("4_16vkk")]([SubResource("Resource_u0xy6")]) diff --git a/guide_examples/2d_axis_mapping/mapping_contexts/move.tres b/guide_examples/2d_axis_mapping/mapping_contexts/move.tres new file mode 100644 index 0000000..e7a9540 --- /dev/null +++ b/guide_examples/2d_axis_mapping/mapping_contexts/move.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cxn2ibe1mn3sa"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_anxy1"] + +[resource] +script = ExtResource("1_anxy1") +name = &"" +action_value_type = 2 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/2d_axis_mapping/player.gd b/guide_examples/2d_axis_mapping/player.gd new file mode 100644 index 0000000..36e5569 --- /dev/null +++ b/guide_examples/2d_axis_mapping/player.gd @@ -0,0 +1,10 @@ +## A very simple player script for a player who can only move. +extends Node2D + +@export var speed:float = 300 +@export var move_action:GUIDEAction + +func _process(delta:float) -> void: + # GUIDE already gives us a full 2D axis. We don't need to build it + # ourselves using Input.get_vector. + position += move_action.value_axis_2d.normalized() * speed * delta diff --git a/guide_examples/2d_axis_mapping/player.gd.uid b/guide_examples/2d_axis_mapping/player.gd.uid new file mode 100644 index 0000000..7895c7b --- /dev/null +++ b/guide_examples/2d_axis_mapping/player.gd.uid @@ -0,0 +1 @@ +uid://b3l3w1askqxgo diff --git a/guide_examples/action_priority/action_priority.gd b/guide_examples/action_priority/action_priority.gd new file mode 100644 index 0000000..b862bf4 --- /dev/null +++ b/guide_examples/action_priority/action_priority.gd @@ -0,0 +1,14 @@ +extends Node2D + + +@export var mapping_context:GUIDEMappingContext +@export var spell_toggle:GUIDEAction + +@onready var _layer_1:Control = %Layer1 +@onready var _layer_2:Control = %Layer2 + + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) + spell_toggle.triggered.connect(func(): _layer_1.hide(); _layer_2.show()) + spell_toggle.completed.connect(func(): _layer_1.show(); _layer_2.hide()) diff --git a/guide_examples/action_priority/action_priority.gd.uid b/guide_examples/action_priority/action_priority.gd.uid new file mode 100644 index 0000000..11f1293 --- /dev/null +++ b/guide_examples/action_priority/action_priority.gd.uid @@ -0,0 +1 @@ +uid://cycxhrywjuggp diff --git a/guide_examples/action_priority/action_priority.tscn b/guide_examples/action_priority/action_priority.tscn new file mode 100644 index 0000000..30a7120 --- /dev/null +++ b/guide_examples/action_priority/action_priority.tscn @@ -0,0 +1,125 @@ +[gd_scene load_steps=25 format=3 uid="uid://c03o20jchp7kb"] + +[ext_resource type="Script" path="res://guide_examples/action_priority/action_priority.gd" id="1_segid"] +[ext_resource type="Resource" uid="uid://ragqbe7yjfwe" path="res://guide_examples/action_priority/mapping_contexts/action_priority.tres" id="2_spx2e"] +[ext_resource type="Resource" uid="uid://c5eq1avod0lu8" path="res://guide_examples/action_priority/mapping_contexts/actions/spell_toggle.tres" id="3_k38f6"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="3_ocaq1"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="4_ur8xb"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="4_v7mqo"] +[ext_resource type="Resource" uid="uid://esf4ilpf0inv" path="res://guide_examples/action_priority/mapping_contexts/actions/acid_bolt.tres" id="5_oqj0p"] +[ext_resource type="Resource" uid="uid://bhq3gby2yiibf" path="res://guide_examples/action_priority/mapping_contexts/actions/acid_enchantment.tres" id="6_ue1ny"] +[ext_resource type="PackedScene" uid="uid://bsv0uwfyqbbbw" path="res://guide_examples/action_priority/dpad_spells/dpad_spells.tscn" id="7_48cit"] +[ext_resource type="Resource" uid="uid://cdhpb7yuq5pkb" path="res://guide_examples/action_priority/mapping_contexts/actions/mana_bolt.tres" id="7_ruu3d"] +[ext_resource type="Texture2D" uid="uid://emjksgvvx8kr" path="res://guide_examples/action_priority/icons/fireball-acid-3.png" id="8_pbht4"] +[ext_resource type="Resource" uid="uid://dsp8h1ycwd6tt" path="res://guide_examples/action_priority/mapping_contexts/actions/heal.tres" id="8_tl0ch"] +[ext_resource type="Texture2D" uid="uid://do0b76wher5pk" path="res://guide_examples/action_priority/icons/fireball-sky-3.png" id="9_6ehip"] +[ext_resource type="Resource" uid="uid://b5plj56pss47x" path="res://guide_examples/action_priority/mapping_contexts/actions/shield.tres" id="9_rbwtd"] +[ext_resource type="Texture2D" uid="uid://bb2whckygsgvj" path="res://guide_examples/action_priority/icons/heal-royal-3.png" id="10_vp0as"] +[ext_resource type="Resource" uid="uid://do3hivxhwoqvi" path="res://guide_examples/action_priority/mapping_contexts/actions/mana_enchantment.tres" id="11_223o5"] +[ext_resource type="Texture2D" uid="uid://dvy7bcy022rqq" path="res://guide_examples/action_priority/icons/protect-blue-2.png" id="11_t3r7p"] +[ext_resource type="Texture2D" uid="uid://dbwgq8udtj2hp" path="res://guide_examples/action_priority/icons/enchant-acid-3.png" id="12_2ht6b"] +[ext_resource type="Resource" uid="uid://dtr3jy86gc3rk" path="res://guide_examples/action_priority/mapping_contexts/actions/healing_enchantment.tres" id="12_4o7kv"] +[ext_resource type="Resource" uid="uid://bfskfiw1k8574" path="res://guide_examples/action_priority/mapping_contexts/actions/fire_enchantment.tres" id="13_6g6j5"] +[ext_resource type="Texture2D" uid="uid://b3j6yx4455rj0" path="res://guide_examples/action_priority/icons/enchant-blue-3.png" id="13_yufl8"] +[ext_resource type="Texture2D" uid="uid://djexj402ii0qp" path="res://guide_examples/action_priority/icons/enchant-jade-3.png" id="14_dpiqo"] +[ext_resource type="PackedScene" uid="uid://cx8f0hljh5dhs" path="res://guide_examples/action_priority/spell_indicator/spell_indicator.tscn" id="14_gmycm"] +[ext_resource type="Texture2D" uid="uid://bcls6cfcyhf0t" path="res://guide_examples/action_priority/icons/enchant-red-3.png" id="15_xjepw"] + +[node name="ActionPriority" type="Node2D"] +script = ExtResource("1_segid") +mapping_context = ExtResource("2_spx2e") +spell_toggle = ExtResource("3_k38f6") + +[node name="UILayer" type="CanvasLayer" parent="."] + +[node name="Instructions Label" type="RichTextLabel" parent="UILayer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -78.0 +offset_top = 19.0 +offset_right = -38.0 +offset_bottom = 42.0 +grow_horizontal = 0 +theme = ExtResource("4_ur8xb") +script = ExtResource("4_v7mqo") +instructions_text = "%s - acid bolt +%s - mana bolt +%s - heal +%s - shield +%s - acid enchantment +%s - mana enchantment +%s - healing enchantment +%s - fire enchantment" +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("5_oqj0p"), ExtResource("7_ruu3d"), ExtResource("8_tl0ch"), ExtResource("9_rbwtd"), ExtResource("6_ue1ny"), ExtResource("11_223o5"), ExtResource("12_4o7kv"), ExtResource("13_6g6j5")]) + +[node name="SpellIndicators" type="Node2D" parent="UILayer"] +position = Vector2(1149, 781) + +[node name="AcidBolt" parent="UILayer/SpellIndicators" instance=ExtResource("14_gmycm")] +action = ExtResource("5_oqj0p") +texture = ExtResource("8_pbht4") + +[node name="ManaBolt" parent="UILayer/SpellIndicators" instance=ExtResource("14_gmycm")] +action = ExtResource("7_ruu3d") +texture = ExtResource("9_6ehip") + +[node name="Heal" parent="UILayer/SpellIndicators" instance=ExtResource("14_gmycm")] +action = ExtResource("8_tl0ch") +texture = ExtResource("10_vp0as") + +[node name="Shield" parent="UILayer/SpellIndicators" instance=ExtResource("14_gmycm")] +action = ExtResource("9_rbwtd") +texture = ExtResource("11_t3r7p") + +[node name="AcidEnchant" parent="UILayer/SpellIndicators" instance=ExtResource("14_gmycm")] +action = ExtResource("6_ue1ny") +texture = ExtResource("12_2ht6b") + +[node name="ManaEnchant" parent="UILayer/SpellIndicators" instance=ExtResource("14_gmycm")] +action = ExtResource("11_223o5") +texture = ExtResource("13_yufl8") + +[node name="HealingEnchant" parent="UILayer/SpellIndicators" instance=ExtResource("14_gmycm")] +action = ExtResource("12_4o7kv") +texture = ExtResource("14_dpiqo") + +[node name="FireEnchant" parent="UILayer/SpellIndicators" instance=ExtResource("14_gmycm")] +action = ExtResource("13_6g6j5") +texture = ExtResource("15_xjepw") + +[node name="Spells" type="MarginContainer" parent="UILayer"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -529.0 +offset_top = 5.0 +offset_right = -85.0 +offset_bottom = 455.0 +grow_horizontal = 2 +grow_vertical = 2 +pivot_offset = Vector2(171, 194) + +[node name="Layer1" parent="UILayer/Spells" instance=ExtResource("7_48cit")] +unique_name_in_owner = true +layout_mode = 2 +up = ExtResource("8_pbht4") +left = ExtResource("9_6ehip") +right = ExtResource("10_vp0as") +down = ExtResource("11_t3r7p") + +[node name="Layer2" parent="UILayer/Spells" instance=ExtResource("7_48cit")] +unique_name_in_owner = true +visible = false +layout_mode = 2 +up = ExtResource("12_2ht6b") +left = ExtResource("13_yufl8") +right = ExtResource("14_dpiqo") +down = ExtResource("15_xjepw") + +[node name="DebugLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="DebugLayer" instance=ExtResource("3_ocaq1")] +theme = ExtResource("4_ur8xb") diff --git a/guide_examples/action_priority/dpad_spells/dpad_spells.gd b/guide_examples/action_priority/dpad_spells/dpad_spells.gd new file mode 100644 index 0000000..3b29af5 --- /dev/null +++ b/guide_examples/action_priority/dpad_spells/dpad_spells.gd @@ -0,0 +1,52 @@ +@tool +extends GridContainer + +@onready var _up:TextureRect = %Up +@onready var _left:TextureRect = %Left +@onready var _right:TextureRect = %Right +@onready var _down:TextureRect = %Down + + +@export var up:Texture2D: + set(value): + if value == up: + return + up = value + _refresh() + + +@export var left:Texture2D: + set(value): + if value == left: + return + left = value + _refresh() + + +@export var right:Texture2D: + set(value): + if value == right: + return + right= value + _refresh() + +@export var down:Texture2D: + set(value): + if value == down: + return + down = value + _refresh() + + +func _ready(): + _refresh() + + +func _refresh(): + if not is_node_ready(): + return + + _up.texture = up + _down.texture = down + _left.texture = left + _right.texture = right diff --git a/guide_examples/action_priority/dpad_spells/dpad_spells.gd.uid b/guide_examples/action_priority/dpad_spells/dpad_spells.gd.uid new file mode 100644 index 0000000..5e3e073 --- /dev/null +++ b/guide_examples/action_priority/dpad_spells/dpad_spells.gd.uid @@ -0,0 +1 @@ +uid://wsbm3iwylkto diff --git a/guide_examples/action_priority/dpad_spells/dpad_spells.tscn b/guide_examples/action_priority/dpad_spells/dpad_spells.tscn new file mode 100644 index 0000000..a126355 --- /dev/null +++ b/guide_examples/action_priority/dpad_spells/dpad_spells.tscn @@ -0,0 +1,56 @@ +[gd_scene load_steps=2 format=3 uid="uid://bsv0uwfyqbbbw"] + +[ext_resource type="Script" path="res://guide_examples/action_priority/dpad_spells/dpad_spells.gd" id="1_pl5jh"] + +[node name="DpadSpells" type="GridContainer"] +offset_right = 323.0 +offset_bottom = 329.0 +columns = 3 +script = ExtResource("1_pl5jh") + +[node name="Spacer" type="Control" parent="."] +layout_mode = 2 + +[node name="Up" type="TextureRect" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +expand_mode = 1 +stretch_mode = 5 + +[node name="Spacer2" type="Control" parent="."] +layout_mode = 2 + +[node name="Left" type="TextureRect" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +expand_mode = 1 +stretch_mode = 5 + +[node name="Spacer3" type="Control" parent="."] +layout_mode = 2 + +[node name="Right" type="TextureRect" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +expand_mode = 1 +stretch_mode = 5 + +[node name="Spacer4" type="Control" parent="."] +layout_mode = 2 + +[node name="Down" type="TextureRect" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +expand_mode = 1 +stretch_mode = 5 + +[node name="Spacer5" type="Control" parent="."] +layout_mode = 2 diff --git a/guide_examples/action_priority/icons/enchant-acid-3.png b/guide_examples/action_priority/icons/enchant-acid-3.png new file mode 100644 index 0000000..f4bc794 Binary files /dev/null and b/guide_examples/action_priority/icons/enchant-acid-3.png differ diff --git a/guide_examples/action_priority/icons/enchant-acid-3.png.import b/guide_examples/action_priority/icons/enchant-acid-3.png.import new file mode 100644 index 0000000..d942730 --- /dev/null +++ b/guide_examples/action_priority/icons/enchant-acid-3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dbwgq8udtj2hp" +path="res://.godot/imported/enchant-acid-3.png-e1947aa390c674d1399abe634bc54deb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/action_priority/icons/enchant-acid-3.png" +dest_files=["res://.godot/imported/enchant-acid-3.png-e1947aa390c674d1399abe634bc54deb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/action_priority/icons/enchant-blue-3.png b/guide_examples/action_priority/icons/enchant-blue-3.png new file mode 100644 index 0000000..5fad1c7 Binary files /dev/null and b/guide_examples/action_priority/icons/enchant-blue-3.png differ diff --git a/guide_examples/action_priority/icons/enchant-blue-3.png.import b/guide_examples/action_priority/icons/enchant-blue-3.png.import new file mode 100644 index 0000000..922c12b --- /dev/null +++ b/guide_examples/action_priority/icons/enchant-blue-3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b3j6yx4455rj0" +path="res://.godot/imported/enchant-blue-3.png-7fbde34e03a870571687bd67f54ff1a7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/action_priority/icons/enchant-blue-3.png" +dest_files=["res://.godot/imported/enchant-blue-3.png-7fbde34e03a870571687bd67f54ff1a7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/action_priority/icons/enchant-jade-3.png b/guide_examples/action_priority/icons/enchant-jade-3.png new file mode 100644 index 0000000..1cd28c4 Binary files /dev/null and b/guide_examples/action_priority/icons/enchant-jade-3.png differ diff --git a/guide_examples/action_priority/icons/enchant-jade-3.png.import b/guide_examples/action_priority/icons/enchant-jade-3.png.import new file mode 100644 index 0000000..34d097d --- /dev/null +++ b/guide_examples/action_priority/icons/enchant-jade-3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djexj402ii0qp" +path="res://.godot/imported/enchant-jade-3.png-dbada551fd0e4cb0fb15a3867cb2ef6b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/action_priority/icons/enchant-jade-3.png" +dest_files=["res://.godot/imported/enchant-jade-3.png-dbada551fd0e4cb0fb15a3867cb2ef6b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/action_priority/icons/enchant-red-3.png b/guide_examples/action_priority/icons/enchant-red-3.png new file mode 100644 index 0000000..b4f41be Binary files /dev/null and b/guide_examples/action_priority/icons/enchant-red-3.png differ diff --git a/guide_examples/action_priority/icons/enchant-red-3.png.import b/guide_examples/action_priority/icons/enchant-red-3.png.import new file mode 100644 index 0000000..2bad14d --- /dev/null +++ b/guide_examples/action_priority/icons/enchant-red-3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bcls6cfcyhf0t" +path="res://.godot/imported/enchant-red-3.png-82aa47d9224cc61c8bdf354866612b90.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/action_priority/icons/enchant-red-3.png" +dest_files=["res://.godot/imported/enchant-red-3.png-82aa47d9224cc61c8bdf354866612b90.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/action_priority/icons/fireball-acid-3.png b/guide_examples/action_priority/icons/fireball-acid-3.png new file mode 100644 index 0000000..364d7aa Binary files /dev/null and b/guide_examples/action_priority/icons/fireball-acid-3.png differ diff --git a/guide_examples/action_priority/icons/fireball-acid-3.png.import b/guide_examples/action_priority/icons/fireball-acid-3.png.import new file mode 100644 index 0000000..0f3391c --- /dev/null +++ b/guide_examples/action_priority/icons/fireball-acid-3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://emjksgvvx8kr" +path="res://.godot/imported/fireball-acid-3.png-17a549b7e763ef3fa4170fd9d37c6d27.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/action_priority/icons/fireball-acid-3.png" +dest_files=["res://.godot/imported/fireball-acid-3.png-17a549b7e763ef3fa4170fd9d37c6d27.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/action_priority/icons/fireball-sky-3.png b/guide_examples/action_priority/icons/fireball-sky-3.png new file mode 100644 index 0000000..8319de9 Binary files /dev/null and b/guide_examples/action_priority/icons/fireball-sky-3.png differ diff --git a/guide_examples/action_priority/icons/fireball-sky-3.png.import b/guide_examples/action_priority/icons/fireball-sky-3.png.import new file mode 100644 index 0000000..af85a67 --- /dev/null +++ b/guide_examples/action_priority/icons/fireball-sky-3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://do0b76wher5pk" +path="res://.godot/imported/fireball-sky-3.png-ef89177b310ec94cab7573ba28dfb564.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/action_priority/icons/fireball-sky-3.png" +dest_files=["res://.godot/imported/fireball-sky-3.png-ef89177b310ec94cab7573ba28dfb564.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/action_priority/icons/heal-royal-3.png b/guide_examples/action_priority/icons/heal-royal-3.png new file mode 100644 index 0000000..8053f69 Binary files /dev/null and b/guide_examples/action_priority/icons/heal-royal-3.png differ diff --git a/guide_examples/action_priority/icons/heal-royal-3.png.import b/guide_examples/action_priority/icons/heal-royal-3.png.import new file mode 100644 index 0000000..8ea65e9 --- /dev/null +++ b/guide_examples/action_priority/icons/heal-royal-3.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bb2whckygsgvj" +path="res://.godot/imported/heal-royal-3.png-a1b67309c29c3e0722cb4efa430d5f09.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/action_priority/icons/heal-royal-3.png" +dest_files=["res://.godot/imported/heal-royal-3.png-a1b67309c29c3e0722cb4efa430d5f09.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/action_priority/icons/protect-blue-2.png b/guide_examples/action_priority/icons/protect-blue-2.png new file mode 100644 index 0000000..61a06b5 Binary files /dev/null and b/guide_examples/action_priority/icons/protect-blue-2.png differ diff --git a/guide_examples/action_priority/icons/protect-blue-2.png.import b/guide_examples/action_priority/icons/protect-blue-2.png.import new file mode 100644 index 0000000..f81a95f --- /dev/null +++ b/guide_examples/action_priority/icons/protect-blue-2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dvy7bcy022rqq" +path="res://.godot/imported/protect-blue-2.png-abb9ef1d1e06e180429074d0e9b24edb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/action_priority/icons/protect-blue-2.png" +dest_files=["res://.godot/imported/protect-blue-2.png-abb9ef1d1e06e180429074d0e9b24edb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/action_priority/mapping_contexts/action_priority.tres b/guide_examples/action_priority/mapping_contexts/action_priority.tres new file mode 100644 index 0000000..3f94190 --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/action_priority.tres @@ -0,0 +1,263 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=56 format=3 uid="uid://ragqbe7yjfwe"] + +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_asqiw"] +[ext_resource type="Resource" uid="uid://bhq3gby2yiibf" path="res://guide_examples/action_priority/mapping_contexts/actions/acid_enchantment.tres" id="1_pwefn"] +[ext_resource type="Resource" uid="uid://c5eq1avod0lu8" path="res://guide_examples/action_priority/mapping_contexts/actions/spell_toggle.tres" id="2_swo1r"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="4_6rx1x"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="4_n7mmu"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="5_cxbyx"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_chorded_action.gd" id="5_w86oe"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="6_4koxr"] +[ext_resource type="Resource" uid="uid://esf4ilpf0inv" path="res://guide_examples/action_priority/mapping_contexts/actions/acid_bolt.tres" id="7_35imv"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_axis_1d.gd" id="8_avuuj"] +[ext_resource type="Resource" uid="uid://do3hivxhwoqvi" path="res://guide_examples/action_priority/mapping_contexts/actions/mana_enchantment.tres" id="8_lmhmq"] +[ext_resource type="Resource" uid="uid://dtr3jy86gc3rk" path="res://guide_examples/action_priority/mapping_contexts/actions/healing_enchantment.tres" id="9_xfl3h"] +[ext_resource type="Resource" uid="uid://cdhpb7yuq5pkb" path="res://guide_examples/action_priority/mapping_contexts/actions/mana_bolt.tres" id="10_krd45"] +[ext_resource type="Resource" uid="uid://bfskfiw1k8574" path="res://guide_examples/action_priority/mapping_contexts/actions/fire_enchantment.tres" id="10_m3nrn"] +[ext_resource type="Resource" uid="uid://dsp8h1ycwd6tt" path="res://guide_examples/action_priority/mapping_contexts/actions/heal.tres" id="12_w4t7r"] +[ext_resource type="Resource" uid="uid://b5plj56pss47x" path="res://guide_examples/action_priority/mapping_contexts/actions/shield.tres" id="14_qai3i"] + +[sub_resource type="Resource" id="Resource_2fxes"] +script = ExtResource("5_cxbyx") +button = 11 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_jhb3c"] +script = ExtResource("5_w86oe") +action = ExtResource("2_swo1r") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_i54ow"] +script = ExtResource("4_n7mmu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_fjuhd"] +script = ExtResource("4_6rx1x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_2fxes") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_jhb3c"), SubResource("Resource_i54ow")]) + +[sub_resource type="Resource" id="Resource_ai5ps"] +script = ExtResource("6_4koxr") +action = ExtResource("1_pwefn") +input_mappings = Array[ExtResource("4_6rx1x")]([SubResource("Resource_fjuhd")]) +metadata/_guide_input_mappings_collapsed = true + +[sub_resource type="Resource" id="Resource_w2qty"] +script = ExtResource("5_cxbyx") +button = 13 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_rl1q7"] +script = ExtResource("5_w86oe") +action = ExtResource("2_swo1r") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_4y1rh"] +script = ExtResource("4_n7mmu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_d8nq3"] +script = ExtResource("4_6rx1x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_w2qty") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_rl1q7"), SubResource("Resource_4y1rh")]) + +[sub_resource type="Resource" id="Resource_jwd6q"] +script = ExtResource("6_4koxr") +action = ExtResource("8_lmhmq") +input_mappings = Array[ExtResource("4_6rx1x")]([SubResource("Resource_d8nq3")]) +metadata/_guide_input_mappings_collapsed = true + +[sub_resource type="Resource" id="Resource_mxqg0"] +script = ExtResource("5_cxbyx") +button = 14 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_ip7ia"] +script = ExtResource("5_w86oe") +action = ExtResource("2_swo1r") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_i6wfw"] +script = ExtResource("4_n7mmu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_m8ya7"] +script = ExtResource("4_6rx1x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_mxqg0") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_ip7ia"), SubResource("Resource_i6wfw")]) + +[sub_resource type="Resource" id="Resource_22c0i"] +script = ExtResource("6_4koxr") +action = ExtResource("9_xfl3h") +input_mappings = Array[ExtResource("4_6rx1x")]([SubResource("Resource_m8ya7")]) +metadata/_guide_input_mappings_collapsed = true + +[sub_resource type="Resource" id="Resource_u2m40"] +script = ExtResource("5_cxbyx") +button = 12 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_7owy8"] +script = ExtResource("5_w86oe") +action = ExtResource("2_swo1r") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_tchgu"] +script = ExtResource("4_n7mmu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_2q1gn"] +script = ExtResource("4_6rx1x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_u2m40") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_7owy8"), SubResource("Resource_tchgu")]) + +[sub_resource type="Resource" id="Resource_4acdf"] +script = ExtResource("6_4koxr") +action = ExtResource("10_m3nrn") +input_mappings = Array[ExtResource("4_6rx1x")]([SubResource("Resource_2q1gn")]) +metadata/_guide_input_mappings_collapsed = true + +[sub_resource type="Resource" id="Resource_5sjq4"] +script = ExtResource("5_cxbyx") +button = 11 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_fkk8p"] +script = ExtResource("4_n7mmu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_vswh4"] +script = ExtResource("4_6rx1x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_5sjq4") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_fkk8p")]) + +[sub_resource type="Resource" id="Resource_8wvmf"] +script = ExtResource("6_4koxr") +action = ExtResource("7_35imv") +input_mappings = Array[ExtResource("4_6rx1x")]([SubResource("Resource_vswh4")]) +metadata/_guide_input_mappings_collapsed = true + +[sub_resource type="Resource" id="Resource_mbfh8"] +script = ExtResource("5_cxbyx") +button = 13 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_umt5k"] +script = ExtResource("4_n7mmu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_b8our"] +script = ExtResource("4_6rx1x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_mbfh8") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_umt5k")]) + +[sub_resource type="Resource" id="Resource_8p32p"] +script = ExtResource("6_4koxr") +action = ExtResource("10_krd45") +input_mappings = Array[ExtResource("4_6rx1x")]([SubResource("Resource_b8our")]) +metadata/_guide_input_mappings_collapsed = true + +[sub_resource type="Resource" id="Resource_utha0"] +script = ExtResource("5_cxbyx") +button = 14 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_sm46b"] +script = ExtResource("4_n7mmu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_1f76r"] +script = ExtResource("4_6rx1x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_utha0") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_sm46b")]) + +[sub_resource type="Resource" id="Resource_73ywc"] +script = ExtResource("6_4koxr") +action = ExtResource("12_w4t7r") +input_mappings = Array[ExtResource("4_6rx1x")]([SubResource("Resource_1f76r")]) +metadata/_guide_input_mappings_collapsed = true + +[sub_resource type="Resource" id="Resource_ov80l"] +script = ExtResource("5_cxbyx") +button = 12 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_wu6o8"] +script = ExtResource("4_n7mmu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_ggg1r"] +script = ExtResource("4_6rx1x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_ov80l") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_wu6o8")]) + +[sub_resource type="Resource" id="Resource_rleu1"] +script = ExtResource("6_4koxr") +action = ExtResource("14_qai3i") +input_mappings = Array[ExtResource("4_6rx1x")]([SubResource("Resource_ggg1r")]) +metadata/_guide_input_mappings_collapsed = true + +[sub_resource type="Resource" id="Resource_m51uq"] +script = ExtResource("8_avuuj") +axis = 4 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_2hg0t"] +script = ExtResource("4_6rx1x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_m51uq") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_uj8l6"] +script = ExtResource("6_4koxr") +action = ExtResource("2_swo1r") +input_mappings = Array[ExtResource("4_6rx1x")]([SubResource("Resource_2hg0t")]) + +[resource] +script = ExtResource("1_asqiw") +display_name = "" +mappings = Array[ExtResource("6_4koxr")]([SubResource("Resource_ai5ps"), SubResource("Resource_jwd6q"), SubResource("Resource_22c0i"), SubResource("Resource_4acdf"), SubResource("Resource_8wvmf"), SubResource("Resource_8p32p"), SubResource("Resource_73ywc"), SubResource("Resource_rleu1"), SubResource("Resource_uj8l6")]) diff --git a/guide_examples/action_priority/mapping_contexts/actions/acid_bolt.tres b/guide_examples/action_priority/mapping_contexts/actions/acid_bolt.tres new file mode 100644 index 0000000..49322f2 --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/actions/acid_bolt.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://esf4ilpf0inv"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_867co"] + +[resource] +script = ExtResource("1_867co") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/action_priority/mapping_contexts/actions/acid_enchantment.tres b/guide_examples/action_priority/mapping_contexts/actions/acid_enchantment.tres new file mode 100644 index 0000000..4fb98c0 --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/actions/acid_enchantment.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bhq3gby2yiibf"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_w7kln"] + +[resource] +script = ExtResource("1_w7kln") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/action_priority/mapping_contexts/actions/fire_enchantment.tres b/guide_examples/action_priority/mapping_contexts/actions/fire_enchantment.tres new file mode 100644 index 0000000..22369ed --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/actions/fire_enchantment.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bfskfiw1k8574"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_rlep8"] + +[resource] +script = ExtResource("1_rlep8") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/action_priority/mapping_contexts/actions/heal.tres b/guide_examples/action_priority/mapping_contexts/actions/heal.tres new file mode 100644 index 0000000..c3c16fa --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/actions/heal.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://dsp8h1ycwd6tt"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_o3iqb"] + +[resource] +script = ExtResource("1_o3iqb") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/action_priority/mapping_contexts/actions/healing_enchantment.tres b/guide_examples/action_priority/mapping_contexts/actions/healing_enchantment.tres new file mode 100644 index 0000000..c234cb0 --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/actions/healing_enchantment.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://dtr3jy86gc3rk"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_0fh74"] + +[resource] +script = ExtResource("1_0fh74") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/action_priority/mapping_contexts/actions/mana_bolt.tres b/guide_examples/action_priority/mapping_contexts/actions/mana_bolt.tres new file mode 100644 index 0000000..23e46c5 --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/actions/mana_bolt.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cdhpb7yuq5pkb"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_ka3gg"] + +[resource] +script = ExtResource("1_ka3gg") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/action_priority/mapping_contexts/actions/mana_enchantment.tres b/guide_examples/action_priority/mapping_contexts/actions/mana_enchantment.tres new file mode 100644 index 0000000..acedcd7 --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/actions/mana_enchantment.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://do3hivxhwoqvi"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_4c7tt"] + +[resource] +script = ExtResource("1_4c7tt") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/action_priority/mapping_contexts/actions/shield.tres b/guide_examples/action_priority/mapping_contexts/actions/shield.tres new file mode 100644 index 0000000..de94f8b --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/actions/shield.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://b5plj56pss47x"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_kmjgp"] + +[resource] +script = ExtResource("1_kmjgp") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/action_priority/mapping_contexts/actions/spell_toggle.tres b/guide_examples/action_priority/mapping_contexts/actions/spell_toggle.tres new file mode 100644 index 0000000..863790a --- /dev/null +++ b/guide_examples/action_priority/mapping_contexts/actions/spell_toggle.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://c5eq1avod0lu8"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_m4tof"] + +[resource] +script = ExtResource("1_m4tof") +name = &"" +action_value_type = 0 +block_lower_priority_actions = false +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/action_priority/spell_indicator/spell_indicator.gd b/guide_examples/action_priority/spell_indicator/spell_indicator.gd new file mode 100644 index 0000000..875748a --- /dev/null +++ b/guide_examples/action_priority/spell_indicator/spell_indicator.gd @@ -0,0 +1,11 @@ +extends Node2D + +@export var action:GUIDEAction +@export var texture:Texture2D + +@onready var _animation_player:AnimationPlayer = %AnimationPlayer +@onready var _sprite_2d:Sprite2D = %Sprite2D + +func _ready(): + _sprite_2d.texture = texture + action.triggered.connect(_animation_player.play.bind("run")) diff --git a/guide_examples/action_priority/spell_indicator/spell_indicator.gd.uid b/guide_examples/action_priority/spell_indicator/spell_indicator.gd.uid new file mode 100644 index 0000000..a06abbc --- /dev/null +++ b/guide_examples/action_priority/spell_indicator/spell_indicator.gd.uid @@ -0,0 +1 @@ +uid://b3h0rac24v3l0 diff --git a/guide_examples/action_priority/spell_indicator/spell_indicator.tscn b/guide_examples/action_priority/spell_indicator/spell_indicator.tscn new file mode 100644 index 0000000..26ea533 --- /dev/null +++ b/guide_examples/action_priority/spell_indicator/spell_indicator.tscn @@ -0,0 +1,79 @@ +[gd_scene load_steps=6 format=3 uid="uid://cx8f0hljh5dhs"] + +[ext_resource type="Texture2D" uid="uid://dbwgq8udtj2hp" path="res://guide_examples/action_priority/icons/enchant-acid-3.png" id="1_7l2hh"] +[ext_resource type="Script" path="res://guide_examples/action_priority/spell_indicator/spell_indicator.gd" id="1_hpegm"] + +[sub_resource type="Animation" id="Animation_j3vtt"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Sprite2D:modulate") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 0)] +} + +[sub_resource type="Animation" id="Animation_4iqo1"] +resource_name = "run" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0, 0), Vector2(0, -346)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Sprite2D:modulate") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 0.176777), +"update": 0, +"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_h1go0"] +_data = { +"RESET": SubResource("Animation_j3vtt"), +"run": SubResource("Animation_4iqo1") +} + +[node name="SpellIndicator" type="Node2D"] +script = ExtResource("1_hpegm") + +[node name="Sprite2D" type="Sprite2D" parent="."] +unique_name_in_owner = true +modulate = Color(1, 1, 1, 0) +scale = Vector2(0.5, 0.5) +texture = ExtResource("1_7l2hh") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +unique_name_in_owner = true +libraries = { +"": SubResource("AnimationLibrary_h1go0") +} diff --git a/guide_examples/combos/combos.gd b/guide_examples/combos/combos.gd new file mode 100644 index 0000000..22d974a --- /dev/null +++ b/guide_examples/combos/combos.gd @@ -0,0 +1,7 @@ +extends Node2D + +@export var mapping_context:GUIDEMappingContext + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) + diff --git a/guide_examples/combos/combos.gd.uid b/guide_examples/combos/combos.gd.uid new file mode 100644 index 0000000..3c330ff --- /dev/null +++ b/guide_examples/combos/combos.gd.uid @@ -0,0 +1 @@ +uid://dk0t3b28kxhf8 diff --git a/guide_examples/combos/combos.tscn b/guide_examples/combos/combos.tscn new file mode 100644 index 0000000..e13af57 --- /dev/null +++ b/guide_examples/combos/combos.tscn @@ -0,0 +1,87 @@ +[gd_scene load_steps=18 format=3 uid="uid://b12bmbtmbuame"] + +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="1_eyn1y"] +[ext_resource type="Script" path="res://guide_examples/combos/combos.gd" id="1_kdeb4"] +[ext_resource type="Resource" uid="uid://c7uloa16ajj5p" path="res://guide_examples/combos/mapping_contexts/combos.tres" id="2_ahmv3"] +[ext_resource type="Script" path="res://guide_examples/combos/player.gd" id="3_kulxp"] +[ext_resource type="Resource" uid="uid://b2wemrcnxfbmo" path="res://guide_examples/combos/mapping_contexts/basic_actions/move_horizontal.tres" id="4_7328w"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="4_uej32"] +[ext_resource type="Resource" uid="uid://b0761600n8fnb" path="res://guide_examples/combos/mapping_contexts/combo_actions/fireball_left.tres" id="4_uvwd5"] +[ext_resource type="Resource" uid="uid://dj83uxjdx6r2c" path="res://guide_examples/combos/mapping_contexts/combo_actions/dash_left.tres" id="5_s5wpr"] +[ext_resource type="Resource" uid="uid://5ve3hevhhgnw" path="res://guide_examples/combos/mapping_contexts/combo_actions/dash_right.tres" id="6_vd0bg"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="11_i5q2v"] +[ext_resource type="Resource" uid="uid://wdh7cg7kjul0" path="res://guide_examples/combos/mapping_contexts/combo_actions/fireball_right.tres" id="11_n707x"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="11_obfhv"] +[ext_resource type="Resource" uid="uid://bqiryilvj5mqv" path="res://guide_examples/combos/mapping_contexts/basic_actions/move_left.tres" id="12_0mhlm"] +[ext_resource type="PackedScene" uid="uid://c36cnvgv2ur60" path="res://guide_examples/shared/fireball/fireball.tscn" id="12_fl88r"] +[ext_resource type="Resource" uid="uid://bk54ofxos3xxg" path="res://guide_examples/combos/mapping_contexts/basic_actions/move_right.tres" id="13_xn6qb"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_8kkfa"] +size = Vector2(137, 138) + +[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_0s5wn"] + +[node name="Combos" type="Node2D"] +script = ExtResource("1_kdeb4") +mapping_context = ExtResource("2_ahmv3") + +[node name="Player" type="CharacterBody2D" parent="."] +position = Vector2(902, 841) +script = ExtResource("3_kulxp") +dash_speed_bonus = 400.0 +horizontal_movement = ExtResource("4_7328w") +dash_left = ExtResource("5_s5wpr") +dash_right = ExtResource("6_vd0bg") +fireball_left = ExtResource("4_uvwd5") +fireball_right = ExtResource("11_n707x") +fireball_scene = ExtResource("12_fl88r") + +[node name="Sprite" type="Sprite2D" parent="Player"] +texture = ExtResource("4_uej32") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] +position = Vector2(1.5, 1) +shape = SubResource("RectangleShape2D_8kkfa") + +[node name="Ground" type="StaticBody2D" parent="."] +position = Vector2(-44, 954) + +[node name="ColorRect" type="ColorRect" parent="Ground"] +offset_left = -427.0 +offset_right = 2555.0 +offset_bottom = 150.0 +color = Color(0.285871, 0.0915713, 0.0208481, 1) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Ground"] +position = Vector2(869, 1) +shape = SubResource("WorldBoundaryShape2D_0s5wn") + +[node name="UILayer" type="CanvasLayer" parent="."] + +[node name="InstructionsLabel" type="RichTextLabel" parent="UILayer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -482.0 +offset_top = 21.0 +offset_bottom = 205.0 +grow_horizontal = 0 +theme = ExtResource("11_i5q2v") +bbcode_enabled = true +text = "Lore, ipsum dolor sit amet." +fit_content = true +scroll_active = false +script = ExtResource("11_obfhv") +instructions_text = "Press %s to move left. +Press %s to move right. +Press %s to dash left. +Press %s to dash right. +Press %s shoot a fireball to the left. +Press %s to shoot a fireball to the right." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("12_0mhlm"), ExtResource("13_xn6qb"), ExtResource("5_s5wpr"), ExtResource("6_vd0bg"), ExtResource("4_uvwd5"), ExtResource("11_n707x")]) + +[node name="DebuggerLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="DebuggerLayer" instance=ExtResource("1_eyn1y")] +theme = ExtResource("11_i5q2v") +metadata/_edit_lock_ = true diff --git a/guide_examples/combos/mapping_contexts/basic_actions/fire.tres b/guide_examples/combos/mapping_contexts/basic_actions/fire.tres new file mode 100644 index 0000000..c2ba86c --- /dev/null +++ b/guide_examples/combos/mapping_contexts/basic_actions/fire.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cgr4iegvrkebx"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_pxjqb"] + +[resource] +script = ExtResource("1_pxjqb") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "Player Controls" diff --git a/guide_examples/combos/mapping_contexts/basic_actions/move_horizontal.tres b/guide_examples/combos/mapping_contexts/basic_actions/move_horizontal.tres new file mode 100644 index 0000000..f8f3013 --- /dev/null +++ b/guide_examples/combos/mapping_contexts/basic_actions/move_horizontal.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://b2wemrcnxfbmo"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_bg42k"] + +[resource] +script = ExtResource("1_bg42k") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/combos/mapping_contexts/basic_actions/move_left.tres b/guide_examples/combos/mapping_contexts/basic_actions/move_left.tres new file mode 100644 index 0000000..795c18f --- /dev/null +++ b/guide_examples/combos/mapping_contexts/basic_actions/move_left.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bqiryilvj5mqv"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_pxjqb"] + +[resource] +script = ExtResource("1_pxjqb") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/combos/mapping_contexts/basic_actions/move_right.tres b/guide_examples/combos/mapping_contexts/basic_actions/move_right.tres new file mode 100644 index 0000000..5c2d0d6 --- /dev/null +++ b/guide_examples/combos/mapping_contexts/basic_actions/move_right.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bk54ofxos3xxg"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_ppgom"] + +[resource] +script = ExtResource("1_ppgom") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/combos/mapping_contexts/combo_actions/dash_left.tres b/guide_examples/combos/mapping_contexts/combo_actions/dash_left.tres new file mode 100644 index 0000000..13b6b54 --- /dev/null +++ b/guide_examples/combos/mapping_contexts/combo_actions/dash_left.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://dj83uxjdx6r2c"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_hxh8l"] + +[resource] +script = ExtResource("1_hxh8l") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/combos/mapping_contexts/combo_actions/dash_right.tres b/guide_examples/combos/mapping_contexts/combo_actions/dash_right.tres new file mode 100644 index 0000000..d18a91b --- /dev/null +++ b/guide_examples/combos/mapping_contexts/combo_actions/dash_right.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://5ve3hevhhgnw"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_cbjx7"] + +[resource] +script = ExtResource("1_cbjx7") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/combos/mapping_contexts/combo_actions/fireball_left.tres b/guide_examples/combos/mapping_contexts/combo_actions/fireball_left.tres new file mode 100644 index 0000000..60e1d6e --- /dev/null +++ b/guide_examples/combos/mapping_contexts/combo_actions/fireball_left.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://b0761600n8fnb"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_exrdu"] + +[resource] +script = ExtResource("1_exrdu") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/combos/mapping_contexts/combo_actions/fireball_right.tres b/guide_examples/combos/mapping_contexts/combo_actions/fireball_right.tres new file mode 100644 index 0000000..beb8e47 --- /dev/null +++ b/guide_examples/combos/mapping_contexts/combo_actions/fireball_right.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://wdh7cg7kjul0"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_clys2"] + +[resource] +script = ExtResource("1_clys2") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/combos/mapping_contexts/combos.tres b/guide_examples/combos/mapping_contexts/combos.tres new file mode 100644 index 0000000..173fae3 --- /dev/null +++ b/guide_examples/combos/mapping_contexts/combos.tres @@ -0,0 +1,299 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=57 format=3 uid="uid://c7uloa16ajj5p"] + +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_bycs2"] +[ext_resource type="Resource" uid="uid://bqiryilvj5mqv" path="res://guide_examples/combos/mapping_contexts/basic_actions/move_left.tres" id="1_pb347"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="2_o8ffe"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_wsx31"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_dnh2v"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="3_ji605"] +[ext_resource type="Resource" uid="uid://bk54ofxos3xxg" path="res://guide_examples/combos/mapping_contexts/basic_actions/move_right.tres" id="5_jksbs"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_action.gd" id="8_04uuh"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_combo_cancel_action.gd" id="8_ewrgg"] +[ext_resource type="Resource" uid="uid://5ve3hevhhgnw" path="res://guide_examples/combos/mapping_contexts/combo_actions/dash_right.tres" id="9_ciqk8"] +[ext_resource type="Resource" uid="uid://b0761600n8fnb" path="res://guide_examples/combos/mapping_contexts/combo_actions/fireball_left.tres" id="9_lvx6c"] +[ext_resource type="Resource" uid="uid://wdh7cg7kjul0" path="res://guide_examples/combos/mapping_contexts/combo_actions/fireball_right.tres" id="12_icm8e"] +[ext_resource type="Resource" uid="uid://b2wemrcnxfbmo" path="res://guide_examples/combos/mapping_contexts/basic_actions/move_horizontal.tres" id="13_u4d84"] +[ext_resource type="Resource" uid="uid://cgr4iegvrkebx" path="res://guide_examples/combos/mapping_contexts/basic_actions/fire.tres" id="17_yw71c"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_combo.gd" id="19_kw0e0"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_combo_step.gd" id="20_226av"] +[ext_resource type="Resource" uid="uid://dj83uxjdx6r2c" path="res://guide_examples/combos/mapping_contexts/combo_actions/dash_left.tres" id="21_wfbjl"] + +[sub_resource type="Resource" id="Resource_le3gd"] +script = ExtResource("2_wsx31") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_jphf8"] +script = ExtResource("3_dnh2v") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_le3gd") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) +metadata/_guide_modifiers_collapsed = true + +[sub_resource type="Resource" id="Resource_ohm7l"] +script = ExtResource("2_o8ffe") +action = ExtResource("1_pb347") +input_mappings = Array[ExtResource("3_dnh2v")]([SubResource("Resource_jphf8")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_bf80h"] +script = ExtResource("2_wsx31") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_o2rir"] +script = ExtResource("3_dnh2v") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_bf80h") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_3ojw4"] +script = ExtResource("2_o8ffe") +action = ExtResource("5_jksbs") +input_mappings = Array[ExtResource("3_dnh2v")]([SubResource("Resource_o2rir")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_xe8bg"] +script = ExtResource("8_04uuh") +action = ExtResource("1_pb347") + +[sub_resource type="Resource" id="Resource_tisnm"] +script = ExtResource("3_ji605") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_6q14n"] +script = ExtResource("3_dnh2v") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_xe8bg") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_tisnm")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_p31qj"] +script = ExtResource("8_04uuh") +action = ExtResource("5_jksbs") + +[sub_resource type="Resource" id="Resource_m3jub"] +script = ExtResource("3_dnh2v") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_p31qj") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_nypfm"] +script = ExtResource("2_o8ffe") +action = ExtResource("13_u4d84") +input_mappings = Array[ExtResource("3_dnh2v")]([SubResource("Resource_6q14n"), SubResource("Resource_m3jub")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_rgf84"] +script = ExtResource("2_wsx31") +key = 32 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_wf4jl"] +script = ExtResource("3_dnh2v") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_rgf84") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_qxroc"] +script = ExtResource("2_o8ffe") +action = ExtResource("17_yw71c") +input_mappings = Array[ExtResource("3_dnh2v")]([SubResource("Resource_wf4jl")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_ai4v6"] +script = ExtResource("8_ewrgg") +action = ExtResource("5_jksbs") +completion_events = 1 + +[sub_resource type="Resource" id="Resource_22wmg"] +script = ExtResource("20_226av") +action = ExtResource("1_pb347") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_m5xce"] +script = ExtResource("20_226av") +action = ExtResource("1_pb347") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_bc2sa"] +script = ExtResource("19_kw0e0") +enable_debug_print = false +steps = Array[ExtResource("20_226av")]([SubResource("Resource_22wmg"), SubResource("Resource_m5xce")]) +cancellation_actions = Array[ExtResource("8_ewrgg")]([SubResource("Resource_ai4v6")]) +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_00r0g"] +script = ExtResource("3_dnh2v") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_bc2sa")]) + +[sub_resource type="Resource" id="Resource_abarl"] +script = ExtResource("2_o8ffe") +action = ExtResource("21_wfbjl") +input_mappings = Array[ExtResource("3_dnh2v")]([SubResource("Resource_00r0g")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_w3it8"] +script = ExtResource("8_ewrgg") +action = ExtResource("1_pb347") +completion_events = 1 + +[sub_resource type="Resource" id="Resource_o1r17"] +script = ExtResource("20_226av") +action = ExtResource("5_jksbs") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_y7323"] +script = ExtResource("20_226av") +action = ExtResource("5_jksbs") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_0x6c4"] +script = ExtResource("19_kw0e0") +enable_debug_print = false +steps = Array[ExtResource("20_226av")]([SubResource("Resource_o1r17"), SubResource("Resource_y7323")]) +cancellation_actions = Array[ExtResource("8_ewrgg")]([SubResource("Resource_w3it8")]) +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_wnc21"] +script = ExtResource("3_dnh2v") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_0x6c4")]) + +[sub_resource type="Resource" id="Resource_1vsh7"] +script = ExtResource("2_o8ffe") +action = ExtResource("9_ciqk8") +input_mappings = Array[ExtResource("3_dnh2v")]([SubResource("Resource_wnc21")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_cbc1w"] +script = ExtResource("20_226av") +action = ExtResource("5_jksbs") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_k4x1t"] +script = ExtResource("20_226av") +action = ExtResource("1_pb347") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_ryygs"] +script = ExtResource("20_226av") +action = ExtResource("17_yw71c") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_wocqt"] +script = ExtResource("19_kw0e0") +enable_debug_print = false +steps = Array[ExtResource("20_226av")]([SubResource("Resource_cbc1w"), SubResource("Resource_k4x1t"), SubResource("Resource_ryygs")]) +cancellation_actions = Array[ExtResource("8_ewrgg")]([]) +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_v7om3"] +script = ExtResource("3_dnh2v") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_wocqt")]) + +[sub_resource type="Resource" id="Resource_40qct"] +script = ExtResource("2_o8ffe") +action = ExtResource("9_lvx6c") +input_mappings = Array[ExtResource("3_dnh2v")]([SubResource("Resource_v7om3")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_2ivmb"] +script = ExtResource("20_226av") +action = ExtResource("1_pb347") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_o88yx"] +script = ExtResource("20_226av") +action = ExtResource("5_jksbs") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_j6a01"] +script = ExtResource("20_226av") +action = ExtResource("17_yw71c") +completion_events = 16 +time_to_actuate = 0.5 + +[sub_resource type="Resource" id="Resource_lonke"] +script = ExtResource("19_kw0e0") +enable_debug_print = false +steps = Array[ExtResource("20_226av")]([SubResource("Resource_2ivmb"), SubResource("Resource_o88yx"), SubResource("Resource_j6a01")]) +cancellation_actions = Array[ExtResource("8_ewrgg")]([]) +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_do51u"] +script = ExtResource("3_dnh2v") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_lonke")]) + +[sub_resource type="Resource" id="Resource_pn365"] +script = ExtResource("2_o8ffe") +action = ExtResource("12_icm8e") +input_mappings = Array[ExtResource("3_dnh2v")]([SubResource("Resource_do51u")]) +metadata/_guide_input_mappings_collapsed = false + +[resource] +script = ExtResource("1_bycs2") +display_name = "" +mappings = Array[ExtResource("2_o8ffe")]([SubResource("Resource_ohm7l"), SubResource("Resource_3ojw4"), SubResource("Resource_nypfm"), SubResource("Resource_qxroc"), SubResource("Resource_abarl"), SubResource("Resource_1vsh7"), SubResource("Resource_40qct"), SubResource("Resource_pn365")]) +metadata/_guide_action_mappings_collapsed = false diff --git a/guide_examples/combos/player.gd b/guide_examples/combos/player.gd new file mode 100644 index 0000000..6153761 --- /dev/null +++ b/guide_examples/combos/player.gd @@ -0,0 +1,50 @@ +## This is a somewhat more complex player example. Note how all the combos +## are completely handled by GUIDE, the player doesn't need to know which +## inputs trigger them. +extends CharacterBody2D + +@export var speed:float = 150 +@export var dash_speed_bonus:float = 250 + +@export var horizontal_movement:GUIDEAction +@export var dash_left:GUIDEAction +@export var dash_right:GUIDEAction +@export var fireball_left:GUIDEAction +@export var fireball_right:GUIDEAction + +@export var fireball_scene:PackedScene + +var _dash_bonus:float + +func _ready(): + # We can use the event system to get notified whenever + # the combo actions trigger. This way we don't need to check them + # in _physics_process every frame. + dash_left.triggered.connect(func(): _dash_bonus = -1) + dash_right.triggered.connect(func(): _dash_bonus = 1) + fireball_left.triggered.connect(_spawn_fireball.bind(Vector2.LEFT)) + fireball_right.triggered.connect(_spawn_fireball.bind(Vector2.RIGHT)) + + +func _physics_process(delta): + # Get current left-right input + var movement:float = horizontal_movement.value_axis_1d + + # Move any dash bonus towards zero + _dash_bonus = move_toward(_dash_bonus, 0, delta) + + # Calculate new velocity + velocity.x = movement * speed + _dash_bonus * dash_speed_bonus + velocity.y = 980 + move_and_slide() + + +func _spawn_fireball(direction:Vector2) -> void: + # spawn a new fireball + var fireball:Node2D = fireball_scene.instantiate() + # add it to the tree + get_parent().add_child(fireball) + # start at our position/orientation + fireball.global_transform = global_transform + # fly into the given direction + fireball.direction = direction diff --git a/guide_examples/combos/player.gd.uid b/guide_examples/combos/player.gd.uid new file mode 100644 index 0000000..1bf5ea7 --- /dev/null +++ b/guide_examples/combos/player.gd.uid @@ -0,0 +1 @@ +uid://bd1xrcr5qu5yd diff --git a/guide_examples/input_contexts/boat.gd b/guide_examples/input_contexts/boat.gd new file mode 100644 index 0000000..428af07 --- /dev/null +++ b/guide_examples/input_contexts/boat.gd @@ -0,0 +1,58 @@ +extends CharacterBody2D + +signal exited() +@export var speed:float = 300 +@export var turn_speed_degrees:float = 180 + +@export var context:GUIDEMappingContext +@export var accelerate:GUIDEAction +@export var turn:GUIDEAction +@export var leave:GUIDEAction + + +@onready var _player_spot:Node2D = %PlayerSpot +@onready var _exit_spot:Node2D = %ExitSpot + +var _player:Node2D + +func _ready(): + leave.triggered.connect(_on_leave) + + +func _physics_process(delta): + # rotate by our turn axis + rotate(turn.value_axis_1d * deg_to_rad(turn_speed_degrees) * delta) + # accelerate by our acceleration axis + velocity = transform.x * accelerate.value_axis_1d * speed + move_and_slide() + + +func enter(player:Node2D): + # Move the player to the player spot + _player = player + player.reparent(_player_spot, false) + _player.position = Vector2.ZERO + + # And enable the boat controls + GUIDE.enable_mapping_context(context) + + +func _on_leave(): + # Disable boat controls + GUIDE.disable_mapping_context(context) + + # put player back in the world + _player.reparent(get_parent(), false) + _player.global_position = _exit_spot.global_position + + # this is to prevent the physics engine from going crazy when moving + # the player's body + await get_tree().physics_frame + + # notify any interested parties that the player has exited + exited.emit() + + + + + diff --git a/guide_examples/input_contexts/boat.gd.uid b/guide_examples/input_contexts/boat.gd.uid new file mode 100644 index 0000000..fe289b9 --- /dev/null +++ b/guide_examples/input_contexts/boat.gd.uid @@ -0,0 +1 @@ +uid://bkggahcvec2hd diff --git a/guide_examples/input_contexts/boat.svg b/guide_examples/input_contexts/boat.svg new file mode 100644 index 0000000..e3c2d18 --- /dev/null +++ b/guide_examples/input_contexts/boat.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/guide_examples/input_contexts/boat.svg.import b/guide_examples/input_contexts/boat.svg.import new file mode 100644 index 0000000..d4bcdff --- /dev/null +++ b/guide_examples/input_contexts/boat.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cyqlk5nkvswx7" +path="res://.godot/imported/boat.svg-547042152e7d4e4afdfc306682d6e571.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/input_contexts/boat.svg" +dest_files=["res://.godot/imported/boat.svg-547042152e7d4e4afdfc306682d6e571.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/guide_examples/input_contexts/input_contexts.gd b/guide_examples/input_contexts/input_contexts.gd new file mode 100644 index 0000000..bcd9c3d --- /dev/null +++ b/guide_examples/input_contexts/input_contexts.gd @@ -0,0 +1,6 @@ +extends Node2D + +@export var starting_context:GUIDEMappingContext + +func _ready(): + GUIDE.enable_mapping_context(starting_context) diff --git a/guide_examples/input_contexts/input_contexts.gd.uid b/guide_examples/input_contexts/input_contexts.gd.uid new file mode 100644 index 0000000..bf71e30 --- /dev/null +++ b/guide_examples/input_contexts/input_contexts.gd.uid @@ -0,0 +1 @@ +uid://cnf3xx5jxiu8q diff --git a/guide_examples/input_contexts/input_contexts.tscn b/guide_examples/input_contexts/input_contexts.tscn new file mode 100644 index 0000000..217aa8d --- /dev/null +++ b/guide_examples/input_contexts/input_contexts.tscn @@ -0,0 +1,194 @@ +[gd_scene load_steps=25 format=3 uid="uid://b6h4wnjfjs70m"] + +[ext_resource type="Script" path="res://guide_examples/input_contexts/boat.gd" id="1_61cdj"] +[ext_resource type="Script" path="res://guide_examples/input_contexts/input_contexts.gd" id="1_386pq"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="1_x61i0"] +[ext_resource type="Texture2D" uid="uid://cyqlk5nkvswx7" path="res://guide_examples/input_contexts/boat.svg" id="1_yfaid"] +[ext_resource type="Resource" uid="uid://bv3t73wg3atf7" path="res://guide_examples/input_contexts/mapping_contexts/boat_context.tres" id="2_ha2ml"] +[ext_resource type="Resource" uid="uid://5jercxe6t3go" path="res://guide_examples/input_contexts/mapping_contexts/boat_actions/accelerate.tres" id="3_8s4br"] +[ext_resource type="Script" path="res://guide_examples/input_contexts/player.gd" id="3_kn2qk"] +[ext_resource type="Resource" uid="uid://cplpvxhus6bwb" path="res://guide_examples/input_contexts/mapping_contexts/player_context.tres" id="4_3xwjv"] +[ext_resource type="Resource" uid="uid://qsysw0ljlj0l" path="res://guide_examples/input_contexts/mapping_contexts/boat_actions/turn.tres" id="4_w1gps"] +[ext_resource type="Resource" uid="uid://cnaj42xnfcibo" path="res://guide_examples/input_contexts/mapping_contexts/player_actions/move.tres" id="5_70jqj"] +[ext_resource type="Resource" uid="uid://bk2j1ww7iwqd0" path="res://guide_examples/input_contexts/mapping_contexts/boat_actions/leave.tres" id="5_typxl"] +[ext_resource type="Resource" uid="uid://crjkk2edn8g8k" path="res://guide_examples/input_contexts/mapping_contexts/player_actions/use.tres" id="6_aiqns"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="12_jcoq7"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="12_u0g3a"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="14_ui0u7"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_w57h4"] +size = Vector2(1972, 59) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_r5hqg"] +size = Vector2(59, 1161) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_ifvju"] +size = Vector2(2030.5, 60.5) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_qarqo"] +size = Vector2(102, 1160.5) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_la1oy"] +size = Vector2(446.5, 1141) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_3q8sb"] +size = Vector2(368, 148) + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_54ta5"] +radius = 75.0 +height = 252.0 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_3lf7l"] +size = Vector2(126, 130) + +[sub_resource type="CircleShape2D" id="CircleShape2D_dt2nf"] +radius = 141.891 + +[node name="InputContexts" type="Node2D"] +script = ExtResource("1_386pq") +starting_context = ExtResource("4_3xwjv") + +[node name="World" type="Node2D" parent="."] + +[node name="Sea" type="ColorRect" parent="World"] +offset_right = 2009.0 +offset_bottom = 1129.0 +color = Color(0.0440738, 0.000205037, 0.549847, 1) +metadata/_edit_lock_ = true + +[node name="Land" type="Polygon2D" parent="World"] +color = Color(0.336331, 0.394587, 0.063959, 1) +polygon = PackedVector2Array(55, -51, 259, -24, 398, 124, 356, 225, 279, 461, 394, 656, 412, 865, 342, 1085, -15, 1119, -22, -67) +metadata/_edit_lock_ = true + +[node name="Jetty" type="ColorRect" parent="World/Land"] +offset_left = 283.0 +offset_top = 144.0 +offset_right = 641.0 +offset_bottom = 280.0 +color = Color(0.243329, 0.15798, 7.21961e-08, 1) + +[node name="World Boundaries" type="StaticBody2D" parent="World"] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="World/World Boundaries"] +position = Vector2(976, -19.5) +shape = SubResource("RectangleShape2D_w57h4") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="World/World Boundaries"] +position = Vector2(-10, 532) +shape = SubResource("RectangleShape2D_r5hqg") + +[node name="CollisionShape2D3" type="CollisionShape2D" parent="World/World Boundaries"] +position = Vector2(975.75, 1082.25) +shape = SubResource("RectangleShape2D_ifvju") + +[node name="CollisionShape2D4" type="CollisionShape2D" parent="World/World Boundaries"] +position = Vector2(1940, 532.25) +shape = SubResource("RectangleShape2D_qarqo") + +[node name="NoBoatZone" type="StaticBody2D" parent="World"] +collision_layer = 2 +collision_mask = 0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="World/NoBoatZone"] +position = Vector2(210.75, 556.5) +shape = SubResource("RectangleShape2D_la1oy") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="World/NoBoatZone"] +position = Vector2(454, 211) +shape = SubResource("RectangleShape2D_3q8sb") + +[node name="Boat" type="CharacterBody2D" parent="."] +position = Vector2(744, 269) +rotation = -1.44336 +collision_layer = 5 +collision_mask = 3 +script = ExtResource("1_61cdj") +speed = 500.0 +context = ExtResource("2_ha2ml") +accelerate = ExtResource("3_8s4br") +turn = ExtResource("4_w1gps") +leave = ExtResource("5_typxl") + +[node name="Boat" type="Sprite2D" parent="Boat"] +texture = ExtResource("1_yfaid") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Boat"] +position = Vector2(-13, 0) +rotation = -1.57573 +shape = SubResource("CapsuleShape2D_54ta5") + +[node name="PlayerSpot" type="Node2D" parent="Boat"] +unique_name_in_owner = true +rotation = 1.5708 +scale = Vector2(0.8, 0.8) + +[node name="ExitSpot" type="Marker2D" parent="Boat"] +unique_name_in_owner = true +position = Vector2(-11.0732, -212.314) + +[node name="Player" type="CharacterBody2D" parent="."] +position = Vector2(205, 212) +script = ExtResource("3_kn2qk") +context = ExtResource("4_3xwjv") +move = ExtResource("5_70jqj") +use = ExtResource("6_aiqns") + +[node name="Icon" type="Sprite2D" parent="Player"] +texture = ExtResource("1_x61i0") + +[node name="CollisionShape" type="CollisionShape2D" parent="Player"] +unique_name_in_owner = true +position = Vector2(-1, 1) +shape = SubResource("RectangleShape2D_3lf7l") + +[node name="DetectionArea" type="Area2D" parent="Player"] +unique_name_in_owner = true +collision_layer = 0 +collision_mask = 4 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Player/DetectionArea"] +shape = SubResource("CircleShape2D_dt2nf") + +[node name="UILayer" type="CanvasLayer" parent="."] + +[node name="Label" type="Label" parent="UILayer"] +offset_left = 894.0 +offset_top = 24.0 +offset_right = 1872.0 +offset_bottom = 132.0 +theme = ExtResource("12_u0g3a") +text = "This demonstrates the use of multiple mapping contexts. We have one for the player +and one for the boat. When the player enters the boat, the boat mappings will +become active and will become inactive once the player leaves. " + +[node name="BoatInstructions" type="RichTextLabel" parent="UILayer"] +offset_left = 1316.0 +offset_top = 772.0 +offset_right = 1356.0 +offset_bottom = 812.0 +theme = ExtResource("12_u0g3a") +script = ExtResource("14_ui0u7") +instructions_text = "%s to accelerate/break. +%s to turn the boat. +%s to leave the boat." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("3_8s4br"), ExtResource("4_w1gps"), ExtResource("5_typxl")]) +limit_to_context = ExtResource("2_ha2ml") + +[node name="PlayerInstructions" type="RichTextLabel" parent="UILayer"] +offset_left = 1316.0 +offset_top = 772.0 +offset_right = 1356.0 +offset_bottom = 812.0 +theme = ExtResource("12_u0g3a") +script = ExtResource("14_ui0u7") +instructions_text = "%s to move. +%s to enter the boat. +" +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("5_70jqj"), ExtResource("6_aiqns")]) +limit_to_context = ExtResource("4_3xwjv") + +[node name="DebugLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="DebugLayer" instance=ExtResource("12_jcoq7")] +theme = ExtResource("12_u0g3a") diff --git a/guide_examples/input_contexts/mapping_contexts/boat_actions/accelerate.tres b/guide_examples/input_contexts/mapping_contexts/boat_actions/accelerate.tres new file mode 100644 index 0000000..42879f6 --- /dev/null +++ b/guide_examples/input_contexts/mapping_contexts/boat_actions/accelerate.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://5jercxe6t3go"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_tkn2p"] + +[resource] +script = ExtResource("1_tkn2p") +name = &"" +action_value_type = 1 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/input_contexts/mapping_contexts/boat_actions/leave.tres b/guide_examples/input_contexts/mapping_contexts/boat_actions/leave.tres new file mode 100644 index 0000000..39c22eb --- /dev/null +++ b/guide_examples/input_contexts/mapping_contexts/boat_actions/leave.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bk2j1ww7iwqd0"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_3d3m7"] + +[resource] +script = ExtResource("1_3d3m7") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/input_contexts/mapping_contexts/boat_actions/turn.tres b/guide_examples/input_contexts/mapping_contexts/boat_actions/turn.tres new file mode 100644 index 0000000..d33c369 --- /dev/null +++ b/guide_examples/input_contexts/mapping_contexts/boat_actions/turn.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://qsysw0ljlj0l"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_4gxp2"] + +[resource] +script = ExtResource("1_4gxp2") +name = &"" +action_value_type = 1 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/input_contexts/mapping_contexts/boat_context.tres b/guide_examples/input_contexts/mapping_contexts/boat_context.tres new file mode 100644 index 0000000..1133364 --- /dev/null +++ b/guide_examples/input_contexts/mapping_contexts/boat_context.tres @@ -0,0 +1,142 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=26 format=3 uid="uid://bv3t73wg3atf7"] + +[ext_resource type="Resource" uid="uid://qsysw0ljlj0l" path="res://guide_examples/input_contexts/mapping_contexts/boat_actions/turn.tres" id="1_ovglr"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_0hduu"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="3_jicb2"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="4_ymfat"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="5_3quxn"] +[ext_resource type="Resource" uid="uid://5jercxe6t3go" path="res://guide_examples/input_contexts/mapping_contexts/boat_actions/accelerate.tres" id="6_pocgd"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="7_1yt57"] +[ext_resource type="Resource" uid="uid://bk2j1ww7iwqd0" path="res://guide_examples/input_contexts/mapping_contexts/boat_actions/leave.tres" id="7_t38lc"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_released.gd" id="8_f0mvl"] + +[sub_resource type="Resource" id="Resource_2l73a"] +script = ExtResource("2_0hduu") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_p26ag"] +script = ExtResource("4_ymfat") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_2l73a") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_fndx2"] +script = ExtResource("2_0hduu") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_8c6p8"] +script = ExtResource("3_jicb2") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_7ubh7"] +script = ExtResource("4_ymfat") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_fndx2") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_8c6p8")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_yd1l1"] +script = ExtResource("5_3quxn") +action = ExtResource("6_pocgd") +input_mappings = Array[ExtResource("4_ymfat")]([SubResource("Resource_p26ag"), SubResource("Resource_7ubh7")]) + +[sub_resource type="Resource" id="Resource_bw7vh"] +script = ExtResource("2_0hduu") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_55txo"] +script = ExtResource("3_jicb2") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_4pm2b"] +script = ExtResource("4_ymfat") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_bw7vh") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_55txo")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_mathf"] +script = ExtResource("2_0hduu") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_j5i1b"] +script = ExtResource("4_ymfat") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_mathf") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_siw8f"] +script = ExtResource("5_3quxn") +action = ExtResource("1_ovglr") +input_mappings = Array[ExtResource("4_ymfat")]([SubResource("Resource_4pm2b"), SubResource("Resource_j5i1b")]) + +[sub_resource type="Resource" id="Resource_xiqqo"] +script = ExtResource("2_0hduu") +key = 69 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_ooy6b"] +script = ExtResource("8_f0mvl") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_8047g"] +script = ExtResource("4_ymfat") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_xiqqo") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_ooy6b")]) + +[sub_resource type="Resource" id="Resource_npqbc"] +script = ExtResource("5_3quxn") +action = ExtResource("7_t38lc") +input_mappings = Array[ExtResource("4_ymfat")]([SubResource("Resource_8047g")]) + +[resource] +script = ExtResource("7_1yt57") +display_name = "" +mappings = Array[ExtResource("5_3quxn")]([SubResource("Resource_yd1l1"), SubResource("Resource_siw8f"), SubResource("Resource_npqbc")]) diff --git a/guide_examples/input_contexts/mapping_contexts/player_actions/move.tres b/guide_examples/input_contexts/mapping_contexts/player_actions/move.tres new file mode 100644 index 0000000..0728e9a --- /dev/null +++ b/guide_examples/input_contexts/mapping_contexts/player_actions/move.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cnaj42xnfcibo"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_amhrr"] + +[resource] +script = ExtResource("1_amhrr") +name = &"" +action_value_type = 2 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/input_contexts/mapping_contexts/player_actions/use.tres b/guide_examples/input_contexts/mapping_contexts/player_actions/use.tres new file mode 100644 index 0000000..0d12a51 --- /dev/null +++ b/guide_examples/input_contexts/mapping_contexts/player_actions/use.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://crjkk2edn8g8k"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_7lwep"] + +[resource] +script = ExtResource("1_7lwep") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/input_contexts/mapping_contexts/player_context.tres b/guide_examples/input_contexts/mapping_contexts/player_context.tres new file mode 100644 index 0000000..eba76aa --- /dev/null +++ b/guide_examples/input_contexts/mapping_contexts/player_context.tres @@ -0,0 +1,145 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=27 format=3 uid="uid://cplpvxhus6bwb"] + +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_126cd"] +[ext_resource type="Resource" uid="uid://cnaj42xnfcibo" path="res://guide_examples/input_contexts/mapping_contexts/player_actions/move.tres" id="1_hm3wk"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_xomf3"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_input_swizzle.gd" id="3_0ask7"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="4_07e03"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="5_1myws"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="6_h3mfx"] +[ext_resource type="Resource" uid="uid://crjkk2edn8g8k" path="res://guide_examples/input_contexts/mapping_contexts/player_actions/use.tres" id="7_dx1om"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_released.gd" id="8_hlvtj"] + +[sub_resource type="Resource" id="Resource_5yf1p"] +script = ExtResource("2_xomf3") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = false + +[sub_resource type="Resource" id="Resource_vo6fb"] +script = ExtResource("3_0ask7") +order = 0 + +[sub_resource type="Resource" id="Resource_ixhgx"] +script = ExtResource("4_07e03") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_pia7e"] +script = ExtResource("5_1myws") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_5yf1p") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_vo6fb"), SubResource("Resource_ixhgx")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_a11mt"] +script = ExtResource("2_xomf3") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = false + +[sub_resource type="Resource" id="Resource_6ecpg"] +script = ExtResource("3_0ask7") +order = 0 + +[sub_resource type="Resource" id="Resource_s1oiy"] +script = ExtResource("5_1myws") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_a11mt") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_6ecpg")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_m84eo"] +script = ExtResource("2_xomf3") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = false + +[sub_resource type="Resource" id="Resource_qn63o"] +script = ExtResource("4_07e03") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_4dh7v"] +script = ExtResource("5_1myws") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_m84eo") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_qn63o")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_njvt5"] +script = ExtResource("2_xomf3") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = false + +[sub_resource type="Resource" id="Resource_hvhr4"] +script = ExtResource("5_1myws") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_njvt5") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_o0rtq"] +script = ExtResource("6_h3mfx") +action = ExtResource("1_hm3wk") +input_mappings = Array[ExtResource("5_1myws")]([SubResource("Resource_pia7e"), SubResource("Resource_s1oiy"), SubResource("Resource_4dh7v"), SubResource("Resource_hvhr4")]) + +[sub_resource type="Resource" id="Resource_t3oa4"] +script = ExtResource("2_xomf3") +key = 69 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = false + +[sub_resource type="Resource" id="Resource_ocal3"] +script = ExtResource("8_hlvtj") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_o528y"] +script = ExtResource("5_1myws") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_t3oa4") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_ocal3")]) + +[sub_resource type="Resource" id="Resource_0a33p"] +script = ExtResource("6_h3mfx") +action = ExtResource("7_dx1om") +input_mappings = Array[ExtResource("5_1myws")]([SubResource("Resource_o528y")]) + +[resource] +script = ExtResource("1_126cd") +display_name = "" +mappings = Array[ExtResource("6_h3mfx")]([SubResource("Resource_o0rtq"), SubResource("Resource_0a33p")]) diff --git a/guide_examples/input_contexts/player.gd b/guide_examples/input_contexts/player.gd new file mode 100644 index 0000000..8c1aaaa --- /dev/null +++ b/guide_examples/input_contexts/player.gd @@ -0,0 +1,42 @@ +extends CharacterBody2D + +@export var context:GUIDEMappingContext +@export var move:GUIDEAction +@export var use:GUIDEAction + +@export var speed:float = 300 + +@onready var _detection_area:Area2D = %DetectionArea +@onready var _collision_shape:CollisionShape2D = %CollisionShape + +func _ready(): + use.triggered.connect(_enter_boat) + +func _physics_process(_delta): + velocity = move.value_axis_2d.normalized() * speed + move_and_slide() + + +func _enter_boat(): + var boats := _detection_area.get_overlapping_bodies() + if boats.is_empty(): + return + + # Disable player input while in the boat + GUIDE.disable_mapping_context(context) + + # disable our own collisions while in the boat + _collision_shape.set_deferred("disabled", true) + + # enter the boat + boats[0].enter(self) + boats[0].exited.connect(_boat_exited, CONNECT_ONE_SHOT) + + +func _boat_exited(): + # re-enable our own mapping context + GUIDE.enable_mapping_context(context) + + # and re-enable our collisions + _collision_shape.set_deferred("disabled", false) + diff --git a/guide_examples/input_contexts/player.gd.uid b/guide_examples/input_contexts/player.gd.uid new file mode 100644 index 0000000..e67bdcc --- /dev/null +++ b/guide_examples/input_contexts/player.gd.uid @@ -0,0 +1 @@ +uid://bc00xf6yb6mw0 diff --git a/guide_examples/input_scheme_switching/input_scheme_switching.gd b/guide_examples/input_scheme_switching/input_scheme_switching.gd new file mode 100644 index 0000000..0053d01 --- /dev/null +++ b/guide_examples/input_scheme_switching/input_scheme_switching.gd @@ -0,0 +1,21 @@ +## This example shows how to switch the input scheme on the fly. +extends Node + +@export var joystick_scheme:GUIDEMappingContext +@export var keyboard_scheme:GUIDEMappingContext +@export var switch_to_keyboard:GUIDEAction +@export var switch_to_joystick:GUIDEAction + +func _ready(): + # When we get a command to switch the input scheme, we + # switch. + switch_to_keyboard.triggered.connect(_switch_input_scheme.bind(keyboard_scheme)) + switch_to_joystick.triggered.connect(_switch_input_scheme.bind(joystick_scheme)) + + # And switch now to enable keyboard + _switch_input_scheme(keyboard_scheme) + + +func _switch_input_scheme(context:GUIDEMappingContext): + GUIDE.enable_mapping_context(context, true) + diff --git a/guide_examples/input_scheme_switching/input_scheme_switching.gd.uid b/guide_examples/input_scheme_switching/input_scheme_switching.gd.uid new file mode 100644 index 0000000..e326345 --- /dev/null +++ b/guide_examples/input_scheme_switching/input_scheme_switching.gd.uid @@ -0,0 +1 @@ +uid://fhw2j8umfqty diff --git a/guide_examples/input_scheme_switching/input_scheme_switching.tscn b/guide_examples/input_scheme_switching/input_scheme_switching.tscn new file mode 100644 index 0000000..764d4ee --- /dev/null +++ b/guide_examples/input_scheme_switching/input_scheme_switching.tscn @@ -0,0 +1,60 @@ +[gd_scene load_steps=14 format=3 uid="uid://dvbxt8jyo8okp"] + +[ext_resource type="Script" path="res://guide_examples/input_scheme_switching/input_scheme_switching.gd" id="1_7l2n1"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="1_t4jeg"] +[ext_resource type="Resource" uid="uid://x33fk5wo7l2r" path="res://guide_examples/input_scheme_switching/mapping_contexts/joystick_scheme.tres" id="2_fx1v6"] +[ext_resource type="Resource" uid="uid://2hl7iqpondhi" path="res://guide_examples/input_scheme_switching/mapping_contexts/keyboard_scheme.tres" id="3_pvyn2"] +[ext_resource type="Resource" uid="uid://cxn2ibe1mn3sb" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/move.tres" id="4_3bnea"] +[ext_resource type="Resource" uid="uid://b11rcmd3hse58" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_keyboard.tres" id="4_tts5j"] +[ext_resource type="Resource" uid="uid://c7htf8h44vbwi" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/shoot.tres" id="5_4yg1b"] +[ext_resource type="Resource" uid="uid://vctiwgvnl0ba" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_joystick.tres" id="6_b05vw"] +[ext_resource type="Script" path="res://guide_examples/input_scheme_switching/player.gd" id="7_2r4ev"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="8_nv6u5"] +[ext_resource type="PackedScene" uid="uid://c36cnvgv2ur60" path="res://guide_examples/shared/fireball/fireball.tscn" id="8_t3npb"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="10_vp4t3"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="11_qdni4"] + +[node name="InputSchemeSwitching" type="Node2D"] +script = ExtResource("1_7l2n1") +joystick_scheme = ExtResource("2_fx1v6") +keyboard_scheme = ExtResource("3_pvyn2") +switch_to_keyboard = ExtResource("4_tts5j") +switch_to_joystick = ExtResource("6_b05vw") + +[node name="Player" type="Node2D" parent="."] +position = Vector2(929, 695) +script = ExtResource("7_2r4ev") +speed = 300.0 +move_action = ExtResource("4_3bnea") +shoot_action = ExtResource("5_4yg1b") +fireball_scene = ExtResource("8_t3npb") + +[node name="GodotLogo" type="Sprite2D" parent="Player"] +texture = ExtResource("1_t4jeg") + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="InstructionsLabel" type="RichTextLabel" parent="UI"] +unique_name_in_owner = true +custom_minimum_size = Vector2(500, 0) +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -552.0 +offset_top = 85.0 +offset_right = -52.0 +offset_bottom = 125.0 +grow_horizontal = 0 +theme = ExtResource("10_vp4t3") +bbcode_enabled = true +text = "Lorem Ipsum Dolor" +fit_content = true +script = ExtResource("11_qdni4") +instructions_text = "%s to move. +%s to shoot a fireball." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("4_3bnea"), ExtResource("5_4yg1b")]) + +[node name="Debugger" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="Debugger" instance=ExtResource("8_nv6u5")] +theme = ExtResource("10_vp4t3") diff --git a/guide_examples/input_scheme_switching/mapping_contexts/actions/move.tres b/guide_examples/input_scheme_switching/mapping_contexts/actions/move.tres new file mode 100644 index 0000000..ab4db08 --- /dev/null +++ b/guide_examples/input_scheme_switching/mapping_contexts/actions/move.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cxn2ibe1mn3sb"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_anxy1"] + +[resource] +script = ExtResource("1_anxy1") +name = &"" +action_value_type = 2 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/input_scheme_switching/mapping_contexts/actions/shoot.tres b/guide_examples/input_scheme_switching/mapping_contexts/actions/shoot.tres new file mode 100644 index 0000000..7702a43 --- /dev/null +++ b/guide_examples/input_scheme_switching/mapping_contexts/actions/shoot.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://c7htf8h44vbwi"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_bkoj8"] + +[resource] +script = ExtResource("1_bkoj8") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_joystick.tres b/guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_joystick.tres new file mode 100644 index 0000000..ef381e4 --- /dev/null +++ b/guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_joystick.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://vctiwgvnl0ba"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_8q327"] + +[resource] +script = ExtResource("1_8q327") +name = &"" +action_value_type = 0 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_keyboard.tres b/guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_keyboard.tres new file mode 100644 index 0000000..aedd67c --- /dev/null +++ b/guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_keyboard.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://b11rcmd3hse58"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_4oh0y"] + +[resource] +script = ExtResource("1_4oh0y") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/input_scheme_switching/mapping_contexts/joystick_scheme.tres b/guide_examples/input_scheme_switching/mapping_contexts/joystick_scheme.tres new file mode 100644 index 0000000..9cd9be0 --- /dev/null +++ b/guide_examples/input_scheme_switching/mapping_contexts/joystick_scheme.tres @@ -0,0 +1,97 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=23 format=3 uid="uid://x33fk5wo7l2r"] + +[ext_resource type="Resource" uid="uid://cxn2ibe1mn3sb" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/move.tres" id="1_hupae"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_axis_2d.gd" id="2_t6p7a"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_6jy3p"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_deadzone.gd" id="3_c1g58"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="4_ssubt"] +[ext_resource type="Resource" uid="uid://c7htf8h44vbwi" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/shoot.tres" id="5_pd4bb"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="6_eieuy"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="7_0nn3e"] +[ext_resource type="Resource" uid="uid://b11rcmd3hse58" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_keyboard.tres" id="8_7nlt6"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_any.gd" id="8_hdd7g"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="9_1vdw8"] + +[sub_resource type="Resource" id="Resource_7qyuq"] +script = ExtResource("2_t6p7a") +x = 0 +y = 1 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_8pjab"] +script = ExtResource("3_c1g58") +lower_threshold = 0.2 +upper_threshold = 1.0 + +[sub_resource type="Resource" id="Resource_wxd67"] +script = ExtResource("3_6jy3p") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_7qyuq") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_8pjab")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_lomew"] +script = ExtResource("4_ssubt") +action = ExtResource("1_hupae") +input_mappings = Array[ExtResource("3_6jy3p")]([SubResource("Resource_wxd67")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_guotu"] +script = ExtResource("6_eieuy") +button = 0 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_ws3e0"] +script = ExtResource("7_0nn3e") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_b21ub"] +script = ExtResource("3_6jy3p") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_guotu") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_ws3e0")]) + +[sub_resource type="Resource" id="Resource_tmt5r"] +script = ExtResource("4_ssubt") +action = ExtResource("5_pd4bb") +input_mappings = Array[ExtResource("3_6jy3p")]([SubResource("Resource_b21ub")]) + +[sub_resource type="Resource" id="Resource_41j1i"] +script = ExtResource("8_hdd7g") +mouse_buttons = false +mouse_movement = false +minimum_mouse_movement_distance = 1.0 +joy_buttons = false +joy_axes = false +minimum_joy_axis_actuation_strength = 0.2 +keyboard = true +touch = false +mouse = false +joy = false + +[sub_resource type="Resource" id="Resource_ncpby"] +script = ExtResource("3_6jy3p") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_41j1i") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_28cwt"] +script = ExtResource("4_ssubt") +action = ExtResource("8_7nlt6") +input_mappings = Array[ExtResource("3_6jy3p")]([SubResource("Resource_ncpby")]) + +[resource] +script = ExtResource("9_1vdw8") +display_name = "" +mappings = Array[ExtResource("4_ssubt")]([SubResource("Resource_lomew"), SubResource("Resource_tmt5r"), SubResource("Resource_28cwt")]) diff --git a/guide_examples/input_scheme_switching/mapping_contexts/keyboard_scheme.tres b/guide_examples/input_scheme_switching/mapping_contexts/keyboard_scheme.tres new file mode 100644 index 0000000..f4d3952 --- /dev/null +++ b/guide_examples/input_scheme_switching/mapping_contexts/keyboard_scheme.tres @@ -0,0 +1,175 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=32 format=3 uid="uid://2hl7iqpondhi"] + +[ext_resource type="Resource" uid="uid://cxn2ibe1mn3sb" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/move.tres" id="1_wyjhr"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_10ro5"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_input_swizzle.gd" id="3_uaw8o"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="4_hv31f"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="5_v5abd"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="6_5qe2r"] +[ext_resource type="Resource" uid="uid://c7htf8h44vbwi" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/shoot.tres" id="7_diyqh"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="8_enquy"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_any.gd" id="9_j1ko4"] +[ext_resource type="Resource" uid="uid://vctiwgvnl0ba" path="res://guide_examples/input_scheme_switching/mapping_contexts/actions/switch_to_joystick.tres" id="9_p8ck7"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="11_rkw8m"] + +[sub_resource type="Resource" id="Resource_ckatg"] +script = ExtResource("2_10ro5") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_8rr5k"] +script = ExtResource("3_uaw8o") +order = 0 + +[sub_resource type="Resource" id="Resource_4c38v"] +script = ExtResource("4_hv31f") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_xot0n"] +script = ExtResource("5_v5abd") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_ckatg") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_8rr5k"), SubResource("Resource_4c38v")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_v2una"] +script = ExtResource("2_10ro5") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_tu604"] +script = ExtResource("4_hv31f") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_vh7xg"] +script = ExtResource("5_v5abd") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_v2una") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_tu604")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_sko3c"] +script = ExtResource("2_10ro5") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_x4ewt"] +script = ExtResource("3_uaw8o") +order = 0 + +[sub_resource type="Resource" id="Resource_1bv7n"] +script = ExtResource("5_v5abd") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_sko3c") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_x4ewt")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_o6q2e"] +script = ExtResource("2_10ro5") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_ggp85"] +script = ExtResource("5_v5abd") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_o6q2e") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_lomew"] +script = ExtResource("6_5qe2r") +action = ExtResource("1_wyjhr") +input_mappings = Array[ExtResource("5_v5abd")]([SubResource("Resource_xot0n"), SubResource("Resource_vh7xg"), SubResource("Resource_1bv7n"), SubResource("Resource_ggp85")]) + +[sub_resource type="Resource" id="Resource_wxbv3"] +script = ExtResource("2_10ro5") +key = 32 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_a515r"] +script = ExtResource("8_enquy") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_u0geb"] +script = ExtResource("5_v5abd") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_wxbv3") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_a515r")]) + +[sub_resource type="Resource" id="Resource_f8tqv"] +script = ExtResource("6_5qe2r") +action = ExtResource("7_diyqh") +input_mappings = Array[ExtResource("5_v5abd")]([SubResource("Resource_u0geb")]) + +[sub_resource type="Resource" id="Resource_1wnrb"] +script = ExtResource("9_j1ko4") +mouse_buttons = false +mouse_movement = false +minimum_mouse_movement_distance = 1.0 +joy_buttons = true +joy_axes = false +minimum_joy_axis_actuation_strength = 0.2 +keyboard = false +touch = false +mouse = false +joy = true + +[sub_resource type="Resource" id="Resource_i18os"] +script = ExtResource("5_v5abd") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_1wnrb") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_im7a2"] +script = ExtResource("6_5qe2r") +action = ExtResource("9_p8ck7") +input_mappings = Array[ExtResource("5_v5abd")]([SubResource("Resource_i18os")]) + +[resource] +script = ExtResource("11_rkw8m") +display_name = "" +mappings = Array[ExtResource("6_5qe2r")]([SubResource("Resource_lomew"), SubResource("Resource_f8tqv"), SubResource("Resource_im7a2")]) diff --git a/guide_examples/input_scheme_switching/player.gd b/guide_examples/input_scheme_switching/player.gd new file mode 100644 index 0000000..366cfbd --- /dev/null +++ b/guide_examples/input_scheme_switching/player.gd @@ -0,0 +1,27 @@ +## Our player. The player has no knowledge about input schemes, it just +## reacts to actions triggering. +extends Node2D + +@export var speed:float = 200 + +@export var move_action:GUIDEAction +@export var shoot_action:GUIDEAction +@export var fireball_scene:PackedScene + + +func _ready(): + shoot_action.triggered.connect(_shoot_fireball) + + +func _process(delta:float) -> void: + position += move_action.value_axis_2d.normalized() * speed * delta + + +func _shoot_fireball(): + var fireball = fireball_scene.instantiate() + fireball.direction = Vector2.UP + get_parent().add_child(fireball) + + fireball.global_transform = global_transform + + diff --git a/guide_examples/input_scheme_switching/player.gd.uid b/guide_examples/input_scheme_switching/player.gd.uid new file mode 100644 index 0000000..7ebe989 --- /dev/null +++ b/guide_examples/input_scheme_switching/player.gd.uid @@ -0,0 +1 @@ +uid://csjgtlek7infj diff --git a/guide_examples/mouse_position_2d/background.gd b/guide_examples/mouse_position_2d/background.gd new file mode 100644 index 0000000..681b9a5 --- /dev/null +++ b/guide_examples/mouse_position_2d/background.gd @@ -0,0 +1,16 @@ +## This just keeps the sprite endlessly scrolling. It's not related to input. +extends Sprite2D + + +func _process(delta): + # get rect of visible screen in world coordinates + var rect = get_viewport().canvas_transform.affine_inverse() * get_viewport_rect() + # fit the bg into the viewport + global_position = rect.position + global_scale = rect.size / texture.get_size() + + # update scaling so the texture scales according to zoom level + material.set_shader_parameter("scale", global_scale) + var offset = rect.position / texture.get_size() + # and offset so we pick a texture offset relative to the movement of the camera + material.set_shader_parameter("offset", offset) diff --git a/guide_examples/mouse_position_2d/background.gd.uid b/guide_examples/mouse_position_2d/background.gd.uid new file mode 100644 index 0000000..a20ffdb --- /dev/null +++ b/guide_examples/mouse_position_2d/background.gd.uid @@ -0,0 +1 @@ +uid://by6w26jgvaitm diff --git a/guide_examples/mouse_position_2d/background.svg b/guide_examples/mouse_position_2d/background.svg new file mode 100644 index 0000000..e649b9e --- /dev/null +++ b/guide_examples/mouse_position_2d/background.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/guide_examples/mouse_position_2d/background.svg.import b/guide_examples/mouse_position_2d/background.svg.import new file mode 100644 index 0000000..b71c4de --- /dev/null +++ b/guide_examples/mouse_position_2d/background.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://slnmn5k0drdb" +path="res://.godot/imported/background.svg-2c00776905f8df1964b7da3b2242aa3e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/mouse_position_2d/background.svg" +dest_files=["res://.godot/imported/background.svg-2c00776905f8df1964b7da3b2242aa3e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/guide_examples/mouse_position_2d/camera_2d.gd b/guide_examples/mouse_position_2d/camera_2d.gd new file mode 100644 index 0000000..ae66c34 --- /dev/null +++ b/guide_examples/mouse_position_2d/camera_2d.gd @@ -0,0 +1,19 @@ +## Camera control. We listen to GUIDE's actions to move and zoom the camera. Note how we can +## mix event-based and polling based input handling, depending on what works better for the +## use case. +extends Camera2D + + +@export var camera_movement:GUIDEAction +@export var camera_zoom:GUIDEAction +@export var speed:float = 300 + + +func _ready(): + camera_zoom.triggered.connect(_zoom_camera) + +func _process(delta): + position += camera_movement.value_axis_2d * speed * delta + +func _zoom_camera(): + zoom = clamp( zoom + Vector2.ONE * camera_zoom.value_axis_1d, Vector2(0.1, 0.1), Vector2(3, 3)) diff --git a/guide_examples/mouse_position_2d/camera_2d.gd.uid b/guide_examples/mouse_position_2d/camera_2d.gd.uid new file mode 100644 index 0000000..a4f760f --- /dev/null +++ b/guide_examples/mouse_position_2d/camera_2d.gd.uid @@ -0,0 +1 @@ +uid://cndto72qu3boe diff --git a/guide_examples/mouse_position_2d/godot_head.gd b/guide_examples/mouse_position_2d/godot_head.gd new file mode 100644 index 0000000..2ca46aa --- /dev/null +++ b/guide_examples/mouse_position_2d/godot_head.gd @@ -0,0 +1,15 @@ +extends Node2D + +@export var lifetime_seconds:float = 5.0 +var _remaining_time_seconds:float = 0 + +func _ready(): + _remaining_time_seconds = lifetime_seconds + +func _process(delta:float) -> void: + _remaining_time_seconds -= delta + if _remaining_time_seconds <= 0: + queue_free() + return + + modulate.a = _remaining_time_seconds / lifetime_seconds diff --git a/guide_examples/mouse_position_2d/godot_head.gd.uid b/guide_examples/mouse_position_2d/godot_head.gd.uid new file mode 100644 index 0000000..2358c67 --- /dev/null +++ b/guide_examples/mouse_position_2d/godot_head.gd.uid @@ -0,0 +1 @@ +uid://c5wpkmya4n248 diff --git a/guide_examples/mouse_position_2d/godot_head.tscn b/guide_examples/mouse_position_2d/godot_head.tscn new file mode 100644 index 0000000..6680112 --- /dev/null +++ b/guide_examples/mouse_position_2d/godot_head.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://cj8m2n32yjxka"] + +[ext_resource type="Script" path="res://guide_examples/mouse_position_2d/godot_head.gd" id="1_7od3t"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="1_1168h"] + +[node name="GodotHead" type="Node2D"] +script = ExtResource("1_7od3t") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("1_1168h") diff --git a/guide_examples/mouse_position_2d/mapping_contexts/actions/camera_movement.tres b/guide_examples/mouse_position_2d/mapping_contexts/actions/camera_movement.tres new file mode 100644 index 0000000..42e0558 --- /dev/null +++ b/guide_examples/mouse_position_2d/mapping_contexts/actions/camera_movement.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://ehdejslyo58y"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_clx3u"] + +[resource] +script = ExtResource("1_clx3u") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_2d/mapping_contexts/actions/camera_zoom.tres b/guide_examples/mouse_position_2d/mapping_contexts/actions/camera_zoom.tres new file mode 100644 index 0000000..ab27451 --- /dev/null +++ b/guide_examples/mouse_position_2d/mapping_contexts/actions/camera_zoom.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://6dm5j1sdhdp2"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_u52q5"] + +[resource] +script = ExtResource("1_u52q5") +name = &"" +action_value_type = 1 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_2d/mapping_contexts/actions/cursor.tres b/guide_examples/mouse_position_2d/mapping_contexts/actions/cursor.tres new file mode 100644 index 0000000..99d9051 --- /dev/null +++ b/guide_examples/mouse_position_2d/mapping_contexts/actions/cursor.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://y7q516rtjlt8"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_casem"] + +[resource] +script = ExtResource("1_casem") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_2d/mapping_contexts/actions/spawn.tres b/guide_examples/mouse_position_2d/mapping_contexts/actions/spawn.tres new file mode 100644 index 0000000..4a9ca29 --- /dev/null +++ b/guide_examples/mouse_position_2d/mapping_contexts/actions/spawn.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cap7r63x8tait"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_y7wt7"] + +[resource] +script = ExtResource("1_y7wt7") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_2d/mapping_contexts/modifiers/zoom_sensitivity.tres b/guide_examples/mouse_position_2d/mapping_contexts/modifiers/zoom_sensitivity.tres new file mode 100644 index 0000000..4462ffc --- /dev/null +++ b/guide_examples/mouse_position_2d/mapping_contexts/modifiers/zoom_sensitivity.tres @@ -0,0 +1,8 @@ +[gd_resource type="Resource" script_class="GUIDEModifierScale" load_steps=2 format=3 uid="uid://d0brjke26hsk8"] + +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_scale.gd" id="1_vqbea"] + +[resource] +script = ExtResource("1_vqbea") +scale = Vector3(0.1, 1, 1) +apply_delta_time = false diff --git a/guide_examples/mouse_position_2d/mapping_contexts/mouse_position.tres b/guide_examples/mouse_position_2d/mapping_contexts/mouse_position.tres new file mode 100644 index 0000000..d750d67 --- /dev/null +++ b/guide_examples/mouse_position_2d/mapping_contexts/mouse_position.tres @@ -0,0 +1,207 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=43 format=3 uid="uid://cfbk5croqnocs"] + +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_ru5nv"] +[ext_resource type="Resource" uid="uid://y7q516rtjlt8" path="res://guide_examples/mouse_position_2d/mapping_contexts/actions/cursor.tres" id="1_ybilq"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_mouse_position.gd" id="2_xu301"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_vy8se"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="4_pisoh"] +[ext_resource type="Resource" uid="uid://ehdejslyo58y" path="res://guide_examples/mouse_position_2d/mapping_contexts/actions/camera_movement.tres" id="6_qfh27"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="6_u43ni"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="7_668rf"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_input_swizzle.gd" id="8_o7tqa"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_mouse_button.gd" id="10_g5tce"] +[ext_resource type="Resource" uid="uid://cap7r63x8tait" path="res://guide_examples/mouse_position_2d/mapping_contexts/actions/spawn.tres" id="10_ohwve"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="11_5ifuu"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_canvas_coordinates.gd" id="11_j8wbm"] +[ext_resource type="Resource" uid="uid://6dm5j1sdhdp2" path="res://guide_examples/mouse_position_2d/mapping_contexts/actions/camera_zoom.tres" id="13_htiyk"] +[ext_resource type="Resource" uid="uid://d0brjke26hsk8" path="res://guide_examples/mouse_position_2d/mapping_contexts/modifiers/zoom_sensitivity.tres" id="14_0gubt"] + +[sub_resource type="Resource" id="Resource_420bm"] +script = ExtResource("2_xu301") + +[sub_resource type="Resource" id="Resource_hqwk3"] +script = ExtResource("11_j8wbm") +relative_input = false + +[sub_resource type="Resource" id="Resource_wsyf2"] +script = ExtResource("3_vy8se") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_420bm") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_hqwk3")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_4f0pb"] +script = ExtResource("4_pisoh") +action = ExtResource("1_ybilq") +input_mappings = Array[ExtResource("3_vy8se")]([SubResource("Resource_wsyf2")]) + +[sub_resource type="Resource" id="Resource_jlr8l"] +script = ExtResource("6_u43ni") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_o78ws"] +script = ExtResource("7_668rf") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_8gssa"] +script = ExtResource("8_o7tqa") +order = 0 + +[sub_resource type="Resource" id="Resource_qmv1n"] +script = ExtResource("3_vy8se") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_jlr8l") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_o78ws"), SubResource("Resource_8gssa")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_7q6a3"] +script = ExtResource("6_u43ni") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_l8svn"] +script = ExtResource("8_o7tqa") +order = 0 + +[sub_resource type="Resource" id="Resource_j8u0l"] +script = ExtResource("3_vy8se") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_7q6a3") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_l8svn")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_asguk"] +script = ExtResource("6_u43ni") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_ly8fj"] +script = ExtResource("7_668rf") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_6m3qh"] +script = ExtResource("3_vy8se") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_asguk") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_ly8fj")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_vbr6o"] +script = ExtResource("6_u43ni") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_xiclq"] +script = ExtResource("3_vy8se") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_vbr6o") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_hvdyr"] +script = ExtResource("4_pisoh") +action = ExtResource("6_qfh27") +input_mappings = Array[ExtResource("3_vy8se")]([SubResource("Resource_qmv1n"), SubResource("Resource_j8u0l"), SubResource("Resource_6m3qh"), SubResource("Resource_xiclq")]) + +[sub_resource type="Resource" id="Resource_3v4no"] +script = ExtResource("10_g5tce") +button = 4 + +[sub_resource type="Resource" id="Resource_l152p"] +script = ExtResource("3_vy8se") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_3v4no") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([ExtResource("14_0gubt")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_wlhft"] +script = ExtResource("10_g5tce") +button = 5 + +[sub_resource type="Resource" id="Resource_b581m"] +script = ExtResource("7_668rf") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_xrajm"] +script = ExtResource("3_vy8se") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_wlhft") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_b581m"), ExtResource("14_0gubt")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_otc05"] +script = ExtResource("4_pisoh") +action = ExtResource("13_htiyk") +input_mappings = Array[ExtResource("3_vy8se")]([SubResource("Resource_l152p"), SubResource("Resource_xrajm")]) + +[sub_resource type="Resource" id="Resource_w5sbr"] +script = ExtResource("10_g5tce") +button = 1 + +[sub_resource type="Resource" id="Resource_omxoi"] +script = ExtResource("11_5ifuu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_8n6aa"] +script = ExtResource("3_vy8se") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_w5sbr") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_omxoi")]) + +[sub_resource type="Resource" id="Resource_iivaa"] +script = ExtResource("4_pisoh") +action = ExtResource("10_ohwve") +input_mappings = Array[ExtResource("3_vy8se")]([SubResource("Resource_8n6aa")]) + +[resource] +script = ExtResource("1_ru5nv") +display_name = "" +mappings = Array[ExtResource("4_pisoh")]([SubResource("Resource_4f0pb"), SubResource("Resource_hvdyr"), SubResource("Resource_otc05"), SubResource("Resource_iivaa")]) diff --git a/guide_examples/mouse_position_2d/mouse_position.gd b/guide_examples/mouse_position_2d/mouse_position.gd new file mode 100644 index 0000000..f939942 --- /dev/null +++ b/guide_examples/mouse_position_2d/mouse_position.gd @@ -0,0 +1,26 @@ +## This example shows how to get access to the mouse cursor without being +## specific about where the input comes from. +extends Node2D + + +@export var mapping_context:GUIDEMappingContext +@export var spawn:GUIDEAction +@export var cursor:GUIDEAction + +@export var godot_head_scene:PackedScene + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) + spawn.triggered.connect(_spawn_godot_head) + + +func _spawn_godot_head(): + # Gets the mouse cursor from G.U.I.D.E. Note how the Canvas Coordinates + # modifier automatically gives us mouse coordinates in canvas space + # which means we don't need to take into acount the camera panning and + # zoom level and can just use the coordinates we get to directly place + # a Godot head at the cursor position. + var head = godot_head_scene.instantiate() + add_child(head) + + head.global_position = cursor.value_axis_2d diff --git a/guide_examples/mouse_position_2d/mouse_position.gd.uid b/guide_examples/mouse_position_2d/mouse_position.gd.uid new file mode 100644 index 0000000..ba92ac7 --- /dev/null +++ b/guide_examples/mouse_position_2d/mouse_position.gd.uid @@ -0,0 +1 @@ +uid://cvoeomxm2dwyr diff --git a/guide_examples/mouse_position_2d/mouse_position.tscn b/guide_examples/mouse_position_2d/mouse_position.tscn new file mode 100644 index 0000000..7f1abea --- /dev/null +++ b/guide_examples/mouse_position_2d/mouse_position.tscn @@ -0,0 +1,79 @@ +[gd_scene load_steps=16 format=3 uid="uid://c4de28wapdqtp"] + +[ext_resource type="Script" path="res://guide_examples/mouse_position_2d/mouse_position.gd" id="1_rkyn8"] +[ext_resource type="Resource" uid="uid://cfbk5croqnocs" path="res://guide_examples/mouse_position_2d/mapping_contexts/mouse_position.tres" id="2_f4xly"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="2_yylue"] +[ext_resource type="Resource" uid="uid://y7q516rtjlt8" path="res://guide_examples/mouse_position_2d/mapping_contexts/actions/cursor.tres" id="3_e2cui"] +[ext_resource type="Resource" uid="uid://cap7r63x8tait" path="res://guide_examples/mouse_position_2d/mapping_contexts/actions/spawn.tres" id="3_e16oi"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="3_xcjwc"] +[ext_resource type="Script" path="res://guide_examples/mouse_position_2d/camera_2d.gd" id="3_xpjlw"] +[ext_resource type="PackedScene" uid="uid://cj8m2n32yjxka" path="res://guide_examples/mouse_position_2d/godot_head.tscn" id="5_6xobh"] +[ext_resource type="Resource" uid="uid://ehdejslyo58y" path="res://guide_examples/mouse_position_2d/mapping_contexts/actions/camera_movement.tres" id="5_snwnm"] +[ext_resource type="Texture2D" uid="uid://slnmn5k0drdb" path="res://guide_examples/mouse_position_2d/background.svg" id="6_1tobk"] +[ext_resource type="Script" path="res://guide_examples/mouse_position_2d/background.gd" id="7_4oihe"] +[ext_resource type="Resource" uid="uid://6dm5j1sdhdp2" path="res://guide_examples/mouse_position_2d/mapping_contexts/actions/camera_zoom.tres" id="8_6tg1h"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="9_y8piq"] + +[sub_resource type="Shader" id="Shader_v4pj1"] +code = "shader_type canvas_item; + +uniform vec2 scale; +uniform vec2 offset; + +void vertex() { + UV = UV * scale + offset; +} + + +//void light() { + // Called for every pixel for every light affecting the CanvasItem. + // Uncomment to replace the default light processing function with this one. +//} +" + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_1sa2x"] +shader = SubResource("Shader_v4pj1") +shader_parameter/scale = Vector2(1, 1) +shader_parameter/offset = Vector2(0, 0) + +[node name="MousePosition" type="Node2D"] +script = ExtResource("1_rkyn8") +mapping_context = ExtResource("2_f4xly") +spawn = ExtResource("3_e16oi") +cursor = ExtResource("3_e2cui") +godot_head_scene = ExtResource("5_6xobh") + +[node name="Camera2D" type="Camera2D" parent="."] +script = ExtResource("3_xpjlw") +camera_movement = ExtResource("5_snwnm") +camera_zoom = ExtResource("8_6tg1h") + +[node name="BG" type="Sprite2D" parent="."] +texture_repeat = 2 +material = SubResource("ShaderMaterial_1sa2x") +texture = ExtResource("6_1tobk") +centered = false +script = ExtResource("7_4oihe") + +[node name="UILayer" type="CanvasLayer" parent="."] + +[node name="RichTextLabel" type="RichTextLabel" parent="UILayer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -107.0 +offset_top = 41.0 +offset_right = -67.0 +offset_bottom = 81.0 +grow_horizontal = 0 +theme = ExtResource("3_xcjwc") +script = ExtResource("9_y8piq") +instructions_text = "%s to move the camera. +%s to zoom the camera. +%s to place a Godot head." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("5_snwnm"), ExtResource("8_6tg1h"), ExtResource("3_e16oi")]) + +[node name="DebuggerLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="DebuggerLayer" instance=ExtResource("2_yylue")] +theme = ExtResource("3_xcjwc") diff --git a/guide_examples/mouse_position_3d/camera_control.gd b/guide_examples/mouse_position_3d/camera_control.gd new file mode 100644 index 0000000..565d738 --- /dev/null +++ b/guide_examples/mouse_position_3d/camera_control.gd @@ -0,0 +1,42 @@ +## GUIDE makes controlling a camera pretty easy. By using the +## window-relative and scale modifiers we can translate mouse input +## directly into a format suitable for rotation. GUIDE also takes +## care of only sending yaw and pitch input when the camera toggle +## is pressed, so we don't need to have any complex input code in +## our camera control script. +extends Node3D + +@export var camera_pitch:GUIDEAction +@export var camera_yaw:GUIDEAction +@export var camera_toggle:GUIDEAction +@export var camera_move:GUIDEAction + +@export var movement_speed:float = 1 +@onready var _camera_yaw:Node3D = %CameraYaw +@onready var _camera_pitch:SpringArm3D = %CameraPitch + +func _ready(): + camera_toggle.triggered.connect(_hide_mouse) + camera_toggle.completed.connect(_show_mouse) + camera_yaw.triggered.connect(_yaw) + camera_pitch.triggered.connect(_pitch) + +func _hide_mouse(): + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + +func _show_mouse(): + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + +func _yaw(): + _camera_yaw.rotate_y(camera_yaw.value_axis_1d) + +func _pitch(): + _camera_pitch.rotate_x(camera_pitch.value_axis_1d) + _camera_pitch.rotation_degrees.x = clamp(_camera_pitch.rotation_degrees.x, -75.0, 0.0) + + +func _process(delta): + # we already used the input-swizzle modifier to get forward as -z, backward as z + # left as -x and right as x, so we can use this immediately + position += basis * camera_move.value_axis_3d * movement_speed * delta + diff --git a/guide_examples/mouse_position_3d/camera_control.gd.uid b/guide_examples/mouse_position_3d/camera_control.gd.uid new file mode 100644 index 0000000..c8c1a58 --- /dev/null +++ b/guide_examples/mouse_position_3d/camera_control.gd.uid @@ -0,0 +1 @@ +uid://c560cjrqx328f diff --git a/guide_examples/mouse_position_3d/mapping_context/actions/camera_move.tres b/guide_examples/mouse_position_3d/mapping_context/actions/camera_move.tres new file mode 100644 index 0000000..34dc17b --- /dev/null +++ b/guide_examples/mouse_position_3d/mapping_context/actions/camera_move.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://ceti1avx1l1qw"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_ehoni"] + +[resource] +script = ExtResource("1_ehoni") +name = &"" +action_value_type = 3 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_3d/mapping_context/actions/camera_pitch.tres b/guide_examples/mouse_position_3d/mapping_context/actions/camera_pitch.tres new file mode 100644 index 0000000..d085bd7 --- /dev/null +++ b/guide_examples/mouse_position_3d/mapping_context/actions/camera_pitch.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bago2pmgvpepb"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_uluq2"] + +[resource] +script = ExtResource("1_uluq2") +name = &"" +action_value_type = 1 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_3d/mapping_context/actions/camera_toggle.tres b/guide_examples/mouse_position_3d/mapping_context/actions/camera_toggle.tres new file mode 100644 index 0000000..ff04e54 --- /dev/null +++ b/guide_examples/mouse_position_3d/mapping_context/actions/camera_toggle.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cpljlaavuq515"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_gal8q"] + +[resource] +script = ExtResource("1_gal8q") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_3d/mapping_context/actions/camera_yaw.tres b/guide_examples/mouse_position_3d/mapping_context/actions/camera_yaw.tres new file mode 100644 index 0000000..eb84c7b --- /dev/null +++ b/guide_examples/mouse_position_3d/mapping_context/actions/camera_yaw.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bltmi1lr7umq0"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_273ub"] + +[resource] +script = ExtResource("1_273ub") +name = &"" +action_value_type = 1 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_3d/mapping_context/actions/cursor_3d.tres b/guide_examples/mouse_position_3d/mapping_context/actions/cursor_3d.tres new file mode 100644 index 0000000..d62f1c6 --- /dev/null +++ b/guide_examples/mouse_position_3d/mapping_context/actions/cursor_3d.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://2b0ncq7ogvv0"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_3to1y"] + +[resource] +script = ExtResource("1_3to1y") +name = &"" +action_value_type = 3 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_3d/mapping_context/actions/select.tres b/guide_examples/mouse_position_3d/mapping_context/actions/select.tres new file mode 100644 index 0000000..12a38c2 --- /dev/null +++ b/guide_examples/mouse_position_3d/mapping_context/actions/select.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://b2jb27062t2mh"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_nysth"] + +[resource] +script = ExtResource("1_nysth") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/mouse_position_3d/mapping_context/mouse_position_3d.tres b/guide_examples/mouse_position_3d/mapping_context/mouse_position_3d.tres new file mode 100644 index 0000000..8b0e88a --- /dev/null +++ b/guide_examples/mouse_position_3d/mapping_context/mouse_position_3d.tres @@ -0,0 +1,270 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=59 format=3 uid="uid://bpatu7vi2kj4l"] + +[ext_resource type="Resource" uid="uid://bltmi1lr7umq0" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_yaw.tres" id="1_8aom2"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_rde8c"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_mouse_position.gd" id="2_nomn0"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_mouse_axis_1d.gd" id="2_qlocd"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_window_relative.gd" id="3_p61vs"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_3d_coordinates.gd" id="3_uds3g"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="4_6a0qh"] +[ext_resource type="Resource" uid="uid://cpljlaavuq515" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_toggle.tres" id="4_jyoym"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="4_mho8x"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="5_4hkur"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_scale.gd" id="5_b42iu"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_chorded_action.gd" id="5_qvvu8"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_mouse_button.gd" id="7_7w5i6"] +[ext_resource type="Resource" uid="uid://bago2pmgvpepb" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_pitch.tres" id="7_swef3"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="8_5glyu"] +[ext_resource type="Resource" uid="uid://2b0ncq7ogvv0" path="res://guide_examples/mouse_position_3d/mapping_context/actions/cursor_3d.tres" id="9_rxgkr"] +[ext_resource type="Resource" uid="uid://ceti1avx1l1qw" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_move.tres" id="12_v8r8p"] +[ext_resource type="Resource" uid="uid://b2jb27062t2mh" path="res://guide_examples/mouse_position_3d/mapping_context/actions/select.tres" id="12_wmpes"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="13_x2lbs"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_input_swizzle.gd" id="14_2r6td"] + +[sub_resource type="Resource" id="Resource_46a3k"] +script = ExtResource("2_qlocd") +axis = 0 + +[sub_resource type="Resource" id="Resource_0uhrt"] +script = ExtResource("3_p61vs") + +[sub_resource type="Resource" id="Resource_eipue"] +script = ExtResource("4_mho8x") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_66vbo"] +script = ExtResource("5_b42iu") +scale = Vector3(6.28, 1, 1) +apply_delta_time = false + +[sub_resource type="Resource" id="Resource_wvbgw"] +script = ExtResource("5_qvvu8") +action = ExtResource("4_jyoym") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_aqfvw"] +script = ExtResource("4_6a0qh") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_46a3k") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_0uhrt"), SubResource("Resource_eipue"), SubResource("Resource_66vbo")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_wvbgw")]) + +[sub_resource type="Resource" id="Resource_g62j8"] +script = ExtResource("5_4hkur") +action = ExtResource("1_8aom2") +input_mappings = Array[ExtResource("4_6a0qh")]([SubResource("Resource_aqfvw")]) + +[sub_resource type="Resource" id="Resource_jyaeo"] +script = ExtResource("2_qlocd") +axis = 1 + +[sub_resource type="Resource" id="Resource_lo1xm"] +script = ExtResource("3_p61vs") + +[sub_resource type="Resource" id="Resource_f41et"] +script = ExtResource("4_mho8x") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_os02k"] +script = ExtResource("5_b42iu") +scale = Vector3(6.28, 1, 1) +apply_delta_time = false + +[sub_resource type="Resource" id="Resource_t4dub"] +script = ExtResource("5_qvvu8") +action = ExtResource("4_jyoym") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_jsmry"] +script = ExtResource("4_6a0qh") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_jyaeo") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_lo1xm"), SubResource("Resource_f41et"), SubResource("Resource_os02k")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_t4dub")]) + +[sub_resource type="Resource" id="Resource_4sqcw"] +script = ExtResource("5_4hkur") +action = ExtResource("7_swef3") +input_mappings = Array[ExtResource("4_6a0qh")]([SubResource("Resource_jsmry")]) + +[sub_resource type="Resource" id="Resource_ki4s5"] +script = ExtResource("7_7w5i6") +button = 2 + +[sub_resource type="Resource" id="Resource_djtqh"] +script = ExtResource("4_6a0qh") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_ki4s5") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_nyq6u"] +script = ExtResource("5_4hkur") +action = ExtResource("4_jyoym") +input_mappings = Array[ExtResource("4_6a0qh")]([SubResource("Resource_djtqh")]) + +[sub_resource type="Resource" id="Resource_20kay"] +script = ExtResource("13_x2lbs") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_0syad"] +script = ExtResource("14_2r6td") +order = 1 + +[sub_resource type="Resource" id="Resource_0bn66"] +script = ExtResource("4_mho8x") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_7gp34"] +script = ExtResource("4_6a0qh") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_20kay") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_0syad"), SubResource("Resource_0bn66")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_v2uh1"] +script = ExtResource("13_x2lbs") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_axfl8"] +script = ExtResource("14_2r6td") +order = 1 + +[sub_resource type="Resource" id="Resource_vij8n"] +script = ExtResource("4_6a0qh") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_v2uh1") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_axfl8")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_rauax"] +script = ExtResource("13_x2lbs") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_8xh6c"] +script = ExtResource("4_mho8x") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_8urnd"] +script = ExtResource("4_6a0qh") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_rauax") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_8xh6c")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_utvoa"] +script = ExtResource("13_x2lbs") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_tj7qw"] +script = ExtResource("4_6a0qh") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_utvoa") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_mlu0g"] +script = ExtResource("5_4hkur") +action = ExtResource("12_v8r8p") +input_mappings = Array[ExtResource("4_6a0qh")]([SubResource("Resource_7gp34"), SubResource("Resource_vij8n"), SubResource("Resource_8urnd"), SubResource("Resource_tj7qw")]) + +[sub_resource type="Resource" id="Resource_hh3gq"] +script = ExtResource("2_nomn0") + +[sub_resource type="Resource" id="Resource_nkih0"] +script = ExtResource("3_uds3g") +max_depth = 1000.0 +collide_with_areas = false +collision_mask = 1 + +[sub_resource type="Resource" id="Resource_wvei4"] +script = ExtResource("4_6a0qh") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_hh3gq") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_nkih0")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_6b6vt"] +script = ExtResource("5_4hkur") +action = ExtResource("9_rxgkr") +input_mappings = Array[ExtResource("4_6a0qh")]([SubResource("Resource_wvei4")]) + +[sub_resource type="Resource" id="Resource_lawue"] +script = ExtResource("7_7w5i6") +button = 1 + +[sub_resource type="Resource" id="Resource_tvue7"] +script = ExtResource("8_5glyu") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_m30sl"] +script = ExtResource("4_6a0qh") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_lawue") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_tvue7")]) + +[sub_resource type="Resource" id="Resource_8y4cb"] +script = ExtResource("5_4hkur") +action = ExtResource("12_wmpes") +input_mappings = Array[ExtResource("4_6a0qh")]([SubResource("Resource_m30sl")]) + +[resource] +script = ExtResource("1_rde8c") +display_name = "" +mappings = Array[ExtResource("5_4hkur")]([SubResource("Resource_g62j8"), SubResource("Resource_4sqcw"), SubResource("Resource_nyq6u"), SubResource("Resource_mlu0g"), SubResource("Resource_6b6vt"), SubResource("Resource_8y4cb")]) diff --git a/guide_examples/mouse_position_3d/mou4D8E.tmp b/guide_examples/mouse_position_3d/mou4D8E.tmp new file mode 100644 index 0000000..972edf3 --- /dev/null +++ b/guide_examples/mouse_position_3d/mou4D8E.tmp @@ -0,0 +1,128 @@ +[gd_scene load_steps=21 format=3 uid="uid://dmpv0dh2nk5j"] + +[ext_resource type="Script" path="res://guide_examples/mouse_position_3d/mouse_position_3d.gd" id="1_8oqik"] +[ext_resource type="Resource" uid="uid://bpatu7vi2kj4l" path="res://guide_examples/mouse_position_3d/mapping_context/mouse_position_3d.tres" id="2_bb21n"] +[ext_resource type="Script" path="res://guide_examples/mouse_position_3d/camera_control.gd" id="3_4etic"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="3_m2gj2"] +[ext_resource type="Script" path="res://guide_examples/mouse_position_3d/mouse_indicator.gd" id="3_tunsg"] +[ext_resource type="Resource" uid="uid://2b0ncq7ogvv0" path="res://guide_examples/mouse_position_3d/mapping_context/actions/cursor_3d.tres" id="4_dla1l"] +[ext_resource type="Resource" uid="uid://bago2pmgvpepb" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_pitch.tres" id="4_xr1vq"] +[ext_resource type="Script" path="res://guide_examples/mouse_position_3d/player.gd" id="5_8nflt"] +[ext_resource type="Resource" uid="uid://bltmi1lr7umq0" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_yaw.tres" id="5_mnyiu"] +[ext_resource type="Resource" uid="uid://cpljlaavuq515" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_toggle.tres" id="6_51csy"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="6_lyxvk"] +[ext_resource type="Resource" uid="uid://b2jb27062t2mh" path="res://guide_examples/mouse_position_3d/mapping_context/actions/select.tres" id="6_uviri"] +[ext_resource type="Resource" uid="uid://ceti1avx1l1qw" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_move.tres" id="7_1vbs8"] + +[sub_resource type="NavigationMesh" id="NavigationMesh_sfop5"] +vertices = PackedVector3Array(2.25, 2.656, -7, 2.25, 2.656, -3.5, 4.25, 1.156, -3.5, 4.25, 1.156, -7, 4.25, 1.156, -7, 4.25, 1.156, -3.5, 4.75, 0.905995, -2.5, 9, 0.905995, -2.5, 9, 0.905995, -9, 4.75, 0.905995, -8.5, 9, 0.905995, -9, 4.25, 0.905995, -9, 4.75, 0.905995, -8.5, -3.5, 3.656, -3.5, 2.25, 2.656, -3.5, 2.25, 2.656, -7, -7.5, 3.656, -7, 0.8125, 3.656, -3.5, 0.857143, 3.656, -7, -7.5, 3.656, 5.25, -4.25, 3.656, 5.25, -4.25, 3.656, -2.75, -7.5, 3.656, -7, -4.25, 3.656, -2.75, -3.5, 3.656, -3.5, -7.5, 3.656, -7, 9, 0.905995, -2.5, 4.75, 0.905995, -2.5, 4.25, 0.905995, -1.5, -3, 0.905995, 7.25, -9, 0.905995, 7, -9, 0.905995, 9, 9, 0.905995, 9, 4.25, 0.905995, -1.5, -2.25, 0.905995, -1.5, -2.25, 0.905995, 6.5, 9, 0.905995, 9, 9, 0.905995, -2.5, 4.25, 0.905995, -1.5, -2.25, 0.905995, 6.5, -2.25, 0.905995, 6.5, -3, 0.905995, 7.25, 9, 0.905995, 9) +polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1), PackedInt32Array(5, 4, 6), PackedInt32Array(6, 4, 9), PackedInt32Array(6, 9, 7), PackedInt32Array(7, 9, 8), PackedInt32Array(10, 12, 11), PackedInt32Array(15, 14, 18), PackedInt32Array(18, 14, 17), PackedInt32Array(18, 17, 13), PackedInt32Array(18, 13, 16), PackedInt32Array(20, 19, 21), PackedInt32Array(21, 19, 22), PackedInt32Array(25, 24, 23), PackedInt32Array(28, 27, 26), PackedInt32Array(30, 29, 31), PackedInt32Array(31, 29, 32), PackedInt32Array(35, 34, 33), PackedInt32Array(37, 36, 38), PackedInt32Array(38, 36, 39), PackedInt32Array(42, 41, 40)] +agent_radius = 1.0 + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_taqbr"] + +[sub_resource type="Sky" id="Sky_qlesy"] +sky_material = SubResource("ProceduralSkyMaterial_taqbr") + +[sub_resource type="Environment" id="Environment_wd3mo"] +background_mode = 2 +sky = SubResource("Sky_qlesy") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_q83ll"] +transparency = 1 +albedo_color = Color(0.890196, 0.176471, 0.133333, 0.678431) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ubo0r"] +albedo_color = Color(1.15514e-06, 0.522721, 0.747218, 1) + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_3a636"] +radius = 0.6 +height = 2.3 + +[node name="MousePosition3d" type="Node3D"] +script = ExtResource("1_8oqik") +mapping_context = ExtResource("2_bb21n") + +[node name="CameraYaw" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(0.435231, 0, 0.900319, 0, 1, 0, -0.900319, 0, 0.435231, 6.62904, 4.72731, 0) +script = ExtResource("3_4etic") +camera_pitch = ExtResource("4_xr1vq") +camera_yaw = ExtResource("5_mnyiu") +camera_toggle = ExtResource("6_51csy") +camera_move = ExtResource("7_1vbs8") +movement_speed = 8.0 + +[node name="CameraPitch" type="SpringArm3D" parent="CameraYaw"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.984808, 0.173648, 0, -0.173648, 0.984808, 0, 0, 0) +spring_length = 8.0 + +[node name="Camera3D" type="Camera3D" parent="CameraYaw/CameraPitch"] + +[node name="World" type="Node3D" parent="."] + +[node name="NavigationRegion3D" type="NavigationRegion3D" parent="World"] +navigation_mesh = SubResource("NavigationMesh_sfop5") + +[node name="CSGBox3D" type="CSGBox3D" parent="World/NavigationRegion3D"] +use_collision = true +size = Vector3(20, 1, 20) + +[node name="CSGBox3D2" type="CSGBox3D" parent="World/NavigationRegion3D"] +transform = Transform3D(0.80368, 0.595061, 0, -0.595061, 0.80368, 0, 0, 0, 1, 2.07477, 0.832275, -5.22408) +use_collision = true +size = Vector3(5.14954, 2.2251, 5.07178) + +[node name="CSGBox3D3" type="CSGBox3D" parent="World/NavigationRegion3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.8367, 2.1428, -5.22408) +use_collision = true +size = Vector3(9.01666, 2.2251, 5.07178) + +[node name="CSGBox3D4" type="CSGBox3D" parent="World/NavigationRegion3D"] +transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -5.81752, 2.1428, 1.66142) +use_collision = true +size = Vector3(9.01666, 2.2251, 5.07178) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="World"] +environment = SubResource("Environment_wd3mo") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="World"] +transform = Transform3D(1, 0, 0, 0, 0.780496, 0.625161, 0, -0.625161, 0.780496, 0, 4.93937, 0) +shadow_enabled = true + +[node name="MouseIndicator" type="CSGSphere3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.84397, 1.04571, 0) +material = SubResource("StandardMaterial3D_q83ll") +script = ExtResource("3_tunsg") +cursor = ExtResource("4_dla1l") +camera_toggle = ExtResource("6_51csy") + +[node name="CharacterBody3D" type="CharacterBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.26495, 0) +collision_layer = 2 +input_ray_pickable = false +floor_constant_speed = true +script = ExtResource("5_8nflt") +select = ExtResource("6_uviri") +cursor = ExtResource("4_dla1l") + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="CharacterBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.28249, 0) +material = SubResource("StandardMaterial3D_ubo0r") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="CharacterBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.26098, 0) +shape = SubResource("CapsuleShape3D_3a636") + +[node name="NavigationAgent3D" type="NavigationAgent3D" parent="CharacterBody3D"] +unique_name_in_owner = true +debug_enabled = true +debug_use_custom = true +debug_path_custom_color = Color(0.886095, 0.359614, 0.933159, 1) +debug_path_custom_point_size = 7.17 + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="CanvasLayer" instance=ExtResource("3_m2gj2")] +theme = ExtResource("6_lyxvk") diff --git a/guide_examples/mouse_position_3d/mouse_indicator.gd b/guide_examples/mouse_position_3d/mouse_indicator.gd new file mode 100644 index 0000000..08f7a3d --- /dev/null +++ b/guide_examples/mouse_position_3d/mouse_indicator.gd @@ -0,0 +1,13 @@ +extends CSGSphere3D + +@export var cursor:GUIDEAction +@export var camera_toggle:GUIDEAction + +func _process(delta): + var new_pos = cursor.value_axis_3d + if not new_pos.is_finite() or camera_toggle.is_triggered(): + visible = false + return + + visible = true + global_position = new_pos diff --git a/guide_examples/mouse_position_3d/mouse_indicator.gd.uid b/guide_examples/mouse_position_3d/mouse_indicator.gd.uid new file mode 100644 index 0000000..a98002b --- /dev/null +++ b/guide_examples/mouse_position_3d/mouse_indicator.gd.uid @@ -0,0 +1 @@ +uid://mj7s4e2n6fpm diff --git a/guide_examples/mouse_position_3d/mouse_position_3d.gd b/guide_examples/mouse_position_3d/mouse_position_3d.gd new file mode 100644 index 0000000..82d18d0 --- /dev/null +++ b/guide_examples/mouse_position_3d/mouse_position_3d.gd @@ -0,0 +1,7 @@ +extends Node3D + + +@export var mapping_context:GUIDEMappingContext + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) diff --git a/guide_examples/mouse_position_3d/mouse_position_3d.gd.uid b/guide_examples/mouse_position_3d/mouse_position_3d.gd.uid new file mode 100644 index 0000000..051380a --- /dev/null +++ b/guide_examples/mouse_position_3d/mouse_position_3d.gd.uid @@ -0,0 +1 @@ +uid://5x7dcnegcvlb diff --git a/guide_examples/mouse_position_3d/mouse_position_3d.tscn b/guide_examples/mouse_position_3d/mouse_position_3d.tscn new file mode 100644 index 0000000..77a2388 --- /dev/null +++ b/guide_examples/mouse_position_3d/mouse_position_3d.tscn @@ -0,0 +1,148 @@ +[gd_scene load_steps=22 format=3 uid="uid://dmpv0dh2nk5j"] + +[ext_resource type="Script" path="res://guide_examples/mouse_position_3d/mouse_position_3d.gd" id="1_8oqik"] +[ext_resource type="Resource" uid="uid://bpatu7vi2kj4l" path="res://guide_examples/mouse_position_3d/mapping_context/mouse_position_3d.tres" id="2_bb21n"] +[ext_resource type="Script" path="res://guide_examples/mouse_position_3d/camera_control.gd" id="3_4etic"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="3_m2gj2"] +[ext_resource type="Script" path="res://guide_examples/mouse_position_3d/mouse_indicator.gd" id="3_tunsg"] +[ext_resource type="Resource" uid="uid://2b0ncq7ogvv0" path="res://guide_examples/mouse_position_3d/mapping_context/actions/cursor_3d.tres" id="4_dla1l"] +[ext_resource type="Resource" uid="uid://bago2pmgvpepb" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_pitch.tres" id="4_xr1vq"] +[ext_resource type="Script" path="res://guide_examples/mouse_position_3d/player.gd" id="5_8nflt"] +[ext_resource type="Resource" uid="uid://bltmi1lr7umq0" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_yaw.tres" id="5_mnyiu"] +[ext_resource type="Resource" uid="uid://cpljlaavuq515" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_toggle.tres" id="6_51csy"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="6_lyxvk"] +[ext_resource type="Resource" uid="uid://b2jb27062t2mh" path="res://guide_examples/mouse_position_3d/mapping_context/actions/select.tres" id="6_uviri"] +[ext_resource type="Resource" uid="uid://ceti1avx1l1qw" path="res://guide_examples/mouse_position_3d/mapping_context/actions/camera_move.tres" id="7_1vbs8"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="12_c4bk3"] + +[sub_resource type="NavigationMesh" id="NavigationMesh_sfop5"] +vertices = PackedVector3Array(2.25, 2.656, -7, 2.25, 2.656, -3.5, 4.25, 1.156, -3.5, 4.25, 1.156, -7, 4.25, 1.156, -7, 4.25, 1.156, -3.5, 4.75, 0.905995, -2.5, 9, 0.905995, -2.5, 9, 0.905995, -9, 4.75, 0.905995, -8.5, 9, 0.905995, -9, 4.25, 0.905995, -9, 4.75, 0.905995, -8.5, -3.5, 3.656, -3.5, 2.25, 2.656, -3.5, 2.25, 2.656, -7, -7.5, 3.656, -7, 0.8125, 3.656, -3.5, 0.857143, 3.656, -7, -7.5, 3.656, 5.25, -4.25, 3.656, 5.25, -4.25, 3.656, -2.75, -7.5, 3.656, -7, -4.25, 3.656, -2.75, -3.5, 3.656, -3.5, -7.5, 3.656, -7, 9, 0.905995, -2.5, 4.75, 0.905995, -2.5, 4.25, 0.905995, -1.5, -3, 0.905995, 7.25, -9, 0.905995, 7, -9, 0.905995, 9, 9, 0.905995, 9, 4.25, 0.905995, -1.5, -2.25, 0.905995, -1.5, -2.25, 0.905995, 6.5, 9, 0.905995, 9, 9, 0.905995, -2.5, 4.25, 0.905995, -1.5, -2.25, 0.905995, 6.5, -2.25, 0.905995, 6.5, -3, 0.905995, 7.25, 9, 0.905995, 9) +polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1), PackedInt32Array(5, 4, 6), PackedInt32Array(6, 4, 9), PackedInt32Array(6, 9, 7), PackedInt32Array(7, 9, 8), PackedInt32Array(10, 12, 11), PackedInt32Array(15, 14, 18), PackedInt32Array(18, 14, 17), PackedInt32Array(18, 17, 13), PackedInt32Array(18, 13, 16), PackedInt32Array(20, 19, 21), PackedInt32Array(21, 19, 22), PackedInt32Array(25, 24, 23), PackedInt32Array(28, 27, 26), PackedInt32Array(30, 29, 31), PackedInt32Array(31, 29, 32), PackedInt32Array(35, 34, 33), PackedInt32Array(37, 36, 38), PackedInt32Array(38, 36, 39), PackedInt32Array(42, 41, 40)] +agent_radius = 1.0 + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_taqbr"] + +[sub_resource type="Sky" id="Sky_qlesy"] +sky_material = SubResource("ProceduralSkyMaterial_taqbr") + +[sub_resource type="Environment" id="Environment_wd3mo"] +background_mode = 2 +sky = SubResource("Sky_qlesy") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_q83ll"] +transparency = 1 +albedo_color = Color(0.890196, 0.176471, 0.133333, 0.678431) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ubo0r"] +albedo_color = Color(1.15514e-06, 0.522721, 0.747218, 1) + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_3a636"] +radius = 0.6 +height = 2.3 + +[node name="MousePosition3d" type="Node3D"] +script = ExtResource("1_8oqik") +mapping_context = ExtResource("2_bb21n") + +[node name="CameraYaw" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(0.435231, 0, 0.900319, 0, 1, 0, -0.900319, 0, 0.435231, 6.62904, 4.72731, 0) +script = ExtResource("3_4etic") +camera_pitch = ExtResource("4_xr1vq") +camera_yaw = ExtResource("5_mnyiu") +camera_toggle = ExtResource("6_51csy") +camera_move = ExtResource("7_1vbs8") +movement_speed = 8.0 + +[node name="CameraPitch" type="SpringArm3D" parent="CameraYaw"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.984808, 0.173648, 0, -0.173648, 0.984808, 0, 0, 0) +spring_length = 8.0 + +[node name="Camera3D" type="Camera3D" parent="CameraYaw/CameraPitch"] + +[node name="World" type="Node3D" parent="."] + +[node name="NavigationRegion3D" type="NavigationRegion3D" parent="World"] +navigation_mesh = SubResource("NavigationMesh_sfop5") + +[node name="CSGBox3D" type="CSGBox3D" parent="World/NavigationRegion3D"] +use_collision = true +size = Vector3(20, 1, 20) + +[node name="CSGBox3D2" type="CSGBox3D" parent="World/NavigationRegion3D"] +transform = Transform3D(0.80368, 0.595061, 0, -0.595061, 0.80368, 0, 0, 0, 1, 2.07477, 0.832275, -5.22408) +use_collision = true +size = Vector3(5.14954, 2.2251, 5.07178) + +[node name="CSGBox3D3" type="CSGBox3D" parent="World/NavigationRegion3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.8367, 2.1428, -5.22408) +use_collision = true +size = Vector3(9.01666, 2.2251, 5.07178) + +[node name="CSGBox3D4" type="CSGBox3D" parent="World/NavigationRegion3D"] +transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -5.81752, 2.1428, 1.66142) +use_collision = true +size = Vector3(9.01666, 2.2251, 5.07178) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="World"] +environment = SubResource("Environment_wd3mo") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="World"] +transform = Transform3D(1, 0, 0, 0, 0.780496, 0.625161, 0, -0.625161, 0.780496, 0, 4.93937, 0) +shadow_enabled = true + +[node name="MouseIndicator" type="CSGSphere3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.84397, 1.04571, 0) +material = SubResource("StandardMaterial3D_q83ll") +script = ExtResource("3_tunsg") +cursor = ExtResource("4_dla1l") +camera_toggle = ExtResource("6_51csy") + +[node name="CharacterBody3D" type="CharacterBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.26495, 0) +collision_layer = 2 +input_ray_pickable = false +floor_constant_speed = true +script = ExtResource("5_8nflt") +select = ExtResource("6_uviri") +cursor = ExtResource("4_dla1l") + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="CharacterBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.28249, 0) +material = SubResource("StandardMaterial3D_ubo0r") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="CharacterBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.26098, 0) +shape = SubResource("CapsuleShape3D_3a636") + +[node name="NavigationAgent3D" type="NavigationAgent3D" parent="CharacterBody3D"] +unique_name_in_owner = true +debug_enabled = true +debug_use_custom = true +debug_path_custom_color = Color(0.886095, 0.359614, 0.933159, 1) +debug_path_custom_point_size = 7.17 + +[node name="UILayer" type="CanvasLayer" parent="."] + +[node name="RichTextLabel" type="RichTextLabel" parent="UILayer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -104.0 +offset_top = 56.0 +offset_right = -64.0 +offset_bottom = 96.0 +grow_horizontal = 0 +theme = ExtResource("6_lyxvk") +script = ExtResource("12_c4bk3") +instructions_text = "%s to send the agent somewhere. +%s to move the camera. +%s to rotate the camera. +%s to tilt the camera." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("6_uviri"), ExtResource("7_1vbs8"), ExtResource("5_mnyiu"), ExtResource("4_xr1vq")]) + +[node name="DebuggerLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="DebuggerLayer" instance=ExtResource("3_m2gj2")] +theme = ExtResource("6_lyxvk") diff --git a/guide_examples/mouse_position_3d/player.gd b/guide_examples/mouse_position_3d/player.gd new file mode 100644 index 0000000..d2cc190 --- /dev/null +++ b/guide_examples/mouse_position_3d/player.gd @@ -0,0 +1,30 @@ +extends CharacterBody3D + +@export var select:GUIDEAction +@export var cursor:GUIDEAction +@export var speed:float = 5.0 + +@onready var _navigation_agent_3d:NavigationAgent3D = %NavigationAgent3D + +func _ready(): + select.triggered.connect(_new_destination) + +func _physics_process(delta): + if not _navigation_agent_3d.is_navigation_finished(): + var next_pos = _navigation_agent_3d.get_next_path_position() + velocity = global_position.direction_to(next_pos) * speed + else: + velocity = Vector3.ZERO + + if not is_on_floor(): + velocity.y = -9.18 + + move_and_slide() + +func _new_destination(): + var destination = cursor.value_axis_3d + if not destination.is_finite(): + return + _navigation_agent_3d.target_position = destination + + diff --git a/guide_examples/mouse_position_3d/player.gd.uid b/guide_examples/mouse_position_3d/player.gd.uid new file mode 100644 index 0000000..a890acc --- /dev/null +++ b/guide_examples/mouse_position_3d/player.gd.uid @@ -0,0 +1 @@ +uid://kp2vh24w5jih diff --git a/guide_examples/quick_start/game.gd b/guide_examples/quick_start/game.gd new file mode 100644 index 0000000..9412cc8 --- /dev/null +++ b/guide_examples/quick_start/game.gd @@ -0,0 +1,7 @@ +extends Node2D + +## The mapping context that we use +@export var mapping_context:GUIDEMappingContext + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) diff --git a/guide_examples/quick_start/game.gd.uid b/guide_examples/quick_start/game.gd.uid new file mode 100644 index 0000000..94008d1 --- /dev/null +++ b/guide_examples/quick_start/game.gd.uid @@ -0,0 +1 @@ +uid://ceq2p7x1uhe8x diff --git a/guide_examples/quick_start/mapping_contexts/actions/move.tres b/guide_examples/quick_start/mapping_contexts/actions/move.tres new file mode 100644 index 0000000..360a345 --- /dev/null +++ b/guide_examples/quick_start/mapping_contexts/actions/move.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://uscuhd84vv0i"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_mqwm6"] + +[resource] +script = ExtResource("1_mqwm6") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/quick_start/mapping_contexts/actions/say_hi.tres b/guide_examples/quick_start/mapping_contexts/actions/say_hi.tres new file mode 100644 index 0000000..05af31a --- /dev/null +++ b/guide_examples/quick_start/mapping_contexts/actions/say_hi.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://d0dmecppsgpo6"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_ocdl4"] + +[resource] +script = ExtResource("1_ocdl4") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/quick_start/mapping_contexts/quickstart.tres b/guide_examples/quick_start/mapping_contexts/quickstart.tres new file mode 100644 index 0000000..6f36a6f --- /dev/null +++ b/guide_examples/quick_start/mapping_contexts/quickstart.tres @@ -0,0 +1,145 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=27 format=3 uid="uid://b2becclfhsxec"] + +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_1hcuh"] +[ext_resource type="Resource" uid="uid://uscuhd84vv0i" path="res://guide_examples/quick_start/mapping_contexts/actions/move.tres" id="1_5uqll"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_xl7hk"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="3_mr5va"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_input_swizzle.gd" id="4_4a1ev"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="5_1m2pq"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="6_ydpah"] +[ext_resource type="Resource" uid="uid://d0dmecppsgpo6" path="res://guide_examples/quick_start/mapping_contexts/actions/say_hi.tres" id="7_wuqd4"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="8_khp4m"] + +[sub_resource type="Resource" id="Resource_f0kb3"] +script = ExtResource("2_xl7hk") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_fvwu2"] +script = ExtResource("3_mr5va") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_xg24o"] +script = ExtResource("4_4a1ev") +order = 0 + +[sub_resource type="Resource" id="Resource_cgtrg"] +script = ExtResource("5_1m2pq") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_f0kb3") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_fvwu2"), SubResource("Resource_xg24o")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_i7s5n"] +script = ExtResource("2_xl7hk") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_6l7af"] +script = ExtResource("4_4a1ev") +order = 0 + +[sub_resource type="Resource" id="Resource_o72ru"] +script = ExtResource("5_1m2pq") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_i7s5n") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_6l7af")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_4kbei"] +script = ExtResource("2_xl7hk") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_t12km"] +script = ExtResource("3_mr5va") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_3xdyg"] +script = ExtResource("5_1m2pq") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_4kbei") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_t12km")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_uld1v"] +script = ExtResource("2_xl7hk") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_fhxmh"] +script = ExtResource("5_1m2pq") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_uld1v") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_y44kn"] +script = ExtResource("6_ydpah") +action = ExtResource("1_5uqll") +input_mappings = Array[ExtResource("5_1m2pq")]([SubResource("Resource_cgtrg"), SubResource("Resource_o72ru"), SubResource("Resource_3xdyg"), SubResource("Resource_fhxmh")]) + +[sub_resource type="Resource" id="Resource_cl30n"] +script = ExtResource("2_xl7hk") +key = 32 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_31mjc"] +script = ExtResource("8_khp4m") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_dq2sf"] +script = ExtResource("5_1m2pq") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_cl30n") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_31mjc")]) + +[sub_resource type="Resource" id="Resource_7p43t"] +script = ExtResource("6_ydpah") +action = ExtResource("7_wuqd4") +input_mappings = Array[ExtResource("5_1m2pq")]([SubResource("Resource_dq2sf")]) + +[resource] +script = ExtResource("1_1hcuh") +display_name = "" +mappings = Array[ExtResource("6_ydpah")]([SubResource("Resource_y44kn"), SubResource("Resource_7p43t")]) diff --git a/guide_examples/quick_start/player.gd b/guide_examples/quick_start/player.gd new file mode 100644 index 0000000..1d50b4c --- /dev/null +++ b/guide_examples/quick_start/player.gd @@ -0,0 +1,22 @@ +extends Sprite2D + +## The speed at which the player moves. +@export var speed:float = 300 +## The action that moves the player. +@export var move_action:GUIDEAction +## The action that says hi. +@export var say_hi_action:GUIDEAction + +func _ready(): + # Call the `say_hi` function whenever the say_hi_action is triggered. + say_hi_action.triggered.connect(_say_hi) + +func _say_hi(): + # Quickly show and hide message panel + %MessagePanel.visible = true + await get_tree().create_timer(0.5).timeout + %MessagePanel.visible = false + +func _process(delta:float): + # Get the input value from the action and move the player. + position += move_action.value_axis_2d * speed * delta diff --git a/guide_examples/quick_start/player.gd.uid b/guide_examples/quick_start/player.gd.uid new file mode 100644 index 0000000..9d06d51 --- /dev/null +++ b/guide_examples/quick_start/player.gd.uid @@ -0,0 +1 @@ +uid://c0b6whgglitqe diff --git a/guide_examples/quick_start/quick_start.tscn b/guide_examples/quick_start/quick_start.tscn new file mode 100644 index 0000000..a0b2bea --- /dev/null +++ b/guide_examples/quick_start/quick_start.tscn @@ -0,0 +1,32 @@ +[gd_scene load_steps=7 format=3 uid="uid://cye0mxa62e7lh"] + +[ext_resource type="Script" path="res://guide_examples/quick_start/game.gd" id="1_eetgd"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="1_twtcc"] +[ext_resource type="Script" path="res://guide_examples/quick_start/player.gd" id="2_75sqh"] +[ext_resource type="Resource" uid="uid://b2becclfhsxec" path="res://guide_examples/quick_start/mapping_contexts/quickstart.tres" id="2_enypg"] +[ext_resource type="Resource" uid="uid://uscuhd84vv0i" path="res://guide_examples/quick_start/mapping_contexts/actions/move.tres" id="3_nwedj"] +[ext_resource type="Resource" uid="uid://d0dmecppsgpo6" path="res://guide_examples/quick_start/mapping_contexts/actions/say_hi.tres" id="6_xqef5"] + +[node name="QuickStart" type="Node2D"] +script = ExtResource("1_eetgd") +mapping_context = ExtResource("2_enypg") + +[node name="Player" type="Sprite2D" parent="."] +position = Vector2(979, 544) +texture = ExtResource("1_twtcc") +script = ExtResource("2_75sqh") +move_action = ExtResource("3_nwedj") +say_hi_action = ExtResource("6_xqef5") + +[node name="MessagePanel" type="PanelContainer" parent="Player"] +unique_name_in_owner = true +visible = false +offset_left = 38.0 +offset_top = -161.0 +offset_right = 122.0 +offset_bottom = -73.0 + +[node name="Label" type="Label" parent="Player/MessagePanel"] +layout_mode = 2 +theme_override_font_sizes/font_size = 64 +text = "Hi!" diff --git a/guide_examples/remapping/mapping_contexts/binding_controller.tres b/guide_examples/remapping/mapping_contexts/binding_controller.tres new file mode 100644 index 0000000..59b95d1 --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/binding_controller.tres @@ -0,0 +1,147 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=33 format=3 uid="uid://dubuepcs1w17f"] + +[ext_resource type="Resource" uid="uid://bohjda85owgnc" path="res://guide_examples/remapping/mapping_contexts/controller_actions/ui_accept.tres" id="1_rokdq"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="2_30snk"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_ifcmr"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="4_bn4su"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="5_wtinc"] +[ext_resource type="Resource" uid="uid://bcum2m26we6ct" path="res://guide_examples/remapping/mapping_contexts/shared_actions/close_menu.tres" id="6_mbh1l"] +[ext_resource type="Resource" uid="uid://ce3ytxn2tcxxe" path="res://guide_examples/remapping/mapping_contexts/controller_actions/switch_to_keyboard.tres" id="7_e2y7c"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_released.gd" id="7_ofh8l"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_any.gd" id="8_qiw4m"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="9_rcbwk"] +[ext_resource type="Resource" uid="uid://dg1or0do0s1ad" path="res://guide_examples/remapping/mapping_contexts/controller_actions/next_tab.tres" id="10_5tveu"] +[ext_resource type="Resource" uid="uid://cfrx54l1vmjey" path="res://guide_examples/remapping/mapping_contexts/controller_actions/previous_tab.tres" id="11_iu0wm"] + +[sub_resource type="Resource" id="Resource_uri0r"] +script = ExtResource("2_30snk") +button = 0 +joy_index = 0 + +[sub_resource type="Resource" id="Resource_i518v"] +script = ExtResource("7_ofh8l") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_kpld2"] +script = ExtResource("3_ifcmr") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_uri0r") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_i518v")]) + +[sub_resource type="Resource" id="Resource_33xax"] +script = ExtResource("5_wtinc") +action = ExtResource("1_rokdq") +input_mappings = Array[ExtResource("3_ifcmr")]([SubResource("Resource_kpld2")]) + +[sub_resource type="Resource" id="Resource_lu1fr"] +script = ExtResource("2_30snk") +button = 6 +joy_index = 0 + +[sub_resource type="Resource" id="Resource_oikmn"] +script = ExtResource("7_ofh8l") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_lju6e"] +script = ExtResource("3_ifcmr") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_lu1fr") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_oikmn")]) + +[sub_resource type="Resource" id="Resource_djru6"] +script = ExtResource("5_wtinc") +action = ExtResource("6_mbh1l") +input_mappings = Array[ExtResource("3_ifcmr")]([SubResource("Resource_lju6e")]) + +[sub_resource type="Resource" id="Resource_mc0ue"] +script = ExtResource("8_qiw4m") +mouse_buttons = true +mouse_movement = false +minimum_mouse_movement_distance = 1.0 +joy_buttons = false +joy_axes = false +minimum_joy_axis_actuation_strength = 0.2 +keyboard = true +touch = false +mouse = true +joy = false + +[sub_resource type="Resource" id="Resource_vsgae"] +script = ExtResource("4_bn4su") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_vwjgy"] +script = ExtResource("3_ifcmr") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_mc0ue") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_vsgae")]) + +[sub_resource type="Resource" id="Resource_38x5y"] +script = ExtResource("5_wtinc") +action = ExtResource("7_e2y7c") +input_mappings = Array[ExtResource("3_ifcmr")]([SubResource("Resource_vwjgy")]) + +[sub_resource type="Resource" id="Resource_sudy1"] +script = ExtResource("2_30snk") +button = 10 +joy_index = 0 + +[sub_resource type="Resource" id="Resource_4j53a"] +script = ExtResource("4_bn4su") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_1g85d"] +script = ExtResource("3_ifcmr") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_sudy1") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_4j53a")]) + +[sub_resource type="Resource" id="Resource_qsusb"] +script = ExtResource("5_wtinc") +action = ExtResource("10_5tveu") +input_mappings = Array[ExtResource("3_ifcmr")]([SubResource("Resource_1g85d")]) + +[sub_resource type="Resource" id="Resource_dkk46"] +script = ExtResource("2_30snk") +button = 9 +joy_index = 0 + +[sub_resource type="Resource" id="Resource_taj0d"] +script = ExtResource("4_bn4su") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_35h1x"] +script = ExtResource("3_ifcmr") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_dkk46") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_taj0d")]) + +[sub_resource type="Resource" id="Resource_rl360"] +script = ExtResource("5_wtinc") +action = ExtResource("11_iu0wm") +input_mappings = Array[ExtResource("3_ifcmr")]([SubResource("Resource_35h1x")]) + +[resource] +script = ExtResource("9_rcbwk") +display_name = "" +mappings = Array[ExtResource("5_wtinc")]([SubResource("Resource_33xax"), SubResource("Resource_djru6"), SubResource("Resource_38x5y"), SubResource("Resource_qsusb"), SubResource("Resource_rl360")]) diff --git a/guide_examples/remapping/mapping_contexts/binding_keyboard.tres b/guide_examples/remapping/mapping_contexts/binding_keyboard.tres new file mode 100644 index 0000000..9dbaef0 --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/binding_keyboard.tres @@ -0,0 +1,76 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=18 format=3 uid="uid://bqd45wwsetlyg"] + +[ext_resource type="Resource" uid="uid://bcum2m26we6ct" path="res://guide_examples/remapping/mapping_contexts/shared_actions/close_menu.tres" id="1_j25bp"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_a3vaw"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_n037t"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_released.gd" id="4_008yb"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="4_t70fr"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="5_xuekb"] +[ext_resource type="Resource" uid="uid://3vqfs786vcsa" path="res://guide_examples/remapping/mapping_contexts/keyboard_actions/switch_to_controller.tres" id="6_lkk3b"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="6_rsvyd"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_any.gd" id="7_b4hkn"] + +[sub_resource type="Resource" id="Resource_rqm6k"] +script = ExtResource("2_a3vaw") +key = 4194305 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_yfr8v"] +script = ExtResource("4_008yb") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_lju6e"] +script = ExtResource("3_n037t") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_rqm6k") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_yfr8v")]) + +[sub_resource type="Resource" id="Resource_djru6"] +script = ExtResource("5_xuekb") +action = ExtResource("1_j25bp") +input_mappings = Array[ExtResource("3_n037t")]([SubResource("Resource_lju6e")]) + +[sub_resource type="Resource" id="Resource_mpqi8"] +script = ExtResource("7_b4hkn") +mouse_buttons = false +mouse_movement = false +minimum_mouse_movement_distance = 1.0 +joy_buttons = true +joy_axes = false +minimum_joy_axis_actuation_strength = 0.2 +keyboard = false +touch = false +mouse = false +joy = true + +[sub_resource type="Resource" id="Resource_4apa3"] +script = ExtResource("4_t70fr") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_0hgmj"] +script = ExtResource("3_n037t") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_mpqi8") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_4apa3")]) + +[sub_resource type="Resource" id="Resource_2neno"] +script = ExtResource("5_xuekb") +action = ExtResource("6_lkk3b") +input_mappings = Array[ExtResource("3_n037t")]([SubResource("Resource_0hgmj")]) + +[resource] +script = ExtResource("6_rsvyd") +display_name = "" +mappings = Array[ExtResource("5_xuekb")]([SubResource("Resource_djru6"), SubResource("Resource_2neno")]) diff --git a/guide_examples/remapping/mapping_contexts/controller.tres b/guide_examples/remapping/mapping_contexts/controller.tres new file mode 100644 index 0000000..e30704b --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/controller.tres @@ -0,0 +1,127 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=31 format=3 uid="uid://bexjevffjsh3i"] + +[ext_resource type="Resource" uid="uid://chhw5umkd1j2p" path="res://guide_examples/remapping/mapping_contexts/shared_actions/player_movement_2d.tres" id="1_78yyx"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_l4253"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_deadzone.gd" id="3_rbwxh"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="4_m37gr"] +[ext_resource type="Resource" uid="uid://qikyr1rgxw2l" path="res://guide_examples/remapping/mapping_contexts/controller_actions/player_movement_stick_invert.tres" id="4_qbgwt"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="5_167oa"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_axis_2d.gd" id="6_y041f"] +[ext_resource type="Resource" uid="uid://ce3ytxn2tcxxe" path="res://guide_examples/remapping/mapping_contexts/controller_actions/switch_to_keyboard.tres" id="8_4d4ov"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_any.gd" id="9_0d1uf"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_released.gd" id="9_eexjp"] +[ext_resource type="Resource" uid="uid://c65tsmp268vdq" path="res://guide_examples/remapping/mapping_contexts/shared_actions/open_menu.tres" id="9_l4c4j"] +[ext_resource type="Resource" uid="uid://b1iaet1m2gi2e" path="res://guide_examples/remapping/mapping_contexts/shared_actions/fire.tres" id="9_tkveh"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="10_a30o8"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="11_avbpy"] + +[sub_resource type="Resource" id="Resource_nr3w6"] +script = ExtResource("6_y041f") +x = 0 +y = 1 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_towa1"] +script = ExtResource("3_rbwxh") +lower_threshold = 0.2 +upper_threshold = 1.0 + +[sub_resource type="Resource" id="Resource_gpn8l"] +script = ExtResource("4_m37gr") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_nr3w6") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_towa1"), ExtResource("4_qbgwt")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_6h1my"] +script = ExtResource("5_167oa") +action = ExtResource("1_78yyx") +input_mappings = Array[ExtResource("4_m37gr")]([SubResource("Resource_gpn8l")]) + +[sub_resource type="Resource" id="Resource_p73kx"] +script = ExtResource("10_a30o8") +button = 6 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_uov21"] +script = ExtResource("9_eexjp") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_f4p62"] +script = ExtResource("4_m37gr") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_p73kx") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_uov21")]) + +[sub_resource type="Resource" id="Resource_wa31m"] +script = ExtResource("5_167oa") +action = ExtResource("9_l4c4j") +input_mappings = Array[ExtResource("4_m37gr")]([SubResource("Resource_f4p62")]) + +[sub_resource type="Resource" id="Resource_iwnk1"] +script = ExtResource("9_0d1uf") +mouse_buttons = false +mouse_movement = false +minimum_mouse_movement_distance = 1.0 +joy_buttons = false +joy_axes = false +minimum_joy_axis_actuation_strength = 0.2 +keyboard = true +touch = false +mouse = false +joy = false + +[sub_resource type="Resource" id="Resource_jwpon"] +script = ExtResource("11_avbpy") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_limxc"] +script = ExtResource("4_m37gr") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_iwnk1") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_jwpon")]) + +[sub_resource type="Resource" id="Resource_rtwk8"] +script = ExtResource("5_167oa") +action = ExtResource("8_4d4ov") +input_mappings = Array[ExtResource("4_m37gr")]([SubResource("Resource_limxc")]) + +[sub_resource type="Resource" id="Resource_tsvy3"] +script = ExtResource("10_a30o8") +button = 0 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_qvmci"] +script = ExtResource("11_avbpy") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_hf22v"] +script = ExtResource("4_m37gr") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_tsvy3") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_qvmci")]) + +[sub_resource type="Resource" id="Resource_t70e5"] +script = ExtResource("5_167oa") +action = ExtResource("9_tkveh") +input_mappings = Array[ExtResource("4_m37gr")]([SubResource("Resource_hf22v")]) + +[resource] +script = ExtResource("1_l4253") +display_name = "" +mappings = Array[ExtResource("5_167oa")]([SubResource("Resource_6h1my"), SubResource("Resource_wa31m"), SubResource("Resource_rtwk8"), SubResource("Resource_t70e5")]) diff --git a/guide_examples/remapping/mapping_contexts/controller_actions/next_tab.tres b/guide_examples/remapping/mapping_contexts/controller_actions/next_tab.tres new file mode 100644 index 0000000..bcb3748 --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/controller_actions/next_tab.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://dg1or0do0s1ad"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_432ak"] + +[resource] +script = ExtResource("1_432ak") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/remapping/mapping_contexts/controller_actions/player_movement_stick_invert.tres b/guide_examples/remapping/mapping_contexts/controller_actions/player_movement_stick_invert.tres new file mode 100644 index 0000000..a583d40 --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/controller_actions/player_movement_stick_invert.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="GUIDEModifierNegate" load_steps=2 format=3 uid="uid://qikyr1rgxw2l"] + +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="1_geiqh"] + +[resource] +script = ExtResource("1_geiqh") +x = false +y = false +z = false diff --git a/guide_examples/remapping/mapping_contexts/controller_actions/previous_tab.tres b/guide_examples/remapping/mapping_contexts/controller_actions/previous_tab.tres new file mode 100644 index 0000000..be266f8 --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/controller_actions/previous_tab.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cfrx54l1vmjey"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_mbx72"] + +[resource] +script = ExtResource("1_mbx72") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/remapping/mapping_contexts/controller_actions/switch_to_keyboard.tres b/guide_examples/remapping/mapping_contexts/controller_actions/switch_to_keyboard.tres new file mode 100644 index 0000000..49d5db2 --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/controller_actions/switch_to_keyboard.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://ce3ytxn2tcxxe"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_gwq63"] + +[resource] +script = ExtResource("1_gwq63") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/remapping/mapping_contexts/controller_actions/ui_accept.tres b/guide_examples/remapping/mapping_contexts/controller_actions/ui_accept.tres new file mode 100644 index 0000000..ccbc3ba --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/controller_actions/ui_accept.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bohjda85owgnc"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_laec0"] + +[resource] +script = ExtResource("1_laec0") +name = &"ui_accept" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = true +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/remapping/mapping_contexts/keyboard.tres b/guide_examples/remapping/mapping_contexts/keyboard.tres new file mode 100644 index 0000000..6d51f3c --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/keyboard.tres @@ -0,0 +1,208 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=38 format=3 uid="uid://cu0dhstc00cj5"] + +[ext_resource type="Resource" uid="uid://chhw5umkd1j2p" path="res://guide_examples/remapping/mapping_contexts/shared_actions/player_movement_2d.tres" id="1_uy1j0"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="4_5oaiq"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="5_d2nln"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_input_swizzle.gd" id="8_vp516"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="10_xpxg7"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="12_msrvd"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_released.gd" id="13_11jxi"] +[ext_resource type="Resource" uid="uid://c65tsmp268vdq" path="res://guide_examples/remapping/mapping_contexts/shared_actions/open_menu.tres" id="13_m7li8"] +[ext_resource type="Resource" uid="uid://3vqfs786vcsa" path="res://guide_examples/remapping/mapping_contexts/keyboard_actions/switch_to_controller.tres" id="14_57mry"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="14_gcar0"] +[ext_resource type="Resource" uid="uid://b1iaet1m2gi2e" path="res://guide_examples/remapping/mapping_contexts/shared_actions/fire.tres" id="15_7eor3"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_any.gd" id="15_51tw7"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="15_qjsfb"] + +[sub_resource type="Resource" id="Resource_d5vxv"] +script = ExtResource("12_msrvd") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_d5crb"] +script = ExtResource("8_vp516") +order = 0 + +[sub_resource type="Resource" id="Resource_cwfnu"] +script = ExtResource("4_5oaiq") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_u7h55"] +script = ExtResource("5_d2nln") +override_action_settings = true +is_remappable = true +display_name = "Up" +display_category = "" +input = SubResource("Resource_d5vxv") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_d5crb"), SubResource("Resource_cwfnu")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_syl0m"] +script = ExtResource("12_msrvd") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_8rcpo"] +script = ExtResource("8_vp516") +order = 0 + +[sub_resource type="Resource" id="Resource_te6bu"] +script = ExtResource("5_d2nln") +override_action_settings = true +is_remappable = true +display_name = "Down" +display_category = "" +input = SubResource("Resource_syl0m") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_8rcpo")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_erj62"] +script = ExtResource("12_msrvd") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_84clu"] +script = ExtResource("4_5oaiq") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_ho2kd"] +script = ExtResource("5_d2nln") +override_action_settings = true +is_remappable = true +display_name = "Left" +display_category = "" +input = SubResource("Resource_erj62") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_84clu")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_ybtim"] +script = ExtResource("12_msrvd") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_bnk54"] +script = ExtResource("5_d2nln") +override_action_settings = true +is_remappable = true +display_name = "Right" +display_category = "" +input = SubResource("Resource_ybtim") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_358t4"] +script = ExtResource("10_xpxg7") +action = ExtResource("1_uy1j0") +input_mappings = Array[ExtResource("5_d2nln")]([SubResource("Resource_u7h55"), SubResource("Resource_te6bu"), SubResource("Resource_ho2kd"), SubResource("Resource_bnk54")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_la24a"] +script = ExtResource("12_msrvd") +key = 4194305 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_dbmrn"] +script = ExtResource("13_11jxi") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_wr8lq"] +script = ExtResource("5_d2nln") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_la24a") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_dbmrn")]) + +[sub_resource type="Resource" id="Resource_iwmfr"] +script = ExtResource("10_xpxg7") +action = ExtResource("13_m7li8") +input_mappings = Array[ExtResource("5_d2nln")]([SubResource("Resource_wr8lq")]) +metadata/_guide_input_mappings_collapsed = false + +[sub_resource type="Resource" id="Resource_ke2lc"] +script = ExtResource("15_51tw7") +mouse_buttons = false +mouse_movement = false +minimum_mouse_movement_distance = 1.0 +joy_buttons = true +joy_axes = false +minimum_joy_axis_actuation_strength = 0.2 +keyboard = false +touch = false +mouse = false +joy = true + +[sub_resource type="Resource" id="Resource_oh8td"] +script = ExtResource("5_d2nln") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_ke2lc") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_unkjf"] +script = ExtResource("10_xpxg7") +action = ExtResource("14_57mry") +input_mappings = Array[ExtResource("5_d2nln")]([SubResource("Resource_oh8td")]) + +[sub_resource type="Resource" id="Resource_h3p6j"] +script = ExtResource("12_msrvd") +key = 32 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_saax4"] +script = ExtResource("14_gcar0") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_nm3w5"] +script = ExtResource("5_d2nln") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_h3p6j") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_saax4")]) + +[sub_resource type="Resource" id="Resource_cv74y"] +script = ExtResource("10_xpxg7") +action = ExtResource("15_7eor3") +input_mappings = Array[ExtResource("5_d2nln")]([SubResource("Resource_nm3w5")]) +metadata/_guide_input_mappings_collapsed = false + +[resource] +script = ExtResource("15_qjsfb") +display_name = "Keyboard and Mouse" +mappings = Array[ExtResource("10_xpxg7")]([SubResource("Resource_358t4"), SubResource("Resource_iwmfr"), SubResource("Resource_unkjf"), SubResource("Resource_cv74y")]) diff --git a/guide_examples/remapping/mapping_contexts/keyboard_actions/switch_to_controller.tres b/guide_examples/remapping/mapping_contexts/keyboard_actions/switch_to_controller.tres new file mode 100644 index 0000000..627ddc4 --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/keyboard_actions/switch_to_controller.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://3vqfs786vcsa"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_ahfs1"] + +[resource] +script = ExtResource("1_ahfs1") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/remapping/mapping_contexts/shared_actions/close_menu.tres b/guide_examples/remapping/mapping_contexts/shared_actions/close_menu.tres new file mode 100644 index 0000000..2b2371e --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/shared_actions/close_menu.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bcum2m26we6ct"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_q87d1"] + +[resource] +script = ExtResource("1_q87d1") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/remapping/mapping_contexts/shared_actions/fire.tres b/guide_examples/remapping/mapping_contexts/shared_actions/fire.tres new file mode 100644 index 0000000..394fd79 --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/shared_actions/fire.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://b1iaet1m2gi2e"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_d1iw0"] + +[resource] +script = ExtResource("1_d1iw0") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = true +display_name = "Fire" +display_category = "Player Actions" diff --git a/guide_examples/remapping/mapping_contexts/shared_actions/open_menu.tres b/guide_examples/remapping/mapping_contexts/shared_actions/open_menu.tres new file mode 100644 index 0000000..8a17ab3 --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/shared_actions/open_menu.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://c65tsmp268vdq"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_rdx5a"] + +[resource] +script = ExtResource("1_rdx5a") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/remapping/mapping_contexts/shared_actions/player_movement_2d.tres b/guide_examples/remapping/mapping_contexts/shared_actions/player_movement_2d.tres new file mode 100644 index 0000000..c61263f --- /dev/null +++ b/guide_examples/remapping/mapping_contexts/shared_actions/player_movement_2d.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://chhw5umkd1j2p"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_ecpj4"] + +[resource] +script = ExtResource("1_ecpj4") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = true +display_name = "" +display_category = "Player Actions" diff --git a/guide_examples/remapping/player.gd b/guide_examples/remapping/player.gd new file mode 100644 index 0000000..72cec67 --- /dev/null +++ b/guide_examples/remapping/player.gd @@ -0,0 +1,24 @@ +## This is the player script. Note how it has no clue about controllers, axis inversion +## etc. This is all handled by GUIDE and the remapping dialog. +extends Node2D + +@export var speed:float = 300 +@export var move_action:GUIDEAction +@export var fire_action:GUIDEAction + +@export var fireball_scene:PackedScene + +func _ready(): + fire_action.triggered.connect(_shoot_fireball) + + +func _process(delta:float) -> void: + position += move_action.value_axis_2d.normalized() * speed * delta + + +func _shoot_fireball(): + var fireball = fireball_scene.instantiate() + fireball.direction = Vector2.UP + get_parent().add_child(fireball) + + fireball.global_transform = global_transform diff --git a/guide_examples/remapping/player.gd.uid b/guide_examples/remapping/player.gd.uid new file mode 100644 index 0000000..76fa85f --- /dev/null +++ b/guide_examples/remapping/player.gd.uid @@ -0,0 +1 @@ +uid://bhn2nskt2cgym diff --git a/guide_examples/remapping/remapping.gd b/guide_examples/remapping/remapping.gd new file mode 100644 index 0000000..3b99891 --- /dev/null +++ b/guide_examples/remapping/remapping.gd @@ -0,0 +1,57 @@ +## This is the main game controller. It enables a control scheme at the start and is +## responsible for controlling the remapping dialog. +extends Node + +const Utils = preload("utils.gd") + +@export_group("Context & Modifiers") +@export var keyboard:GUIDEMappingContext +@export var controller:GUIDEMappingContext +@export var controller_axis_invert_modifier:GUIDEModifierNegate + +@export_group("Actions") +@export var switch_to_keyboard:GUIDEAction +@export var switch_to_controller:GUIDEAction +@export var open_menu:GUIDEAction + + +@onready var _remapping_dialog:Control = %RemappingDialog + +func _ready(): + # React when the open menu action is triggered. + open_menu.triggered.connect(_open_menu) + + # and switching to controller / keyboard ... + switch_to_controller.triggered.connect(_switch.bind(controller)) + switch_to_keyboard.triggered.connect(_switch.bind(keyboard)) + + # Also listen to when the remapping dialog closes and re-apply the changed + # mapping config + _remapping_dialog.closed.connect(_load_remapping_config) + + # Start with the keyboard scheme + GUIDE.enable_mapping_context(keyboard) + + # finally enable all controls with the last saved remapping configuration + _load_remapping_config(Utils.load_remapping_config()) + + +func _open_menu() -> void: + # and show the remapping dialog + _remapping_dialog.open() + + +func _load_remapping_config(config:GUIDERemappingConfig): + GUIDE.set_remapping_config(config) + + # also apply changes to our modifiers + controller_axis_invert_modifier.x = config.custom_data.get(Utils.CUSTOM_DATA_INVERT_HORIZONTAL, false) + controller_axis_invert_modifier.y = config.custom_data.get(Utils.CUSTOM_DATA_INVERT_VERTICAL, false) + + +func _switch(context:GUIDEMappingContext): + # ignore while remapping is active, remapping will take care of it + if _remapping_dialog.visible: + return + + GUIDE.enable_mapping_context(context, true) diff --git a/guide_examples/remapping/remapping.gd.uid b/guide_examples/remapping/remapping.gd.uid new file mode 100644 index 0000000..f7e0634 --- /dev/null +++ b/guide_examples/remapping/remapping.gd.uid @@ -0,0 +1 @@ +uid://ba5134rplb4y diff --git a/guide_examples/remapping/remapping.tscn b/guide_examples/remapping/remapping.tscn new file mode 100644 index 0000000..5016c47 --- /dev/null +++ b/guide_examples/remapping/remapping.tscn @@ -0,0 +1,67 @@ +[gd_scene load_steps=17 format=3 uid="uid://gjweqc0stfqh"] + +[ext_resource type="Script" path="res://guide_examples/remapping/remapping.gd" id="1_3d1tp"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="1_gkmxq"] +[ext_resource type="Resource" uid="uid://qikyr1rgxw2l" path="res://guide_examples/remapping/mapping_contexts/controller_actions/player_movement_stick_invert.tres" id="2_3dav4"] +[ext_resource type="Resource" uid="uid://cu0dhstc00cj5" path="res://guide_examples/remapping/mapping_contexts/keyboard.tres" id="2_issuo"] +[ext_resource type="Script" path="res://guide_examples/remapping/player.gd" id="2_n3drv"] +[ext_resource type="Resource" uid="uid://bexjevffjsh3i" path="res://guide_examples/remapping/mapping_contexts/controller.tres" id="3_apwxt"] +[ext_resource type="Resource" uid="uid://c65tsmp268vdq" path="res://guide_examples/remapping/mapping_contexts/shared_actions/open_menu.tres" id="3_g1dlj"] +[ext_resource type="Resource" uid="uid://chhw5umkd1j2p" path="res://guide_examples/remapping/mapping_contexts/shared_actions/player_movement_2d.tres" id="4_07jn1"] +[ext_resource type="Resource" uid="uid://ce3ytxn2tcxxe" path="res://guide_examples/remapping/mapping_contexts/controller_actions/switch_to_keyboard.tres" id="5_aqwgr"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="5_kdgir"] +[ext_resource type="Resource" uid="uid://b1iaet1m2gi2e" path="res://guide_examples/remapping/mapping_contexts/shared_actions/fire.tres" id="6_esnhm"] +[ext_resource type="Resource" uid="uid://3vqfs786vcsa" path="res://guide_examples/remapping/mapping_contexts/keyboard_actions/switch_to_controller.tres" id="6_jncg0"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="7_8t2l7"] +[ext_resource type="PackedScene" uid="uid://bq0w7uaotgfct" path="res://guide_examples/remapping/ui/remapping_dialog.tscn" id="7_g0vxv"] +[ext_resource type="PackedScene" uid="uid://c36cnvgv2ur60" path="res://guide_examples/shared/fireball/fireball.tscn" id="7_w2y2e"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="14_e0a18"] + +[node name="Remapping" type="Node"] +script = ExtResource("1_3d1tp") +keyboard = ExtResource("2_issuo") +controller = ExtResource("3_apwxt") +controller_axis_invert_modifier = ExtResource("2_3dav4") +switch_to_keyboard = ExtResource("5_aqwgr") +switch_to_controller = ExtResource("6_jncg0") +open_menu = ExtResource("3_g1dlj") + +[node name="Player" type="Sprite2D" parent="."] +position = Vector2(546, 317) +texture = ExtResource("1_gkmxq") +script = ExtResource("2_n3drv") +move_action = ExtResource("4_07jn1") +fire_action = ExtResource("6_esnhm") +fireball_scene = ExtResource("7_w2y2e") + +[node name="HUD Layer" type="CanvasLayer" parent="."] + +[node name="Label" type="RichTextLabel" parent="HUD Layer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -16.0 +offset_top = 12.0 +offset_right = -15.0 +offset_bottom = 12.0 +grow_horizontal = 0 +theme = ExtResource("7_8t2l7") +bbcode_enabled = true +fit_content = true +autowrap_mode = 0 +script = ExtResource("14_e0a18") +instructions_text = "Use %s to move. +Press %s to fire a fireball. +Press %s to change input mappings." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("4_07jn1"), ExtResource("6_esnhm"), ExtResource("3_g1dlj")]) + +[node name="UI Layer" type="CanvasLayer" parent="."] + +[node name="RemappingDialog" parent="UI Layer" instance=ExtResource("7_g0vxv")] +unique_name_in_owner = true +visible = false + +[node name="DebugLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="DebugLayer" instance=ExtResource("5_kdgir")] +theme = ExtResource("7_8t2l7") diff --git a/guide_examples/remapping/ui/binding_row.gd b/guide_examples/remapping/ui/binding_row.gd new file mode 100644 index 0000000..c8d3597 --- /dev/null +++ b/guide_examples/remapping/ui/binding_row.gd @@ -0,0 +1,29 @@ +extends HBoxContainer + + +signal rebind(item:GUIDERemapper.ConfigItem) + +@onready var _action_name:Button = %ActionName +@onready var _action_binding:RichTextLabel = %ActionBinding + +var _formatter:GUIDEInputFormatter = GUIDEInputFormatter.new(48) +var _item:GUIDERemapper.ConfigItem + +func initialize(item:GUIDERemapper.ConfigItem, input:GUIDEInput): + _item = item + _action_name.text = item.display_name + _item.changed.connect(_show_input) + _show_input(input) + + +func _on_action_name_pressed(): + if _item != null: + rebind.emit(_item) + + +func _show_input(input:GUIDEInput): + if input != null: + var text = await _formatter.input_as_richtext_async(input) + _action_binding.parse_bbcode(text) + else: + _action_binding.parse_bbcode("") diff --git a/guide_examples/remapping/ui/binding_row.gd.uid b/guide_examples/remapping/ui/binding_row.gd.uid new file mode 100644 index 0000000..25b19c9 --- /dev/null +++ b/guide_examples/remapping/ui/binding_row.gd.uid @@ -0,0 +1 @@ +uid://cfukq2iogf0k4 diff --git a/guide_examples/remapping/ui/binding_row.tscn b/guide_examples/remapping/ui/binding_row.tscn new file mode 100644 index 0000000..e2670f9 --- /dev/null +++ b/guide_examples/remapping/ui/binding_row.tscn @@ -0,0 +1,32 @@ +[gd_scene load_steps=2 format=3 uid="uid://bme1y0ikthda7"] + +[ext_resource type="Script" path="res://guide_examples/remapping/ui/binding_row.gd" id="1_mc50g"] + +[node name="BindingRow" type="HBoxContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/separation = 10 +script = ExtResource("1_mc50g") + +[node name="ActionName" type="Button" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 10 +text = "Lorem ipsum" +flat = true + +[node name="ActionBinding" type="RichTextLabel" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 2 +size_flags_vertical = 4 +bbcode_enabled = true +fit_content = true +scroll_active = false +autowrap_mode = 0 +shortcut_keys_enabled = false + +[connection signal="pressed" from="ActionName" to="." method="_on_action_name_pressed"] diff --git a/guide_examples/remapping/ui/binding_section.gd b/guide_examples/remapping/ui/binding_section.gd new file mode 100644 index 0000000..7e9f41d --- /dev/null +++ b/guide_examples/remapping/ui/binding_section.gd @@ -0,0 +1,18 @@ +@tool +extends MarginContainer + +@onready var _label:Label = %Label + +@export var text:String: + set(value): + text = value + _refresh() + + +func _ready(): + _refresh() + +func _refresh(): + if _label != null: + _label.text = text + diff --git a/guide_examples/remapping/ui/binding_section.gd.uid b/guide_examples/remapping/ui/binding_section.gd.uid new file mode 100644 index 0000000..b1402ff --- /dev/null +++ b/guide_examples/remapping/ui/binding_section.gd.uid @@ -0,0 +1 @@ +uid://dt4gdj0rt5mnw diff --git a/guide_examples/remapping/ui/binding_section.tscn b/guide_examples/remapping/ui/binding_section.tscn new file mode 100644 index 0000000..539eaf7 --- /dev/null +++ b/guide_examples/remapping/ui/binding_section.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=3 format=3 uid="uid://cj1h0wxamje4s"] + +[ext_resource type="Script" path="res://guide_examples/remapping/ui/binding_section.gd" id="1_hoxsv"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_h8l7u"] +bg_color = Color(0.355314, 0.355314, 0.355313, 1) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[node name="MarginContainer" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_top = 10 +theme_override_constants/margin_bottom = 10 +script = ExtResource("1_hoxsv") + +[node name="Panel" type="Panel" parent="."] +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_h8l7u") + +[node name="BindingSection" type="MarginContainer" parent="."] +layout_mode = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="Label" type="Label" parent="BindingSection"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_font_sizes/font_size = 22 diff --git a/guide_examples/remapping/ui/remapping_dialog.gd b/guide_examples/remapping/ui/remapping_dialog.gd new file mode 100644 index 0000000..04cb0d8 --- /dev/null +++ b/guide_examples/remapping/ui/remapping_dialog.gd @@ -0,0 +1,198 @@ +## The remapping dialog. +extends MarginContainer + +signal closed(applied_config:GUIDERemappingConfig) + +const Utils = preload("../utils.gd") + +# Input +@export var keyboard_context:GUIDEMappingContext +@export var controller_context:GUIDEMappingContext +@export var binding_keyboard_context:GUIDEMappingContext +@export var binding_controller_context:GUIDEMappingContext +@export var close_dialog:GUIDEAction +@export var switch_to_controller:GUIDEAction +@export var switch_to_keyboard:GUIDEAction +@export var previous_tab:GUIDEAction +@export var next_tab:GUIDEAction + +# UI +@export var binding_row_scene:PackedScene +@export var binding_section_scene:PackedScene + +@onready var _keyboard_bindings:Container = %KeyboardBindings +@onready var _controller_bindings:Container = %ControllerBindings +@onready var _press_prompt:Control = %PressPrompt +@onready var _controller_invert_horizontal:CheckBox = %ControllerInvertHorizontal +@onready var _controller_invert_vertical:CheckBox = %ControllerInvertVertical +@onready var _tab_container:TabContainer = %TabContainer + +## The input detector for detecting new input +@onready var _input_detector:GUIDEInputDetector = %GUIDEInputDetector + +## The remapper, helps us quickly remap inputs. +var _remapper:GUIDERemapper = GUIDERemapper.new() + +## The config we're currently working on +var _remapping_config:GUIDERemappingConfig + +## The last control that was focused when we started input detection. +## Used to restore focus afterwards. +var _focused_control:Control = null + +func _ready(): + # connect the actions that the remapping dialog uses + close_dialog.triggered.connect(_on_close_dialog) + switch_to_controller.triggered.connect(_switch.bind(binding_controller_context)) + switch_to_keyboard.triggered.connect(_switch.bind(binding_keyboard_context)) + previous_tab.triggered.connect(_switch_tab.bind(-1)) + next_tab.triggered.connect(_switch_tab.bind(1)) + + +func open(): + # switch the tab to the scheme that is currently enabled + # to make life a bit easier for the player, and also + # enable the correct mapping context for the binding dialog + if GUIDE.is_mapping_context_enabled(controller_context): + _tab_container.current_tab = 1 + GUIDE.enable_mapping_context(binding_controller_context, true) + else: + _tab_container.current_tab = 0 + GUIDE.enable_mapping_context(binding_keyboard_context, true) + + # todo provide specific actions for the tab bar controller + _tab_container.get_tab_bar().grab_focus() + + # Open the user's last edited remapping config, if it exists + _remapping_config = Utils.load_remapping_config() + + # And initialize the remapper + _remapper.initialize([keyboard_context, controller_context], _remapping_config) + + _clear(_keyboard_bindings) + _clear(_controller_bindings) + + # fill the keyboard section + _fill_remappable_items(keyboard_context, _keyboard_bindings) + + # fill the controller section + _fill_remappable_items(controller_context, _controller_bindings) + + _controller_invert_horizontal.button_pressed = _remapper.get_custom_data("invert_horizontal", false) + _controller_invert_vertical.button_pressed = _remapper.get_custom_data("invert_vertical", false) + + + visible = true + + +## Fills remappable items and sub-sections into the given container +func _fill_remappable_items(context:GUIDEMappingContext, root:Container): + var items := _remapper.get_remappable_items(context) + var section_name = "" + for item in items: + if item.display_category != section_name: + section_name = item.display_category + var section = binding_section_scene.instantiate() + root.add_child(section) + section.text = section_name + + var instance = binding_row_scene.instantiate() + root.add_child(instance) + + # Show the current binding. + instance.initialize(item, _remapper.get_bound_input_or_null(item)) + instance.rebind.connect(_rebind_item) + + + +func _rebind_item(item:GUIDERemapper.ConfigItem): + _focused_control = get_viewport().gui_get_focus_owner() + _focused_control.release_focus() + + _press_prompt.visible = true + + # Limit the devices that we can detect based on which + # mapping context we're currently working on. So + # for keyboard only keys can be bound and for controller + # only controller buttons can be bound. + var device := GUIDEInputDetector.DeviceType.KEYBOARD + if item.context == controller_context: + device = GUIDEInputDetector.DeviceType.JOY + + # detect a new input + _input_detector.detect(item.value_type, [device]) + var input = await _input_detector.input_detected + + _press_prompt.visible = false + + _focused_control.grab_focus() + + # check if the detection was aborted. + if input == null: + return + + # check for collisions + var collisions := _remapper.get_input_collisions(item, input) + + # if any collision is from a non-bindable mapping, we cannot use this input + if collisions.any(func(it:GUIDERemapper.ConfigItem): return not it.is_remappable): + return + + # unbind the colliding entries. + for collision in collisions: + _remapper.set_bound_input(collision, null) + + # now bind the new input + _remapper.set_bound_input(item, input) + + + +func _clear(root:Container): + for child in root.get_children(): + root.remove_child(child) + child.queue_free() + + +func _on_abort_detection(): + _input_detector.abort_detection() + +func _on_close_dialog(): + if _input_detector.is_detecting: + return + # same as pressing return to game + _on_return_to_game_pressed() + +func _on_controller_invert_horizontal_toggled(toggled_on:bool): + _remapper.set_custom_data(Utils.CUSTOM_DATA_INVERT_HORIZONTAL, toggled_on) + + +func _on_controller_invert_vertical_toggled(toggled_on:bool): + _remapper.set_custom_data(Utils.CUSTOM_DATA_INVERT_VERTICAL, toggled_on) + + +func _on_return_to_game_pressed(): + # get the modified config + var final_config := _remapper.get_mapping_config() + # store it + Utils.save_remapping_config(final_config) + + # restore main mapping context based on what is currently active + if GUIDE.is_mapping_context_enabled(binding_keyboard_context): + GUIDE.enable_mapping_context(keyboard_context, true) + else: + GUIDE.enable_mapping_context(controller_context, true) + + # and close the dialog + visible = false + closed.emit(final_config) + + +func _switch_tab(index:int): + _tab_container.current_tab = posmod(_tab_container.current_tab + index, 2) + +func _switch(context:GUIDEMappingContext): + # only do this when the dialog is visible + if not visible: + return + + GUIDE.enable_mapping_context(context, true) diff --git a/guide_examples/remapping/ui/remapping_dialog.gd.uid b/guide_examples/remapping/ui/remapping_dialog.gd.uid new file mode 100644 index 0000000..dcd820e --- /dev/null +++ b/guide_examples/remapping/ui/remapping_dialog.gd.uid @@ -0,0 +1 @@ +uid://5crxnd8ysf6 diff --git a/guide_examples/remapping/ui/remapping_dialog.tscn b/guide_examples/remapping/ui/remapping_dialog.tscn new file mode 100644 index 0000000..00bde01 --- /dev/null +++ b/guide_examples/remapping/ui/remapping_dialog.tscn @@ -0,0 +1,224 @@ +[gd_scene load_steps=21 format=3 uid="uid://bq0w7uaotgfct"] + +[ext_resource type="Script" path="res://guide_examples/remapping/ui/remapping_dialog.gd" id="1_6hgqj"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="1_uhsj0"] +[ext_resource type="Resource" uid="uid://cu0dhstc00cj5" path="res://guide_examples/remapping/mapping_contexts/keyboard.tres" id="2_cgour"] +[ext_resource type="Script" path="res://addons/guide/remapping/guide_input_detector.gd" id="3_o0nvn"] +[ext_resource type="Resource" uid="uid://bexjevffjsh3i" path="res://guide_examples/remapping/mapping_contexts/controller.tres" id="3_tgkdx"] +[ext_resource type="PackedScene" uid="uid://bme1y0ikthda7" path="res://guide_examples/remapping/ui/binding_row.tscn" id="4_iojgu"] +[ext_resource type="PackedScene" uid="uid://cj1h0wxamje4s" path="res://guide_examples/remapping/ui/binding_section.tscn" id="5_8v80s"] +[ext_resource type="Resource" uid="uid://bqd45wwsetlyg" path="res://guide_examples/remapping/mapping_contexts/binding_keyboard.tres" id="5_tw3jw"] +[ext_resource type="Resource" uid="uid://dubuepcs1w17f" path="res://guide_examples/remapping/mapping_contexts/binding_controller.tres" id="6_gdrkn"] +[ext_resource type="Resource" uid="uid://bcum2m26we6ct" path="res://guide_examples/remapping/mapping_contexts/shared_actions/close_menu.tres" id="7_djty7"] +[ext_resource type="Resource" uid="uid://3vqfs786vcsa" path="res://guide_examples/remapping/mapping_contexts/keyboard_actions/switch_to_controller.tres" id="8_lj8gw"] +[ext_resource type="Resource" uid="uid://ce3ytxn2tcxxe" path="res://guide_examples/remapping/mapping_contexts/controller_actions/switch_to_keyboard.tres" id="9_brmt1"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="10_xsw70"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="11_e078a"] +[ext_resource type="Resource" uid="uid://cfrx54l1vmjey" path="res://guide_examples/remapping/mapping_contexts/controller_actions/previous_tab.tres" id="11_uxwof"] +[ext_resource type="Resource" uid="uid://dg1or0do0s1ad" path="res://guide_examples/remapping/mapping_contexts/controller_actions/next_tab.tres" id="12_byojv"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="12_hftpv"] + +[sub_resource type="Resource" id="Resource_f3bao"] +script = ExtResource("11_e078a") +key = 4194305 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = false + +[sub_resource type="Resource" id="Resource_twrga"] +script = ExtResource("12_hftpv") +button = 4 +joy_index = -1 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bagfg"] +bg_color = Color(0.266575, 0.266575, 0.266575, 1) + +[node name="RemappingDialog" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_uhsj0") +script = ExtResource("1_6hgqj") +keyboard_context = ExtResource("2_cgour") +controller_context = ExtResource("3_tgkdx") +binding_keyboard_context = ExtResource("5_tw3jw") +binding_controller_context = ExtResource("6_gdrkn") +close_dialog = ExtResource("7_djty7") +switch_to_controller = ExtResource("8_lj8gw") +switch_to_keyboard = ExtResource("9_brmt1") +previous_tab = ExtResource("11_uxwof") +next_tab = ExtResource("12_byojv") +binding_row_scene = ExtResource("4_iojgu") +binding_section_scene = ExtResource("5_8v80s") + +[node name="Blocker" type="ColorRect" parent="."] +layout_mode = 2 +color = Color(8.66354e-07, 0.331199, 0.634906, 0.352941) + +[node name="CenterContainer" type="CenterContainer" parent="."] +layout_mode = 2 + +[node name="PanelContainer" type="PanelContainer" parent="CenterContainer"] +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/PanelContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 + +[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/PanelContainer/MarginContainer"] +custom_minimum_size = Vector2(800, 600) +layout_mode = 2 +theme_override_constants/separation = 20 + +[node name="Label" type="Label" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_type_variation = &"HeaderLarge" +text = "Input Rebinding" +horizontal_alignment = 1 + +[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="TabContainer" type="TabContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +tab_alignment = 1 +current_tab = 1 +clip_tabs = false + +[node name="Keyboard" type="PanelContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer"] +visible = false +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Keyboard"] +layout_mode = 2 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 10 +theme_override_constants/margin_right = 10 +theme_override_constants/margin_bottom = 10 + +[node name="ScrollContainer" type="ScrollContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Keyboard/MarginContainer"] +layout_mode = 2 + +[node name="KeyboardBindings" type="VBoxContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Keyboard/MarginContainer/ScrollContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Controller" type="PanelContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer"] +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Controller"] +layout_mode = 2 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 10 +theme_override_constants/margin_right = 10 +theme_override_constants/margin_bottom = 10 + +[node name="ScrollContainer" type="ScrollContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Controller/MarginContainer"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Controller/MarginContainer/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ControllerBindings" type="VBoxContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Controller/MarginContainer/ScrollContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Section" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Controller/MarginContainer/ScrollContainer/VBoxContainer" instance=ExtResource("5_8v80s")] +layout_mode = 2 +text = "Miscellaneous" + +[node name="ControllerInvertHorizontal" type="CheckBox" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Controller/MarginContainer/ScrollContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Invert horizontal movement" + +[node name="ControllerInvertVertical" type="CheckBox" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Controller/MarginContainer/ScrollContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Invert vertical movement" + +[node name="HBoxContainer" type="HBoxContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer"] +layout_mode = 2 +mouse_filter = 2 + +[node name="RichTextLabel" type="RichTextLabel" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/HBoxContainer"] +layout_mode = 2 +mouse_filter = 2 +fit_content = true +scroll_active = false +autowrap_mode = 0 +script = ExtResource("10_xsw70") +instructions_text = "%s" +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("11_uxwof")]) + +[node name="Control" type="Control" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +mouse_filter = 2 + +[node name="RichTextLabel2" type="RichTextLabel" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/HBoxContainer"] +layout_mode = 2 +mouse_filter = 2 +fit_content = true +scroll_active = false +autowrap_mode = 0 +script = ExtResource("10_xsw70") +instructions_text = "%s" +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("12_byojv")]) + +[node name="HBoxContainer" type="HBoxContainer" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="ReturnToGame" type="Button" parent="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Return to game" + +[node name="GUIDEInputDetector" type="Node" parent="."] +unique_name_in_owner = true +editor_description = "This node has two inputs specified which count as abort for detection (Escape and Controller back button)." +script = ExtResource("3_o0nvn") +detection_countdown_seconds = 0.1 +abort_detection_on = Array[Resource("res://addons/guide/inputs/guide_input.gd")]([SubResource("Resource_f3bao"), SubResource("Resource_twrga")]) + +[node name="PressPrompt" type="MarginContainer" parent="."] +unique_name_in_owner = true +visible = false +layout_mode = 2 +mouse_filter = 0 + +[node name="CenterContainer" type="CenterContainer" parent="PressPrompt"] +layout_mode = 2 + +[node name="Panel" type="PanelContainer" parent="PressPrompt/CenterContainer"] +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_bagfg") + +[node name="MarginContainer" type="MarginContainer" parent="PressPrompt/CenterContainer/Panel"] +layout_mode = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 + +[node name="Label" type="Label" parent="PressPrompt/CenterContainer/Panel/MarginContainer"] +layout_mode = 2 +text = "Press new input..." + +[connection signal="toggled" from="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Controller/MarginContainer/ScrollContainer/VBoxContainer/ControllerInvertHorizontal" to="." method="_on_controller_invert_horizontal_toggled"] +[connection signal="toggled" from="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/MarginContainer/TabContainer/Controller/MarginContainer/ScrollContainer/VBoxContainer/ControllerInvertVertical" to="." method="_on_controller_invert_vertical_toggled"] +[connection signal="pressed" from="CenterContainer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ReturnToGame" to="." method="_on_return_to_game_pressed"] diff --git a/guide_examples/remapping/utils.gd b/guide_examples/remapping/utils.gd new file mode 100644 index 0000000..613ae32 --- /dev/null +++ b/guide_examples/remapping/utils.gd @@ -0,0 +1,18 @@ +const REMAPPING_CONFIG_PATH = "user://remapping_config.tres" + +# Constants for custom data that we store in the remapping config. +const CUSTOM_DATA_INVERT_HORIZONTAL = "invert_horizontal" +const CUSTOM_DATA_INVERT_VERTICAL = "invert_vertical" + +## Loads the saved remapping config if it exists, or an empty remapping +## config if none exists. +static func load_remapping_config() -> GUIDERemappingConfig: + if ResourceLoader.exists(REMAPPING_CONFIG_PATH): + return ResourceLoader.load(REMAPPING_CONFIG_PATH) + else: + return GUIDERemappingConfig.new() + +## Saves the given remapping config to the user folder +static func save_remapping_config(config:GUIDERemappingConfig) -> void: + ResourceSaver.save(config, REMAPPING_CONFIG_PATH) + config.take_over_path(REMAPPING_CONFIG_PATH) diff --git a/guide_examples/remapping/utils.gd.uid b/guide_examples/remapping/utils.gd.uid new file mode 100644 index 0000000..a6e948d --- /dev/null +++ b/guide_examples/remapping/utils.gd.uid @@ -0,0 +1 @@ +uid://chnxcg46gaypy diff --git a/guide_examples/shared/fireball/fireball.gd b/guide_examples/shared/fireball/fireball.gd new file mode 100644 index 0000000..ff6f835 --- /dev/null +++ b/guide_examples/shared/fireball/fireball.gd @@ -0,0 +1,13 @@ +extends Node2D + +@export var speed:float = 600 +var direction:Vector2 = Vector2.ZERO + + +func _ready(): + await get_tree().create_timer(5).timeout + queue_free() + + +func _process(delta): + position += speed * direction * delta diff --git a/guide_examples/shared/fireball/fireball.gd.uid b/guide_examples/shared/fireball/fireball.gd.uid new file mode 100644 index 0000000..8e47ec1 --- /dev/null +++ b/guide_examples/shared/fireball/fireball.gd.uid @@ -0,0 +1 @@ +uid://bvlq6u3twn6x2 diff --git a/guide_examples/shared/fireball/fireball.svg b/guide_examples/shared/fireball/fireball.svg new file mode 100644 index 0000000..3a7079b --- /dev/null +++ b/guide_examples/shared/fireball/fireball.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/guide_examples/shared/fireball/fireball.svg.import b/guide_examples/shared/fireball/fireball.svg.import new file mode 100644 index 0000000..787001d --- /dev/null +++ b/guide_examples/shared/fireball/fireball.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://buu21kg4kkhiw" +path="res://.godot/imported/fireball.svg-da8480a7a8e47ac511e0971f6fa164bd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/shared/fireball/fireball.svg" +dest_files=["res://.godot/imported/fireball.svg-da8480a7a8e47ac511e0971f6fa164bd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/guide_examples/shared/fireball/fireball.tscn b/guide_examples/shared/fireball/fireball.tscn new file mode 100644 index 0000000..4b288ef --- /dev/null +++ b/guide_examples/shared/fireball/fireball.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://c36cnvgv2ur60"] + +[ext_resource type="Script" path="res://guide_examples/shared/fireball/fireball.gd" id="1_jxcno"] +[ext_resource type="Texture2D" uid="uid://buu21kg4kkhiw" path="res://guide_examples/shared/fireball/fireball.svg" id="2_5ckxn"] + +[node name="Fireball" type="Node2D"] +script = ExtResource("1_jxcno") + +[node name="Fireball" type="Sprite2D" parent="."] +texture = ExtResource("2_5ckxn") diff --git a/guide_examples/shared/godot_logo.svg b/guide_examples/shared/godot_logo.svg new file mode 100644 index 0000000..3fe4f4a --- /dev/null +++ b/guide_examples/shared/godot_logo.svg @@ -0,0 +1 @@ + diff --git a/guide_examples/shared/godot_logo.svg.import b/guide_examples/shared/godot_logo.svg.import new file mode 100644 index 0000000..6dbb436 --- /dev/null +++ b/guide_examples/shared/godot_logo.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://byjxtsekdl8t2" +path="res://.godot/imported/godot_logo.svg-ce7d52346b74cfa0766735b0b77afab9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/shared/godot_logo.svg" +dest_files=["res://.godot/imported/godot_logo.svg-ce7d52346b74cfa0766735b0b77afab9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/guide_examples/shared/instructions_label.gd b/guide_examples/shared/instructions_label.gd new file mode 100644 index 0000000..06799f3 --- /dev/null +++ b/guide_examples/shared/instructions_label.gd @@ -0,0 +1,52 @@ +## This is an example for how input prompts can be shown to the player. +extends RichTextLabel + +## The instructions text. Should contain %s where the action text should go. +@export_multiline var instructions_text:String +## The actions which should be used for rendering the instructions. One action for +## each %s in the text. +@export var actions:Array[GUIDEAction] = [] +## The icon size to be used for rendering. +@export var icon_size:int = 48 + +## If set, the label will only show when the given mapping context is active. +@export var limit_to_context:GUIDEMappingContext + +# The formatter. This will do the actual work of formatting action inputs into prompts. +var _formatter:GUIDEInputFormatter + +func _ready(): + bbcode_enabled = true + fit_content = true + scroll_active = false + autowrap_mode = TextServer.AUTOWRAP_OFF + + # Subscribe to the input mappings change so we can update the prompts or hide the label + # when any inputs change. This way the label can automatically update itself if we switch + # from keyboard to controller input or rebind some keys. + GUIDE.input_mappings_changed.connect(_update_instructions) + _formatter = GUIDEInputFormatter.for_active_contexts(icon_size) + + +func _update_instructions(): + # If we only show for a certain context, hide if that context isn't active right now. + if limit_to_context != null and not GUIDE.is_mapping_context_enabled(limit_to_context): + visible = false + return + + # if no mapping context is active, we'll not be able to show instructions, so bail out here. + if GUIDE.get_enabled_mapping_contexts().is_empty(): + visible = false + return + + visible = true + + # Update the prompts. + var replacements:Array[String] = [] + for action in actions: + replacements.append(await _formatter.action_as_richtext_async(action)) + + parse_bbcode(instructions_text % replacements) + + + diff --git a/guide_examples/shared/instructions_label.gd.uid b/guide_examples/shared/instructions_label.gd.uid new file mode 100644 index 0000000..f935ab6 --- /dev/null +++ b/guide_examples/shared/instructions_label.gd.uid @@ -0,0 +1 @@ +uid://w8q1xlqw60qh diff --git a/guide_examples/shared/ui_theme.tres b/guide_examples/shared/ui_theme.tres new file mode 100644 index 0000000..ba66776 --- /dev/null +++ b/guide_examples/shared/ui_theme.tres @@ -0,0 +1,5 @@ +[gd_resource type="Theme" format=3 uid="uid://dot0gi1yoqmrl"] + +[resource] +default_font_size = 24 +HeaderLarge/font_sizes/font_size = 30 diff --git a/guide_examples/simple_input/mapping_contexts/move_down.tres b/guide_examples/simple_input/mapping_contexts/move_down.tres new file mode 100644 index 0000000..489c421 --- /dev/null +++ b/guide_examples/simple_input/mapping_contexts/move_down.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cjfdsja54wtus"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_yaxge"] + +[resource] +script = ExtResource("1_yaxge") +name = "" +display_name = "" +display_category = "" diff --git a/guide_examples/simple_input/mapping_contexts/move_left.tres b/guide_examples/simple_input/mapping_contexts/move_left.tres new file mode 100644 index 0000000..1039eda --- /dev/null +++ b/guide_examples/simple_input/mapping_contexts/move_left.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://b7rcj2usvx7iu"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_2lu1r"] + +[resource] +script = ExtResource("1_2lu1r") +name = "" +display_name = "" +display_category = "" diff --git a/guide_examples/simple_input/mapping_contexts/move_right.tres b/guide_examples/simple_input/mapping_contexts/move_right.tres new file mode 100644 index 0000000..8768587 --- /dev/null +++ b/guide_examples/simple_input/mapping_contexts/move_right.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cn4nypfrnusrn"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_o2mf7"] + +[resource] +script = ExtResource("1_o2mf7") +name = "" +display_name = "" +display_category = "" diff --git a/guide_examples/simple_input/mapping_contexts/move_up.tres b/guide_examples/simple_input/mapping_contexts/move_up.tres new file mode 100644 index 0000000..6e9e71e --- /dev/null +++ b/guide_examples/simple_input/mapping_contexts/move_up.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cjohgt5cdoxvd"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_1p8w8"] + +[resource] +script = ExtResource("1_1p8w8") +name = "" +display_name = "" +display_category = "" diff --git a/guide_examples/simple_input/mapping_contexts/simple_input.tres b/guide_examples/simple_input/mapping_contexts/simple_input.tres new file mode 100644 index 0000000..5c00af1 --- /dev/null +++ b/guide_examples/simple_input/mapping_contexts/simple_input.tres @@ -0,0 +1,111 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=21 format=3 uid="uid://c161ru5ubsvm5"] + +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_1q401"] +[ext_resource type="Resource" uid="uid://cjohgt5cdoxvd" path="res://guide_examples/simple_input/mapping_contexts/move_up.tres" id="1_p6dvd"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_dmcv6"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_j3d4x"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="4_5ymhe"] +[ext_resource type="Resource" uid="uid://cjfdsja54wtus" path="res://guide_examples/simple_input/mapping_contexts/move_down.tres" id="5_x3j1d"] +[ext_resource type="Resource" uid="uid://b7rcj2usvx7iu" path="res://guide_examples/simple_input/mapping_contexts/move_left.tres" id="6_3n2n7"] +[ext_resource type="Resource" uid="uid://cn4nypfrnusrn" path="res://guide_examples/simple_input/mapping_contexts/move_right.tres" id="7_mgx2j"] + +[sub_resource type="Resource" id="Resource_x4hy0"] +script = ExtResource("2_dmcv6") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_skv88"] +script = ExtResource("3_j3d4x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_x4hy0") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_13yll"] +script = ExtResource("4_5ymhe") +action = ExtResource("1_p6dvd") +input_mappings = Array[ExtResource("3_j3d4x")]([SubResource("Resource_skv88")]) + +[sub_resource type="Resource" id="Resource_kjfiu"] +script = ExtResource("2_dmcv6") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_11cob"] +script = ExtResource("3_j3d4x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_kjfiu") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_olvia"] +script = ExtResource("4_5ymhe") +action = ExtResource("5_x3j1d") +input_mappings = Array[ExtResource("3_j3d4x")]([SubResource("Resource_11cob")]) + +[sub_resource type="Resource" id="Resource_rkxlb"] +script = ExtResource("2_dmcv6") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_j7qak"] +script = ExtResource("3_j3d4x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_rkxlb") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_gs5ov"] +script = ExtResource("4_5ymhe") +action = ExtResource("6_3n2n7") +input_mappings = Array[ExtResource("3_j3d4x")]([SubResource("Resource_j7qak")]) + +[sub_resource type="Resource" id="Resource_jek7t"] +script = ExtResource("2_dmcv6") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_m4m5w"] +script = ExtResource("3_j3d4x") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_jek7t") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_hk2n5"] +script = ExtResource("4_5ymhe") +action = ExtResource("7_mgx2j") +input_mappings = Array[ExtResource("3_j3d4x")]([SubResource("Resource_m4m5w")]) + +[resource] +script = ExtResource("1_1q401") +display_name = "" +mappings = Array[ExtResource("4_5ymhe")]([SubResource("Resource_13yll"), SubResource("Resource_olvia"), SubResource("Resource_gs5ov"), SubResource("Resource_hk2n5")]) diff --git a/guide_examples/simple_input/player.gd b/guide_examples/simple_input/player.gd new file mode 100644 index 0000000..5e8c28f --- /dev/null +++ b/guide_examples/simple_input/player.gd @@ -0,0 +1,32 @@ +extends Node2D + +@export var speed:float = 100 + +@export var left_action:GUIDEAction +@export var right_action:GUIDEAction +@export var up_action:GUIDEAction +@export var down_action:GUIDEAction + +func _process(delta:float) -> void: + # This is close to how input would be handled with Godot's built-in + # input. GUIDE can actually combine the input into a 2D axis for you + # (similar to Godot's Input.get_vector). Because this is + # done in the mapping context, the script doesn't need to know about + # it. Look at the 2d_axis_mapping example to see how to streamline + # this code quite a bit. + + var offset:Vector2 = Vector2.ZERO + + if left_action.is_triggered(): + offset.x = -1 + + if right_action.is_triggered(): + offset.x = 1 + + if up_action.is_triggered(): + offset.y = -1 + + if down_action.is_triggered(): + offset.y = 1 + + position += offset * speed * delta diff --git a/guide_examples/simple_input/player.gd.uid b/guide_examples/simple_input/player.gd.uid new file mode 100644 index 0000000..c3dc1c6 --- /dev/null +++ b/guide_examples/simple_input/player.gd.uid @@ -0,0 +1 @@ +uid://dhpub7a1ixyxj diff --git a/guide_examples/simple_input/simple_input.gd b/guide_examples/simple_input/simple_input.gd new file mode 100644 index 0000000..40a6fba --- /dev/null +++ b/guide_examples/simple_input/simple_input.gd @@ -0,0 +1,6 @@ +extends Node + +@export var mapping_context:GUIDEMappingContext + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) diff --git a/guide_examples/simple_input/simple_input.gd.uid b/guide_examples/simple_input/simple_input.gd.uid new file mode 100644 index 0000000..0c13831 --- /dev/null +++ b/guide_examples/simple_input/simple_input.gd.uid @@ -0,0 +1 @@ +uid://dej0g6ye7nfxi diff --git a/guide_examples/simple_input/simple_input.tscn b/guide_examples/simple_input/simple_input.tscn new file mode 100644 index 0000000..1769dd5 --- /dev/null +++ b/guide_examples/simple_input/simple_input.tscn @@ -0,0 +1,53 @@ +[gd_scene load_steps=12 format=3 uid="uid://cchyatnt0wl5x"] + +[ext_resource type="Script" path="res://guide_examples/simple_input/simple_input.gd" id="1_cgpw0"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="1_t8vwd"] +[ext_resource type="Script" path="res://guide_examples/simple_input/player.gd" id="2_o6vg3"] +[ext_resource type="Resource" uid="uid://c161ru5ubsvm5" path="res://guide_examples/simple_input/mapping_contexts/simple_input.tres" id="3_2b24x"] +[ext_resource type="Resource" uid="uid://b7rcj2usvx7iu" path="res://guide_examples/simple_input/mapping_contexts/move_left.tres" id="4_50on6"] +[ext_resource type="Resource" uid="uid://cn4nypfrnusrn" path="res://guide_examples/simple_input/mapping_contexts/move_right.tres" id="5_47yin"] +[ext_resource type="Resource" uid="uid://cjohgt5cdoxvd" path="res://guide_examples/simple_input/mapping_contexts/move_up.tres" id="6_b7h5t"] +[ext_resource type="Resource" uid="uid://cjfdsja54wtus" path="res://guide_examples/simple_input/mapping_contexts/move_down.tres" id="7_4pdc5"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="8_tko8y"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="9_hqrkx"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="10_3ap6u"] + +[node name="SimpleInput" type="Node"] +script = ExtResource("1_cgpw0") +mapping_context = ExtResource("3_2b24x") + +[node name="Player" type="Sprite2D" parent="."] +position = Vector2(546, 317) +texture = ExtResource("1_t8vwd") +script = ExtResource("2_o6vg3") +speed = 300.0 +left_action = ExtResource("4_50on6") +right_action = ExtResource("5_47yin") +up_action = ExtResource("6_b7h5t") +down_action = ExtResource("7_4pdc5") + +[node name="UI Layer" type="CanvasLayer" parent="."] + +[node name="Instructions Label" type="RichTextLabel" parent="UI Layer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -286.0 +offset_top = 24.0 +offset_right = -39.0 +offset_bottom = 47.0 +grow_horizontal = 0 +theme = ExtResource("8_tko8y") +script = ExtResource("9_hqrkx") +instructions_text = "%s to move left. +%s to move right. +%s to move up. +%s to move down." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("4_50on6"), ExtResource("5_47yin"), ExtResource("6_b7h5t"), ExtResource("7_4pdc5")]) +metadata/_edit_use_anchors_ = true + +[node name="Debug Layer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="Debug Layer" instance=ExtResource("10_3ap6u")] +theme = ExtResource("8_tko8y") +metadata/_edit_lock_ = true diff --git a/guide_examples/tap_and_hold/mapping_contexts/jump.tres b/guide_examples/tap_and_hold/mapping_contexts/jump.tres new file mode 100644 index 0000000..e7cf095 --- /dev/null +++ b/guide_examples/tap_and_hold/mapping_contexts/jump.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://djow080f02fos"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_dxeu7"] + +[resource] +script = ExtResource("1_dxeu7") +name = &"" +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/tap_and_hold/mapping_contexts/somersault.tres b/guide_examples/tap_and_hold/mapping_contexts/somersault.tres new file mode 100644 index 0000000..da1b5d9 --- /dev/null +++ b/guide_examples/tap_and_hold/mapping_contexts/somersault.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://dcdlaiw50k4t3"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_mgxtb"] + +[resource] +script = ExtResource("1_mgxtb") +name = "" +display_name = "" +display_category = "" diff --git a/guide_examples/tap_and_hold/mapping_contexts/tap_and_hold.tres b/guide_examples/tap_and_hold/mapping_contexts/tap_and_hold.tres new file mode 100644 index 0000000..cb12516 --- /dev/null +++ b/guide_examples/tap_and_hold/mapping_contexts/tap_and_hold.tres @@ -0,0 +1,74 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=17 format=3 uid="uid://dkorp45s6fjqk"] + +[ext_resource type="Resource" uid="uid://djow080f02fos" path="res://guide_examples/tap_and_hold/mapping_contexts/jump.tres" id="1_pwkn3"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_6utl5"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_sfabf"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_tap.gd" id="4_0qfc2"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="4_nrdxn"] +[ext_resource type="Resource" uid="uid://dcdlaiw50k4t3" path="res://guide_examples/tap_and_hold/mapping_contexts/somersault.tres" id="6_5qh27"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_hold.gd" id="7_sj5n7"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="8_q4q7m"] + +[sub_resource type="Resource" id="Resource_fvatf"] +script = ExtResource("2_6utl5") +key = 32 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_k188c"] +script = ExtResource("4_0qfc2") +tap_threshold = 0.2 +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_tg2ja"] +script = ExtResource("3_sfabf") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_fvatf") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_k188c")]) + +[sub_resource type="Resource" id="Resource_ghgfq"] +script = ExtResource("4_nrdxn") +action = ExtResource("1_pwkn3") +input_mappings = Array[ExtResource("3_sfabf")]([SubResource("Resource_tg2ja")]) + +[sub_resource type="Resource" id="Resource_75xxu"] +script = ExtResource("2_6utl5") +key = 32 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_dum1i"] +script = ExtResource("7_sj5n7") +hold_treshold = 0.5 +is_one_shot = true +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_tbykh"] +script = ExtResource("3_sfabf") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_75xxu") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_dum1i")]) + +[sub_resource type="Resource" id="Resource_5u3vu"] +script = ExtResource("4_nrdxn") +action = ExtResource("6_5qh27") +input_mappings = Array[ExtResource("3_sfabf")]([SubResource("Resource_tbykh")]) + +[resource] +script = ExtResource("8_q4q7m") +display_name = "" +mappings = Array[ExtResource("4_nrdxn")]([SubResource("Resource_ghgfq"), SubResource("Resource_5u3vu")]) diff --git a/guide_examples/tap_and_hold/player.gd b/guide_examples/tap_and_hold/player.gd new file mode 100644 index 0000000..c957649 --- /dev/null +++ b/guide_examples/tap_and_hold/player.gd @@ -0,0 +1,30 @@ +extends Node2D + + +@onready var _animation_player:AnimationPlayer = %AnimationPlayer +@onready var _progress_bar:ProgressBar = %ProgressBar + +@export var jump_action:GUIDEAction +@export var somersault_action:GUIDEAction + +func _ready(): + jump_action.triggered.connect(_play.bind("jump")) + somersault_action.triggered.connect(_play.bind("somersault")) + somersault_action.ongoing.connect(_update_progress_bar) + somersault_action.triggered.connect(_hide_progress_bar) + somersault_action.cancelled.connect(_hide_progress_bar) + +func _play(animation:String): + if _animation_player.is_playing(): + return + + _animation_player.play(animation) + +func _update_progress_bar(): + # exceeds tap time + if somersault_action.elapsed_seconds > 0.1: + _progress_bar.value = somersault_action.elapsed_ratio + _progress_bar.visible = true + +func _hide_progress_bar(): + _progress_bar.visible = false diff --git a/guide_examples/tap_and_hold/player.gd.uid b/guide_examples/tap_and_hold/player.gd.uid new file mode 100644 index 0000000..ab83abb --- /dev/null +++ b/guide_examples/tap_and_hold/player.gd.uid @@ -0,0 +1 @@ +uid://brd1oa6q1qsl3 diff --git a/guide_examples/tap_and_hold/tap_and_hold.gd b/guide_examples/tap_and_hold/tap_and_hold.gd new file mode 100644 index 0000000..40a6fba --- /dev/null +++ b/guide_examples/tap_and_hold/tap_and_hold.gd @@ -0,0 +1,6 @@ +extends Node + +@export var mapping_context:GUIDEMappingContext + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) diff --git a/guide_examples/tap_and_hold/tap_and_hold.gd.uid b/guide_examples/tap_and_hold/tap_and_hold.gd.uid new file mode 100644 index 0000000..576b9e2 --- /dev/null +++ b/guide_examples/tap_and_hold/tap_and_hold.gd.uid @@ -0,0 +1 @@ +uid://dpkjsi6bk64ly diff --git a/guide_examples/tap_and_hold/tap_and_hold.tscn b/guide_examples/tap_and_hold/tap_and_hold.tscn new file mode 100644 index 0000000..ea5317d --- /dev/null +++ b/guide_examples/tap_and_hold/tap_and_hold.tscn @@ -0,0 +1,154 @@ +[gd_scene load_steps=14 format=3 uid="uid://bq1y86drsbsgc"] + +[ext_resource type="Script" path="res://guide_examples/tap_and_hold/tap_and_hold.gd" id="1_ek3h7"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="1_segxn"] +[ext_resource type="Script" path="res://guide_examples/tap_and_hold/player.gd" id="2_gpfh8"] +[ext_resource type="Resource" uid="uid://dkorp45s6fjqk" path="res://guide_examples/tap_and_hold/mapping_contexts/tap_and_hold.tres" id="3_u8e88"] +[ext_resource type="Resource" uid="uid://djow080f02fos" path="res://guide_examples/tap_and_hold/mapping_contexts/jump.tres" id="4_8qeav"] +[ext_resource type="Resource" uid="uid://dcdlaiw50k4t3" path="res://guide_examples/tap_and_hold/mapping_contexts/somersault.tres" id="5_wp1cr"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="6_r6oud"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="6_vjlt4"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="7_304xo"] + +[sub_resource type="Animation" id="Animation_j3lvc"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Player:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(546, 317)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Player:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} + +[sub_resource type="Animation" id="Animation_a86xu"] +resource_name = "jump" +length = 0.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Player:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2, 0.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(546, 317), Vector2(546, 260), Vector2(546, 317)] +} + +[sub_resource type="Animation" id="Animation_fir1a"] +resource_name = "somersault" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Player:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(546, 317), Vector2(546, 200), Vector2(546, 317)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Player:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.3, 0.5, 0.7), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, -3.14159, -6.28319] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_8sm1c"] +_data = { +"RESET": SubResource("Animation_j3lvc"), +"jump": SubResource("Animation_a86xu"), +"somersault": SubResource("Animation_fir1a") +} + +[node name="TapAndHold" type="Node"] +script = ExtResource("1_ek3h7") +mapping_context = ExtResource("3_u8e88") + +[node name="Player" type="Sprite2D" parent="."] +position = Vector2(546, 317) +texture = ExtResource("1_segxn") +script = ExtResource("2_gpfh8") +jump_action = ExtResource("4_8qeav") +somersault_action = ExtResource("5_wp1cr") + +[node name="ProgressBar" type="ProgressBar" parent="Player"] +unique_name_in_owner = true +visible = false +offset_left = -58.0 +offset_top = 64.0 +offset_right = 57.0 +offset_bottom = 91.0 +max_value = 1.0 +show_percentage = false + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +unique_name_in_owner = true +libraries = { +"": SubResource("AnimationLibrary_8sm1c") +} + +[node name="UI Layer" type="CanvasLayer" parent="."] + +[node name="Instructions Label" type="RichTextLabel" parent="UI Layer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -473.0 +offset_top = 527.0 +offset_right = -226.0 +offset_bottom = 550.0 +grow_horizontal = 0 +theme = ExtResource("6_r6oud") +script = ExtResource("7_304xo") +instructions_text = "Tap %s to jump. +Hold %s to somersault." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("4_8qeav"), ExtResource("5_wp1cr")]) +metadata/_edit_use_anchors_ = true + +[node name="Label" type="Label" parent="UI Layer"] +visible = false +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -660.0 +offset_top = 71.0 +offset_right = -57.0 +offset_bottom = 223.0 +grow_horizontal = 0 +theme = ExtResource("6_r6oud") +text = "This demonstrates using the hold and tap triggers to bind multiple actions to the same key. This also uses the hold action's elapsed_ratio property to drive a hold progress bar to indicate how long the key needs to be held." +autowrap_mode = 2 + +[node name="Debug Layer" type="CanvasLayer" parent="."] +visible = false + +[node name="GuideDebugger" parent="Debug Layer" instance=ExtResource("6_vjlt4")] +theme = ExtResource("6_r6oud") +metadata/_edit_lock_ = true diff --git a/guide_examples/top_down_shooter/bolt/bolt.gd b/guide_examples/top_down_shooter/bolt/bolt.gd new file mode 100644 index 0000000..6b1902b --- /dev/null +++ b/guide_examples/top_down_shooter/bolt/bolt.gd @@ -0,0 +1,10 @@ +extends Sprite2D + +@export var speed:float = 500 +@export var lifetime:float = 1.0 + +func _process(delta: float) -> void: + position += transform.x * delta * speed + lifetime -= delta + if lifetime <= 0: + queue_free() diff --git a/guide_examples/top_down_shooter/bolt/bolt.gd.uid b/guide_examples/top_down_shooter/bolt/bolt.gd.uid new file mode 100644 index 0000000..89604a8 --- /dev/null +++ b/guide_examples/top_down_shooter/bolt/bolt.gd.uid @@ -0,0 +1 @@ +uid://w7nan374op8 diff --git a/guide_examples/top_down_shooter/bolt/bolt.png b/guide_examples/top_down_shooter/bolt/bolt.png new file mode 100644 index 0000000..73bf0ba Binary files /dev/null and b/guide_examples/top_down_shooter/bolt/bolt.png differ diff --git a/guide_examples/top_down_shooter/bolt/bolt.png.import b/guide_examples/top_down_shooter/bolt/bolt.png.import new file mode 100644 index 0000000..2da19d9 --- /dev/null +++ b/guide_examples/top_down_shooter/bolt/bolt.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dfpdumvnepffe" +path="res://.godot/imported/bolt.png-d2b4175f016737de6380cafdf09c07c0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/top_down_shooter/bolt/bolt.png" +dest_files=["res://.godot/imported/bolt.png-d2b4175f016737de6380cafdf09c07c0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/top_down_shooter/bolt/bolt.tscn b/guide_examples/top_down_shooter/bolt/bolt.tscn new file mode 100644 index 0000000..221ee13 --- /dev/null +++ b/guide_examples/top_down_shooter/bolt/bolt.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://c0fqv8e3tljmp"] + +[ext_resource type="Texture2D" uid="uid://dfpdumvnepffe" path="res://guide_examples/top_down_shooter/bolt/bolt.png" id="1_b5s4m"] +[ext_resource type="Script" path="res://guide_examples/top_down_shooter/bolt/bolt.gd" id="2_o61jt"] + +[node name="Bolt" type="Sprite2D"] +texture = ExtResource("1_b5s4m") +script = ExtResource("2_o61jt") +speed = 1000.0 +lifetime = 2.0 diff --git a/guide_examples/top_down_shooter/mapping_contexts/controller.tres b/guide_examples/top_down_shooter/mapping_contexts/controller.tres new file mode 100644 index 0000000..15af017 --- /dev/null +++ b/guide_examples/top_down_shooter/mapping_contexts/controller.tres @@ -0,0 +1,123 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=28 format=3 uid="uid://dysrgn1ubf15g"] + +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_3vbsc"] +[ext_resource type="Resource" uid="uid://ch070wegl722t" path="res://guide_examples/top_down_shooter/mapping_contexts/move.tres" id="1_epjja"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_axis_2d.gd" id="2_bwpvf"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="2_skach"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_deadzone.gd" id="3_872fr"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="3_e36mu"] +[ext_resource type="Resource" uid="uid://vpsh1myp67ws" path="res://guide_examples/top_down_shooter/mapping_contexts/look_relative.tres" id="6_5clnx"] +[ext_resource type="Resource" uid="uid://coktqyup12g3w" path="res://guide_examples/top_down_shooter/mapping_contexts/fire.tres" id="7_pfi7b"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_axis_1d.gd" id="8_gtkor"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="9_i3uls"] +[ext_resource type="Resource" uid="uid://bnd2jguy7tfti" path="res://guide_examples/top_down_shooter/mapping_contexts/switch_to_keyboard_and_mouse.tres" id="10_m7sth"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_any.gd" id="11_jpwmq"] + +[sub_resource type="Resource" id="Resource_uwau4"] +script = ExtResource("2_bwpvf") +x = 0 +y = 1 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_i1fx3"] +script = ExtResource("3_872fr") +lower_threshold = 0.2 +upper_threshold = 1.0 + +[sub_resource type="Resource" id="Resource_7mv4j"] +script = ExtResource("2_skach") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_uwau4") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_i1fx3")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_x8yon"] +script = ExtResource("3_e36mu") +action = ExtResource("1_epjja") +input_mappings = Array[ExtResource("2_skach")]([SubResource("Resource_7mv4j")]) + +[sub_resource type="Resource" id="Resource_2nugj"] +script = ExtResource("2_bwpvf") +x = 2 +y = 3 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_iln10"] +script = ExtResource("3_872fr") +lower_threshold = 0.607 +upper_threshold = 1.0 + +[sub_resource type="Resource" id="Resource_yxygj"] +script = ExtResource("2_skach") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_2nugj") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_iln10")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_ropdf"] +script = ExtResource("3_e36mu") +action = ExtResource("6_5clnx") +input_mappings = Array[ExtResource("2_skach")]([SubResource("Resource_yxygj")]) + +[sub_resource type="Resource" id="Resource_mnoq7"] +script = ExtResource("8_gtkor") +axis = 5 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_7u5im"] +script = ExtResource("9_i3uls") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_ssica"] +script = ExtResource("2_skach") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_mnoq7") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_7u5im")]) + +[sub_resource type="Resource" id="Resource_a7lt0"] +script = ExtResource("3_e36mu") +action = ExtResource("7_pfi7b") +input_mappings = Array[ExtResource("2_skach")]([SubResource("Resource_ssica")]) + +[sub_resource type="Resource" id="Resource_konxq"] +script = ExtResource("11_jpwmq") +mouse_buttons = true +mouse_movement = true +minimum_mouse_movement_distance = 1.0 +joy_buttons = false +joy_axes = false +minimum_joy_axis_actuation_strength = 0.2 +keyboard = true +touch = false +mouse = true +joy = false + +[sub_resource type="Resource" id="Resource_lid0f"] +script = ExtResource("2_skach") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_konxq") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_6hier"] +script = ExtResource("3_e36mu") +action = ExtResource("10_m7sth") +input_mappings = Array[ExtResource("2_skach")]([SubResource("Resource_lid0f")]) + +[resource] +script = ExtResource("1_3vbsc") +display_name = "" +mappings = Array[ExtResource("3_e36mu")]([SubResource("Resource_x8yon"), SubResource("Resource_ropdf"), SubResource("Resource_a7lt0"), SubResource("Resource_6hier")]) diff --git a/guide_examples/top_down_shooter/mapping_contexts/fire.tres b/guide_examples/top_down_shooter/mapping_contexts/fire.tres new file mode 100644 index 0000000..09f9093 --- /dev/null +++ b/guide_examples/top_down_shooter/mapping_contexts/fire.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://coktqyup12g3w"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_jmn08"] + +[resource] +script = ExtResource("1_jmn08") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/top_down_shooter/mapping_contexts/keyboard_and_mouse.tres b/guide_examples/top_down_shooter/mapping_contexts/keyboard_and_mouse.tres new file mode 100644 index 0000000..3beb79f --- /dev/null +++ b/guide_examples/top_down_shooter/mapping_contexts/keyboard_and_mouse.tres @@ -0,0 +1,196 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=40 format=3 uid="uid://dhp7nup127wxw"] + +[ext_resource type="Resource" uid="uid://ch070wegl722t" path="res://guide_examples/top_down_shooter/mapping_contexts/move.tres" id="1_o40br"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_key.gd" id="2_r8xkm"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="3_mxuhd"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="4_nld8w"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_input_swizzle.gd" id="4_sdo77"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="5_wiw4m"] +[ext_resource type="Resource" uid="uid://c4tpipfhludsi" path="res://guide_examples/top_down_shooter/mapping_contexts/look_absolute.tres" id="7_4uvlp"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="7_dx1p2"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_mouse_position.gd" id="8_hys4n"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_canvas_coordinates.gd" id="9_5f66x"] +[ext_resource type="Resource" uid="uid://coktqyup12g3w" path="res://guide_examples/top_down_shooter/mapping_contexts/fire.tres" id="10_he1ky"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_mouse_button.gd" id="11_btbxh"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="12_ce85k"] +[ext_resource type="Resource" uid="uid://byu565ktximg2" path="res://guide_examples/top_down_shooter/mapping_contexts/switch_to_controller.tres" id="13_0evsu"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_any.gd" id="14_ulkgf"] + +[sub_resource type="Resource" id="Resource_rqldx"] +script = ExtResource("2_r8xkm") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_fedub"] +script = ExtResource("4_sdo77") +order = 0 + +[sub_resource type="Resource" id="Resource_sithj"] +script = ExtResource("3_mxuhd") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_gvylm"] +script = ExtResource("4_nld8w") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_rqldx") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_fedub"), SubResource("Resource_sithj")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_2grck"] +script = ExtResource("2_r8xkm") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_e6ufd"] +script = ExtResource("4_sdo77") +order = 0 + +[sub_resource type="Resource" id="Resource_hclrp"] +script = ExtResource("4_nld8w") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_2grck") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_e6ufd")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_0e6tb"] +script = ExtResource("2_r8xkm") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_o7bio"] +script = ExtResource("3_mxuhd") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_085kd"] +script = ExtResource("4_nld8w") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_0e6tb") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_o7bio")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_h42bk"] +script = ExtResource("2_r8xkm") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_vnoud"] +script = ExtResource("4_nld8w") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_h42bk") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_x8yon"] +script = ExtResource("5_wiw4m") +action = ExtResource("1_o40br") +input_mappings = Array[ExtResource("4_nld8w")]([SubResource("Resource_gvylm"), SubResource("Resource_hclrp"), SubResource("Resource_085kd"), SubResource("Resource_vnoud")]) + +[sub_resource type="Resource" id="Resource_dgqq1"] +script = ExtResource("8_hys4n") + +[sub_resource type="Resource" id="Resource_qegvf"] +script = ExtResource("9_5f66x") +relative_input = false + +[sub_resource type="Resource" id="Resource_yxygj"] +script = ExtResource("4_nld8w") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_dgqq1") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_qegvf")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_ropdf"] +script = ExtResource("5_wiw4m") +action = ExtResource("7_4uvlp") +input_mappings = Array[ExtResource("4_nld8w")]([SubResource("Resource_yxygj")]) + +[sub_resource type="Resource" id="Resource_omwno"] +script = ExtResource("11_btbxh") +button = 1 + +[sub_resource type="Resource" id="Resource_7jcut"] +script = ExtResource("12_ce85k") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_4uxij"] +script = ExtResource("4_nld8w") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_omwno") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_7jcut")]) + +[sub_resource type="Resource" id="Resource_8w3dk"] +script = ExtResource("5_wiw4m") +action = ExtResource("10_he1ky") +input_mappings = Array[ExtResource("4_nld8w")]([SubResource("Resource_4uxij")]) + +[sub_resource type="Resource" id="Resource_nqj7r"] +script = ExtResource("14_ulkgf") +mouse_buttons = false +mouse_movement = false +minimum_mouse_movement_distance = 1.0 +joy_buttons = true +joy_axes = true +minimum_joy_axis_actuation_strength = 0.5 +keyboard = false +touch = false +mouse = false +joy = true + +[sub_resource type="Resource" id="Resource_bk656"] +script = ExtResource("4_nld8w") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_nqj7r") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_ewfkl"] +script = ExtResource("5_wiw4m") +action = ExtResource("13_0evsu") +input_mappings = Array[ExtResource("4_nld8w")]([SubResource("Resource_bk656")]) + +[resource] +script = ExtResource("7_dx1p2") +display_name = "" +mappings = Array[ExtResource("5_wiw4m")]([SubResource("Resource_x8yon"), SubResource("Resource_ropdf"), SubResource("Resource_8w3dk"), SubResource("Resource_ewfkl")]) diff --git a/guide_examples/top_down_shooter/mapping_contexts/look_absolute.tres b/guide_examples/top_down_shooter/mapping_contexts/look_absolute.tres new file mode 100644 index 0000000..cf4ee01 --- /dev/null +++ b/guide_examples/top_down_shooter/mapping_contexts/look_absolute.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://c4tpipfhludsi"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_ujbw2"] + +[resource] +script = ExtResource("1_ujbw2") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/top_down_shooter/mapping_contexts/look_relative.tres b/guide_examples/top_down_shooter/mapping_contexts/look_relative.tres new file mode 100644 index 0000000..1baf03f --- /dev/null +++ b/guide_examples/top_down_shooter/mapping_contexts/look_relative.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://vpsh1myp67ws"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_upkuf"] + +[resource] +script = ExtResource("1_upkuf") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/top_down_shooter/mapping_contexts/move.tres b/guide_examples/top_down_shooter/mapping_contexts/move.tres new file mode 100644 index 0000000..ceb54f0 --- /dev/null +++ b/guide_examples/top_down_shooter/mapping_contexts/move.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://ch070wegl722t"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_w0ans"] + +[resource] +script = ExtResource("1_w0ans") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/top_down_shooter/mapping_contexts/switch_to_controller.tres b/guide_examples/top_down_shooter/mapping_contexts/switch_to_controller.tres new file mode 100644 index 0000000..7f6758f --- /dev/null +++ b/guide_examples/top_down_shooter/mapping_contexts/switch_to_controller.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://byu565ktximg2"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_ghtdg"] + +[resource] +script = ExtResource("1_ghtdg") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/top_down_shooter/mapping_contexts/switch_to_keyboard_and_mouse.tres b/guide_examples/top_down_shooter/mapping_contexts/switch_to_keyboard_and_mouse.tres new file mode 100644 index 0000000..5b0a1e0 --- /dev/null +++ b/guide_examples/top_down_shooter/mapping_contexts/switch_to_keyboard_and_mouse.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bnd2jguy7tfti"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_gxqso"] + +[resource] +script = ExtResource("1_gxqso") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/top_down_shooter/player/mrg0000.png b/guide_examples/top_down_shooter/player/mrg0000.png new file mode 100644 index 0000000..6b6a9af Binary files /dev/null and b/guide_examples/top_down_shooter/player/mrg0000.png differ diff --git a/guide_examples/top_down_shooter/player/mrg0000.png.import b/guide_examples/top_down_shooter/player/mrg0000.png.import new file mode 100644 index 0000000..7dd9fe6 --- /dev/null +++ b/guide_examples/top_down_shooter/player/mrg0000.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c22k1y6rbntlw" +path="res://.godot/imported/mrg0000.png-2c8ef2c24386191b7c1a03703c595faf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/top_down_shooter/player/mrg0000.png" +dest_files=["res://.godot/imported/mrg0000.png-2c8ef2c24386191b7c1a03703c595faf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/top_down_shooter/player/player.gd b/guide_examples/top_down_shooter/player/player.gd new file mode 100644 index 0000000..abb340b --- /dev/null +++ b/guide_examples/top_down_shooter/player/player.gd @@ -0,0 +1,46 @@ +extends CharacterBody2D + + +@export var speed:float = 300 +@export var look_relative:GUIDEAction +@export var look_absolute:GUIDEAction +@export var move:GUIDEAction +@export var fire:GUIDEAction + +@export var bolt:PackedScene + +@onready var left_hand:Node2D = %LeftHand +@onready var right_hand:Node2D = %RightHand + + +func _ready(): + # fire some bolts when the fire action triggers + fire.triggered.connect(_fire) + +func _physics_process(delta): + var target = Vector2.INF + + # Looking at absolute coordinates. This is the case when we use a mouse. + if look_absolute.is_triggered(): + target = look_absolute.value_axis_2d + # Looking at relative coordinates. This is the case when we use a controller + elif look_relative.is_triggered(): + target = global_position + look_relative.value_axis_2d + + # If we have a target, rotate towards it + if target.is_finite(): + var target_orientation = Transform2D()\ + .translated(transform.origin)\ + .looking_at(target) + transform = transform.interpolate_with(target_orientation, 5 * delta) + + # and move according to the input. + velocity = speed * move.value_axis_2d + move_and_slide() + +func _fire(): + # for each hand of the player, spawn a bolt + for hand in [left_hand, right_hand]: + var a_bolt:Node2D = bolt.instantiate() + get_parent().add_child(a_bolt) + a_bolt.global_transform = hand.global_transform diff --git a/guide_examples/top_down_shooter/player/player.gd.uid b/guide_examples/top_down_shooter/player/player.gd.uid new file mode 100644 index 0000000..728668e --- /dev/null +++ b/guide_examples/top_down_shooter/player/player.gd.uid @@ -0,0 +1 @@ +uid://blx1seoclt48w diff --git a/guide_examples/top_down_shooter/top_down_shooter.gd b/guide_examples/top_down_shooter/top_down_shooter.gd new file mode 100644 index 0000000..f19478c --- /dev/null +++ b/guide_examples/top_down_shooter/top_down_shooter.gd @@ -0,0 +1,20 @@ +extends Node2D + +@export var keyboard_and_mouse:GUIDEMappingContext +@export var controller:GUIDEMappingContext + +@export var switch_to_controller:GUIDEAction +@export var switch_to_keyboard_and_mouse:GUIDEAction + +func _ready(): + # enable controller at the start + GUIDE.enable_mapping_context(controller) + + # Switch the control scheme depending on the input. + switch_to_controller.triggered \ + .connect(func(): GUIDE.enable_mapping_context(controller, true)) + switch_to_keyboard_and_mouse.triggered \ + .connect(func(): GUIDE.enable_mapping_context(keyboard_and_mouse, true)) + + + diff --git a/guide_examples/top_down_shooter/top_down_shooter.gd.uid b/guide_examples/top_down_shooter/top_down_shooter.gd.uid new file mode 100644 index 0000000..a1ed5fa --- /dev/null +++ b/guide_examples/top_down_shooter/top_down_shooter.gd.uid @@ -0,0 +1 @@ +uid://sh4xv5urdau8 diff --git a/guide_examples/top_down_shooter/top_down_shooter.tscn b/guide_examples/top_down_shooter/top_down_shooter.tscn new file mode 100644 index 0000000..2d1c2a4 --- /dev/null +++ b/guide_examples/top_down_shooter/top_down_shooter.tscn @@ -0,0 +1,138 @@ +[gd_scene load_steps=18 format=3 uid="uid://kmamxwy5rcyc"] + +[ext_resource type="Script" path="res://guide_examples/top_down_shooter/top_down_shooter.gd" id="1_gvlv5"] +[ext_resource type="Script" path="res://guide_examples/top_down_shooter/player/player.gd" id="1_pm1t3"] +[ext_resource type="Resource" uid="uid://dhp7nup127wxw" path="res://guide_examples/top_down_shooter/mapping_contexts/keyboard_and_mouse.tres" id="2_bl5ot"] +[ext_resource type="Texture2D" uid="uid://c22k1y6rbntlw" path="res://guide_examples/top_down_shooter/player/mrg0000.png" id="2_rc4yh"] +[ext_resource type="Resource" uid="uid://dysrgn1ubf15g" path="res://guide_examples/top_down_shooter/mapping_contexts/controller.tres" id="3_tldv6"] +[ext_resource type="Resource" uid="uid://byu565ktximg2" path="res://guide_examples/top_down_shooter/mapping_contexts/switch_to_controller.tres" id="4_rfvaw"] +[ext_resource type="Resource" uid="uid://vpsh1myp67ws" path="res://guide_examples/top_down_shooter/mapping_contexts/look_relative.tres" id="5_hxqcn"] +[ext_resource type="Resource" uid="uid://bnd2jguy7tfti" path="res://guide_examples/top_down_shooter/mapping_contexts/switch_to_keyboard_and_mouse.tres" id="5_usevy"] +[ext_resource type="Resource" uid="uid://c4tpipfhludsi" path="res://guide_examples/top_down_shooter/mapping_contexts/look_absolute.tres" id="6_viqho"] +[ext_resource type="Resource" uid="uid://ch070wegl722t" path="res://guide_examples/top_down_shooter/mapping_contexts/move.tres" id="7_gtewy"] +[ext_resource type="Resource" uid="uid://coktqyup12g3w" path="res://guide_examples/top_down_shooter/mapping_contexts/fire.tres" id="8_kmeb0"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="9_kqgcv"] +[ext_resource type="PackedScene" uid="uid://c0fqv8e3tljmp" path="res://guide_examples/top_down_shooter/bolt/bolt.tscn" id="9_ybbsa"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="14_ipln3"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="15_d8ctw"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_jh0ar"] +radius = 118.54 + +[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_duktp"] + +[node name="TopDownShooter" type="Node2D"] +script = ExtResource("1_gvlv5") +keyboard_and_mouse = ExtResource("2_bl5ot") +controller = ExtResource("3_tldv6") +switch_to_controller = ExtResource("4_rfvaw") +switch_to_keyboard_and_mouse = ExtResource("5_usevy") + +[node name="Player" type="CharacterBody2D" parent="."] +position = Vector2(911, 479) +motion_mode = 1 +script = ExtResource("1_pm1t3") +look_relative = ExtResource("5_hxqcn") +look_absolute = ExtResource("6_viqho") +move = ExtResource("7_gtewy") +fire = ExtResource("8_kmeb0") +bolt = ExtResource("9_ybbsa") + +[node name="Mrg0000" type="Sprite2D" parent="Player"] +texture = ExtResource("2_rc4yh") +metadata/_edit_lock_ = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] +shape = SubResource("CircleShape2D_jh0ar") +metadata/_edit_lock_ = true + +[node name="LeftHand" type="Marker2D" parent="Player"] +unique_name_in_owner = true +position = Vector2(41, -105) +metadata/_edit_lock_ = true + +[node name="RightHand" type="Marker2D" parent="Player"] +unique_name_in_owner = true +position = Vector2(41, 109) +metadata/_edit_lock_ = true + +[node name="Boundary" type="StaticBody2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Boundary"] +position = Vector2(831, 1077) +shape = SubResource("WorldBoundaryShape2D_duktp") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="Boundary"] +position = Vector2(950, 1) +rotation = 3.14159 +shape = SubResource("WorldBoundaryShape2D_duktp") + +[node name="CollisionShape2D3" type="CollisionShape2D" parent="Boundary"] +position = Vector2(1919, 523) +rotation = 4.71239 +shape = SubResource("WorldBoundaryShape2D_duktp") + +[node name="CollisionShape2D4" type="CollisionShape2D" parent="Boundary"] +position = Vector2(-1, 530) +rotation = 1.5708 +shape = SubResource("WorldBoundaryShape2D_duktp") + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="CanvasLayer" instance=ExtResource("9_kqgcv")] +theme = ExtResource("14_ipln3") + +[node name="BG" type="CanvasLayer" parent="."] +layer = -1 + +[node name="ColorRect" type="ColorRect" parent="BG"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(0.0869374, 0.147497, 0.00609748, 1) + +[node name="UI Layer" type="CanvasLayer" parent="."] + +[node name="Instructions Label Controller" type="RichTextLabel" parent="UI Layer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -352.0 +offset_top = 15.0 +offset_right = -105.0 +offset_bottom = 38.0 +grow_horizontal = 0 +theme = ExtResource("14_ipln3") +script = ExtResource("15_d8ctw") +instructions_text = "Look around with %s. +Move with %s. +Fire with %s. + +Press any key or move the mouse to switch to +keyboard and mouse." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("5_hxqcn"), ExtResource("7_gtewy"), ExtResource("8_kmeb0")]) +limit_to_context = ExtResource("3_tldv6") +metadata/_edit_use_anchors_ = true + +[node name="Instructions Label Keyboard and Mouse" type="RichTextLabel" parent="UI Layer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -352.0 +offset_top = 15.0 +offset_right = -105.0 +offset_bottom = 38.0 +grow_horizontal = 0 +theme = ExtResource("14_ipln3") +script = ExtResource("15_d8ctw") +instructions_text = "Look around with %s. +Move with %s. +Fire with %s. + +Use any controller input to switch to controller." +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("6_viqho"), ExtResource("7_gtewy"), ExtResource("8_kmeb0")]) +limit_to_context = ExtResource("2_bl5ot") +metadata/_edit_use_anchors_ = true diff --git a/guide_examples/touch/background.gd b/guide_examples/touch/background.gd new file mode 100644 index 0000000..681b9a5 --- /dev/null +++ b/guide_examples/touch/background.gd @@ -0,0 +1,16 @@ +## This just keeps the sprite endlessly scrolling. It's not related to input. +extends Sprite2D + + +func _process(delta): + # get rect of visible screen in world coordinates + var rect = get_viewport().canvas_transform.affine_inverse() * get_viewport_rect() + # fit the bg into the viewport + global_position = rect.position + global_scale = rect.size / texture.get_size() + + # update scaling so the texture scales according to zoom level + material.set_shader_parameter("scale", global_scale) + var offset = rect.position / texture.get_size() + # and offset so we pick a texture offset relative to the movement of the camera + material.set_shader_parameter("offset", offset) diff --git a/guide_examples/touch/background.gd.uid b/guide_examples/touch/background.gd.uid new file mode 100644 index 0000000..6fef513 --- /dev/null +++ b/guide_examples/touch/background.gd.uid @@ -0,0 +1 @@ +uid://o678yabwitsl diff --git a/guide_examples/touch/background.svg b/guide_examples/touch/background.svg new file mode 100644 index 0000000..e649b9e --- /dev/null +++ b/guide_examples/touch/background.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/guide_examples/touch/background.svg.import b/guide_examples/touch/background.svg.import new file mode 100644 index 0000000..272297b --- /dev/null +++ b/guide_examples/touch/background.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://jveia1jgm1x5" +path="res://.godot/imported/background.svg-fba6babf7434090927a142c997b03f8a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/touch/background.svg" +dest_files=["res://.godot/imported/background.svg-fba6babf7434090927a142c997b03f8a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/guide_examples/touch/camera_2d.gd b/guide_examples/touch/camera_2d.gd new file mode 100644 index 0000000..23a5c44 --- /dev/null +++ b/guide_examples/touch/camera_2d.gd @@ -0,0 +1,42 @@ +## Camera control. We listen to GUIDE's actions to move and zoom the camera. Note how we can +## mix event-based and polling based input handling, depending on what works better for the +## use case. +extends Camera2D + + +@export var camera_movement:GUIDEAction +@export var camera_zoom:GUIDEAction +@export var camera_rotation:GUIDEAction +@export var camera_reset:GUIDEAction + + +@onready var _reference_zoom:Vector2 = zoom +@onready var _reference_rotation:float = rotation + +func _ready(): + camera_zoom.triggered.connect(_zoom_camera) + camera_rotation.triggered.connect(_rotate_camera) + camera_reset.triggered.connect(_reset_camera) + # whenever zooming completes, we store the new reference zoom + camera_zoom.completed.connect(func(): _reference_zoom = zoom) + # whenever rotation completes, we store the new reference rotation + camera_rotation.completed.connect(func(): _reference_rotation = rotation) + + + +func _process(delta): + position += camera_movement.value_axis_2d + + +func _zoom_camera(): + zoom = clamp( _reference_zoom * camera_zoom.value_axis_1d, Vector2(0.1, 0.1), Vector2(3, 3)) + +func _rotate_camera(): + rotation = fmod(_reference_rotation + camera_rotation.value_axis_1d, TAU) + + +func _reset_camera(): + zoom = Vector2.ONE + rotation = 0 + _reference_zoom = zoom + _reference_rotation = rotation diff --git a/guide_examples/touch/camera_2d.gd.uid b/guide_examples/touch/camera_2d.gd.uid new file mode 100644 index 0000000..f02c5ed --- /dev/null +++ b/guide_examples/touch/camera_2d.gd.uid @@ -0,0 +1 @@ +uid://bcr7lx14f4a7o diff --git a/guide_examples/touch/godot_head.gd b/guide_examples/touch/godot_head.gd new file mode 100644 index 0000000..2ca46aa --- /dev/null +++ b/guide_examples/touch/godot_head.gd @@ -0,0 +1,15 @@ +extends Node2D + +@export var lifetime_seconds:float = 5.0 +var _remaining_time_seconds:float = 0 + +func _ready(): + _remaining_time_seconds = lifetime_seconds + +func _process(delta:float) -> void: + _remaining_time_seconds -= delta + if _remaining_time_seconds <= 0: + queue_free() + return + + modulate.a = _remaining_time_seconds / lifetime_seconds diff --git a/guide_examples/touch/godot_head.gd.uid b/guide_examples/touch/godot_head.gd.uid new file mode 100644 index 0000000..0d2f810 --- /dev/null +++ b/guide_examples/touch/godot_head.gd.uid @@ -0,0 +1 @@ +uid://cpb72t1olm3ug diff --git a/guide_examples/touch/godot_head.tscn b/guide_examples/touch/godot_head.tscn new file mode 100644 index 0000000..f342585 --- /dev/null +++ b/guide_examples/touch/godot_head.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=3 uid="uid://c3kfkmt7p66c2"] + +[ext_resource type="Script" path="res://guide_examples/mouse_position_2d/godot_head.gd" id="1_1ibdt"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="2_8cdku"] + +[node name="GodotHead" type="Node2D"] +script = ExtResource("1_1ibdt") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("2_8cdku") diff --git a/guide_examples/touch/mapping_contexts/actions/camera_movement.tres b/guide_examples/touch/mapping_contexts/actions/camera_movement.tres new file mode 100644 index 0000000..45d1b4c --- /dev/null +++ b/guide_examples/touch/mapping_contexts/actions/camera_movement.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://brsk1axa7e3h"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_j5nuk"] + +[resource] +script = ExtResource("1_j5nuk") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/touch/mapping_contexts/actions/camera_reset.tres b/guide_examples/touch/mapping_contexts/actions/camera_reset.tres new file mode 100644 index 0000000..32dbfc5 --- /dev/null +++ b/guide_examples/touch/mapping_contexts/actions/camera_reset.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://dhtj0p55ylhcu"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_x2v6j"] + +[resource] +script = ExtResource("1_x2v6j") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/touch/mapping_contexts/actions/camera_rotation.tres b/guide_examples/touch/mapping_contexts/actions/camera_rotation.tres new file mode 100644 index 0000000..b302edf --- /dev/null +++ b/guide_examples/touch/mapping_contexts/actions/camera_rotation.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://dpu1f4xeigqdr"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_a2xs0"] + +[resource] +script = ExtResource("1_a2xs0") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/touch/mapping_contexts/actions/camera_zoom.tres b/guide_examples/touch/mapping_contexts/actions/camera_zoom.tres new file mode 100644 index 0000000..50c61e5 --- /dev/null +++ b/guide_examples/touch/mapping_contexts/actions/camera_zoom.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://b2xbr2rqob6gw"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_s4uaa"] + +[resource] +script = ExtResource("1_s4uaa") +name = &"" +action_value_type = 1 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/touch/mapping_contexts/actions/spawn.tres b/guide_examples/touch/mapping_contexts/actions/spawn.tres new file mode 100644 index 0000000..cff8473 --- /dev/null +++ b/guide_examples/touch/mapping_contexts/actions/spawn.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://iilpc2tjr5mx"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_4jgns"] + +[resource] +script = ExtResource("1_4jgns") +name = &"" +action_value_type = 2 +block_lower_priority_actions = false +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/touch/mapping_contexts/modifiers/zoom_sensitivity.tres b/guide_examples/touch/mapping_contexts/modifiers/zoom_sensitivity.tres new file mode 100644 index 0000000..dc6ecf2 --- /dev/null +++ b/guide_examples/touch/mapping_contexts/modifiers/zoom_sensitivity.tres @@ -0,0 +1,8 @@ +[gd_resource type="Resource" script_class="GUIDEModifierScale" load_steps=2 format=3 uid="uid://x0g11r4xtmcv"] + +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_scale.gd" id="1_42gxx"] + +[resource] +script = ExtResource("1_42gxx") +scale = Vector3(0.1, 1, 1) +apply_delta_time = false diff --git a/guide_examples/touch/mapping_contexts/touch.tres b/guide_examples/touch/mapping_contexts/touch.tres new file mode 100644 index 0000000..23d5e8a --- /dev/null +++ b/guide_examples/touch/mapping_contexts/touch.tres @@ -0,0 +1,157 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=41 format=3 uid="uid://bcepjnqawyxeb"] + +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_touch_position.gd" id="2_r7fg4"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_canvas_coordinates.gd" id="3_br0pk"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="4_ni8em"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="5_jvujq"] +[ext_resource type="Resource" uid="uid://brsk1axa7e3h" path="res://guide_examples/touch/mapping_contexts/actions/camera_movement.tres" id="6_5nijj"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_touch_axis_2d.gd" id="7_1c4fi"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="8_kce4k"] +[ext_resource type="Resource" uid="uid://b2xbr2rqob6gw" path="res://guide_examples/touch/mapping_contexts/actions/camera_zoom.tres" id="10_s0k2q"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_touch_distance.gd" id="10_xxwru"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_down.gd" id="11_q5ylu"] +[ext_resource type="Resource" uid="uid://iilpc2tjr5mx" path="res://guide_examples/touch/mapping_contexts/actions/spawn.tres" id="13_6meol"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_stability.gd" id="14_iw0b0"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="15_1y05x"] +[ext_resource type="Resource" uid="uid://dpu1f4xeigqdr" path="res://guide_examples/touch/mapping_contexts/actions/camera_rotation.tres" id="15_2s3pg"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_hold.gd" id="15_qneu5"] +[ext_resource type="Resource" uid="uid://dhtj0p55ylhcu" path="res://guide_examples/touch/mapping_contexts/actions/camera_reset.tres" id="16_r67n2"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_touch_angle.gd" id="16_xv1hs"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_tap.gd" id="17_h6kd2"] + +[sub_resource type="Resource" id="Resource_pajkc"] +script = ExtResource("7_1c4fi") +finger_count = 1 +finger_index = 0 + +[sub_resource type="Resource" id="Resource_citsh"] +script = ExtResource("8_kce4k") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_ojjbt"] +script = ExtResource("3_br0pk") +relative_input = true + +[sub_resource type="Resource" id="Resource_fagqu"] +script = ExtResource("4_ni8em") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_pajkc") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_citsh"), SubResource("Resource_ojjbt")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_hvdyr"] +script = ExtResource("5_jvujq") +action = ExtResource("6_5nijj") +input_mappings = Array[ExtResource("4_ni8em")]([SubResource("Resource_fagqu")]) + +[sub_resource type="Resource" id="Resource_6jr42"] +script = ExtResource("10_xxwru") + +[sub_resource type="Resource" id="Resource_oysb7"] +script = ExtResource("11_q5ylu") +actuation_threshold = 0.0 + +[sub_resource type="Resource" id="Resource_drjxq"] +script = ExtResource("4_ni8em") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_6jr42") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_oysb7")]) + +[sub_resource type="Resource" id="Resource_otc05"] +script = ExtResource("5_jvujq") +action = ExtResource("10_s0k2q") +input_mappings = Array[ExtResource("4_ni8em")]([SubResource("Resource_drjxq")]) + +[sub_resource type="Resource" id="Resource_7c46x"] +script = ExtResource("2_r7fg4") +finger_count = 1 +finger_index = 0 + +[sub_resource type="Resource" id="Resource_l3wvc"] +script = ExtResource("3_br0pk") +relative_input = false + +[sub_resource type="Resource" id="Resource_o1rij"] +script = ExtResource("14_iw0b0") +max_deviation = 1.0 +trigger_when = 0 +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_i8pe1"] +script = ExtResource("15_qneu5") +hold_treshold = 1.0 +is_one_shot = true +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_8n6aa"] +script = ExtResource("4_ni8em") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_7c46x") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_l3wvc")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_o1rij"), SubResource("Resource_i8pe1")]) + +[sub_resource type="Resource" id="Resource_iivaa"] +script = ExtResource("5_jvujq") +action = ExtResource("13_6meol") +input_mappings = Array[ExtResource("4_ni8em")]([SubResource("Resource_8n6aa")]) + +[sub_resource type="Resource" id="Resource_p0nkc"] +script = ExtResource("16_xv1hs") +unit = 0 + +[sub_resource type="Resource" id="Resource_6twam"] +script = ExtResource("4_ni8em") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_p0nkc") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_tt5mo"] +script = ExtResource("5_jvujq") +action = ExtResource("15_2s3pg") +input_mappings = Array[ExtResource("4_ni8em")]([SubResource("Resource_6twam")]) + +[sub_resource type="Resource" id="Resource_4nu5w"] +script = ExtResource("2_r7fg4") +finger_count = 3 +finger_index = 0 + +[sub_resource type="Resource" id="Resource_rvgtf"] +script = ExtResource("17_h6kd2") +tap_threshold = 0.2 +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_lpakr"] +script = ExtResource("4_ni8em") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_4nu5w") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_rvgtf")]) + +[sub_resource type="Resource" id="Resource_vikxq"] +script = ExtResource("5_jvujq") +action = ExtResource("16_r67n2") +input_mappings = Array[ExtResource("4_ni8em")]([SubResource("Resource_lpakr")]) + +[resource] +script = ExtResource("15_1y05x") +display_name = "" +mappings = Array[ExtResource("5_jvujq")]([SubResource("Resource_hvdyr"), SubResource("Resource_otc05"), SubResource("Resource_iivaa"), SubResource("Resource_tt5mo"), SubResource("Resource_vikxq")]) diff --git a/guide_examples/touch/placement_indicator/placement_indicator.gd b/guide_examples/touch/placement_indicator/placement_indicator.gd new file mode 100644 index 0000000..0978d56 --- /dev/null +++ b/guide_examples/touch/placement_indicator/placement_indicator.gd @@ -0,0 +1,26 @@ +# This component shows a progress bar for the hold time, indicating to the player +# that they must keep touching the screen until something is placed. +extends Node2D + +@export var spawn:GUIDEAction +@onready var texture_progress_bar:TextureProgressBar = %TextureProgressBar + +func _ready(): + visible = false + # While the hold trigger is evaluating show the progress bar + spawn.ongoing.connect(_show) + # Once it is done, hide it again + spawn.triggered.connect(_hide) + # Same when it was cancelled + spawn.cancelled.connect(_hide) + +func _show(): + # show the indicator + visible = true + # move it to where we would spawn + global_position = spawn.value_axis_2d + # and update the progress bar + texture_progress_bar.value = spawn.elapsed_seconds + +func _hide(): + visible = false diff --git a/guide_examples/touch/placement_indicator/placement_indicator.gd.uid b/guide_examples/touch/placement_indicator/placement_indicator.gd.uid new file mode 100644 index 0000000..66465f2 --- /dev/null +++ b/guide_examples/touch/placement_indicator/placement_indicator.gd.uid @@ -0,0 +1 @@ +uid://cnb3sumemposh diff --git a/guide_examples/touch/placement_indicator/placement_indicator.tscn b/guide_examples/touch/placement_indicator/placement_indicator.tscn new file mode 100644 index 0000000..8c2cf2f --- /dev/null +++ b/guide_examples/touch/placement_indicator/placement_indicator.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=4 format=3 uid="uid://c1ht6xduduxri"] + +[ext_resource type="Script" path="res://guide_examples/touch/placement_indicator/placement_indicator.gd" id="1_gnpc8"] +[ext_resource type="Resource" uid="uid://iilpc2tjr5mx" path="res://guide_examples/touch/mapping_contexts/actions/spawn.tres" id="2_grp35"] +[ext_resource type="Texture2D" uid="uid://geq3rs2fxqs4" path="res://guide_examples/touch/placement_indicator/radial_progress.png" id="2_slqs6"] + +[node name="PlacementIndicator" type="Node2D"] +script = ExtResource("1_gnpc8") +spawn = ExtResource("2_grp35") + +[node name="TextureProgressBar" type="TextureProgressBar" parent="."] +unique_name_in_owner = true +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -96.0 +offset_top = -96.0 +offset_right = 96.0 +offset_bottom = 96.0 +grow_horizontal = 2 +grow_vertical = 2 +max_value = 1.0 +step = 0.0 +fill_mode = 4 +texture_progress = ExtResource("2_slqs6") diff --git a/guide_examples/touch/placement_indicator/radial_progress.png b/guide_examples/touch/placement_indicator/radial_progress.png new file mode 100644 index 0000000..9ed97ef Binary files /dev/null and b/guide_examples/touch/placement_indicator/radial_progress.png differ diff --git a/guide_examples/touch/placement_indicator/radial_progress.png.import b/guide_examples/touch/placement_indicator/radial_progress.png.import new file mode 100644 index 0000000..e469567 --- /dev/null +++ b/guide_examples/touch/placement_indicator/radial_progress.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://geq3rs2fxqs4" +path="res://.godot/imported/radial_progress.png-a1f0b05f25628c67f45ec0be27847631.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/touch/placement_indicator/radial_progress.png" +dest_files=["res://.godot/imported/radial_progress.png-a1f0b05f25628c67f45ec0be27847631.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/guide_examples/touch/touch.gd b/guide_examples/touch/touch.gd new file mode 100644 index 0000000..8d4ed70 --- /dev/null +++ b/guide_examples/touch/touch.gd @@ -0,0 +1,24 @@ +## This example shows how to use touch gestures on mobile. +extends Node2D + + +@export var mapping_context:GUIDEMappingContext +@export var spawn:GUIDEAction + +@export var godot_head_scene:PackedScene + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) + spawn.triggered.connect(_spawn_godot_head) + + +func _spawn_godot_head(): + # Gets the mouse cursor from G.U.I.D.E. Note how the Canvas Coordinates + # modifier automatically gives us touch coordinates in canvas space + # which means we don't need to take into acount the camera panning and + # zoom level and can just use the coordinates we get to directly place + # a Godot head at the cursor position. + var head = godot_head_scene.instantiate() + add_child(head) + + head.global_position = spawn.value_axis_2d diff --git a/guide_examples/touch/touch.gd.uid b/guide_examples/touch/touch.gd.uid new file mode 100644 index 0000000..c49ccd6 --- /dev/null +++ b/guide_examples/touch/touch.gd.uid @@ -0,0 +1 @@ +uid://b1kmuvj74kgk8 diff --git a/guide_examples/touch/touch.tscn b/guide_examples/touch/touch.tscn new file mode 100644 index 0000000..880f616 --- /dev/null +++ b/guide_examples/touch/touch.tscn @@ -0,0 +1,88 @@ +[gd_scene load_steps=18 format=3 uid="uid://hxx7y33rfrnh"] + +[ext_resource type="Script" path="res://guide_examples/touch/touch.gd" id="1_gq4pr"] +[ext_resource type="Resource" uid="uid://bcepjnqawyxeb" path="res://guide_examples/touch/mapping_contexts/touch.tres" id="2_btyg8"] +[ext_resource type="Resource" uid="uid://iilpc2tjr5mx" path="res://guide_examples/touch/mapping_contexts/actions/spawn.tres" id="3_nwdqb"] +[ext_resource type="Script" path="res://guide_examples/touch/camera_2d.gd" id="5_k0qyy"] +[ext_resource type="PackedScene" uid="uid://c3kfkmt7p66c2" path="res://guide_examples/touch/godot_head.tscn" id="5_mimge"] +[ext_resource type="Resource" uid="uid://brsk1axa7e3h" path="res://guide_examples/touch/mapping_contexts/actions/camera_movement.tres" id="7_hbc7d"] +[ext_resource type="Resource" uid="uid://b2xbr2rqob6gw" path="res://guide_examples/touch/mapping_contexts/actions/camera_zoom.tres" id="8_t7xto"] +[ext_resource type="Texture2D" uid="uid://slnmn5k0drdb" path="res://guide_examples/mouse_position_2d/background.svg" id="9_0mhj2"] +[ext_resource type="Script" path="res://guide_examples/mouse_position_2d/background.gd" id="10_7apxo"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="11_bclaf"] +[ext_resource type="PackedScene" uid="uid://c1ht6xduduxri" path="res://guide_examples/touch/placement_indicator/placement_indicator.tscn" id="12_e3xb3"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="12_fwxrg"] +[ext_resource type="Resource" uid="uid://dpu1f4xeigqdr" path="res://guide_examples/touch/mapping_contexts/actions/camera_rotation.tres" id="13_lmkyb"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="13_n0vwi"] +[ext_resource type="Resource" uid="uid://dhtj0p55ylhcu" path="res://guide_examples/touch/mapping_contexts/actions/camera_reset.tres" id="14_bfrfr"] + +[sub_resource type="Shader" id="Shader_v4pj1"] +code = "shader_type canvas_item; + +uniform vec2 scale; +uniform vec2 offset; + +void vertex() { + UV = UV * scale + offset; +} + + +//void light() { + // Called for every pixel for every light affecting the CanvasItem. + // Uncomment to replace the default light processing function with this one. +//} +" + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_1sa2x"] +shader = SubResource("Shader_v4pj1") +shader_parameter/scale = Vector2(1, 1) +shader_parameter/offset = Vector2(0, 0) + +[node name="Touch" type="Node2D"] +script = ExtResource("1_gq4pr") +mapping_context = ExtResource("2_btyg8") +spawn = ExtResource("3_nwdqb") +godot_head_scene = ExtResource("5_mimge") + +[node name="Camera2D" type="Camera2D" parent="."] +ignore_rotation = false +script = ExtResource("5_k0qyy") +camera_movement = ExtResource("7_hbc7d") +camera_zoom = ExtResource("8_t7xto") +camera_rotation = ExtResource("13_lmkyb") +camera_reset = ExtResource("14_bfrfr") + +[node name="BG" type="Sprite2D" parent="."] +texture_repeat = 2 +material = SubResource("ShaderMaterial_1sa2x") +texture = ExtResource("9_0mhj2") +centered = false +script = ExtResource("10_7apxo") + +[node name="PlacementIndicator" parent="." instance=ExtResource("12_e3xb3")] + +[node name="UILayer" type="CanvasLayer" parent="."] + +[node name="RichTextLabel" type="RichTextLabel" parent="UILayer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -107.0 +offset_top = 41.0 +offset_right = -67.0 +offset_bottom = 81.0 +grow_horizontal = 0 +theme = ExtResource("11_bclaf") +script = ExtResource("12_fwxrg") +instructions_text = "%s to move the camera. +%s to zoom the camera. +%s to rotate the camera. +%s to reset the camera zoom and rotation. +%s to place a Godot head. +" +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("7_hbc7d"), ExtResource("8_t7xto"), ExtResource("13_lmkyb"), ExtResource("14_bfrfr"), ExtResource("3_nwdqb")]) + +[node name="DebuggerLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="DebuggerLayer" instance=ExtResource("13_n0vwi")] +theme = ExtResource("11_bclaf") diff --git a/guide_examples/two_joysticks/actions/player_one_move.tres b/guide_examples/two_joysticks/actions/player_one_move.tres new file mode 100644 index 0000000..483bfdb --- /dev/null +++ b/guide_examples/two_joysticks/actions/player_one_move.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://d31d5dpoavou1"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_w3ruv"] + +[resource] +script = ExtResource("1_w3ruv") +name = &"player_one_move" +action_value_type = 2 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/two_joysticks/actions/player_two_move.tres b/guide_examples/two_joysticks/actions/player_two_move.tres new file mode 100644 index 0000000..731216f --- /dev/null +++ b/guide_examples/two_joysticks/actions/player_two_move.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://7g78pa31v44m"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_cuk0c"] + +[resource] +script = ExtResource("1_cuk0c") +name = &"player_two_move" +action_value_type = 2 +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/two_joysticks/modifiers/joystick_deadzone.tres b/guide_examples/two_joysticks/modifiers/joystick_deadzone.tres new file mode 100644 index 0000000..8d984cc --- /dev/null +++ b/guide_examples/two_joysticks/modifiers/joystick_deadzone.tres @@ -0,0 +1,8 @@ +[gd_resource type="Resource" script_class="GUIDEModifierDeadzone" load_steps=2 format=3 uid="uid://cxd3gqa1bof30"] + +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_deadzone.gd" id="1_ax1vk"] + +[resource] +script = ExtResource("1_ax1vk") +lower_threshold = 0.2 +upper_threshold = 1.0 diff --git a/guide_examples/two_joysticks/player.gd b/guide_examples/two_joysticks/player.gd new file mode 100644 index 0000000..50906f3 --- /dev/null +++ b/guide_examples/two_joysticks/player.gd @@ -0,0 +1,12 @@ +## This is the player script. Note how we can use the same script for both +## players, by just injecting different actions into them. No needs to check +## which player input we should consume. +extends Node2D + +@export var speed:float = 150 + +@export var move_action:GUIDEAction + +func _process(delta:float) -> void: + position += move_action.value_axis_2d.normalized() * speed * delta + diff --git a/guide_examples/two_joysticks/player.gd.uid b/guide_examples/two_joysticks/player.gd.uid new file mode 100644 index 0000000..7248a5c --- /dev/null +++ b/guide_examples/two_joysticks/player.gd.uid @@ -0,0 +1 @@ +uid://c73evv6t30of diff --git a/guide_examples/two_joysticks/two_joysticks.gd b/guide_examples/two_joysticks/two_joysticks.gd new file mode 100644 index 0000000..aa233b6 --- /dev/null +++ b/guide_examples/two_joysticks/two_joysticks.gd @@ -0,0 +1,6 @@ +extends Node2D + +@export var mapping_context:GUIDEMappingContext + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) diff --git a/guide_examples/two_joysticks/two_joysticks.gd.uid b/guide_examples/two_joysticks/two_joysticks.gd.uid new file mode 100644 index 0000000..0528c60 --- /dev/null +++ b/guide_examples/two_joysticks/two_joysticks.gd.uid @@ -0,0 +1 @@ +uid://byg4578fnips6 diff --git a/guide_examples/two_joysticks/two_joysticks.tres b/guide_examples/two_joysticks/two_joysticks.tres new file mode 100644 index 0000000..66c8efa --- /dev/null +++ b/guide_examples/two_joysticks/two_joysticks.tres @@ -0,0 +1,56 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=14 format=3 uid="uid://chr8ugns0fh70"] + +[ext_resource type="Resource" uid="uid://d31d5dpoavou1" path="res://guide_examples/two_joysticks/actions/player_one_move.tres" id="1_d7e45"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_sp28b"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_axis_2d.gd" id="2_exwu1"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="3_ga6gt"] +[ext_resource type="Resource" uid="uid://cxd3gqa1bof30" path="res://guide_examples/two_joysticks/modifiers/joystick_deadzone.tres" id="3_xy1jy"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="4_mvoug"] +[ext_resource type="Resource" uid="uid://7g78pa31v44m" path="res://guide_examples/two_joysticks/actions/player_two_move.tres" id="5_aeoun"] + +[sub_resource type="Resource" id="Resource_jkkrr"] +script = ExtResource("2_exwu1") +x = 0 +y = 1 +joy_index = 0 + +[sub_resource type="Resource" id="Resource_6efv4"] +script = ExtResource("3_ga6gt") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_jkkrr") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([ExtResource("3_xy1jy")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_kv6y3"] +script = ExtResource("4_mvoug") +action = ExtResource("1_d7e45") +input_mappings = Array[ExtResource("3_ga6gt")]([SubResource("Resource_6efv4")]) + +[sub_resource type="Resource" id="Resource_660yw"] +script = ExtResource("2_exwu1") +x = 0 +y = 1 +joy_index = 1 + +[sub_resource type="Resource" id="Resource_kg721"] +script = ExtResource("3_ga6gt") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_660yw") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([ExtResource("3_xy1jy")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_6ruab"] +script = ExtResource("4_mvoug") +action = ExtResource("5_aeoun") +input_mappings = Array[ExtResource("3_ga6gt")]([SubResource("Resource_kg721")]) + +[resource] +script = ExtResource("1_sp28b") +display_name = "Player Input" +mappings = Array[ExtResource("4_mvoug")]([SubResource("Resource_kv6y3"), SubResource("Resource_6ruab")]) diff --git a/guide_examples/two_joysticks/two_joysticks.tscn b/guide_examples/two_joysticks/two_joysticks.tscn new file mode 100644 index 0000000..aee6f0a --- /dev/null +++ b/guide_examples/two_joysticks/two_joysticks.tscn @@ -0,0 +1,39 @@ +[gd_scene load_steps=8 format=3 uid="uid://b2uycqcjf0hth"] + +[ext_resource type="Script" path="res://guide_examples/two_joysticks/two_joysticks.gd" id="1_1dy65"] +[ext_resource type="Resource" uid="uid://chr8ugns0fh70" path="res://guide_examples/two_joysticks/two_joysticks.tres" id="2_3p2l3"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="2_c65ah"] +[ext_resource type="Script" path="res://guide_examples/two_joysticks/player.gd" id="3_3ycuu"] +[ext_resource type="Resource" uid="uid://d31d5dpoavou1" path="res://guide_examples/two_joysticks/actions/player_one_move.tres" id="4_f356y"] +[ext_resource type="Resource" uid="uid://7g78pa31v44m" path="res://guide_examples/two_joysticks/actions/player_two_move.tres" id="5_700m5"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="7_ojfv8"] + +[node name="TwoJoysticks" type="Node2D"] +script = ExtResource("1_1dy65") +mapping_context = ExtResource("2_3p2l3") + +[node name="Label" type="Label" parent="."] +offset_left = 1359.0 +offset_top = 13.0 +offset_right = 1909.0 +offset_bottom = 135.0 +text = "This demonstrates how to consume different actions in the same script. We have two players each one controlled by a joystick. Both players share a single script and just listen to different actions which are given as export parameters." +autowrap_mode = 2 + +[node name="Player1" type="Sprite2D" parent="."] +position = Vector2(509, 509) +texture = ExtResource("2_c65ah") +script = ExtResource("3_3ycuu") +move_action = ExtResource("4_f356y") + +[node name="Player2" type="Sprite2D" parent="."] +modulate = Color(1, 0.533333, 1, 1) +position = Vector2(1315, 505) +texture = ExtResource("2_c65ah") +script = ExtResource("3_3ycuu") +move_action = ExtResource("5_700m5") + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="CanvasLayer" instance=ExtResource("7_ojfv8")] +metadata/_edit_lock_ = true diff --git a/guide_examples/virtual_cursor/mapping_contexts/actions/click.tres b/guide_examples/virtual_cursor/mapping_contexts/actions/click.tres new file mode 100644 index 0000000..8e28007 --- /dev/null +++ b/guide_examples/virtual_cursor/mapping_contexts/actions/click.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cwtdxy3gy7kud"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_jeypp"] + +[resource] +script = ExtResource("1_jeypp") +name = &"" +action_value_type = 0 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/virtual_cursor/mapping_contexts/actions/cursor_2d.tres b/guide_examples/virtual_cursor/mapping_contexts/actions/cursor_2d.tres new file mode 100644 index 0000000..98fe976 --- /dev/null +++ b/guide_examples/virtual_cursor/mapping_contexts/actions/cursor_2d.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bcumfh8j6k1ln"] + +[ext_resource type="Script" path="res://addons/guide/guide_action.gd" id="1_25sbb"] + +[resource] +script = ExtResource("1_25sbb") +name = &"" +action_value_type = 2 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" diff --git a/guide_examples/virtual_cursor/mapping_contexts/virtual_cursor.tres b/guide_examples/virtual_cursor/mapping_contexts/virtual_cursor.tres new file mode 100644 index 0000000..41782d1 --- /dev/null +++ b/guide_examples/virtual_cursor/mapping_contexts/virtual_cursor.tres @@ -0,0 +1,80 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=22 format=3 uid="uid://b4tn11iq7uvr7"] + +[ext_resource type="Resource" uid="uid://bcumfh8j6k1ln" path="res://guide_examples/virtual_cursor/mapping_contexts/actions/cursor_2d.tres" id="1_0amnw"] +[ext_resource type="Script" path="res://addons/guide/guide_action_mapping.gd" id="1_0ixy4"] +[ext_resource type="Script" path="res://addons/guide/guide_mapping_context.gd" id="1_hs8l5"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_axis_2d.gd" id="2_6ps54"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_deadzone.gd" id="3_jknka"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_virtual_cursor.gd" id="3_smvwl"] +[ext_resource type="Script" path="res://addons/guide/modifiers/guide_modifier_canvas_coordinates.gd" id="4_w4o86"] +[ext_resource type="Script" path="res://addons/guide/guide_input_mapping.gd" id="5_ucwra"] +[ext_resource type="Resource" uid="uid://cwtdxy3gy7kud" path="res://guide_examples/virtual_cursor/mapping_contexts/actions/click.tres" id="8_2fjde"] +[ext_resource type="Script" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="9_15a8y"] +[ext_resource type="Script" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="10_caax3"] + +[sub_resource type="Resource" id="Resource_51lnp"] +script = ExtResource("2_6ps54") +x = 0 +y = 1 +joy_index = 0 + +[sub_resource type="Resource" id="Resource_vtltt"] +script = ExtResource("3_jknka") +lower_threshold = 0.2 +upper_threshold = 1.0 + +[sub_resource type="Resource" id="Resource_tn5ov"] +script = ExtResource("3_smvwl") +initial_position = Vector2(0.5, 0.5) +speed = Vector3(1, 1, 1) +screen_scale = 1 +apply_delta_time = true +scale = Vector3(1, 1, 1) + +[sub_resource type="Resource" id="Resource_r6xcs"] +script = ExtResource("4_w4o86") +relative_input = false + +[sub_resource type="Resource" id="Resource_jede7"] +script = ExtResource("5_ucwra") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_51lnp") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([SubResource("Resource_vtltt"), SubResource("Resource_tn5ov"), SubResource("Resource_r6xcs")]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([]) + +[sub_resource type="Resource" id="Resource_phyr3"] +script = ExtResource("1_0ixy4") +action = ExtResource("1_0amnw") +input_mappings = Array[ExtResource("5_ucwra")]([SubResource("Resource_jede7")]) + +[sub_resource type="Resource" id="Resource_5fidk"] +script = ExtResource("9_15a8y") +button = 0 +joy_index = 0 + +[sub_resource type="Resource" id="Resource_m13js"] +script = ExtResource("10_caax3") +actuation_threshold = 0.5 + +[sub_resource type="Resource" id="Resource_mnbnv"] +script = ExtResource("5_ucwra") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_5fidk") +modifiers = Array[Resource("res://addons/guide/modifiers/guide_modifier.gd")]([]) +triggers = Array[Resource("res://addons/guide/triggers/guide_trigger.gd")]([SubResource("Resource_m13js")]) + +[sub_resource type="Resource" id="Resource_7601p"] +script = ExtResource("1_0ixy4") +action = ExtResource("8_2fjde") +input_mappings = Array[ExtResource("5_ucwra")]([SubResource("Resource_mnbnv")]) + +[resource] +script = ExtResource("1_hs8l5") +display_name = "" +mappings = Array[ExtResource("1_0ixy4")]([SubResource("Resource_phyr3"), SubResource("Resource_7601p")]) diff --git a/guide_examples/virtual_cursor/pointable/pointable.gd b/guide_examples/virtual_cursor/pointable/pointable.gd new file mode 100644 index 0000000..f79a0d8 --- /dev/null +++ b/guide_examples/virtual_cursor/pointable/pointable.gd @@ -0,0 +1,15 @@ +extends Area2D + + +var _is_spinning:bool = false + +func spin(): + if _is_spinning: + return + _is_spinning = true + var tween := create_tween() + tween.tween_property(self, "rotation_degrees", 360, 0.5) + await tween.finished + + rotation_degrees = 0 + _is_spinning = false diff --git a/guide_examples/virtual_cursor/pointable/pointable.gd.uid b/guide_examples/virtual_cursor/pointable/pointable.gd.uid new file mode 100644 index 0000000..031ac6a --- /dev/null +++ b/guide_examples/virtual_cursor/pointable/pointable.gd.uid @@ -0,0 +1 @@ +uid://dghhpx6mxb4lr diff --git a/guide_examples/virtual_cursor/pointable/pointable.tscn b/guide_examples/virtual_cursor/pointable/pointable.tscn new file mode 100644 index 0000000..bbb270d --- /dev/null +++ b/guide_examples/virtual_cursor/pointable/pointable.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=4 format=3 uid="uid://ca51sup6v0qr1"] + +[ext_resource type="Script" path="res://guide_examples/virtual_cursor/pointable/pointable.gd" id="1_ujxlw"] +[ext_resource type="Texture2D" uid="uid://byjxtsekdl8t2" path="res://guide_examples/shared/godot_logo.svg" id="2_i12oa"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_cccqq"] +size = Vector2(128, 128) + +[node name="Pointable" type="Area2D"] +monitoring = false +script = ExtResource("1_ujxlw") + +[node name="GodotLogo" type="Sprite2D" parent="."] +texture = ExtResource("2_i12oa") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_cccqq") diff --git a/guide_examples/virtual_cursor/pointer.gd b/guide_examples/virtual_cursor/pointer.gd new file mode 100644 index 0000000..8b53ed7 --- /dev/null +++ b/guide_examples/virtual_cursor/pointer.gd @@ -0,0 +1,17 @@ +extends Area2D + +@export var cursor_2d:GUIDEAction +@export var click:GUIDEAction + + +func _ready(): + click.triggered.connect(_click) + +func _process(delta): + global_position = cursor_2d.value_axis_2d + + +func _click(): + for clickable in get_overlapping_areas(): + if clickable.has_method("spin"): + clickable.spin() diff --git a/guide_examples/virtual_cursor/pointer.gd.uid b/guide_examples/virtual_cursor/pointer.gd.uid new file mode 100644 index 0000000..ee9f4c4 --- /dev/null +++ b/guide_examples/virtual_cursor/pointer.gd.uid @@ -0,0 +1 @@ +uid://cyhgr4oiher4l diff --git a/guide_examples/virtual_cursor/pointer.svg b/guide_examples/virtual_cursor/pointer.svg new file mode 100644 index 0000000..fc2721f --- /dev/null +++ b/guide_examples/virtual_cursor/pointer.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/guide_examples/virtual_cursor/pointer.svg.import b/guide_examples/virtual_cursor/pointer.svg.import new file mode 100644 index 0000000..a1b1d58 --- /dev/null +++ b/guide_examples/virtual_cursor/pointer.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ntkhw87eedc0" +path="res://.godot/imported/pointer.svg-2068835178847b731dd1d6754048fd27.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://guide_examples/virtual_cursor/pointer.svg" +dest_files=["res://.godot/imported/pointer.svg-2068835178847b731dd1d6754048fd27.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/guide_examples/virtual_cursor/virtual_cursor.gd b/guide_examples/virtual_cursor/virtual_cursor.gd new file mode 100644 index 0000000..a11d284 --- /dev/null +++ b/guide_examples/virtual_cursor/virtual_cursor.gd @@ -0,0 +1,7 @@ +extends Node2D + +@export var mapping_context:GUIDEMappingContext + + +func _ready(): + GUIDE.enable_mapping_context(mapping_context) diff --git a/guide_examples/virtual_cursor/virtual_cursor.gd.uid b/guide_examples/virtual_cursor/virtual_cursor.gd.uid new file mode 100644 index 0000000..98b6068 --- /dev/null +++ b/guide_examples/virtual_cursor/virtual_cursor.gd.uid @@ -0,0 +1 @@ +uid://dvv04npvyv3mh diff --git a/guide_examples/virtual_cursor/virtual_cursor.tscn b/guide_examples/virtual_cursor/virtual_cursor.tscn new file mode 100644 index 0000000..1ba8b37 --- /dev/null +++ b/guide_examples/virtual_cursor/virtual_cursor.tscn @@ -0,0 +1,80 @@ +[gd_scene load_steps=12 format=3 uid="uid://b1f0bnaomla7u"] + +[ext_resource type="Script" path="res://guide_examples/virtual_cursor/virtual_cursor.gd" id="1_g0bre"] +[ext_resource type="Resource" uid="uid://b4tn11iq7uvr7" path="res://guide_examples/virtual_cursor/mapping_contexts/virtual_cursor.tres" id="2_4xju7"] +[ext_resource type="Texture2D" uid="uid://ntkhw87eedc0" path="res://guide_examples/virtual_cursor/pointer.svg" id="2_mxnae"] +[ext_resource type="Script" path="res://guide_examples/virtual_cursor/pointer.gd" id="3_dw1p5"] +[ext_resource type="PackedScene" uid="uid://ca51sup6v0qr1" path="res://guide_examples/virtual_cursor/pointable/pointable.tscn" id="3_uy61q"] +[ext_resource type="Resource" uid="uid://bcumfh8j6k1ln" path="res://guide_examples/virtual_cursor/mapping_contexts/actions/cursor_2d.tres" id="5_tj3fv"] +[ext_resource type="Resource" uid="uid://cwtdxy3gy7kud" path="res://guide_examples/virtual_cursor/mapping_contexts/actions/click.tres" id="6_1ffq2"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="6_hfxka"] +[ext_resource type="Theme" uid="uid://dot0gi1yoqmrl" path="res://guide_examples/shared/ui_theme.tres" id="7_bh7yl"] +[ext_resource type="Script" path="res://guide_examples/shared/instructions_label.gd" id="7_udsq5"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_ltt1b"] +radius = 32.95 + +[node name="VirtualCursor" type="Node2D"] +script = ExtResource("1_g0bre") +mapping_context = ExtResource("2_4xju7") + +[node name="Pointable" parent="." instance=ExtResource("3_uy61q")] +position = Vector2(358, 282) + +[node name="Pointable2" parent="." instance=ExtResource("3_uy61q")] +position = Vector2(915, 209) + +[node name="Pointable3" parent="." instance=ExtResource("3_uy61q")] +position = Vector2(1177, 621) + +[node name="Pointable4" parent="." instance=ExtResource("3_uy61q")] +position = Vector2(338, 859) + +[node name="Pointable5" parent="." instance=ExtResource("3_uy61q")] +position = Vector2(1476, 274) + +[node name="Pointable6" parent="." instance=ExtResource("3_uy61q")] +position = Vector2(791, 808) + +[node name="Pointable7" parent="." instance=ExtResource("3_uy61q")] +position = Vector2(605, 499) + +[node name="Pointable8" parent="." instance=ExtResource("3_uy61q")] +position = Vector2(1515, 845) + +[node name="Pointer" type="Area2D" parent="."] +position = Vector2(813, 485) +script = ExtResource("3_dw1p5") +cursor_2d = ExtResource("5_tj3fv") +click = ExtResource("6_1ffq2") + +[node name="PointerVisual" type="Sprite2D" parent="Pointer"] +texture = ExtResource("2_mxnae") +centered = false + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Pointer"] +shape = SubResource("CircleShape2D_ltt1b") + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="CanvasLayer" instance=ExtResource("6_hfxka")] +theme = ExtResource("7_bh7yl") + +[node name="UILayer" type="CanvasLayer" parent="."] + +[node name="RichTextLabel" type="RichTextLabel" parent="UILayer"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -104.0 +offset_top = 56.0 +offset_right = -64.0 +offset_bottom = 96.0 +grow_horizontal = 0 +theme = ExtResource("7_bh7yl") +script = ExtResource("7_udsq5") +instructions_text = "This shows how to use a controller stick to control a virtual cursor. + +%s to move the the cursor +%s to \"click\"" +actions = Array[Resource("res://addons/guide/guide_action.gd")]([ExtResource("5_tj3fv"), ExtResource("6_1ffq2")]) diff --git a/main.tscn b/main.tscn index 5c9c62c..0a47101 100644 --- a/main.tscn +++ b/main.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=5 format=3 uid="uid://cxbskue0lj2gv"] +[gd_scene load_steps=6 format=3 uid="uid://cxbskue0lj2gv"] [ext_resource type="PackedScene" uid="uid://bei4nhkf8lwdo" path="res://player_controller/PlayerController.tscn" id="1_ig7tw"] +[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="2_0xm2m"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_0xm2m"] sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) @@ -171,3 +172,7 @@ size = Vector3(1.10791, 1.71436, 23.4043) [node name="Player" parent="." instance=ExtResource("1_ig7tw")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 30.2019, 12.6118, 13.3006) + +[node name="DebugLayer" type="CanvasLayer" parent="."] + +[node name="GuideDebugger" parent="DebugLayer" instance=ExtResource("2_0xm2m")] diff --git a/player_controller/PlayerController.tscn b/player_controller/PlayerController.tscn index 00a737d..2c4ac51 100644 --- a/player_controller/PlayerController.tscn +++ b/player_controller/PlayerController.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=26 format=3 uid="uid://bei4nhkf8lwdo"] +[gd_scene load_steps=30 format=3 uid="uid://bei4nhkf8lwdo"] [ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"] [ext_resource type="Material" uid="uid://dtq8i1ka1f2pn" path="res://player_controller/Assets/Materials/Health/CameraVignette.tres" id="2_6hee7"] @@ -15,6 +15,10 @@ [ext_resource type="Script" uid="uid://c6bx47wr7fbdm" path="res://player_controller/Scripts/Mouse.cs" id="11_huhen"] [ext_resource type="Script" uid="uid://b6k73aj5povgv" path="res://player_controller/Scripts/FieldOfView.cs" id="12_m2mxi"] [ext_resource type="Script" uid="uid://bt8flen3mi28r" path="res://player_controller/Scripts/AnimationPlayer.cs" id="13_vnh4e"] +[ext_resource type="Script" uid="uid://b5nk6ntlps3x0" path="res://systems/inputs/input_system.gd" id="16_v31n3"] +[ext_resource type="Resource" uid="uid://htqvokm8mufq" path="res://systems/inputs/walk_mode/move.tres" id="17_h6vvl"] +[ext_resource type="Resource" uid="uid://dijkqkltwkrfe" path="res://systems/inputs/walk_mode/walk_mode.tres" id="18_sik0q"] +[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://systems/inputs/walk_mode/rotate_y.tres" id="18_yvnfg"] [sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"] @@ -249,3 +253,9 @@ target_position = Vector3(0, 1, 0) [node name="HeadCollisionDetector3" type="RayCast3D" parent="HeadCollisionDetectors"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.296, 1.4, 0) target_position = Vector3(0, 1, 0) + +[node name="InputController" type="Node3D" parent="."] +script = ExtResource("16_v31n3") +move = ExtResource("17_h6vvl") +rotate_player = ExtResource("18_yvnfg") +walk_mode = ExtResource("18_sik0q") diff --git a/player_controller/Scripts/Mouse.cs b/player_controller/Scripts/Mouse.cs index 95aa045..a0526bd 100644 --- a/player_controller/Scripts/Mouse.cs +++ b/player_controller/Scripts/Mouse.cs @@ -8,6 +8,8 @@ public partial class Mouse : Node3D [Export(PropertyHint.Range, "0,0.1,0.001,or_greater")] public float Sensitivity { get; set; } = 0.004f; + + private Node3D _head; private Camera3D _camera; diff --git a/project.godot b/project.godot index 8d2f904..1c3c6c5 100644 --- a/project.godot +++ b/project.godot @@ -15,10 +15,18 @@ run/main_scene="uid://cxbskue0lj2gv" config/features=PackedStringArray("4.4", "C#", "Forward Plus") config/icon="res://icon.svg" +[autoload] + +GUIDE="*res://addons/guide/guide.gd" + [dotnet] project/assembly_name="Movement tests" +[editor_plugins] + +enabled=PackedStringArray("res://addons/guide/plugin.cfg") + [input] up={ diff --git a/systems/inputs/input_system.gd b/systems/inputs/input_system.gd new file mode 100644 index 0000000..994ec2b --- /dev/null +++ b/systems/inputs/input_system.gd @@ -0,0 +1,12 @@ +extends Node3D + +@export var move:GUIDEAction +@export var rotate_player:GUIDEAction +@export var walk_mode:GUIDEMappingContext + +func _ready() -> void: + GUIDE.enable_mapping_context(walk_mode) + +func _process(delta: float) -> void: + # print(move.value_axis_3d) + pass diff --git a/systems/inputs/input_system.gd.uid b/systems/inputs/input_system.gd.uid new file mode 100644 index 0000000..a52c722 --- /dev/null +++ b/systems/inputs/input_system.gd.uid @@ -0,0 +1 @@ +uid://b5nk6ntlps3x0 diff --git a/systems/inputs/walk_mode/move.tres b/systems/inputs/walk_mode/move.tres new file mode 100644 index 0000000..eefd145 --- /dev/null +++ b/systems/inputs/walk_mode/move.tres @@ -0,0 +1,14 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://htqvokm8mufq"] + +[ext_resource type="Script" uid="uid://cluhc11vixkf1" path="res://addons/guide/guide_action.gd" id="1_xhsni"] + +[resource] +script = ExtResource("1_xhsni") +name = &"" +action_value_type = 3 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" +metadata/_custom_type_script = "uid://cluhc11vixkf1" diff --git a/systems/inputs/walk_mode/rotate_floorplane.tres b/systems/inputs/walk_mode/rotate_floorplane.tres new file mode 100644 index 0000000..e95676e --- /dev/null +++ b/systems/inputs/walk_mode/rotate_floorplane.tres @@ -0,0 +1,14 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://ccrb5xsnphc8"] + +[ext_resource type="Script" uid="uid://cluhc11vixkf1" path="res://addons/guide/guide_action.gd" id="1_glvw1"] + +[resource] +script = ExtResource("1_glvw1") +name = &"" +action_value_type = 1 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" +metadata/_custom_type_script = "uid://cluhc11vixkf1" diff --git a/systems/inputs/walk_mode/rotate_y.tres b/systems/inputs/walk_mode/rotate_y.tres new file mode 100644 index 0000000..3db2d94 --- /dev/null +++ b/systems/inputs/walk_mode/rotate_y.tres @@ -0,0 +1,14 @@ +[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://cpdaw41ah5gic"] + +[ext_resource type="Script" uid="uid://cluhc11vixkf1" path="res://addons/guide/guide_action.gd" id="1_3jk50"] + +[resource] +script = ExtResource("1_3jk50") +name = &"" +action_value_type = 1 +block_lower_priority_actions = true +emit_as_godot_actions = false +is_remappable = false +display_name = "" +display_category = "" +metadata/_custom_type_script = "uid://cluhc11vixkf1" diff --git a/systems/inputs/walk_mode/walk_mode.tres b/systems/inputs/walk_mode/walk_mode.tres new file mode 100644 index 0000000..90f9fb4 --- /dev/null +++ b/systems/inputs/walk_mode/walk_mode.tres @@ -0,0 +1,242 @@ +[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=49 format=3 uid="uid://dijkqkltwkrfe"] + +[ext_resource type="Script" uid="uid://cpplm41b5bt6m" path="res://addons/guide/guide_action_mapping.gd" id="1_gh445"] +[ext_resource type="Resource" uid="uid://htqvokm8mufq" path="res://systems/inputs/walk_mode/move.tres" id="2_h1oqo"] +[ext_resource type="Script" uid="uid://dsa1dnifd6w32" path="res://addons/guide/guide_mapping_context.gd" id="2_vcm25"] +[ext_resource type="Script" uid="uid://mtx1unc2aqn7" path="res://addons/guide/guide_input_mapping.gd" id="3_pgmnb"] +[ext_resource type="Script" uid="uid://cw71o87tvdx3q" path="res://addons/guide/inputs/guide_input_key.gd" id="4_t5475"] +[ext_resource type="Script" uid="uid://bl8rjl4oaldje" path="res://addons/guide/modifiers/guide_modifier.gd" id="5_dts0n"] +[ext_resource type="Script" uid="uid://ckggy40lm0vjc" path="res://addons/guide/modifiers/guide_modifier_negate.gd" id="6_1advh"] +[ext_resource type="Script" uid="uid://bm5gjgadon6hb" path="res://addons/guide/modifiers/guide_modifier_input_swizzle.gd" id="7_54nr4"] +[ext_resource type="Script" uid="uid://x74mnwgr08a7" path="res://addons/guide/triggers/guide_trigger.gd" id="8_tlno4"] +[ext_resource type="Script" uid="uid://doauobik3xyea" path="res://addons/guide/inputs/guide_input_joy_axis_2d.gd" id="9_xnlyn"] +[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://systems/inputs/walk_mode/rotate_y.tres" id="10_tlno4"] +[ext_resource type="Script" uid="uid://b6bwb7ie85kl1" path="res://addons/guide/inputs/guide_input_mouse_axis_1d.gd" id="11_tlno4"] +[ext_resource type="Script" uid="uid://cgy4anjdob2tp" path="res://addons/guide/modifiers/guide_modifier_window_relative.gd" id="12_xnlyn"] +[ext_resource type="Script" uid="uid://bjm4myqxg4phm" path="res://addons/guide/modifiers/guide_modifier_scale.gd" id="13_dlt74"] +[ext_resource type="Script" uid="uid://bbhoxsiqwo07l" path="res://addons/guide/inputs/guide_input_joy_axis_1d.gd" id="14_74dxk"] +[ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://systems/inputs/walk_mode/rotate_floorplane.tres" id="15_xnlyn"] + +[sub_resource type="Resource" id="Resource_dlt74"] +script = ExtResource("4_t5475") +key = 87 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_74dxk"] +script = ExtResource("6_1advh") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_4g7it"] +script = ExtResource("7_54nr4") +order = 1 + +[sub_resource type="Resource" id="Resource_vagbc"] +script = ExtResource("3_pgmnb") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_dlt74") +modifiers = Array[ExtResource("5_dts0n")]([SubResource("Resource_74dxk"), SubResource("Resource_4g7it")]) +triggers = Array[ExtResource("8_tlno4")]([]) + +[sub_resource type="Resource" id="Resource_mp7q7"] +script = ExtResource("4_t5475") +key = 83 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_h1oqo"] +script = ExtResource("7_54nr4") +order = 1 + +[sub_resource type="Resource" id="Resource_nt051"] +script = ExtResource("3_pgmnb") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_mp7q7") +modifiers = Array[ExtResource("5_dts0n")]([SubResource("Resource_h1oqo")]) +triggers = Array[ExtResource("8_tlno4")]([]) +metadata/_guide_modifiers_collapsed = false + +[sub_resource type="Resource" id="Resource_4ypl0"] +script = ExtResource("4_t5475") +key = 65 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_pgmnb"] +script = ExtResource("6_1advh") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_1g8ta"] +script = ExtResource("3_pgmnb") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_4ypl0") +modifiers = Array[ExtResource("5_dts0n")]([SubResource("Resource_pgmnb")]) +triggers = Array[ExtResource("8_tlno4")]([]) + +[sub_resource type="Resource" id="Resource_jgclc"] +script = ExtResource("4_t5475") +key = 68 +shift = false +control = false +alt = false +meta = false +allow_additional_modifiers = true + +[sub_resource type="Resource" id="Resource_0avlp"] +script = ExtResource("3_pgmnb") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_jgclc") +modifiers = Array[ExtResource("5_dts0n")]([]) +triggers = Array[ExtResource("8_tlno4")]([]) + +[sub_resource type="Resource" id="Resource_r2gek"] +script = ExtResource("9_xnlyn") +x = 0 +y = 1 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_t5475"] +script = ExtResource("7_54nr4") +order = 2 + +[sub_resource type="Resource" id="Resource_5sx4a"] +script = ExtResource("3_pgmnb") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_r2gek") +modifiers = Array[ExtResource("5_dts0n")]([SubResource("Resource_t5475")]) +triggers = Array[ExtResource("8_tlno4")]([]) + +[sub_resource type="Resource" id="Resource_nd8wu"] +script = ExtResource("1_gh445") +action = ExtResource("2_h1oqo") +input_mappings = Array[ExtResource("3_pgmnb")]([SubResource("Resource_vagbc"), SubResource("Resource_nt051"), SubResource("Resource_1g8ta"), SubResource("Resource_0avlp"), SubResource("Resource_5sx4a")]) + +[sub_resource type="Resource" id="Resource_7dbe7"] +script = ExtResource("11_tlno4") +axis = 0 + +[sub_resource type="Resource" id="Resource_jiipn"] +script = ExtResource("12_xnlyn") + +[sub_resource type="Resource" id="Resource_sl76j"] +script = ExtResource("13_dlt74") +scale = Vector3(360, 1, 1) +apply_delta_time = false + +[sub_resource type="Resource" id="Resource_54nr4"] +script = ExtResource("6_1advh") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_lhbic"] +script = ExtResource("3_pgmnb") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_7dbe7") +modifiers = Array[ExtResource("5_dts0n")]([SubResource("Resource_jiipn"), SubResource("Resource_sl76j"), SubResource("Resource_54nr4")]) +triggers = Array[ExtResource("8_tlno4")]([]) + +[sub_resource type="Resource" id="Resource_agr80"] +script = ExtResource("14_74dxk") +axis = 2 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_a5vma"] +script = ExtResource("3_pgmnb") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_agr80") +modifiers = Array[ExtResource("5_dts0n")]([]) +triggers = Array[ExtResource("8_tlno4")]([]) + +[sub_resource type="Resource" id="Resource_fnf72"] +script = ExtResource("1_gh445") +action = ExtResource("10_tlno4") +input_mappings = Array[ExtResource("3_pgmnb")]([SubResource("Resource_lhbic"), SubResource("Resource_a5vma")]) + +[sub_resource type="Resource" id="Resource_q3p6c"] +script = ExtResource("11_tlno4") +axis = 1 + +[sub_resource type="Resource" id="Resource_33awn"] +script = ExtResource("12_xnlyn") + +[sub_resource type="Resource" id="Resource_01l3v"] +script = ExtResource("13_dlt74") +scale = Vector3(360, 1, 1) +apply_delta_time = false + +[sub_resource type="Resource" id="Resource_xrlwl"] +script = ExtResource("6_1advh") +x = true +y = true +z = true + +[sub_resource type="Resource" id="Resource_kyrsw"] +script = ExtResource("3_pgmnb") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_q3p6c") +modifiers = Array[ExtResource("5_dts0n")]([SubResource("Resource_33awn"), SubResource("Resource_01l3v"), SubResource("Resource_xrlwl")]) +triggers = Array[ExtResource("8_tlno4")]([]) + +[sub_resource type="Resource" id="Resource_oov4j"] +script = ExtResource("14_74dxk") +axis = 3 +joy_index = -1 + +[sub_resource type="Resource" id="Resource_1hcnu"] +script = ExtResource("3_pgmnb") +override_action_settings = false +is_remappable = false +display_name = "" +display_category = "" +input = SubResource("Resource_oov4j") +modifiers = Array[ExtResource("5_dts0n")]([]) +triggers = Array[ExtResource("8_tlno4")]([]) + +[sub_resource type="Resource" id="Resource_der0j"] +script = ExtResource("1_gh445") +action = ExtResource("15_xnlyn") +input_mappings = Array[ExtResource("3_pgmnb")]([SubResource("Resource_kyrsw"), SubResource("Resource_1hcnu")]) + +[resource] +script = ExtResource("2_vcm25") +display_name = "" +mappings = Array[ExtResource("1_gh445")]([SubResource("Resource_nd8wu"), SubResource("Resource_fnf72"), SubResource("Resource_der0j")]) +metadata/_custom_type_script = "uid://dsa1dnifd6w32"