using Godot; using System.Collections; using System.Collections.Generic; namespace Rokojori { [Tool] [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/Collider.svg")] public partial class Collider:Node, iNodeState { [Export] public Area3D area; [Export] public CollisionFlag collisionType; [Export] public Action onEntered; [Export] public Action onInside; [Export] public Action onExit; Dictionary _inside = new Dictionary(); public void OnNodeStateChanged() { if ( ! IsProcessing() || ! IsPhysicsProcessing() || Node.ProcessModeEnum.Disabled == this.ProcessMode ) { // this.LogInfo( "Clearing nodes" ); _inside.Clear(); } } public override void _Ready() { if ( area == null ) { return; } area.AreaEntered += TriggerOnEnter; area.BodyEntered += TriggerOnEnter; area.AreaExited += TriggerOnExited; area.BodyExited += TriggerOnExited; } void TriggerOnEnter( Node n ) { if ( ! Math3D.IsValid( area.GlobalPosition ) ) { return; } var collidable = n.Get(); if ( collidable == null || ! collidable.IsCollidingWith( this ) ) { return; } collidable.Collide( this, CollisionPhase.Entered ); if ( onInside == null ) { return; } var tm = Unique.Get(); if ( tm == null ) { return; } var callback = ()=> { collidable.Collide( this, CollisionPhase.Inside ); }; _inside[ collidable ] = callback; tm.AddProcessCallback( callback ); } void TriggerOnExited( Node n ) { var collidable = n.Get(); if ( collidable == null || ! collidable.IsCollidingWith( this ) ) { return; } collidable.Collide( this, CollisionPhase.Exit ); if ( ! _inside.ContainsKey( collidable ) ) { return; } var tm = Unique.Get(); var callback = _inside[ collidable ]; _inside.Remove( collidable ); if ( tm == null ) { return; } tm.RemoveProcessCallback( callback ); } } }