diff --git a/misc/2.5d/addons/node25d/main_screen/gizmo_25d.gd b/misc/2.5d/addons/node25d/main_screen/gizmo_25d.gd index b58253e7..94037413 100644 --- a/misc/2.5d/addons/node25d/main_screen/gizmo_25d.gd +++ b/misc/2.5d/addons/node25d/main_screen/gizmo_25d.gd @@ -1,103 +1,127 @@ @tool extends Node2D + +# If the mouse is farther than this many pixels, it won't grab anything. +const DEADZONE_RADIUS: float = 20 +const DEADZONE_RADIUS_SQ: float = DEADZONE_RADIUS * DEADZONE_RADIUS # Not pixel perfect for all axes in all modes, but works well enough. # Rounding is not done until after the movement is finished. const ROUGHLY_ROUND_TO_PIXELS = true # Set when the node is created. var node_25d: Node25D -var spatial_node +var _spatial_node # Input from Viewport25D, represents if the mouse is clicked. var wants_to_move = false # Used to control the state of movement. var _moving = false -var _start_position = Vector2() +var _start_mouse_position := Vector2.ZERO # Stores state of closest or currently used axis. -var dominant_axis +var _dominant_axis + +@onready var _lines = [$X, $Y, $Z] +@onready var _viewport_overlay: SubViewport = get_parent() +@onready var _viewport_25d_bg: ColorRect = _viewport_overlay.get_parent() -@onready var lines_root = $Lines -@onready var lines = [$Lines/X, $Lines/Y, $Lines/Z] func _process(_delta): - if not lines: - return # Somehow this node hasn't been set up yet. - if not node_25d: - return # We're most likely viewing the Gizmo25D scene. + if not _lines: + return # Somehow this node hasn't been set up yet. + if not node_25d or not _viewport_25d_bg: + return # We're most likely viewing the Gizmo25D scene. + global_position = node_25d.global_position # While getting the mouse position works in any viewport, it doesn't do # anything significant unless the mouse is in the 2.5D viewport. - var mouse_position = get_local_mouse_position() + var mouse_position: Vector2 = _viewport_25d_bg.get_local_mouse_position() + var full_transform: Transform2D = _viewport_overlay.canvas_transform * global_transform + mouse_position = full_transform.affine_inverse() * mouse_position if not _moving: - # If the mouse is farther than this many pixels, it won't grab anything. - var closest_distance = 20.0 - dominant_axis = -1 - for i in range(3): - lines[i].modulate.a = 0.8 # Unrelated, but needs a loop too. - var distance = _distance_to_segment_at_index(i, mouse_position) - if distance < closest_distance: - closest_distance = distance - dominant_axis = i - if dominant_axis == -1: - # If we're not hovering over a line, ensure they are placed correctly. - lines_root.global_position = node_25d.global_position + determine_dominant_axis(mouse_position) + if _dominant_axis == -1: + # If we're not hovering over a line, nothing to do. return - - lines[dominant_axis].modulate.a = 1 + _lines[_dominant_axis].modulate.a = 1 if not wants_to_move: - _moving = false - elif wants_to_move and not _moving: + if _moving: + # When we're done moving, ensure the inspector is updated. + node_25d.notify_property_list_changed() + _moving = false + return + # By this point, we want to move. + if not _moving: _moving = true - _start_position = mouse_position - - if _moving: - # Change modulate of unselected axes. - lines[(dominant_axis + 1) % 3].modulate.a = 0.5 - lines[(dominant_axis + 2) % 3].modulate.a = 0.5 - # Calculate mouse movement and reset for next frame. - var mouse_diff = mouse_position - _start_position - _start_position = mouse_position - # Calculate movement. - var projected_diff = mouse_diff.project(lines[dominant_axis].points[1]) - var movement = projected_diff.length() / Node25D.SCALE - if is_equal_approx(PI, projected_diff.angle_to(lines[dominant_axis].points[1])): - movement *= -1 - # Apply movement. - spatial_node.transform.origin += spatial_node.transform.basis[dominant_axis] * movement - else: - # Make sure the gizmo is located at the object. - global_position = node_25d.global_position - if ROUGHLY_ROUND_TO_PIXELS: - spatial_node.transform.origin = (spatial_node.transform.origin * Node25D.SCALE).round() / Node25D.SCALE - # Move the gizmo lines appropriately. - lines_root.global_position = node_25d.global_position - node_25d.property_list_changed_notify() + _start_mouse_position = mouse_position + # By this point, we are moving. + move_using_mouse(mouse_position) -# Initializes after _ready due to the onready vars, called manually in Viewport25D.gd. +func determine_dominant_axis(mouse_position: Vector2) -> void: + var closest_distance = DEADZONE_RADIUS + _dominant_axis = -1 + for i in range(3): + _lines[i].modulate.a = 0.8 # Unrelated, but needs a loop too. + var distance = _distance_to_segment_at_index(i, mouse_position) + if distance < closest_distance: + closest_distance = distance + _dominant_axis = i + + +func move_using_mouse(mouse_position: Vector2) -> void: + # Change modulate of unselected axes. + _lines[(_dominant_axis + 1) % 3].modulate.a = 0.5 + _lines[(_dominant_axis + 2) % 3].modulate.a = 0.5 + # Calculate movement. + var mouse_diff: Vector2 = mouse_position - _start_mouse_position + var line_end_point: Vector2 = _lines[_dominant_axis].points[1] + var projected_diff: Vector2 = mouse_diff.project(line_end_point) + var movement: float = projected_diff.length() * global_scale.x / Node25D.SCALE + if is_equal_approx(PI, projected_diff.angle_to(line_end_point)): + movement *= -1 + # Apply movement. + var move_dir_3d: Vector3 = _spatial_node.transform.basis[_dominant_axis] + _spatial_node.transform.origin += move_dir_3d * movement + _snap_spatial_position() + # Move the gizmo appropriately. + global_position = node_25d.global_position + + +# Setup after _ready due to the onready vars, called manually in Viewport25D.gd. # Sets up the points based on the basis values of the Node25D. -func initialize(): +func setup(in_node_25d: Node25D): + node_25d = in_node_25d var basis = node_25d.get_basis() for i in range(3): - lines[i].points[1] = basis[i] * 3 + _lines[i].points[1] = basis[i] * 3 global_position = node_25d.global_position - spatial_node = node_25d.get_child(0) + _spatial_node = node_25d.get_child(0) + + +func set_zoom(zoom: float) -> void: + var new_scale: float = EditorInterface.get_editor_scale() / zoom + global_scale = Vector2(new_scale, new_scale) + + +func _snap_spatial_position(step_meters: float = 1.0 / Node25D.SCALE) -> void: + var scaled_px: Vector3 = _spatial_node.transform.origin / step_meters + _spatial_node.transform.origin = scaled_px.round() * step_meters # Figures out if the mouse is very close to a segment. This method is # specialized for this script, it assumes that each segment starts at # (0, 0) and it provides a deadzone around the origin. func _distance_to_segment_at_index(index, point): - if not lines: + if not _lines: return INF - if point.length_squared() < 400: + if point.length_squared() < DEADZONE_RADIUS_SQ: return INF - var segment_end = lines[index].points[1] + var segment_end: Vector2 = _lines[index].points[1] var length_squared = segment_end.length_squared() - if length_squared < 400: + if length_squared < DEADZONE_RADIUS_SQ: return INF var t = clamp(point.dot(segment_end) / length_squared, 0, 1) diff --git a/misc/2.5d/addons/node25d/main_screen/gizmo_25d.tscn b/misc/2.5d/addons/node25d/main_screen/gizmo_25d.tscn index d6d59701..0b09772a 100644 --- a/misc/2.5d/addons/node25d/main_screen/gizmo_25d.tscn +++ b/misc/2.5d/addons/node25d/main_screen/gizmo_25d.tscn @@ -1,23 +1,21 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=2 format=4 uid="uid://cx4xo5jddm0g"] -[ext_resource path="res://addons/node25d/main_screen/gizmo_25d.gd" type="Script" id=1] +[ext_resource type="Script" path="res://addons/node25d/main_screen/gizmo_25d.gd" id="1"] [node name="Gizmo25D" type="Node2D"] -script = ExtResource( 1 ) +script = ExtResource("1") -[node name="Lines" type="Node2D" parent="."] - -[node name="X" type="Line2D" parent="Lines"] +[node name="X" type="Line2D" parent="."] modulate = Color(1, 1, 1, 0.8) points = PackedVector2Array(0, 0, 100, 0) default_color = Color(0.91, 0.273, 0, 1) -[node name="Y" type="Line2D" parent="Lines"] +[node name="Y" type="Line2D" parent="."] modulate = Color(1, 1, 1, 0.8) points = PackedVector2Array(0, 0, 0, -100) default_color = Color(0, 0.91, 0.273, 1) -[node name="Z" type="Line2D" parent="Lines"] +[node name="Z" type="Line2D" parent="."] modulate = Color(1, 1, 1, 0.8) points = PackedVector2Array(0, 0, 0, 100) default_color = Color(0.3, 0, 1, 1) diff --git a/misc/2.5d/addons/node25d/main_screen/main_screen_25d.tscn b/misc/2.5d/addons/node25d/main_screen/main_screen_25d.tscn index 4901146d..84392af5 100644 --- a/misc/2.5d/addons/node25d/main_screen/main_screen_25d.tscn +++ b/misc/2.5d/addons/node25d/main_screen/main_screen_25d.tscn @@ -1,173 +1,119 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=5 format=4 uid="uid://d3xt5cbt06bfy"] -[ext_resource path="res://addons/node25d/main_screen/viewport_25d.gd" type="Script" id=1] -[ext_resource path="res://addons/node25d/main_screen/view_mode_button_group.tres" type="ButtonGroup" id=2] +[ext_resource type="Script" path="res://addons/node25d/main_screen/viewport_25d.gd" id="1"] +[ext_resource type="ButtonGroup" path="res://addons/node25d/main_screen/view_mode_button_group.tres" id="2"] -[sub_resource type="ViewportTexture" id=1] +[sub_resource type="ViewportTexture" id="1"] viewport_path = NodePath("Viewport25D/Viewport2D") -[sub_resource type="ViewportTexture" id=2] +[sub_resource type="ViewportTexture" id="2"] viewport_path = NodePath("Viewport25D/ViewportOverlay") [node name="MainScreen25D" type="VBoxContainer"] +anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 size_flags_horizontal = 3 size_flags_vertical = 3 -__meta__ = { -"_edit_use_anchors_": false -} [node name="TopBar" type="HBoxContainer" parent="."] -offset_right = 1600.0 -offset_bottom = 32.0 -rect_min_size = Vector2(0, 32) +layout_mode = 2 size_flags_horizontal = 3 [node name="ViewModeButtons" type="HBoxContainer" parent="TopBar"] -offset_right = 798.0 -offset_bottom = 32.0 +layout_mode = 2 size_flags_horizontal = 3 [node name="45Degree" type="CheckBox" parent="TopBar/ViewModeButtons"] -offset_right = 94.0 -offset_bottom = 32.0 -pressed = true -group = ExtResource( 2 ) +layout_mode = 2 +button_pressed = true +button_group = ExtResource("2") text = "45 Degree" -__meta__ = { -"_edit_use_anchors_": false -} [node name="Isometric" type="CheckBox" parent="TopBar/ViewModeButtons"] -offset_left = 98.0 -offset_right = 188.0 -offset_bottom = 32.0 -group = ExtResource( 2 ) +layout_mode = 2 +button_group = ExtResource("2") text = "Isometric" -__meta__ = { -"_edit_use_anchors_": false -} [node name="TopDown" type="CheckBox" parent="TopBar/ViewModeButtons"] -offset_left = 192.0 -offset_right = 283.0 -offset_bottom = 32.0 -group = ExtResource( 2 ) +layout_mode = 2 +button_group = ExtResource("2") text = "Top Down" -__meta__ = { -"_edit_use_anchors_": false -} [node name="FrontSide" type="CheckBox" parent="TopBar/ViewModeButtons"] -offset_left = 287.0 -offset_right = 379.0 -offset_bottom = 32.0 -group = ExtResource( 2 ) +layout_mode = 2 +button_group = ExtResource("2") text = "Front Side" -__meta__ = { -"_edit_use_anchors_": false -} [node name="ObliqueY" type="CheckBox" parent="TopBar/ViewModeButtons"] -offset_left = 383.0 -offset_right = 473.0 -offset_bottom = 32.0 -group = ExtResource( 2 ) +layout_mode = 2 +button_group = ExtResource("2") text = "Oblique Y" -__meta__ = { -"_edit_use_anchors_": false -} [node name="ObliqueZ" type="CheckBox" parent="TopBar/ViewModeButtons"] -offset_left = 477.0 -offset_right = 568.0 -offset_bottom = 32.0 -group = ExtResource( 2 ) +layout_mode = 2 +button_group = ExtResource("2") text = "Oblique Z" -__meta__ = { -"_edit_use_anchors_": false -} [node name="Zoom" type="HBoxContainer" parent="TopBar"] -offset_left = 802.0 -offset_right = 1600.0 -offset_bottom = 32.0 +layout_mode = 2 size_flags_horizontal = 3 alignment = 2 [node name="ZoomOut" type="Button" parent="TopBar/Zoom"] -offset_left = 680.0 -offset_right = 710.0 -offset_bottom = 32.0 -rect_min_size = Vector2(30, 0) +custom_minimum_size = Vector2(32, 2.08165e-12) +layout_mode = 2 text = "-" [node name="ZoomPercent" type="Label" parent="TopBar/Zoom"] -offset_left = 714.0 -offset_top = 9.0 -offset_right = 764.0 -offset_bottom = 23.0 -rect_min_size = Vector2(50, 0) +custom_minimum_size = Vector2(100, 2.08165e-12) +layout_mode = 2 text = "100%" -align = 1 -clip_text = true +horizontal_alignment = 1 [node name="ZoomReset" type="Button" parent="TopBar/Zoom/ZoomPercent"] modulate = Color(1, 1, 1, 0) +layout_mode = 0 anchor_right = 1.0 anchor_bottom = 1.0 -__meta__ = { -"_edit_use_anchors_": false -} [node name="ZoomIn" type="Button" parent="TopBar/Zoom"] -offset_left = 768.0 -offset_right = 798.0 -offset_bottom = 32.0 -rect_min_size = Vector2(30, 0) +custom_minimum_size = Vector2(32, 2.08165e-12) +layout_mode = 2 text = "+" +[node name="Spacer" type="Control" parent="TopBar/Zoom"] +layout_mode = 2 + [node name="Viewport25D" type="ColorRect" parent="."] -offset_top = 36.0 -offset_right = 1600.0 -offset_bottom = 900.0 -rect_clip_content = true +layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 color = Color(0.301961, 0.301961, 0.301961, 1) -script = ExtResource( 1 ) +script = ExtResource("1") [node name="Viewport2D" type="SubViewport" parent="Viewport25D"] -size = Vector2(1600, 864) -transparent_bg = true disable_3d = true -usage = 1 -render_target_v_flip = true +transparent_bg = true +size = Vector2i(1600, 864) [node name="ViewportOverlay" type="SubViewport" parent="Viewport25D"] -size = Vector2(1600, 864) -transparent_bg = true disable_3d = true -usage = 1 -render_target_v_flip = true +transparent_bg = true +size = Vector2i(1600, 864) [node name="ViewportTexture" type="TextureRect" parent="Viewport25D"] +layout_mode = 0 anchor_right = 1.0 anchor_bottom = 1.0 -texture = SubResource( 1 ) -expand = true -__meta__ = { -"_edit_use_anchors_": false -} +texture = SubResource("1") +expand_mode = 1 [node name="Overlay" type="TextureRect" parent="Viewport25D/ViewportTexture"] +layout_mode = 0 anchor_right = 1.0 anchor_bottom = 1.0 -texture = SubResource( 2 ) -__meta__ = { -"_edit_use_anchors_": false -} +texture = SubResource("2") [connection signal="pressed" from="TopBar/Zoom/ZoomOut" to="Viewport25D" method="_on_ZoomOut_pressed"] [connection signal="pressed" from="TopBar/Zoom/ZoomPercent/ZoomReset" to="Viewport25D" method="_on_ZoomReset_pressed"] diff --git a/misc/2.5d/addons/node25d/main_screen/viewport_25d.gd b/misc/2.5d/addons/node25d/main_screen/viewport_25d.gd index 8ec16165..08039dad 100644 --- a/misc/2.5d/addons/node25d/main_screen/viewport_25d.gd +++ b/misc/2.5d/addons/node25d/main_screen/viewport_25d.gd @@ -7,15 +7,16 @@ var pan_center: Vector2 var viewport_center: Vector2 var view_mode_index := 0 -var editor_interface: EditorInterface # Set in node25d_plugin.gd +var editor_interface: EditorInterface # Set in node25d_plugin.gd var moving = false @onready var viewport_2d = $Viewport2D @onready var viewport_overlay = $ViewportOverlay -@onready var view_mode_button_group: ButtonGroup = $"../TopBar/ViewModeButtons/45Degree".group +@onready var view_mode_button_group: ButtonGroup = $"../TopBar/ViewModeButtons/45Degree".button_group @onready var zoom_label: Label = $"../TopBar/Zoom/ZoomPercent" @onready var gizmo_25d_scene = preload("res://addons/node25d/main_screen/gizmo_25d.tscn") + func _ready(): # Give Godot a chance to fully load the scene. Should take two frames. await get_tree().process_frame @@ -29,17 +30,19 @@ func _ready(): # Alright, we're loaded up. Now check if we have a valid world and assign it. var world_2d = edited_scene_root.get_viewport().world_2d if world_2d == get_viewport().world_2d: - return # This is the MainScreen25D scene opened in the editor! + return # This is the MainScreen25D scene opened in the editor! viewport_2d.world_2d = world_2d -func _process(delta): - if not editor_interface: # Something's not right... bail! +func _process(_delta): + if not editor_interface: # Something's not right... bail! return # View mode polling. var view_mode_changed_this_frame = false - var new_view_mode = view_mode_button_group.get_pressed_button().get_index() + var new_view_mode = -1 + if view_mode_button_group.get_pressed_button(): + new_view_mode = view_mode_button_group.get_pressed_button().get_index() if view_mode_index != new_view_mode: view_mode_index = new_view_mode view_mode_changed_this_frame = true @@ -53,8 +56,9 @@ func _process(delta): var zoom = _get_zoom_amount() # SubViewport size. - var size = get_global_rect().size - viewport_2d.size = size + var vp_size = get_global_rect().size + viewport_2d.size = vp_size + viewport_overlay.size = vp_size # SubViewport transform. var viewport_trans = Transform2D.IDENTITY @@ -66,27 +70,31 @@ func _process(delta): # Delete unused gizmos. var selection = editor_interface.get_selection().get_selected_nodes() - var overlay_children = viewport_overlay.get_children() - for overlay_child in overlay_children: + var gizmos = viewport_overlay.get_children() + for gizmo in gizmos: var contains = false for selected in selection: - if selected == overlay_child.node_25d and not view_mode_changed_this_frame: + if selected == gizmo.node_25d and not view_mode_changed_this_frame: contains = true if not contains: - overlay_child.queue_free() - + gizmo.queue_free() # Add new gizmos. for selected in selection: if selected is Node25D: - var new = true - for overlay_child in overlay_children: - if selected == overlay_child.node_25d: - new = false - if new: - var gizmo = gizmo_25d_scene.instantiate() - viewport_overlay.add_child(gizmo) - gizmo.node_25d = selected - gizmo.initialize() + _ensure_node25d_has_gizmo(selected, gizmos) + # Update gizmo zoom. + for gizmo in gizmos: + gizmo.set_zoom(zoom) + + +func _ensure_node25d_has_gizmo(node: Node25D, gizmos: Array[Node]) -> void: + var new = true + for gizmo in gizmos: + if node == gizmo.node_25d: + return + var gizmo = gizmo_25d_scene.instantiate() + viewport_overlay.add_child(gizmo) + gizmo.setup(node) # This only accepts input when the mouse is inside of the 2.5D viewport. @@ -101,7 +109,7 @@ func _gui_input(event): accept_event() elif event.button_index == MOUSE_BUTTON_MIDDLE: is_panning = true - pan_center = viewport_center - event.position + pan_center = viewport_center - event.position / _get_zoom_amount() accept_event() elif event.button_index == MOUSE_BUTTON_LEFT: var overlay_children = viewport_overlay.get_children() @@ -118,11 +126,13 @@ func _gui_input(event): accept_event() elif event is InputEventMouseMotion: if is_panning: - viewport_center = pan_center + event.position + viewport_center = pan_center + event.position / _get_zoom_amount() accept_event() func _recursive_change_view_mode(current_node): + if not current_node: + return if current_node.has_method("set_view_mode"): current_node.set_view_mode(view_mode_index) for child in current_node.get_children(): @@ -130,7 +140,7 @@ func _recursive_change_view_mode(current_node): func _get_zoom_amount(): - var zoom_amount = pow(1.05476607648, zoom_level) # 13th root of 2 + var zoom_amount = pow(1.05476607648, zoom_level) # 13th root of 2 zoom_label.text = str(round(zoom_amount * 1000) / 10) + "%" return zoom_amount diff --git a/misc/2.5d/addons/node25d/node25d_plugin.gd b/misc/2.5d/addons/node25d/node25d_plugin.gd index a9aaad21..15e1cdd8 100644 --- a/misc/2.5d/addons/node25d/node25d_plugin.gd +++ b/misc/2.5d/addons/node25d/node25d_plugin.gd @@ -5,15 +5,16 @@ const MainPanel = preload("res://addons/node25d/main_screen/main_screen_25d.tscn var main_panel_instance + func _enter_tree(): main_panel_instance = MainPanel.instantiate() main_panel_instance.get_child(1).editor_interface = get_editor_interface() # Add the main panel to the editor's main viewport. - get_editor_interface().get_editor_viewport().add_child(main_panel_instance) + EditorInterface.get_editor_main_screen().add_child(main_panel_instance) # Hide the main panel. - make_visible(false) + _make_visible(false) # When this plugin node enters tree, add the custom types. add_custom_type("Node25D", "Node2D", preload("node_25d.gd"), preload("icons/node_25d_icon.png")) add_custom_type("YSort25D", "Node", preload("y_sort_25d.gd"), preload("icons/y_sort_25d_icon.png")) @@ -21,27 +22,33 @@ func _enter_tree(): func _exit_tree(): - main_panel_instance.queue_free() + if main_panel_instance: + main_panel_instance.queue_free() # When the plugin node exits the tree, remove the custom types. remove_custom_type("ShadowMath25D") remove_custom_type("YSort25D") remove_custom_type("Node25D") -func has_main_screen(): +func _has_main_screen(): return true -func make_visible(visible): - if visible: - main_panel_instance.show() - else: - main_panel_instance.hide() +func _make_visible(visible): + if main_panel_instance: + if visible: + main_panel_instance.show() + else: + main_panel_instance.hide() -func get_plugin_name(): +func _get_plugin_name(): return "2.5D" -func get_plugin_icon(): +func _get_plugin_icon(): return preload("res://addons/node25d/icons/viewport_25d.svg") + + +func _handles(obj: Object) -> bool: + return obj is Node25D diff --git a/misc/2.5d/addons/node25d/node_25d.gd b/misc/2.5d/addons/node25d/node_25d.gd index e5319940..7e11fd24 100644 --- a/misc/2.5d/addons/node25d/node_25d.gd +++ b/misc/2.5d/addons/node25d/node_25d.gd @@ -2,8 +2,8 @@ # The transformation of its 2D form is controlled by its 3D child. @tool @icon("res://addons/node25d/icons/node_25d_icon.png") -extends Node2D class_name Node25D +extends Node2D # SCALE is the number of 2D units in one 3D unit. Ideally, but not necessarily, an integer. diff --git a/misc/2.5d/addons/node25d/shadow_math_25d.gd b/misc/2.5d/addons/node25d/shadow_math_25d.gd index 61a57d62..cf3a6eba 100644 --- a/misc/2.5d/addons/node25d/shadow_math_25d.gd +++ b/misc/2.5d/addons/node25d/shadow_math_25d.gd @@ -3,12 +3,10 @@ # is below the target object in the scene tree (not as a child). @tool @icon("res://addons/node25d/icons/shadow_math_25d_icon.png") -extends CharacterBody3D class_name ShadowMath25D +extends ShapeCast3D -# The maximum distance below objects that shadows will appear (in 3D units). -var shadow_length = 1000.0 var _shadow_root: Node25D var _target_math: Node3D @@ -16,8 +14,14 @@ var _target_math: Node3D func _ready(): _shadow_root = get_parent() var index = _shadow_root.get_index() - if (index > 0): # Else, Shadow is not in a valid place. - _target_math = _shadow_root.get_parent().get_child(index - 1).get_child(0) + if index > 0: # Else, Shadow is not in a valid place. + var sibling_25d: Node = _shadow_root.get_parent().get_child(index - 1) + if sibling_25d.get_child_count() > 0: + var target = sibling_25d.get_child(0) + if target is Node3D: + _target_math = target + return + printerr("Shadow is not in the correct place, expected a previous sibling node with a 3D first child.") func _physics_process(_delta): @@ -25,11 +29,10 @@ func _physics_process(_delta): if _shadow_root != null: _shadow_root.visible = false return # Shadow is not in a valid place or you're viewing the Shadow25D scene. - position = _target_math.position - var k = move_and_collide(Vector3.DOWN * shadow_length) - if k == null: - _shadow_root.visible = false - else: + force_shapecast_update() + if is_colliding(): + global_position = get_collision_point(0) _shadow_root.visible = true - global_transform = transform + else: + _shadow_root.visible = false diff --git a/misc/2.5d/assets/cube/cube_math.gd b/misc/2.5d/assets/cube/cube_math.gd index e66e8f0e..3ab40c6f 100644 --- a/misc/2.5d/assets/cube/cube_math.gd +++ b/misc/2.5d/assets/cube/cube_math.gd @@ -11,9 +11,9 @@ func _ready(): _parent = get_parent() for i in range(27): - # warning-ignore:integer_division + @warning_ignore("integer_division") var a: int = (i / 9) - 1 - # warning-ignore:integer_division + @warning_ignore("integer_division") var b: int = (i / 3) % 3 - 1 var c: int = (i % 3) - 1 var spatial_position: Vector3 = 5 * (a * Vector3.RIGHT + b * Vector3.UP + c * Vector3.BACK) diff --git a/misc/2.5d/assets/demo_scene.tscn b/misc/2.5d/assets/demo_scene.tscn index 2b9a672b..2e9cac50 100644 --- a/misc/2.5d/assets/demo_scene.tscn +++ b/misc/2.5d/assets/demo_scene.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=12 format=3 uid="uid://bc8akj25hcmiy"] +[gd_scene load_steps=12 format=4 uid="uid://bc8akj25hcmiy"] [ext_resource type="PackedScene" uid="uid://6o8sm5bti8d1" path="res://assets/ui/overlay.tscn" id="1"] [ext_resource type="PackedScene" uid="uid://bg27d8sfehmr4" path="res://assets/player/player_25d.tscn" id="2"] @@ -23,23 +23,23 @@ size = Vector3(10, 1, 10) [node name="Overlay" parent="." instance=ExtResource("1")] [node name="Player25D" parent="." instance=ExtResource("2")] -z_index = -3952 -position = Vector2(0, -226.274) +z_index = -3956 +position = Vector2(0, -11.3137) [node name="Shadow25D" parent="." instance=ExtResource("3")] visible = true z_index = -3958 -position = Vector2(0, -5.3033) -spatial_position = Vector3(0, 0.234375, 0) +position = Vector2(3.5845e-13, 11.3137) +spatial_position = Vector3(1.12016e-14, -0.5, 1.12016e-14) [node name="Platform0" type="Node2D" parent="."] -z_index = -3954 +z_index = -3952 position = Vector2(-256, -113.137) script = ExtResource("4") -spatial_position = Vector3(-8, 5, 0) +spatial_position = Vector3(-8, 5, 2.08165e-12) [node name="PlatformMath" type="StaticBody3D" parent="Platform0"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8, 5, 0) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8, 5, 2.08165e-12) collision_layer = 1048575 collision_mask = 1048575 @@ -52,7 +52,7 @@ texture = ExtResource("6") script = ExtResource("7") [node name="Platform1" type="Node2D" parent="."] -z_index = -3956 +z_index = -3954 position = Vector2(-256, -339.411) script = ExtResource("4") spatial_position = Vector3(-8, 5, -10) diff --git a/misc/2.5d/assets/player/player_25d.tscn b/misc/2.5d/assets/player/player_25d.tscn index e8281d7d..feea8c62 100644 --- a/misc/2.5d/assets/player/player_25d.tscn +++ b/misc/2.5d/assets/player/player_25d.tscn @@ -1,12 +1,11 @@ -[gd_scene load_steps=6 format=3 uid="uid://bg27d8sfehmr4"] +[gd_scene load_steps=6 format=4 uid="uid://bg27d8sfehmr4"] [ext_resource type="Script" path="res://addons/node25d/node_25d.gd" id="1"] [ext_resource type="Script" path="res://assets/player/player_math_25d.gd" id="3"] [ext_resource type="Texture2D" uid="uid://bfdfertqyhf1u" path="res://assets/player/textures/jump.png" id="4"] [ext_resource type="Script" path="res://assets/player/player_sprite.gd" id="5"] -[sub_resource type="BoxShape3D" id="1"] -size = Vector3(1, 2, 1) +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_b17hs"] [node name="Player25D" type="Node2D"] z_index = 100 @@ -19,7 +18,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) script = ExtResource("3") [node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerMath25D"] -shape = SubResource("1") +shape = SubResource("CapsuleShape3D_b17hs") [node name="PlayerSprite" type="Sprite2D" parent="."] z_index = 1 diff --git a/misc/2.5d/assets/player/player_math_25d.gd b/misc/2.5d/assets/player/player_math_25d.gd index ea4d8c93..67a8d030 100644 --- a/misc/2.5d/assets/player/player_math_25d.gd +++ b/misc/2.5d/assets/player/player_math_25d.gd @@ -1,6 +1,6 @@ # Handles Player-specific behavior like moving. We calculate such things with CharacterBody3D. -extends CharacterBody3D class_name PlayerMath25D # No icon necessary +extends CharacterBody3D var vertical_speed := 0.0 var isometric_controls := true @@ -38,7 +38,7 @@ func _horizontal_movement(delta): var movement_vec2 = Input.get_vector(&"move_left", &"move_right", &"move_forward", &"move_back") var move_dir = localX * movement_vec2.x + localZ * movement_vec2.y - velocity = move_dir * delta * 1200 + velocity = move_dir * 10 if Input.is_action_pressed(&"movement_modifier"): velocity /= 2 @@ -47,10 +47,9 @@ func _horizontal_movement(delta): # Checks Jump and applies gravity and vertical speed via move_and_collide. func _vertical_movement(delta): - var localY = Vector3.UP if Input.is_action_just_pressed(&"jump"): - vertical_speed = 0.55 - vertical_speed -= delta * 2 # Gravity - var k = move_and_collide(localY * vertical_speed) + vertical_speed = 60 + vertical_speed -= delta * 240 # Gravity + var k = move_and_collide(Vector3.UP * vertical_speed * delta) if k != null: vertical_speed = 0 diff --git a/misc/2.5d/assets/player/player_sprite.gd b/misc/2.5d/assets/player/player_sprite.gd index b4448674..bbbd8dab 100644 --- a/misc/2.5d/assets/player/player_sprite.gd +++ b/misc/2.5d/assets/player/player_sprite.gd @@ -30,7 +30,7 @@ func _process(delta): if movement: hframes = 6 texture = _run - if (Input.is_action_pressed(&"movement_modifier")): + if Input.is_action_pressed(&"movement_modifier"): delta /= 2 _progress = fmod((_progress + FRAMERATE * delta), 6) frame = _direction * 6 + int(_progress) diff --git a/misc/2.5d/assets/shadow/shadow_25d.tscn b/misc/2.5d/assets/shadow/shadow_25d.tscn index db6fdbb6..f449bcb1 100644 --- a/misc/2.5d/assets/shadow/shadow_25d.tscn +++ b/misc/2.5d/assets/shadow/shadow_25d.tscn @@ -1,13 +1,11 @@ -[gd_scene load_steps=7 format=3 uid="uid://ivolxaqaaddk"] +[gd_scene load_steps=6 format=4 uid="uid://ivolxaqaaddk"] [ext_resource type="Script" path="res://addons/node25d/node_25d.gd" id="1"] [ext_resource type="Script" path="res://addons/node25d/shadow_math_25d.gd" id="3"] -[ext_resource type="Texture2D" uid="uid://dunp4dxxpftxb" path="res://addons/node25d/icons/shadow_math_25d_icon.png" id="4"] [ext_resource type="Texture2D" uid="uid://4fvxohv2aowy" path="res://assets/shadow/textures/forty_five.png" id="5"] [ext_resource type="Script" path="res://assets/shadow/shadow_sprite.gd" id="6"] -[sub_resource type="BoxShape3D" id="1"] -size = Vector3(1, 0.002, 1) +[sub_resource type="SphereShape3D" id="SphereShape3D_v7tld"] [node name="Shadow25D" type="Node2D"] visible = false @@ -15,17 +13,12 @@ position = Vector2(0, 22401.1) script = ExtResource("1") spatial_position = Vector3(0, -990, 0) -[node name="ShadowMath25D" type="CharacterBody3D" parent="."] +[node name="ShadowMath25D" type="ShapeCast3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -990, 0) -collision_layer = 16 +shape = SubResource("SphereShape3D_v7tld") +target_position = Vector3(2.08165e-12, -100, 2.08165e-12) collision_mask = 16 script = ExtResource("3") -__meta__ = { -"_editor_icon": ExtResource("4") -} - -[node name="CollisionShape3D" type="CollisionShape3D" parent="ShadowMath25D"] -shape = SubResource("1") [node name="ShadowSprite" type="Sprite2D" parent="."] texture_filter = 2 diff --git a/misc/2.5d/assets/ui/overlay.tscn b/misc/2.5d/assets/ui/overlay.tscn index 4fdd9918..fe398376 100644 --- a/misc/2.5d/assets/ui/overlay.tscn +++ b/misc/2.5d/assets/ui/overlay.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=2 format=3 uid="uid://6o8sm5bti8d1"] +[gd_scene load_steps=2 format=4 uid="uid://6o8sm5bti8d1"] [ext_resource type="Script" path="res://assets/ui/control_hints.gd" id="1"] diff --git a/misc/2.5d/project.godot b/misc/2.5d/project.godot index 7e638e3c..61690e83 100644 --- a/misc/2.5d/project.godot +++ b/misc/2.5d/project.godot @@ -16,7 +16,7 @@ in Godot by mixing 2D and 3D nodes. It also adds a 2.5D editor viewport for easily editing 2.5D levels." config/tags=PackedStringArray("2d", "demo", "official") run/main_scene="res://assets/demo_scene.tscn" -config/features=PackedStringArray("4.2") +config/features=PackedStringArray("4.3") config/icon="res://icon.webp" [display] @@ -34,120 +34,120 @@ enabled=PackedStringArray("res://addons/node25d/plugin.cfg") move_right={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } move_left={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } move_forward={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } move_back={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } movement_modifier={ "deadzone": 0.2, "events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } jump={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null) ] } reset_position={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":82,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":82,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null) ] } forty_five_mode={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":85,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":85,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) ] } isometric_mode={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":73,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":73,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null) ] } top_down_mode={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":79,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":79,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) ] } front_side_mode={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":74,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":74,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) ] } oblique_y_mode={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":75,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":75,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":4,"pressure":0.0,"pressed":false,"script":null) ] } oblique_z_mode={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":76,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":76,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":5,"pressure":0.0,"pressed":false,"script":null) ] } toggle_isometric_controls={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":84,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":84,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":8,"pressure":0.0,"pressed":false,"script":null) ] } toggle_control_hints={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":10,"pressure":0.0,"pressed":false,"script":null) ] } move_clockwise={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null) ] } move_counterclockwise={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":6,"pressure":0.0,"pressed":false,"script":null) ] } view_cube_demo={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":67,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":67,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null) ] } exit={ "deadzone": 0.2, "events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] }