Files
Babushka/scripts/CSharp/Common/CharacterControls/Detector.cs
T

97 lines
2.7 KiB
C#
Raw Normal View History

2025-12-12 13:46:32 +01:00
using System.Collections.Generic;
2025-10-22 19:30:33 +02:00
using Babushka.scripts.CSharp.Common.Services;
2025-12-12 13:46:32 +01:00
using Babushka.scripts.CSharp.Low_Code.Variables;
2025-10-22 19:30:33 +02:00
using Godot;
namespace Babushka.scripts.CSharp.Common.CharacterControls;
2025-10-24 15:13:35 +02:00
/// <summary>
/// Defines an <see cref="Area2D"/> Node with a <see cref="CollisionShape2D"/> used for detecting <see cref="InteractionArea2D"/> nodes.
/// </summary>
2025-10-22 19:30:33 +02:00
public partial class Detector : Area2D
{
[Export] private bool _active = true;
2025-12-12 13:46:32 +01:00
[Export] private ShapeCast2D _shapeCast2D;
[Export] private VariableResource _itemToTriggerResource;
2025-10-22 19:30:33 +02:00
2025-12-15 22:45:02 +01:00
private List<ulong> _areasInDetector = new();
2025-10-22 19:30:33 +02:00
public bool IsActive
{
get => _active;
2025-10-24 15:13:35 +02:00
set
{
Visible = value;
_active = value;
}
2025-10-22 19:30:33 +02:00
}
public override void _Ready()
{
AreaEntered += OnEnteredInteractable;
AreaExited += OnExitedInteractable;
}
2025-10-24 15:13:35 +02:00
/// <summary>
/// Called every time this node enters an Area2D.
/// </summary>
/// <param name="area"></param>
public void OnEnteredInteractable(Area2D area)
2025-10-22 19:30:33 +02:00
{
if (!_active || !InputService.Instance.InputEnabled)
return;
2025-12-15 22:45:02 +01:00
PopulateList();
CalculateClosestInteractable();
2025-10-22 19:30:33 +02:00
}
2025-10-24 15:13:35 +02:00
/// <summary>
/// Called whenever this node exits an Area2D.
/// </summary>
/// <param name="area"></param>
public void OnExitedInteractable(Area2D area)
2025-10-22 19:30:33 +02:00
{
2025-10-24 15:13:35 +02:00
if (!_active || !InputService.Instance.InputEnabled)
return;
2025-10-22 19:30:33 +02:00
2025-12-15 22:45:02 +01:00
PopulateList();
CalculateClosestInteractable();
}
private void PopulateList()
{
// repopulate the list of areas in the detector to account for enabled / disabled areas
var currentOverlap = GetOverlappingAreas();
_areasInDetector = new List<ulong>();
foreach (var area2D in currentOverlap)
2025-10-22 19:30:33 +02:00
{
2025-12-15 22:45:02 +01:00
if (area2D is DetectableInteractionArea detectable)
{
ulong id = detectable.GetInstanceId();
_areasInDetector.Add(id);
}
2025-10-22 19:30:33 +02:00
}
}
2025-12-12 13:46:32 +01:00
private void CalculateClosestInteractable()
{
float smallestDistance = float.MaxValue;
string closestInteractable = null;
foreach (var area in _areasInDetector)
{
Area2D? area2D = InstanceFromId(area) as Area2D;
if(area2D == null)
continue;
float distance = area2D.GlobalPosition.DistanceSquaredTo(ToGlobal(_shapeCast2D.TargetPosition));
if (distance < smallestDistance)
{
closestInteractable = area.ToString();
smallestDistance = distance;
}
}
_itemToTriggerResource.Payload = closestInteractable;
}
2025-10-22 19:30:33 +02:00
}