Exemple #1
0
        /// <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]));
            }
        }