using GarmentButton.PhysicFillters; using Unity.Burst; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.Jobs; using Unity.Mathematics; using Unity.Physics; namespace GarmentButton.PathFinding { [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))] [BurstCompile] public partial struct CastingCheckSystem : ISystem { private const int CHECK_POINT_BATCH_SIZE = 64; [BurstCompile] public void OnCreate(ref SystemState state) { state.RequireForUpdate(); var query = SystemAPI.QueryBuilder().WithAll().Build(); state.RequireForUpdate(query); state.RequireForUpdate(); } //[BurstCompile] public void OnUpdate(ref SystemState state) { var surfaceTypeLookUp = SystemAPI.GetComponentLookup(true); var ecb = SystemAPI.GetSingleton() .CreateCommandBuffer(state.WorldUnmanaged); foreach (var (grid, additional, updatePoints, data, entity) in SystemAPI .Query, RefRW, RefRO, RefRO>() .WithAll().WithEntityAccess()) { ecb.RemoveComponent(entity); var lenght = updatePoints.ValueRO.Indexes.Length; var physicsWorld = SystemAPI.GetSingleton(); if (lenght > 0) { state.Dependency = new CheckPoint { Points = grid.ValueRO.Value, Size = data.ValueRO.CellSize, CanBeWalked = additional.ValueRW.Types, SurfaceLookUp = surfaceTypeLookUp, Physics = physicsWorld.PhysicsWorld, Indexes = updatePoints.ValueRO.Indexes.AsReadOnly() }.ScheduleParallel(lenght, CHECK_POINT_BATCH_SIZE, state.Dependency); } state.Dependency = new SetUpdateCheck { GridEntity = entity, ECB = ecb, }.Schedule(state.Dependency); } } [BurstCompile] public partial struct CheckPoint : IJobFor { [ReadOnly] public BlobAssetReference Points; [ReadOnly] public float Size; [ReadOnly] public ComponentLookup SurfaceLookUp; [NativeDisableParallelForRestriction] public NativeArray CanBeWalked; [ReadOnly] public PhysicsWorld Physics; [ReadOnly] public NativeArray.ReadOnly Indexes; public const GroundType DEFUALT_STATE = GroundType.Air; public void Execute(int indexe) { var index = Indexes[indexe]; var position = Points.Value.Array[index]; var state = DEFUALT_STATE; var position3D = new float3(position.X, position.Y, position.Z) * 0.1f; var filter = new CollisionFilter { BelongsTo = (uint)CollisionLayer.Trigger, CollidesWith = (uint)(CollisionLayer.Ground) | (uint)(CollisionLayer.Obstacle) | (uint)(CollisionLayer.AIGround), }; var raycast = Physics.CastRay(new RaycastInput { Start = position3D + new float3(0, 10f, 0), End = position3D - new float3(0, 10f, 0), Filter = filter, }, out var raycastHit); if (!raycast) { CanBeWalked[index] = GroundType.Air; return; } var hits = new NativeList(Allocator.Temp); var isHit = Physics.OverlapBox(position3D, quaternion.identity, new float3(Size, Size, Size) * 0.5f, ref hits, filter); if (!isHit) { CanBeWalked[index] = GroundType.Air; hits.Dispose(); return; } for (int i = 0; i < hits.Length; i++) { var entity = hits[i].Entity; if (!SurfaceLookUp.HasComponent(entity)) continue; var type = SurfaceLookUp.GetRefRO(entity); if ((byte)type.ValueRO.Value <= (byte)state) continue; state = type.ValueRO.Value; } hits.Dispose(); CanBeWalked[index] = state; } } [BurstCompile] public partial struct SetUpdateCheck : IJob { public EntityCommandBuffer ECB; public Entity GridEntity; public void Execute() { ECB.AddComponent(GridEntity); } } } }