/// <summary> /// calculate target and update the boid info; /// </summary> /// <param name="sight"></param> /// <param name="targetState"></param> /// <param name="pos"></param> /// <returns></returns> Vector3?calc_update_boid(ref BaseUnitSight.Component sight, TargetState targetState, Vector3 pos) { Vector3?tgt = null; var boidVector = sight.BoidVector; if (boidVector.Potential > 0.0f) { var center = boidVector.Center.ToWorkerPosition(this.Origin); if ((center - pos).sqrMagnitude > boidVector.SqrtBoidRadius()) { tgt = center; } else if (targetState == TargetState.OutOfRange) { tgt = pos + boidVector.GetVector3(sight.TargetRange); } } var current = Time.ElapsedTime; var diffTime = (float)(current - sight.BoidUpdateTime); boidVector.Potential = AttackLogicDictionary.ReduceBoidPotential(boidVector.Potential, diffTime); sight.BoidUpdateTime = current; sight.BoidVector = boidVector; return(tgt); }
protected override void OnUpdate() { if (CheckTime(ref inter) == false) { return; } Entities.With(group).ForEach((Entity entity, ref BoidComponent.Component boid, ref BaseUnitStatus.Component status, ref BaseUnitTarget.Component target, ref CommanderStatus.Component commander, ref BaseUnitMovement.Component movement, ref SpatialEntityId entityId) => { if (status.State != UnitState.Alive) { return; } var trans = EntityManager.GetComponentObject <Transform>(entity); var pos = trans.position; var side = status.Side; var speed = movement.MoveSpeed; var forward = trans.forward; var commanderRank = status.Rank; var soldierRange = RangeDictionary.BaseBoidsRange; var soldiers = getAllyUnits(side, pos, soldierRange, allowDead: false, selfId: entityId.EntityId, GetSingleUnitTypes(UnitType.Soldier)); float f_length = boid.ForwardLength; boid_calculate(pos + forward * f_length, pos, soldierRange, forward * speed, boid.SepareteWeight, boid.AlignmentWeight, boid.CohesionWeight, soldiers); if (commanderRank < 1) { return; } var commanderRange = RangeDictionary.GetBoidsRange(commanderRank); var coms = getAllyUnits(side, pos, commanderRange, allowDead: false, selfId: entityId.EntityId, GetSingleUnitTypes(UnitType.Commander)); commanders.Clear(); foreach (var c in coms) { if (c.rank == commanderRank - 1) { commanders.Add(c); } } f_length = AttackLogicDictionary.RankScaled(f_length, commanderRank); f_length += commander.AllyRange; boid_calculate(pos + forward * f_length, pos, commanderRange, forward * speed, boid.SepareteWeight, boid.AlignmentWeight, boid.CohesionWeight, commanders); }); }
public override void Initialize() { Instance = this; foreach (var o in orderRates) { orderDic[o.order] = o; } }
private void Query(Entity entity, ref BaseUnitSight.Component sight, ref UnitActionData action, ref BaseUnitStatus.Component status, ref BaseUnitTarget.Component target, ref SpatialEntityId entityId) { if (status.State != UnitState.Alive) { return; } if (status.Order == OrderType.Idle) { return; } if (UnitUtils.IsWatcher(status.Type) == false) { return; } // initial target.State = TargetState.None; var id = entityId.EntityId.Id; if (enemyPositionsContainer.ContainsKey(id) == false) { enemyPositionsContainer[id] = new List <FixedPointVector3>(); } var enemyPositions = enemyPositionsContainer[id]; enemyPositions.Clear(); var trans = EntityManager.GetComponentObject <Transform>(entity); var pos = trans.position; UnitInfo enemy = null; var sightRange = action.SightRange; var backBuffer = sightRange / 2; if (status.Type == UnitType.Commander) { backBuffer += RangeDictionary.AllyRange / 2; } // strategy target SetStrategyTarget(pos, backBuffer, ref sight, ref target); // keep logic if (status.Order == OrderType.Keep) { sightRange *= target.PowerRate; } enemy = getNearestEnemy(status.Side, pos, sightRange); if (enemy != null) { var tgtPos = sight.TargetPosition.ToWorkerPosition(this.Origin); var epos = enemy.pos.ToWorldPosition(this.Origin); if (Vector3.Dot(tgtPos - pos, enemy.pos - pos) > 0) { target.State = TargetState.ActionTarget; sight.TargetPosition = epos; sight.TargetSize = enemy.size; } enemyPositions.Add(epos); } float range; switch (target.State) { case TargetState.ActionTarget: range = action.AttackRange; range = AttackLogicDictionary.GetOrderRange(status.Order, range) * target.PowerRate; break; default: range = RangeDictionary.BodySize; break; } // set behind if (status.Type == UnitType.Commander) { var addRange = RangeDictionary.AllyRange / 2; range += AttackLogicDictionary.RankScaled(addRange, status.Rank); } sight.TargetRange = range; sight.State = target.State; }
private void boid_calculate(Vector3 center, Vector3 pos, float range, Vector3 centerMove, float separeteWeight, float alignmentWeight, float cohesionWeight, List <UnitInfo> allies) { var rate = range / RangeDictionary.BaseBoidsRange; var alignmentVector = centerMove.normalized; var centerMoveSpeed = centerMove.magnitude; floatInfoDic.Clear(); float totalLength = 1.0f; foreach (var unit in allies) { if (TryGetComponentObject <Transform>(unit.id, out var t) == false) { continue; } if (TryGetComponent <BaseUnitMovement.Component>(unit.id, out var move) == false) { continue; } var length = Mathf.Max((pos - unit.pos).magnitude, 1.0f); floatInfoDic[unit.id] = new ValueTuple <float, float>(move.Value.MoveSpeed, length); // scaled balance alignmentVector += t.forward * 1.0f / length; totalLength += 1.0f / length; } alignmentVector /= totalLength; foreach (var unit in allies) { if (TryGetComponent <BaseUnitSight.Component>(unit.id, out var sight) == false) { continue; } if (floatInfoDic.TryGetValue(unit.id, out var info) == false) { continue; } var selfSpeed = info.Item1; var length = info.Item2; var boidVector = sight.Value.BoidVector; var baseVec = boidVector.Vector.ToUnityVector(); var boidVec = Vector3.zero; var inter = RangeDictionary.UnitInter; var potential = AttackLogicDictionary.BoidPotential(1, length, range); if (potential <= boidVector.Potential) { continue; } var scaledLength = length / rate; var syncSpeed = (centerMoveSpeed * 1.0f + selfSpeed * scaledLength) / (scaledLength + 1.0f); foreach (var other in allies) { if (other.id == unit.id) { continue; } var sep = (unit.pos - other.pos) / rate; boidVec += sep; } // length scaled weight separeteWeight *= 1.0f / scaledLength; cohesionWeight *= scaledLength / 1.0f; boidVec = (boidVec / allies.Count) * separeteWeight; boidVec += alignmentVector * alignmentWeight; boidVec += ((center - unit.pos) / rate) * cohesionWeight; boidVec = boidVec.normalized * syncSpeed * 10.0f; var diffVec = boidVec - baseVec; var diffCenter = center - sight.Value.BoidVector.Center.ToUnityVector(); if (diffVec.sqrMagnitude < diffMinVec && diffCenter.sqrMagnitude < diffMinPos) { continue; } boidVector = new BoidVector(boidVec.ToFixedPointVector3(), center.ToWorldPosition(this.Origin), range, potential); this.UpdateSystem.SendEvent(new BaseUnitSight.BoidDiffed.Event(boidVector), unit.id); } }