From 690ac102dc46f33a491ca07ffdb6ab24b440ff16 Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 12 Aug 2025 08:43:26 +0200 Subject: [PATCH] Selector changes --- Scenes/Actors/IsoPlayer_FSM.tscn | 2 +- .../FSM/3DPlayer/IsoActivationProvider.cs | 57 ++++++++- .../FSM/3DPlayer/SelectorController.cs | 117 +++++++++++++----- 3 files changed, 141 insertions(+), 35 deletions(-) diff --git a/Scenes/Actors/IsoPlayer_FSM.tscn b/Scenes/Actors/IsoPlayer_FSM.tscn index 2b12392d..2e43f68b 100644 --- a/Scenes/Actors/IsoPlayer_FSM.tscn +++ b/Scenes/Actors/IsoPlayer_FSM.tscn @@ -328,7 +328,7 @@ _selectorController = NodePath("SelectorController") _errorSound = NodePath("AudioStreamPlayer") SelectorScene = ExtResource("24_j6bpw") -[node name="CollisionShape3D" type="CollisionShape3D" parent="ActivationProvider"] +[node name="CollisionShape" type="CollisionShape3D" parent="ActivationProvider"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.294313, 0) shape = SubResource("CylinderShape3D_6d8x8") diff --git a/Scripts/Components/FSM/3DPlayer/IsoActivationProvider.cs b/Scripts/Components/FSM/3DPlayer/IsoActivationProvider.cs index 605bfd08..6ac77773 100644 --- a/Scripts/Components/FSM/3DPlayer/IsoActivationProvider.cs +++ b/Scripts/Components/FSM/3DPlayer/IsoActivationProvider.cs @@ -1,4 +1,6 @@ -using Cirno.Scripts.Components.Actors; +using System.Collections.Generic; +using System.Linq; +using Cirno.Scripts.Components.Actors; using Cirno.Scripts.Interactables; using Godot; @@ -29,6 +31,8 @@ public partial class IsoActivationProvider: Area3D, IModule StateMachine { get; private set; } + private CollisionShape3D _collisionShape; + public void EnterState(PlayerState state) { Enabled = true; @@ -47,6 +51,8 @@ public partial class IsoActivationProvider: Area3D, IModule("CollisionShape"); + _selectorController.Hide(); SpawnSelector(); @@ -102,13 +108,14 @@ public partial class IsoActivationProvider: Area3D, IModule ScanTargets() + { + var spaceState = GetWorld3D().DirectSpaceState; + var query = new PhysicsShapeQueryParameters3D() + { + Shape = _collisionShape.Shape, + CollideWithBodies = false, + CollideWithAreas = true, + CollisionMask = this.CollisionMask, + Exclude = [GetRid()], + + }; + + var targets = spaceState.IntersectShape(query); + if (targets.Count is 0) return null; + var found = targets.Select(resDict => + { + var collider = resDict["collider"].As(); + if (collider.IsInGroup("Interactable") && collider is IInteractable interactable && + interactable.CanActivate()) + { + return interactable; + } + else + { + return null; + } + } + ).Where(x => x is not null).ToList(); + + return found; + } private void _on_interaction_controller_area_entered(Area3D area) { diff --git a/Scripts/Components/FSM/3DPlayer/SelectorController.cs b/Scripts/Components/FSM/3DPlayer/SelectorController.cs index c0be88fe..c60b454b 100644 --- a/Scripts/Components/FSM/3DPlayer/SelectorController.cs +++ b/Scripts/Components/FSM/3DPlayer/SelectorController.cs @@ -6,11 +6,25 @@ namespace Cirno.Scripts.Components.FSM._3DPlayer; public partial class SelectorController : Node { - [Signal] public delegate void ShowSelectorEventHandler(); - [Signal] public delegate void HideSelectorEventHandler(); - [Signal] public delegate void ChangePositionEventHandler(Vector2 position); + [Signal] + public delegate void ShowSelectorEventHandler(); + + [Signal] + public delegate void HideSelectorEventHandler(); + + [Signal] + public delegate void ChangePositionEventHandler(Vector2 position); + + [Signal] + public delegate void ChangeParent3DEventHandler(Node3D node); + + private bool _canSelect = true; + + public bool CanSelect => _canSelect; + + private bool _autoSelect = false; - [Signal] public delegate void ChangeParent3DEventHandler(Node3D node); + private double _cooldownTimer = 0f; private Interactable _lastInteractable; @@ -31,18 +45,25 @@ public partial class SelectorController : Node if (value < 0) { _selectedInteractable = _interactables.Count - 1; + // if (_selectedInteractable < 0) + // { + // _selectedInteractable = 0; + // } } } } - + public IInteractable SelectedInteractable { + // The problem here is that if it's deselected the index is -1 get => - _interactables.Count > 0 - ? SelectedInteractableIndex >= _interactables.Count - ? _interactables[^1] - : _interactables[SelectedInteractableIndex] - : null; + SelectedInteractableIndex < 0 + ? null + : _interactables.Count > 0 + ? SelectedInteractableIndex >= _interactables.Count + ? _interactables[^1] + : _interactables[SelectedInteractableIndex] + : null; set { // Passing null deselects the interactable @@ -63,7 +84,7 @@ public partial class SelectorController : Node NotifyChanged(value); } } - + public void SelectNext() { SelectedInteractableIndex += 1; @@ -73,28 +94,48 @@ public partial class SelectorController : Node // _selectedInteractable = 0; // } - if (_interactables.Count > 0) + if (_interactables.Count <= 0) { - SelectedInteractable = _interactables[_selectedInteractable]; - } - else - { - _selectedInteractable = -1; + SelectedInteractable = null; + //SelectedInteractableIndex = -1; } + // No need to set it because the selection is already handled when reading + // else + // { + // SelectedInteractable = _interactables[_selectedInteractable]; + // } + UpdatePosition(); } - + + public void SelectNextDelayed() + { + if (!_canSelect) + { + _autoSelect = true; + } + else + { + SelectNext(); + } + //CallDeferred(MethodName.SelectNext); + } + public void AddInteractable(IInteractable interactable) { if (!_interactables.Contains(interactable)) { _interactables.Add(interactable); - if (_interactables.Count == 1) - { - _selectedInteractable = 0; - } + // Always set the current one to the newest + SelectedInteractable = interactable; + + // if (_interactables.Count == 1) + // { + // SelectedInteractable = interactable; + // //_selectedInteractable = 0; + // } } UpdatePosition(); @@ -109,8 +150,17 @@ public partial class SelectorController : Node public void Deselect() { - _selectedInteractable = -1; + SelectedInteractable = null; + //SelectedInteractableIndex = -1; EmitSignalHideSelector(); + + } + + public void DeselectWithCooldown() + { + Deselect(); + _canSelect = false; + _cooldownTimer = 0d; } public void UpdatePosition() @@ -127,7 +177,7 @@ public partial class SelectorController : Node EmitSignalHideSelector(); } } - + private void NotifyChanged(IInteractable interactable) { //EmitSignal(nameof(SelectedItemInteractableChanged), interactable); @@ -138,9 +188,18 @@ public partial class SelectorController : Node EmitSignalHideSelector(); } - // public void PhysicsProcess(double delta) - // { - // if (SelectedInteractable is null) return; - // //EmitSignalChangePosition(SelectedInteractable.GetScreenPosition()); - // } + public void PhysicsProcess(double delta) + { + if (_canSelect is true) return; + _cooldownTimer += delta; + + if (!(_cooldownTimer >= 0.2d)) return; + _canSelect = true; + _cooldownTimer = 0; + if (!_autoSelect) return; + _autoSelect = false; + SelectNext(); + //if (SelectedInteractable is null) return; + //EmitSignalChangePosition(SelectedInteractable.GetScreenPosition()); + } } \ No newline at end of file