#Collider Cast hits itself

1 messages · Page 1 of 1 (latest)

south raft
#

Hello. I'm in process of making custom Kinematic Character Controller. I'm currently learning how to work with Unity Physics package and want to know why when I call CapsuleCast, using attached CapsuleCollider component, it detects itself?

Is there other ways of ignoring self collider besides specifying layer mask? I believe I'm misuing Physics API

[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
[UpdateAfter(typeof(PhysicsSystemGroup))]
public partial struct CharacterControllerSystem : ISystem
{
    public void OnCreate(ref SystemState state)
    {
        state.RequireForUpdate<PhysicsWorldSingleton>();
    }

    public void OnUpdate(ref SystemState state)
    {
        PhysicsWorldSingleton physicsWorld = GetSingleton<PhysicsWorldSingleton>();
        CollisionWorld collisionWorld = physicsWorld.CollisionWorld;
        
        foreach (var (lw, collider, _) in Query<RefRO<LocalToWorld>, RefRO<PhysicsCollider>, RefRO<CharacterController>>())
        {
            NativeList<ColliderCastHit> hits = new(Allocator.Temp);
            unsafe
            {
                ColliderCastInput input = new()
                {
                    Collider = collider.ValueRO.ColliderPtr,
                    Orientation = quaternion.identity,
                    Start = lw.ValueRO.Position,
                    End = new(0, 0, 10),
                };

                var isHit = collisionWorld.CastCollider(input, ref hits);
                
                Debug.Log($"{isHit} {hits.Length}");
            }
        }
    }
}
wispy halo
#

Not sure if there is a better way but I use a custom collector and skip the entity in the collector and pass the collector as a ref instead of a list. I also tend to have custom collectors to sort in the collector instead of in the system.
(semi-pseudo code)

[BurstCompile] public struct IgnoreSelfCollector : ICollector<ColliderCastHit>, IDisposable
  {
      Entity self;
      public NativeList<ColliderCastHit> Hits;
      
      [BurstCompile] public bool AddHit(ColliderCastHit hit)
      {
          if (hit.Entity == Self)
              return false;
          NumHits++;
          Hits.Add(hit);
          if (hit.Fraction < MaxFraction)
              MaxFraction = hit.Fraction;
          return true;
      }

      public bool EarlyOutOnFirstHit { get; set; }
      public float MaxFraction { get; private set; }
      public int NumHits { get; private set; }
      public IgnoreSelfCollector(Entity self, Allocator allocator, bool earlyOutOnFirstHit = false)
      {
          this.self = self; 
          EarlyOutOnFirstHit = earlyOutOnFirstHit;
          MaxFraction = 1f;
          NumHits = 0;
          Hits = new NativeList(allocator);
      }
      public void Dispose() => Hits.Dispose();
  }
south raft
south raft
#

Collider Cast casts to itself