You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.9 KiB
99 lines
2.9 KiB
using System.Collections.Generic;
|
|
using Babushka.scripts.CSharp.Common.Services;
|
|
using Babushka.scripts.CSharp.Low_Code.Variables;
|
|
using Godot;
|
|
|
|
namespace Babushka.scripts.CSharp.Common.CharacterControls;
|
|
|
|
/// <summary>
|
|
/// Defines an <see cref="Area2D"/> Node with a <see cref="CollisionShape2D"/> used for detecting <see cref="InteractionArea2D"/> nodes.
|
|
/// </summary>
|
|
public partial class Detector : Area2D
|
|
{
|
|
[Export] private bool _active = true;
|
|
[Export] private ShapeCast2D _shapeCast2D;
|
|
[Export] private VariableResource _itemToTriggerResource;
|
|
|
|
private List<ulong> _areasInDetector = new();
|
|
|
|
public bool IsActive
|
|
{
|
|
get => _active;
|
|
set
|
|
{
|
|
Visible = value;
|
|
_active = value;
|
|
}
|
|
}
|
|
|
|
public override void _Ready()
|
|
{
|
|
AreaEntered += OnEnteredInteractable;
|
|
AreaExited += OnExitedInteractable;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called every time this node enters an Area2D.
|
|
/// </summary>
|
|
/// <param name="area"></param>
|
|
public void OnEnteredInteractable(Area2D area)
|
|
{
|
|
if (!_active || !InputService.Instance.InputEnabled)
|
|
return;
|
|
|
|
PopulateList();
|
|
CalculateClosestInteractable();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called whenever this node exits an Area2D.
|
|
/// </summary>
|
|
/// <param name="area"></param>
|
|
public void OnExitedInteractable(Area2D area)
|
|
{
|
|
if (!_active || !InputService.Instance.InputEnabled)
|
|
return;
|
|
|
|
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)
|
|
{
|
|
if (area2D is DetectableInteractionArea detectable)
|
|
{
|
|
ulong id = detectable.GetInstanceId();
|
|
_areasInDetector.Add(id);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CalculateClosestInteractable()
|
|
{
|
|
GD.Print($"Areas in detector: {_areasInDetector.Count}");
|
|
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;
|
|
}
|
|
}
|
|
GD.Print($"Closest interactable: {closestInteractable}");
|
|
_itemToTriggerResource.Payload = closestInteractable;
|
|
}
|
|
|
|
} |