Пример #1
0
    protected override void OnUpdate()
    {
        var physicsWorld     = _physicsWorldSystem.PhysicsWorld;
        var physicsBodiesMap = _physicsWorldSystem.EntityToPhysicsBody;
        var hits             = new NativeList <DistanceHit>(Allocator.TempJob);
        var outActions       = _gameActionSystem.CreateRequestBuffer();
        var teams            = GetComponentDataFromEntity <Team>(isReadOnly: true);
        var firstInstigators = GetComponentDataFromEntity <FirstInstigator>(isReadOnly: true);
        var tileColliderTags = GetComponentDataFromEntity <TileColliderTag>(isReadOnly: true);
        var mutedActions     = GetSingletonBuffer <MutedContactActionElement>();

        Entities
        .WithReadOnly(physicsWorld)
        .WithReadOnly(physicsBodiesMap)
        .WithReadOnly(teams)
        .WithReadOnly(firstInstigators)
        .WithReadOnly(tileColliderTags)
        .ForEach((Entity entity, DynamicBuffer <ActionOnOverlap> actionsOnOverlap, in FixTranslation position) =>
        {
            bool ignoreLocalEntity      = physicsBodiesMap.Lookup.TryGetValue(entity, out int physicsBody);
            ActorFilterInfo entityAInfo = Helpers.GetActorFilterInfo(entity, teams, firstInstigators, tileColliderTags);

            for (int i = 0; i < actionsOnOverlap.Length; i++)
            {
                var actionOnContact = actionsOnOverlap[i];

                PointDistanceInput pointDistance = new PointDistanceInput()
                {
                    Filter      = CollisionFilter.ThatCollidesWith(actionOnContact.OverlapFilter),
                    MaxDistance = (float)actionOnContact.OverlapRadius,
                    Position    = (float2)position.Value
                };

                if (ignoreLocalEntity)
                {
                    pointDistance.Ignore = new IgnoreHit(physicsBody);
                }

                if (physicsWorld.CalculateDistance(pointDistance, ref hits))
                {
                    foreach (var hit in hits)
                    {
                        if (mutedActions.IsMuted(entity, hit.Entity, actionOnContact.Data.Id))
                        {
                            continue;
                        }

                        ActorFilterInfo entityBInfo = Helpers.GetActorFilterInfo(hit.Entity, teams, firstInstigators, tileColliderTags);

                        if (Helpers.ActorFilterMatches(entityAInfo, entityBInfo, actionOnContact.Data.ActionFilter))
                        {
                            outActions.Add(new GameActionRequest()
                            {
                                Instigator   = entity,
                                Target       = hit.Entity,
                                ActionEntity = actionOnContact.Data.ActionEntity,
                            });

                            if (actionOnContact.Data.SameTargetCooldown > 0)
                            {
                                mutedActions.Add(new MutedContactActionElement()
                                {
                                    Instigator            = entity,
                                    ContactActionBufferId = actionOnContact.Data.Id,
                                    ExpirationTime        = actionOnContact.Data.SameTargetCooldown,
                                    Target = hit.Entity
                                });
                            }
                        }
                    }

                    hits.Clear();
                }
            }
        }).WithDisposeOnCompletion(hits)
        .Schedule();

        _gameActionSystem.HandlesToWaitFor.Add(Dependency);
    }