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

158 lines
2.9 KiB
C#
Raw Normal View History

2024-08-04 09:08:12 +00:00
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
2025-05-21 20:44:28 +00:00
[Tool]
2024-08-04 09:08:12 +00:00
[GlobalClass]
2025-01-08 18:46:17 +00:00
public partial class MultiRayCaster:Caster
2024-08-04 09:08:12 +00:00
{
2025-06-23 11:16:01 +00:00
public enum UpdateMode
{
Process,
Physics_Process
}
2024-08-04 09:08:12 +00:00
[Export]
public float rayLength = 10;
[Export]
2025-10-31 12:09:03 +00:00
public int maxHits = 3;
2024-08-04 09:08:12 +00:00
List<CollisionData> collisions = new List<CollisionData>();
int numCollisions = 0;
[Export]
public Vector3 to;
2025-05-21 20:44:28 +00:00
[Export]
2025-12-11 14:47:57 +00:00
public UpdateMode updateMode = UpdateMode.Physics_Process;
2025-05-21 20:44:28 +00:00
2025-06-23 11:16:01 +00:00
[Export]
2025-12-11 14:47:57 +00:00
public Action beforeProcess;
2025-06-23 11:16:01 +00:00
2025-12-11 14:47:57 +00:00
[Export]
public Action afterProcess;
2024-08-04 09:08:12 +00:00
2025-12-11 14:47:57 +00:00
[ExportGroup( "Debugging")]
[Export]
public Node collider;
2024-08-04 09:08:12 +00:00
2025-12-11 14:47:57 +00:00
[Export]
public bool printColliderNames = false;
2024-08-04 09:08:12 +00:00
PhysicsRayQueryParameters3D rayParameters = new PhysicsRayQueryParameters3D();
2025-12-11 14:47:57 +00:00
public override void _PhysicsProcess( double delta )
{
2025-06-23 11:16:01 +00:00
if ( UpdateMode.Physics_Process != updateMode )
{
return;
}
Update( delta );
}
2024-08-04 09:08:12 +00:00
public override void _Process( double delta )
{
2025-06-23 11:16:01 +00:00
if ( UpdateMode.Process != updateMode )
{
return;
}
Update( delta );
}
2025-10-31 12:09:03 +00:00
[Export]
public bool runInEditor = false;
2025-06-23 11:16:01 +00:00
void Update( double delta )
{
2025-10-31 12:09:03 +00:00
if ( Engine.IsEditorHint() && ! runInEditor )
2025-06-23 11:16:01 +00:00
{
return;
}
2025-01-08 18:46:17 +00:00
Action.Trigger( beforeProcess );
2024-08-04 09:08:12 +00:00
ResolveCollisions();
SortCollisions();
2025-05-21 20:44:28 +00:00
var nextCollider = NumColliders() == 0 ? null : GetCollider( 0 );
if ( nextCollider != collider )
{
collider = nextCollider;
2024-08-04 09:08:12 +00:00
2025-12-11 14:47:57 +00:00
if ( printColliderNames )
{
this.LogInfo( "New Collider:", HierarchyName.Of( collider ) );
}
2025-05-21 20:44:28 +00:00
}
2025-01-08 18:46:17 +00:00
Action.Trigger( afterProcess );
2025-06-23 11:16:01 +00:00
}
2024-08-04 09:08:12 +00:00
CollisionData GetCollisionData( int i )
{
while ( collisions.Count <= i )
{
collisions.Add( new CollisionData() );
}
return collisions[ i ];
}
void ResolveCollisions()
{
var physics = GetWorld3D().DirectSpaceState;
var excludes = new Array<Rid>();
var from = GlobalPosition;
2025-10-31 12:09:03 +00:00
var to = from + this.GlobalForward().Normalized() * rayLength;
2024-08-04 09:08:12 +00:00
this.to = to;
rayParameters.From = from;
rayParameters.To = to;
numCollisions = 0;
for ( int i = 0; i < maxHits; i++ )
{
rayParameters.Exclude = excludes;
var collisionData = GetCollisionData( numCollisions );
collisionData.Get( rayParameters, physics );
2025-10-31 12:09:03 +00:00
if ( ! collisionData.hasCollision || this.DistanceTo( collisionData.position ) > rayLength )
2024-08-04 09:08:12 +00:00
{
return;
}
excludes.Add( collisionData.rid );
if ( IsSelected( collisionData ) )
{
numCollisions ++;
}
}
}
2025-12-11 14:47:57 +00:00
2024-08-04 09:08:12 +00:00
}
}