Ejemplo n.º 1
0
    private JobHandle UpdateWithCollider2ColliderQuery(JobHandle inputDeps)
    {
        var physicsWorldSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystem <BuildPhysicsWorld>();
        var collisionWorld     = physicsWorldSystem.PhysicsWorld.CollisionWorld;

        // this is probably redundant but just for safety lets include all previous physics systems
        inputDeps = JobHandle.CombineDependencies(inputDeps, finalPhysicsSystem.FinalJobHandle);
        inputDeps = JobHandle.CombineDependencies(inputDeps, buildPhysicsSystem.FinalJobHandle);
        inputDeps = JobHandle.CombineDependencies(inputDeps, stepPhysicsSystem.FinalJobHandle);

        inputDeps = Entities.ForEach((Entity entity, ref EntitiesAroundCountCmp around, in Translation translation, in PhysicsCollider collider) =>
        {
            around.count = 0;

            float3 offset          = new float3(around.range, 1, around.range);
            OverlapAabbInput input = new OverlapAabbInput()
            {
                Aabb = new Aabb()
                {
                    Min = translation.Value - offset,
                    Max = translation.Value + offset,
                },
                Filter = CollisionFilter.Default
            };

            NativeList <int> bodyIndices = new NativeList <int>(Allocator.Temp);

            // OverlapAabb is really nice and fast, all expected colliders are returned
            if (collisionWorld.OverlapAabb(input, ref bodyIndices))
            {
                for (int i = 0; i < bodyIndices.Length; ++i)
                {
                    var body = collisionWorld.Bodies[bodyIndices[i]];

                    // why this returns true for colliders in AABB instead of actual distance?
                    var colliderDistanceInput = new ColliderDistanceInput()
                    {
                        Collider    = collider.ColliderPtr,
                        Transform   = RigidTransform.identity,
                        MaxDistance = around.range
                    };

                    // why this always returns false?
                    var pointDistanceInput = new PointDistanceInput()
                    {
                        Filter      = CollisionFilter.Default,
                        MaxDistance = around.range,
                        Position    = translation.Value
                    };

                    if (body.CalculateDistance(pointDistanceInput))
                    {
                        ++around.count;
                    }
                }
            }
            bodyIndices.Dispose();
        })
        public JobHandle OverlapDetectionWithoutDetector(ref OverlapAabbInput input, ref NativeList <Entity> entities, Entity detectorToRemoved)
        {
            var handle = OverlapDetection(ref input, ref entities);

            for (int i = 0; i < entities.Length; i++)
            {
                if (entities[i] == detectorToRemoved)
                {
                    entities.RemoveAtSwapBack(i);
                }
            }
            return(handle);
        }
        public JobHandle OverlapDetection(ref OverlapAabbInput input, ref NativeList <Entity> entities)
        {
            var resultIndices = new NativeList <int>(1, Allocator.TempJob);
            var handle        = new OverlapJob
            {
                World          = m_physicsWorldSystem.PhysicsWorld.CollisionWorld,
                OverlapInput   = input,
                ResultIndices  = resultIndices,
                ResultEntities = entities,
            }.Schedule();

            handle.Complete();
            resultIndices.Dispose(handle);
            return(handle);
        }
    protected override void OnUpdate()
    {
        Dependency.Complete();

        using (var commandBuffer = new EntityCommandBuffer(Allocator.TempJob))
        {
            var physicsWorld = m_BuildPhysicsWorld.PhysicsWorld;
            Entities
            .WithName("DestroyTriggerJob")
            .WithReadOnly(physicsWorld)
            .WithBurst()
            .ForEach((ref Entity e, ref DestroyTrigger destroyComponent) =>
            {
                if (--destroyComponent.FramesToDestroyIn != 0)
                {
                    return;
                }

                commandBuffer.DestroyEntity(e);

                int triggerRbIndex    = physicsWorld.GetRigidBodyIndex(e);
                RigidBody triggerBody = physicsWorld.Bodies[triggerRbIndex];

                // Remove the TriggerEventCheckerComponent of all overlapping bodies
                OverlapAabbInput input = new OverlapAabbInput
                {
                    Aabb   = triggerBody.CalculateAabb(),
                    Filter = CollisionFilter.Default
                };

                NativeList <int> overlappingBodies = new NativeList <int>(Allocator.Temp);

                physicsWorld.CollisionWorld.OverlapAabb(input, ref overlappingBodies);

                for (int i = 0; i < overlappingBodies.Length; i++)
                {
                    Entity overlappingEntity = physicsWorld.Bodies[overlappingBodies[i]].Entity;
                    if (HasComponent <TriggerEventChecker>(overlappingEntity))
                    {
                        commandBuffer.RemoveComponent <TriggerEventChecker>(overlappingEntity);
                    }
                }
            }).Run();

            commandBuffer.Playback(EntityManager);
        }
    }
Ejemplo n.º 5
0
            private bool Overlapped(float3 position, ref FieldOfView setting, ref NativeList <int> hits)
            {
                var radius = setting.Radius;
                var input  = new OverlapAabbInput
                {
                    Aabb = new Aabb
                    {
                        Max = position + new float3(radius, 0, radius),
                        Min = position - new float3(radius, 0, radius)
                    },
                    Filter = new CollisionFilter
                    {
                        BelongsTo = Setting.SelfTag.Value, CollidesWith = Setting.TargetTag.Value,
                    }
                };

                return(World.OverlapAabb(input, ref hits));
            }
Ejemplo n.º 6
0
        public void Execute(int index)
        {
            var allHits = new NativeList <int>(Allocator.Temp);

            var input = new OverlapAabbInput
            {
                Aabb   = Ptr[index].Aabb,
                Filter = new CollisionFilter()
                {
                    BelongsTo      = ~0u,
                    CollidesWith   = 1u << 8, // Obstacle layer
                        GroupIndex = 0
                }
            };

            World.OverlapAabb(input, ref allHits);
            Ptr[index].Walkable = allHits.Length <= 0;
            allHits.Dispose();
        }
Ejemplo n.º 7
0
        public static bool OverlapAabb(ISimGameWorldReadWriteAccessor accessor, fix2 min, fix2 max, NativeList <Entity> outEntities, Entity ignoreEntity = default)
        {
            var physicsSystem = accessor.GetExistingSystem <PhysicsWorldSystem>();

            OverlapAabbInput input = OverlapAabbInput.Default;

            input.Aabb = new Aabb((float2)min, (float2)max);

            if (ignoreEntity != Entity.Null)
            {
                input.Ignore = new IgnoreHit(physicsSystem.GetPhysicsBodyIndex(ignoreEntity));
            }

            NativeList <int> outBodyIndexes = new NativeList <int>(Allocator.Temp);
            bool             hit            = physicsSystem.PhysicsWorld.OverlapAabb(input, outBodyIndexes);

            for (int i = 0; i < outBodyIndexes.Length; i++)
            {
                outEntities.Add(physicsSystem.PhysicsWorld.AllBodies[outBodyIndexes[i]].Entity);
            }

            return(hit);
        }
Ejemplo n.º 8
0
        public static void MakeExplosion(ref PhysicsWorld physicsWorld,
                                         ComponentDataFromEntity <Translation> translationGroup, ComponentDataFromEntity <Rotation> rotationGroup,
                                         ComponentDataFromEntity <PhysicsVelocity> physicsVelocityGroup, ComponentDataFromEntity <PhysicsMass> physicsMassGroup,
                                         ComponentDataFromEntity <PlayerHealth> healthGroup,
                                         float3 origin, float explosionRadius, float explosionForce, float explosionMaxDamage = 0f)
        {
            float3 min             = new float3(origin.x - explosionRadius, origin.y - explosionRadius, origin.z - explosionRadius);
            float3 max             = new float3(origin.x + explosionRadius, origin.y + explosionRadius, origin.z + explosionRadius);
            Aabb   explosionBounds = new Aabb
            {
                Min = min,
                Max = max,
            };

            OverlapAabbInput input = new OverlapAabbInput
            {
                Aabb   = explosionBounds,
                Filter = CollisionFilter.Default,
            };

            NativeList <int> rigidBodyIndexs = new NativeList <int>(256, Allocator.Temp); // indexes into world.Bodies[]

            if (physicsWorld.CollisionWorld.OverlapAabb(input, ref rigidBodyIndexs))
            {
                for (int i = 0; i < rigidBodyIndexs.Length; i++)
                {
                    RigidBody body = physicsWorld.Bodies[rigidBodyIndexs[i]];

                    if (physicsVelocityGroup.Exists(body.Entity) && physicsMassGroup.Exists(body.Entity))
                    {
                        float distance = math.distance(body.WorldFromBody.pos, origin);
                        if (distance < explosionRadius)
                        {
                            float gain  = math.clamp((explosionRadius - distance) / explosionRadius, 0, 1);
                            float force = gain * explosionForce;

                            float3 toBody  = body.WorldFromBody.pos - origin;
                            float3 impulse = math.normalize(toBody) * force;
                            //impulse.y = explosionForceY;

                            var velocity    = physicsVelocityGroup[body.Entity];
                            var mass        = physicsMassGroup[body.Entity];
                            var translation = translationGroup[body.Entity];
                            var rotation    = rotationGroup[body.Entity];

                            velocity.ApplyImpulse(mass, translation, rotation, impulse, origin);

                            physicsVelocityGroup[body.Entity] = velocity;

                            if (healthGroup.Exists(body.Entity))
                            {
                                var health = healthGroup[body.Entity];
                                health.Health           -= explosionMaxDamage * gain;
                                healthGroup[body.Entity] = health;
                            }
                        }
                    }
                }
            }

            rigidBodyIndexs.Dispose();
        }
Ejemplo n.º 9
0
    protected override void OnUpdate()
    {
        if (!HasSingleton <GameStartedTag>())
        {
            Entities
            .ForEach((ref CanMove canMove) =>
            {
                canMove = false;
            }).Run();
            return;
        }

        // by default, everyone alive can move
        Entities
        .ForEach((ref CanMove canMove, in Health hp) =>
        {
            canMove = hp.Value > 0;
        }).Run();

        Entities
        .WithNone <Health>()
        .ForEach((ref CanMove canMove) =>
        {
            canMove = true;
        }).Run();

        // frozen ennemies cannot move
        Entities
        .WithAll <Frozen>()
        .ForEach((ref CanMove canMove, ref PhysicsVelocity velocity) =>
        {
            canMove         = false;
            velocity.Linear = fix2.zero;
        }).Run();

        // If there is a player group, stop all entities that touch the trigger zone
        if (HasSingleton <PlayerGroupDataTag>())
        {
            Entity playerGroupEntity          = GetSingletonEntity <PlayerGroupDataTag>();
            fix2   playerGroupStopTriggerSize = GetComponent <PlayerGroupStopTriggerSize>(playerGroupEntity);
            fix2   playerGroupPosition        = GetComponent <FixTranslation>(playerGroupEntity);
            fix2   min = new fix2(playerGroupPosition.x + SimulationGameConstants.CharacterRadius + (fix)0.05, playerGroupPosition.y - playerGroupStopTriggerSize.y / 2);
            fix2   max = min + playerGroupStopTriggerSize;

            OverlapAabbInput overlapAabbInput = new OverlapAabbInput()
            {
                Aabb   = new Aabb((float2)min, (float2)max),
                Filter = SimulationGameConstants.Physics.CollideWithCharactersFilter.Data,
            };
            NativeList <int> touchedbodies = new NativeList <int>(Allocator.Temp);
            PhysicsWorld     physicsWorld  = _physicsWorldSystem.PhysicsWorld;
            if (physicsWorld.OverlapAabb(overlapAabbInput, touchedbodies))
            {
                SetComponent <CanMove>(playerGroupEntity, false);

                foreach (var bodyIndex in touchedbodies)
                {
                    var body = physicsWorld.AllBodies[bodyIndex];
                    if (HasComponent <CanMove>(body.Entity))
                    {
                        SetComponent <CanMove>(body.Entity, false);
                    }
                }
            }
        }
    }