public static ActorFilterInfo GetActorFilterInfo( Entity entity, ComponentDataFromEntity <Team> Teams, ComponentDataFromEntity <FirstInstigator> FirstInstigators, ComponentDataFromEntity <TileColliderTag> TileColliderTags) { ActorFilterInfo result = new ActorFilterInfo() { Team = Team.None, IsTerrain = false, }; // try to get the team if (Teams.TryGetComponent(entity, out Team team)) { result.Team = team; } else if (FirstInstigators.TryGetComponent(entity, out FirstInstigator firstInstigator)) { if (Teams.TryGetComponent(firstInstigator, out Team firstInstigatorTeam)) { result.Team = firstInstigatorTeam; } } result.IsTerrain = TileColliderTags.HasComponent(entity); return(result); }
public static ActorFilterInfo GetActorFilterInfo(ISimGameWorldReadAccessor accessor, Entity entity) { ActorFilterInfo result = new ActorFilterInfo() { Team = Team.None, IsTerrain = false, }; // try to get the team if (accessor.TryGetComponent(entity, out Team team)) { result.Team = team; } else if (accessor.TryGetComponent(entity, out FirstInstigator firstInstigator)) { if (accessor.TryGetComponent(firstInstigator, out Team firstInstigatorTeam)) { result.Team = firstInstigatorTeam; } } result.IsTerrain = accessor.HasComponent <TileColliderTag>(entity); return(result); }
private void ProcessEntityPair(Entity entityA, Entity entityB) { if (ActionOnContacts.HasComponent(entityA)) { DynamicBuffer <ActionOnColliderContact> actions = ActionOnContacts[entityA]; ActorFilterInfo entityAInfo = Helpers.GetActorFilterInfo(entityA, Teams, FirstInstigators, TileColliderTags); ActorFilterInfo entityBInfo = Helpers.GetActorFilterInfo(entityB, Teams, FirstInstigators, TileColliderTags); for (int i = 0; i < actions.Length; i++) { ActionOnColliderContact actionOnContact = actions[i]; if (MutedActions.IsMuted(entityA, entityB, actionOnContact.Data.Id)) { continue; } if (Helpers.ActorFilterMatches(entityAInfo, entityBInfo, actionOnContact.Data.ActionFilter)) { OutActions.Add(new GameActionRequest() { Instigator = entityA, Target = entityB, ActionEntity = actionOnContact.Data.ActionEntity, }); if (actionOnContact.Data.SameTargetCooldown > 0) { MutedActions.Add(new MutedContactActionElement() { Instigator = entityA, ContactActionBufferId = actionOnContact.Data.Id, ExpirationTime = actionOnContact.Data.SameTargetCooldown, Target = entityB }); } } } } }
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); }
public static bool ActorFilterMatches(ActorFilterInfo actorA, ActorFilterInfo actorB, ActorFilter filter) { return(((filter & ActorFilter.Allies) != 0 && actorA.Team == actorB.Team) || ((filter & ActorFilter.Enemies) != 0 && actorA.Team != actorB.Team) || ((filter & ActorFilter.Terrain) != 0 && actorB.IsTerrain)); }