rj-action-library/Runtime/Interactions/AreaCaster.cs

137 lines
2.7 KiB
C#

using Godot;
using System.Collections;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class AreaCaster:Caster, iNodeState
{
[Export]
public Area3D area;
[Export]
public Action onCollisionsChanged;
[Export]
public Action onCollisionEntered;
[Export]
public Action onCollisionExited;
[ExportGroup( "Debugging")]
[Export]
public Node collider;
[Export]
public bool printColliderNames = false;
public override void _Ready()
{
if ( area == null )
{
return;
}
area.AreaEntered += TriggerOnEnter;
area.BodyEntered += TriggerOnEnter;
area.AreaExited += _TriggerOnExited;
area.BodyExited += _TriggerOnExited;
}
public void TriggerOnEnter( Node3D node3D )
{
this.LogInfo( HierarchyName.Of( node3D ) );
_TriggerOnEnter( node3D );
}
public void TriggerOnExited( Node3D node3D )
{
this.LogInfo( HierarchyName.Of( node3D ) );
_TriggerOnExited( node3D );
}
void _TriggerOnEnter( Node3D n )
{
if ( n == null )
{
return;
}
if ( area != null && ! Math3D.IsValid( area.GlobalPosition ) )
{
return;
}
var selected = IsSelected( n );
if ( ! selected )
{
// this.LogInfo( "Not selected", HierarchyName.Of( n ) );
return;
}
var collisionData = new CollisionData();
collisionData.hasCollision = true;
collisionData.collider = n;
collisionData.position = ( area.GlobalPosition + n.GlobalPosition ) / 2f;
collisionData.normal = ( n.GlobalPosition - area.GlobalPosition ).Normalized();
collisions.Add( collisionData );
numCollisions = collisions.Count;
// this.LogInfo( "Selected", HierarchyName.Of( n ) );
SortCollisions();
onCollisionEntered?.Trigger();
onCollisionsChanged?.Trigger();
}
void _TriggerOnExited( Node n )
{
if ( n == null )
{
return;
}
var insideIndex = collisions.FindIndex( c => c.collider == n );
if ( insideIndex == -1 )
{
return;
}
collisions.RemoveAt( insideIndex );
numCollisions = collisions.Count;
SortCollisions();
onCollisionExited?.Trigger();
onCollisionsChanged?.Trigger();
}
public void OnNodeStateChanged()
{
if ( ! IsProcessing() || ! IsPhysicsProcessing() || Node.ProcessModeEnum.Disabled == this.ProcessMode )
{
// this.LogInfo( "Clearing nodes" );
collisions.Clear();
numCollisions = 0;
}
}
}
}