166 lines
3.5 KiB
C#
166 lines
3.5 KiB
C#
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;
|
|
|
|
[Export]
|
|
public bool activateAlwaysOnInside = false;
|
|
|
|
|
|
Dictionary<Collidable,System.Action> _inside = new Dictionary<Collidable,System.Action>();
|
|
|
|
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;
|
|
}
|
|
|
|
public void TriggerOnCollisionEnter( Projectile p, KinematicCollision3D collision )
|
|
{
|
|
// this.LogInfo( "Collider:", collision.GetCollider( 0 ), "Shape:", collision.GetColliderShape( 0 ) );
|
|
_TriggerOnEnter( (Node) collision.GetCollider( 0 ) );
|
|
}
|
|
|
|
public void TriggerOnCollisionExit( Projectile p, KinematicCollision3D collision )
|
|
{
|
|
// this.LogInfo( "Collider:", collision.GetCollider( 0 ), "Shape:", collision.GetColliderShape( 0 ) );
|
|
_TriggerOnExited( (Node) collision.GetCollider( 0 ) );
|
|
}
|
|
|
|
public void TriggerOnEnter( Node3D node3D )
|
|
{
|
|
// this.LogInfo( "Collider:", collision.GetCollider( 0 ), "Shape:", collision.GetColliderShape( 0 ) );
|
|
_TriggerOnEnter( node3D );
|
|
}
|
|
|
|
public void TriggerOnExited( Node3D node3D )
|
|
{
|
|
// this.LogInfo( HierarchyName.Of( node3D ) );
|
|
_TriggerOnExited( node3D );
|
|
}
|
|
|
|
Collidable GetCollidable( Node n )
|
|
{
|
|
if ( n is Collidable c && c.IsCollidingWith( this ) )
|
|
{
|
|
return c;
|
|
}
|
|
|
|
return n.FindDirectChild<Collidable>( c => c.IsCollidingWith( this ) );
|
|
|
|
}
|
|
|
|
void _TriggerOnEnter( Node n )
|
|
{
|
|
if ( n == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( area != null && ! Math3D.IsValid( area.GlobalPosition ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
var collidable = GetCollidable( n );
|
|
|
|
if ( collidable == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
collidable.Collide( this, CollisionPhase.Entered );
|
|
|
|
if ( ( ! activateAlwaysOnInside ) && onInside == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var tm = Unique<TimeLineManager>.Get();
|
|
|
|
if ( tm == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var callback = ()=>
|
|
{
|
|
collidable.Collide( this, CollisionPhase.Inside );
|
|
};
|
|
|
|
_inside[ collidable ] = callback;
|
|
tm.AddProcessCallback( callback );
|
|
|
|
}
|
|
|
|
void _TriggerOnExited( Node n )
|
|
{
|
|
var collidable = GetCollidable( n );
|
|
|
|
if ( collidable == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
collidable.Collide( this, CollisionPhase.Exit );
|
|
|
|
if ( ! _inside.ContainsKey( collidable ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var tm = Unique<TimeLineManager>.Get();
|
|
|
|
var callback = _inside[ collidable ];
|
|
_inside.Remove( collidable );
|
|
|
|
if ( tm == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
tm.RemoveProcessCallback( callback );
|
|
|
|
|
|
}
|
|
}
|
|
} |