public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) { var targetOrders = new TargetingOrders { Discouraged = DiscouragedTargets, Preferred = PreferredTargets, TargetSameTeam = TargetSameTeam }; dstManager.AddComponentData(entity, targetOrders); }
/// <summary> /// Test a given entity to determine if it is the best target. /// Overwrites currentTarget if the tested entity is best. /// </summary> /// <param name="targetIndex">index of entity to test</param> /// <param name="score">the current score, to beat</param> /// <param name=""></param> /// <param name="currentTarget">the current target entity</param> public void CheckTarget( Team pickerTeam, Team targetTeam, float3 targetPos, float3 pickerPos, float aggroRadius, TargetingOrders orders, AgentCategory.eType targetType, ref float score, ref Entity currentTarget, Entity candidate) { // Cannot target if on the same team. if (pickerTeam.ID == targetTeam.ID) { return; } // Cannot target if outside aggro radius. var newScore = math.lengthsq(targetPos - pickerPos); if (newScore > aggroRadius * aggroRadius) { return; } // Favored and discouraged targets. if ((orders.Preferred & targetType) > 0) { newScore /= 5f; } if ((orders.Discouraged & targetType) > 0) { newScore *= 5f; } if (newScore < score) { score = newScore; currentTarget = candidate; } }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { var localToWorlds = chunk.GetNativeArray(PickerLocalToWorld); var aggroRadii = chunk.GetNativeArray(PickerAggroRadii); var teams = chunk.GetNativeArray(PickerTeams); var pickerTargets = chunk.GetNativeArray(PickerTargets); var pickerTeams = chunk.GetNativeArray(PickerTeams); // Targeting orders var hasPickerOrders = chunk.Has(PickerOrders); var pickerOrders = chunk.GetNativeArray(PickerOrders); var defaultPickerOrders = new TargetingOrders { Discouraged = AgentCategory.eType.None, Preferred = AgentCategory.eType.None }; for (int picker = 0; picker < chunk.Count; picker++) { // Ignore entities which already have a target. if (pickerTargets[picker].Value != Entity.Null) { continue; } // Initialise target loop variables. float score = float.PositiveInfinity; Entity currentTarget = Entity.Null; // Search all bins that cover the given aggro radius. float radius = aggroRadii[picker].Value; var pickerPosition = localToWorlds[picker].Position; float2 vec = new float2(pickerPosition.x, pickerPosition.z); var minBinCoords = BinCoordinates(vec - radius, CellSize); var maxBinCoords = BinCoordinates(vec + radius, CellSize); var orders = hasPickerOrders ? pickerOrders[picker] : defaultPickerOrders; for (int x = minBinCoords.x; x <= maxBinCoords.x; x++) { for (int y = minBinCoords.y; y <= maxBinCoords.y; y++) { // Identify bucket to search var hash = Hash(new int2(x, y)); // Check targets within each bucket. if (!TargetMap.TryGetFirstValue(hash, out int targetIndex, out NativeMultiHashMapIterator <int> iterator)) { continue; } CheckTarget( pickerTeams[picker], TargetTeams[targetIndex], TargetPositions[targetIndex].Position, pickerPosition, aggroRadii[picker].Value, orders, TargetTypes[targetIndex], ref score, ref currentTarget, Targets[targetIndex] ); while (TargetMap.TryGetNextValue(out targetIndex, ref iterator)) { CheckTarget( pickerTeams[picker], TargetTeams[targetIndex], TargetPositions[targetIndex].Position, pickerPosition, aggroRadii[picker].Value, orders, TargetTypes[targetIndex], ref score, ref currentTarget, Targets[targetIndex] ); } } } // If a target was found, write it. if (currentTarget != Entity.Null) { pickerTargets[picker] = new Target { Value = currentTarget } } ; } }