feat: interaction cursor, fix: cards didn't always load at right position
This commit is contained in:
parent
971c162236
commit
3cb7a2d704
|
|
@ -379,7 +379,7 @@ func insert_area(parent: Control, node: Area2D):
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
||||||
if not node in parent.get_children():
|
if not node in parent.get_children():
|
||||||
node.reparent(parent)
|
node.reparent(parent, false) # Don't preserve global transform - we set positions explicitly
|
||||||
if node is StickyNote:
|
if node is StickyNote:
|
||||||
node.on_board = true
|
node.on_board = true
|
||||||
node.owner = self
|
node.owner = self
|
||||||
|
|
@ -630,16 +630,16 @@ func initialise_from_save(savegame: SaveGame) -> void:
|
||||||
# Add all cards
|
# Add all cards
|
||||||
print_debug(" Loading %d cards..." % card_pile["cards"].size())
|
print_debug(" Loading %d cards..." % card_pile["cards"].size())
|
||||||
for card: Card in card_pile["cards"]:
|
for card: Card in card_pile["cards"]:
|
||||||
add_child(card)
|
# Set position BEFORE adding to scene tree to avoid reparent position issues
|
||||||
insert_area(dropzone, card)
|
|
||||||
|
|
||||||
# Set position from save, or generate random if missing (must be after insert_area)
|
|
||||||
if savegame.board_positions.has(card.name):
|
if savegame.board_positions.has(card.name):
|
||||||
card.position = savegame.board_positions[card.name]
|
card.position = savegame.board_positions[card.name]
|
||||||
print_debug(" Card '%s' at %s" % [card.name, card.position])
|
print_debug(" Card '%s' at %s" % [card.name, card.position])
|
||||||
else:
|
else:
|
||||||
card.position = _generate_random_position()
|
card.position = _generate_random_position()
|
||||||
print_debug(" Card '%s' - generated random position: %s" % [card.name, card.position])
|
print_debug(" Card '%s' - generated random position: %s" % [card.name, card.position])
|
||||||
|
|
||||||
|
add_child(card)
|
||||||
|
insert_area(dropzone, card)
|
||||||
|
|
||||||
card.set_owner(self)
|
card.set_owner(self)
|
||||||
card.is_dragable = true
|
card.is_dragable = true
|
||||||
|
|
@ -670,16 +670,16 @@ func initialise_from_save(savegame: SaveGame) -> void:
|
||||||
|
|
||||||
# Sticky is loose on board
|
# Sticky is loose on board
|
||||||
else:
|
else:
|
||||||
add_child(sticky)
|
# Set position BEFORE adding to scene tree to avoid reparent position issues
|
||||||
insert_area(dropzone, sticky)
|
|
||||||
|
|
||||||
# Set position from save, or generate random if missing (must be after insert_area)
|
|
||||||
if savegame.board_positions.has(sticky.name):
|
if savegame.board_positions.has(sticky.name):
|
||||||
sticky.position = savegame.board_positions[sticky.name]
|
sticky.position = savegame.board_positions[sticky.name]
|
||||||
print_debug(" Loose sticky '%s' at %s" % [sticky.name, sticky.position])
|
print_debug(" Loose sticky '%s' at %s" % [sticky.name, sticky.position])
|
||||||
else:
|
else:
|
||||||
sticky.position = _generate_random_position()
|
sticky.position = _generate_random_position()
|
||||||
print_debug(" Loose sticky '%s' - generated random position: %s" % [sticky.name, sticky.position])
|
print_debug(" Loose sticky '%s' - generated random position: %s" % [sticky.name, sticky.position])
|
||||||
|
|
||||||
|
add_child(sticky)
|
||||||
|
insert_area(dropzone, sticky)
|
||||||
|
|
||||||
sticky.set_owner(self)
|
sticky.set_owner(self)
|
||||||
sticky.current_handle = self # Required for input handling
|
sticky.current_handle = self # Required for input handling
|
||||||
|
|
|
||||||
|
|
@ -22,25 +22,31 @@ func _apply_enabled_state() -> void:
|
||||||
jitter_tween.tween_property(self, "jitter_strength", 1.0, 1.0)
|
jitter_tween.tween_property(self, "jitter_strength", 1.0, 1.0)
|
||||||
if has_entered:
|
if has_entered:
|
||||||
ui_exited.emit()
|
ui_exited.emit()
|
||||||
|
# Show hand cursor when player is enabled
|
||||||
|
if hand_cursor:
|
||||||
|
hand_cursor.visible = true
|
||||||
else:
|
else:
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||||
jitter_tween = create_tween()
|
jitter_tween = create_tween()
|
||||||
jitter_tween.tween_property(self, "jitter_strength", 0.0, 0.5)
|
jitter_tween.tween_property(self, "jitter_strength", 0.0, 0.5)
|
||||||
if has_entered:
|
if has_entered:
|
||||||
ui_exited.emit()
|
ui_exited.emit()
|
||||||
|
# Hide hand cursor when player is disabled
|
||||||
|
if hand_cursor:
|
||||||
|
hand_cursor.visible = false
|
||||||
sleeping = not enabled
|
sleeping = not enabled
|
||||||
|
|
||||||
@export var mouse_sensitivity: Vector2 = Vector2(6, 5)
|
@export var mouse_sensitivity: Vector2 = Vector2(6, 5)
|
||||||
|
|
||||||
@export var initial_pitch: float = 50
|
@export var initial_pitch: float = 50
|
||||||
|
|
||||||
@export_range (0, 10) var max_speed: float = 3
|
@export_range (0.0, 10.0) var max_speed: float = 3
|
||||||
@export_range (0, 10) var max_acceleration: float = 5
|
@export_range (0.0, 10.0) var max_acceleration: float = 5
|
||||||
@export_range (0, 20) var damp: float = 10
|
@export_range (0.0, 20.0) var damp: float = 10
|
||||||
@export_range (0.1, 1) var mouse_jerk:float = 0.5
|
@export_range (0.1, 1.0) var mouse_jerk:float = 0.5
|
||||||
@export_range (10, 100) var gamepad_response:float = 50.0
|
@export_range (10.0, 100.0) var gamepad_response:float = 50.0
|
||||||
@export_range (50, 500) var mouse_jerk_rejection:float = 200.0
|
@export_range (50.0, 500.0) var mouse_jerk_rejection:float = 200.0
|
||||||
@export var max_angle:float = 75
|
@export var max_angle:float = 75.0
|
||||||
|
|
||||||
@export var camera_jitter_speed:float = 3
|
@export var camera_jitter_speed:float = 3
|
||||||
@export var angular_jitter:Vector3 = Vector3(0.1, 0, 0.05)
|
@export var angular_jitter:Vector3 = Vector3(0.1, 0, 0.05)
|
||||||
|
|
@ -87,6 +93,11 @@ var crouched:bool = false:
|
||||||
@onready var camera: Camera3D = $Yaw/Pitch/Mount/Camera3D
|
@onready var camera: Camera3D = $Yaw/Pitch/Mount/Camera3D
|
||||||
@onready var focus_ray: RayCast3D = $Yaw/Pitch/Mount/Camera3D/RayCast3D
|
@onready var focus_ray: RayCast3D = $Yaw/Pitch/Mount/Camera3D/RayCast3D
|
||||||
@onready var ui_prober: Area3D = $Yaw/Pitch/Mount/Camera3D/UiProber
|
@onready var ui_prober: Area3D = $Yaw/Pitch/Mount/Camera3D/UiProber
|
||||||
|
@onready var hand_cursor: TextureRect = %Cursor
|
||||||
|
|
||||||
|
# Cursor textures (preloaded for performance)
|
||||||
|
const cursor_default: Texture2D = preload("res://import/interface-elements/cursor_point.png")
|
||||||
|
const cursor_point: Texture2D = preload("res://import/interface-elements/cursor_grab.png")
|
||||||
|
|
||||||
@onready var base_fov := camera.fov
|
@onready var base_fov := camera.fov
|
||||||
var zoomed:bool = false:
|
var zoomed:bool = false:
|
||||||
|
|
@ -116,6 +127,9 @@ func _ready():
|
||||||
$CrouchDetector.area_entered.connect(enter_crouch)
|
$CrouchDetector.area_entered.connect(enter_crouch)
|
||||||
$CrouchDetector.area_exited.connect(exit_crouch)
|
$CrouchDetector.area_exited.connect(exit_crouch)
|
||||||
|
|
||||||
|
# Setup hand cursor
|
||||||
|
_setup_hand_cursor()
|
||||||
|
|
||||||
# Connect to central player enable signal.
|
# Connect to central player enable signal.
|
||||||
# Guard for standalone test scenes without autoloads.
|
# Guard for standalone test scenes without autoloads.
|
||||||
if get_node_or_null("/root/Scenes"):
|
if get_node_or_null("/root/Scenes"):
|
||||||
|
|
@ -128,6 +142,12 @@ func _ready():
|
||||||
func _on_player_enable(enable: bool) -> void:
|
func _on_player_enable(enable: bool) -> void:
|
||||||
enabled = enable
|
enabled = enable
|
||||||
|
|
||||||
|
## Setup the hand cursor in the center of the screen
|
||||||
|
func _setup_hand_cursor() -> void:
|
||||||
|
# Configure the existing TextureRect for cursor display
|
||||||
|
hand_cursor.texture = cursor_default # Start with default cursor
|
||||||
|
hand_cursor.visible = false
|
||||||
|
|
||||||
## Restores player position and camera rotation from save game
|
## Restores player position and camera rotation from save game
|
||||||
func restore_from_save(save: SaveGame) -> void:
|
func restore_from_save(save: SaveGame) -> void:
|
||||||
if save.player_position != Vector3.ZERO:
|
if save.player_position != Vector3.ZERO:
|
||||||
|
|
@ -162,11 +182,17 @@ func _on_ray_entered(_area):
|
||||||
assert(parent != null, "Ray entered non-interactable area!")
|
assert(parent != null, "Ray entered non-interactable area!")
|
||||||
printt("ray entered", parent.name, parent)
|
printt("ray entered", parent.name, parent)
|
||||||
parent.hover = true
|
parent.hover = true
|
||||||
|
# Switch to pointing hand cursor when hovering over interactable
|
||||||
|
if hand_cursor:
|
||||||
|
hand_cursor.texture = cursor_point
|
||||||
|
|
||||||
func _on_ray_exited(_area):
|
func _on_ray_exited(_area):
|
||||||
var parent := _area.get_parent() as Interactable
|
var parent := _area.get_parent() as Interactable
|
||||||
printt("ray exited", parent.name, parent)
|
printt("ray exited", parent.name, parent)
|
||||||
parent.hover = false
|
parent.hover = false
|
||||||
|
# Switch back to default cursor when not hovering
|
||||||
|
if hand_cursor:
|
||||||
|
hand_cursor.texture = cursor_default
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float):
|
func _physics_process(delta: float):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
[gd_scene load_steps=16 format=3 uid="uid://mkccbig41bqb"]
|
[gd_scene load_steps=17 format=3 uid="uid://mkccbig41bqb"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://bk618uyhghswx" path="res://logic-scenes/player_controller/player_controller.gd" id="1_0b4mi"]
|
[ext_resource type="Script" uid="uid://bk618uyhghswx" path="res://logic-scenes/player_controller/player_controller.gd" id="1_0b4mi"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://d005qvnbnishb" path="res://import/interface-elements/cursor_grab.png" id="2_x6v75"]
|
||||||
|
|
||||||
[sub_resource type="PhysicsMaterial" id="10"]
|
[sub_resource type="PhysicsMaterial" id="10"]
|
||||||
friction = 0.0
|
friction = 0.0
|
||||||
|
|
@ -657,6 +658,23 @@ mouse_filter = 2
|
||||||
texture = SubResource("GradientTexture2D_x6v75")
|
texture = SubResource("GradientTexture2D_x6v75")
|
||||||
expand_mode = 4
|
expand_mode = 4
|
||||||
|
|
||||||
|
[node name="Cursor" type="TextureRect" parent="Yaw/Pitch/Mount/Camera3D"]
|
||||||
|
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 = -20.0
|
||||||
|
offset_top = -20.0
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 20.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
texture = ExtResource("2_x6v75")
|
||||||
|
stretch_mode = 3
|
||||||
|
|
||||||
[node name="PlayerCollision" type="CollisionShape3D" parent="."]
|
[node name="PlayerCollision" type="CollisionShape3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, -1, 8.74228e-08, 0, -8.74228e-08, -1, 0, 0.6, 0)
|
transform = Transform3D(1, 0, 0, 0, -1, 8.74228e-08, 0, -8.74228e-08, -1, 0, 0.6, 0)
|
||||||
shape = SubResource("CapsuleShape3D_hpoj0")
|
shape = SubResource("CapsuleShape3D_hpoj0")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue