Inheritance: MonoBehaviour
Exemple #1
0
        /// <summary>
        /// Toggles the selected state of a unit. Actually it only toggles when <paramref name="append"/> is true, otherwise it will select the unit while deselecting all others.
        /// </summary>
        /// <param name="unit">The unit.</param>
        /// <param name="append">if set to <c>true</c> [append].</param>
        public void ToggleSelected(IUnitFacade unit, bool append)
        {
            //So this works differently depending on the append modifier. If append then the unit is toggled, if not the unit is not toggled but always selected while all others aren't.
            if (!append || _selected == _emptyGroup)
            {
                DeselectAll();

                unit.isSelected = true;
                _selected       = GroupingManager.CreateGrouping(unit);
                return;
            }

            unit.isSelected = !unit.isSelected;

            if (unit.isSelected)
            {
                _selected.Add(unit);
            }
            else
            {
                _selected.Remove(unit);
            }

            PostUnitsSelectedMessage(_selected);
        }
        /// <summary>
        /// Initializes the services.
        /// </summary>
        protected virtual void InitializeServices()
        {
            var messageBusFactory = this.As <IMessageBusFactory>();

            if (messageBusFactory == null)
            {
                GameServices.messageBus = new BasicMessageBus();
            }
            else
            {
                GameServices.messageBus = messageBusFactory.CreateMessageBus();
            }

            //The game state manager relies on the message bus so it must be initialized after that
            GameServices.gameStateManager = new GameStateManager(this.As <IUnitFacadeFactory>());

            //Get the grouping strategy for units registered
            var stratFactory = this.As <IUnitGroupingStrategyFactory>();

            if (stratFactory != null)
            {
                GroupingManager.RegisterGroupingStrategy(stratFactory.CreateStrategy());
            }
            else
            {
                GroupingManager.RegisterGroupingStrategy(new DefaultUnitGroupingStrategy());
            }
        }
Exemple #3
0
        private void SpawnGrouping()
        {
            var units = InstantiateUnits(3, 3);

            var grouping = GroupingManager.CreateGrouping(units);

            grouping.MoveTo(target.position, false);
        }
Exemple #4
0
        private void SpawnGroupTwo()
        {
            var orangeUnits = InstantiateUnits(3, 0);
            var greenUnits  = InstantiateUnits(0, 3);

            //You can also create groups from already existing lists
            var grpOrange = GroupingManager.CreateGroup(orangeUnits);
            var grpGreen  = GroupingManager.CreateGroup(greenUnits);

            grpOrange.MoveTo(target.position, false);
            grpGreen.MoveTo(target.position, false);
        }
Exemple #5
0
        private void _coreCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
            case System.Collections.Specialized.NotifyCollectionChangedAction.Add:

                if (CollectionGroups?.Count > 0)
                {
                    foreach (var item in CollectionGroups.OfType <SelfServiceDependencyCollectionViewGroupBase>())
                    {
                        e.NewItems?.OfType <object>().ToList().Select(x => item?.TryAddItemToGroup(x)).ToArray();
                    }
                    e.NewItems?.OfType <object>().ToList().Select(x => GroupingManager?.TryAddItemToGroup(x)).ToArray();
                }
                RefreshPositionValues();
                break;

            case System.Collections.Specialized.NotifyCollectionChangedAction.Move:
                break;

            case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
                if (CollectionGroups?.Count > 0)
                {
                    foreach (var item in CollectionGroups.OfType <SelfServiceDependencyCollectionViewGroupBase>())
                    {
                        e.OldItems?.OfType <object>().ToList().Select(x => item?.TryRemoveItemFromGroup(x)).Any();
                    }
                    e.NewItems?.OfType <object>().ToList().Select(x => GroupingManager?.TryRemoveItemFromGroup(x)).ToArray();
                }
                RefreshPositionValues();
                break;

            case System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
                break;

            case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
                if (CollectionGroups?.Count > 0)
                {
                    foreach (ICollectionViewGroup item in CollectionGroups)
                    {
                        item.GroupItems?.Clear();
                    }
                }
                RefreshPositionValues();
                break;

            default:
                break;
            }
        }
        private void Start()
        {
            //Get the waypoint transforms
            var waypoints = this.GetComponentsInChildren <Transform>().Skip(1).ToArray();

            //Create the orange group. In this example we just create an empty grouping and add members to it
            var grpOrange = GroupingManager.CreateGrouping <IUnitFacade>();

            for (int i = 0; i < 20; i++)
            {
                var agent = Spawn(this.orangeMold, waypoints[0].position);
                grpOrange.Add(agent);
            }

            IFormation formation = new FormationGrid(1.5f);

            grpOrange.SetFormation(formation);

            for (int i = 1; i < 10; i++)
            {
                grpOrange.MoveTo(waypoints[i % waypoints.Length].position, true);
            }

            //Create the green group.
            var grpGreen = GroupingManager.CreateGroup <IUnitFacade>(9);

            for (int i = 0; i < 9; i++)
            {
                var agent = Spawn(this.greenMold, waypoints[3].position);
                grpGreen.Add(agent);
            }

            formation = new FormationEllipsoid(1.5f);
            grpGreen.SetFormation(formation);

            for (int i = 2; i > -10; i--)
            {
                var idx = Math.Abs((i + waypoints.Length) % waypoints.Length);
                grpGreen.MoveTo(waypoints[idx].position, true);
            }

            //Spawn a solo unit
            var solo = Spawn(this.blueMold, waypoints[4].position);

            for (int i = 0; i < 17; i++)
            {
                solo.MoveTo(waypoints[i % waypoints.Length].position, true);
            }
        }
Exemple #7
0
        private void SpawnGroupOne()
        {
            //Here we simply create a groups manually, which will be the most common for AI units
            var grpOrange = GroupingManager.CreateGroup <IUnitFacade>(3);
            var grpGreen  = GroupingManager.CreateGroup <IUnitFacade>(3);

            for (int i = 0; i < 3; i++)
            {
                var go = Instantiate(this.orangeMold, Vector3.zero, Quaternion.identity) as GameObject;
                grpOrange.Add(go.GetUnitFacade());

                go = Instantiate(this.greenMold, Vector3.zero, Quaternion.identity) as GameObject;
                grpGreen.Add(go.GetUnitFacade());
            }

            grpOrange.MoveTo(target.position, false);
            grpGreen.MoveTo(target.position, false);
        }
Exemple #8
0
        /// <summary>
        /// Selects the specified units.
        /// </summary>
        /// <param name="append">if set to <c>true</c> the selection will append to the current selection.</param>
        /// <param name="units">The units.</param>
        public void Select(bool append, IEnumerable <IUnitFacade> units)
        {
            IEnumerable <IUnitFacade> newSelections;

            if (_selected.memberCount < 2)
            {
                //This is either w e have an empty group or we have just one in a group. In that case recreate all,
                //since single unit groups are typically of another type.
                newSelections = units;
                _selected     = GroupingManager.CreateGrouping(units);
            }
            else if (append)
            {
                newSelections = units.Except(_selected.All()).ToArray();
                _selected.Add(newSelections);
            }
            else
            {
                //If we select all the same units as before and maybe some more, we just add those additional ones
                //If the selection does not include all from before, we create a new grouping
                var deselected = _selected.All().Except(units);
                if (deselected.Any())
                {
                    DeselectAll();
                    newSelections = units;
                    _selected     = GroupingManager.CreateGrouping(units);
                }
                else
                {
                    newSelections = units.Except(_selected.All()).ToArray();
                    _selected.Add(newSelections);
                }
            }

            newSelections.Apply(u => u.isSelected = true);

            PostUnitsSelectedMessage(_selected);
        }
        /// <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);
                            }
                        }
                    }
                }
            });
        }