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; } } } }