/// <summary> /// Transfers the formation from an old group to a new one (used only in Portalling). /// </summary> /// <param name="formation">The formation to transfer.</param> /// <param name="expectedCount">The expected group member count.</param> /// <param name="oldGroup">The old group to transfer from.</param> public void TransferFormation(IFormation formation, int expectedCount, DefaultSteeringTransientUnitGroup oldGroup) { if (this.count == 0 || expectedCount == 0 || formation == null || oldGroup == null) { return; } if (_formationPositions == null) { // if the formation positions list is null, then make it now _formationPositions = new DynamicArray <Vector3>(expectedCount); } else { // if the formation positions list is not null, just clear it _formationPositions.Clear(); } // set formation reference _currentFormation = formation; // populate formation positions list with formation positions for (int i = 0; i < expectedCount; i++) { _formationPositions.Add(formation.GetFormationPosition(expectedCount, i, oldGroup[i])); } }
/// <summary> /// Handles portalling. /// </summary> /// <param name="unitData">This unit's UnitFacade.</param> /// <param name="group">This unit's current/old group.</param> /// <param name="vectorField">The vector field.</param> /// <param name="pathPortalIndex">Index of the portal in the current path.</param> /// <param name="grid">The grid.</param> private void HandlePortal(IUnitFacade unitData, DefaultSteeringTransientUnitGroup group, IVectorField vectorField, int pathPortalIndex, IGrid grid) { var portal = _currentPath[pathPortalIndex] as IPortalNode; if (portal == null) { // if the path node that was reported as a portal turns out not to be - return return; } if (object.ReferenceEquals(unitData, group.modelUnit)) { // don't ever let model unit jump portal return; } int groupCount = group.count; var to = _currentPath[pathPortalIndex + 1]; // we consider a portal a "far portal" when the distance between it and its partner is more than the diagonal cell size // 'far portal' means that it is NOT considered a grid stitching connector portal // Requires that grid stitching portals are always placed adjacent to each other float portalNewGroupThreshold = (grid.cellSize * Consts.SquareRootTwo) + 0.1f; bool isFarPortal = (portal.position - portal.partner.position).sqrMagnitude > (portalNewGroupThreshold * portalNewGroupThreshold); if (isFarPortal) { // if it is a far portal, we need to make or use the next group if (group.nextGroup == null) { // new group does not exist yet, so create it and tell the old group about it var groupStrat = GroupingManager.GetGroupingStrategy<IUnitFacade>(); if (groupStrat == null) { Debug.Log("No Grouping Strategy has been registered for IUnitFacade"); return; } var newGroup = groupStrat.CreateGroup(groupCount) as DefaultSteeringTransientUnitGroup; if (newGroup == null) { return; } group.nextGroup = newGroup; _nextGroup = newGroup; } else { // new group exists, so just use it _nextGroup = group.nextGroup; } // make sure to remove the unit from the old group group.Remove(unitData); } _isPortalling = true; // actually execute the portal portal.Execute( unitData.transform, to, () => { _isPortalling = false; if (isFarPortal) { // if it is a far portal, we are supposed to join up with the new group _nextGroup.Add(unitData); unitData.transientGroup = _nextGroup; if (_nextGroup.count == 1) { // let the first unit in the new group be responsible for setting the new group up if (vectorField.destination != null) { // the new group's path starts on the other side of the portal... int pathCount = _currentPath.count; var newPath = new Path(pathCount - (pathPortalIndex + 2)); for (int i = pathCount - 1; i >= pathPortalIndex + 2; i--) { newPath.Push(_currentPath[i]); } // the first member that joins the new group tells the new group to move along the path of the old group Vector3 destination = vectorField.destination.position; if ((to.position - destination).sqrMagnitude > 1f) { // check though that the destination is not the same as the starting position _nextGroup.MoveAlong(newPath); } // pass along old group's waypoints to new group if (group.currentWaypoints.count > 0) { _nextGroup.SetWaypoints(group.currentWaypoints); } // pass along old group's formation to the new group if (group.currentFormation != null) { _nextGroup.TransferFormation(group.currentFormation, groupCount, group); } } } } }); }
/// <summary> /// Transfers the formation from an old group to a new one (used only in Portalling). /// </summary> /// <param name="formation">The formation to transfer.</param> /// <param name="expectedCount">The expected group member count.</param> /// <param name="oldGroup">The old group to transfer from.</param> public void TransferFormation(IFormation formation, int expectedCount, DefaultSteeringTransientUnitGroup oldGroup) { if (this.count == 0 || expectedCount == 0 || formation == null || oldGroup == null) { return; } if (_formationPositions == null) { // if the formation positions list is null, then make it now _formationPositions = new DynamicArray<Vector3>(expectedCount); } else { // if the formation positions list is not null, just clear it _formationPositions.Clear(); } // set formation reference _currentFormation = formation; // populate formation positions list with formation positions for (int i = 0; i < expectedCount; i++) { _formationPositions.Add(formation.GetFormationPosition(expectedCount, i, oldGroup[i])); } }