Exemplo n.º 1
0
        /// <summary>
        /// Checks if this tile contains an agent that obstructs the given agent.
        /// </summary>
        /// <param name="inAgent">Agent to check obstruction for.</param>
        /// <param name="outObstructingAgent">Found agent that is obstructing.</param>
        /// <returns>Whether or not an obstruction was found.</returns>
        public bool IsObstructed(NavTileAgent inAgent, out NavTileAgent outObstructingAgent)
        {
            NavTileAgentManager manager = NavTileManager.Instance.AgentManager;

            outObstructingAgent = null;

            foreach (NavTileAgent agent in OccupyingAgents)
            {
                if (manager.GetValue(inAgent.AgentType, agent.AgentType))
                {
                    outObstructingAgent = agent;
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Recursive function to check agents which this agent is waiting on.
        ///
        /// There are a few situations where the agent should abort waiting.
        ///
        /// 1. When this agent is waiting on an agent which is ultimately waiting for this agent.
        /// 2. When this agent is waiting for an agent which is involved in a circular conflict either itself, or some subsequent agent.
        /// 3. When this agent is waiting for a waiting agent which is ultimately waiting for a stationary agent.
        /// 4. When this agent is waiting for an agent who might be waiting, but its conflict handling setting is lower and therefor will never move again.
        ///
        /// Some of these options can be solved just by letting others solve their conflicts first.
        /// </summary>
        /// <param name="inNextNode">The next node this agent might traverse to.</param>
        /// <param name="inObstructingAgent">The obstructing agent encountered.</param>
        /// <param name="inCheckedAgents">All Checked agents including the obstructed agent.</param>
        private EConflictStatus CheckWaitingOccuypingAgents(PathNode inNextNode, NavTileAgent inObstructingAgent, List <NavTileAgent> inCheckedAgents, ref EAbortReason refAbortReason)
        {
            // Get all agents occupying the tile which the obstructing agent is waiting for, sorted per MovementStatus.
            Dictionary <EMovementStatus, List <NavTileAgent> > sortedAgents = inObstructingAgent.WaitingForTile.GetSortedOccupyingAgents(inObstructingAgent);

            List <NavTileAgent> agents;

            // Check if there are any stationary agents. If so, abort this path.
            if (sortedAgents.TryGetValue(EMovementStatus.Stationary, out agents))
            {
                refAbortReason = EAbortReason.EncounteredStationaryAgent;
                return(EConflictStatus.Abort);
            }
            else if (sortedAgents.TryGetValue(EMovementStatus.Waiting, out agents)) // Check if there are any waiting agents.
            {
                foreach (NavTileAgent agent in agents)
                {
                    // Is the agent found this agent or has it already been checked? Abort path
                    if (agent == this || inCheckedAgents.Contains(agent))
                    {
                        refAbortReason = EAbortReason.EncounteredCircularConflict;
                        return(EConflictStatus.Abort);
                    }

                    // Add the agent to the list
                    inCheckedAgents.Add(agent);

                    // Do this again.
                    return(CheckWaitingOccuypingAgents(inNextNode, agent, inCheckedAgents, ref refAbortReason));
                }
            }
            else // No entries of waiting or stationary agents.
            {
                // Set the timer to be used later and specify which tile this agent is waiting for.
                _didEncounterObstruction = true;
                _obstructionTimer        = _waitAfterFreeTile;

                _waitingForTile = NavTileManager.Instance.SurfaceManager.Data.GetTileData(inNextNode.TilePosition);
            }

            return(EConflictStatus.Processing);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Gets all occupying and obstructing agents ordered per status in a dictionary.
        /// </summary>
        /// <param name="inAgent">Agent to check obstruction for.</param>
        /// <returns>Dictionary containing all obstructing agents order per status.</returns>
        public Dictionary <NavTileAgent.EMovementStatus, List <NavTileAgent> > GetSortedOccupyingAgents(NavTileAgent inAgent)
        {
            Dictionary <NavTileAgent.EMovementStatus, List <NavTileAgent> > dic = new Dictionary <NavTileAgent.EMovementStatus, List <NavTileAgent> >();
            NavTileAgentManager manager = NavTileManager.Instance.AgentManager;

            foreach (NavTileAgent agent in OccupyingAgents)
            {
                if (manager.GetValue(inAgent.AgentType, agent.AgentType))
                {
                    List <NavTileAgent> agents;
                    if (dic.TryGetValue(agent.MovementStatus, out agents))
                    {
                        agents.Add(agent);
                    }
                    else
                    {
                        agents = new List <NavTileAgent>()
                        {
                            agent
                        };

                        dic.Add(agent.MovementStatus, agents);
                    }
                }
            }

            return(dic);
        }
Exemplo n.º 4
0
        private void Awake()
        {
            _agent = GetComponent <NavTileAgent>();

            _agent.AutoTraversePath = true;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Checks whether the perpendicular tiles of a diagonal movement are obstructed.
        ///
        /// E.g. in the case of AB tiles, where an agent traverses over tiles A, positions B1 and B2 get checked for an obstructing agent.
        ///                     BA
        /// </summary>
        private bool IsPerpendicularObstructed(Vector2Int inCurrentTilePosition, Vector2Int inNextNodeTilePosition, out NavTileAgent outObstructingAgent)
        {
            outObstructingAgent = null;

            Vector2Int horizontalPosition = new Vector2Int(inCurrentTilePosition.x, inNextNodeTilePosition.y);
            Vector2Int verticalPosition   = new Vector2Int(inNextNodeTilePosition.x, inCurrentTilePosition.y);

            TileData horizontalTileData = NavTileManager.Instance.SurfaceManager.Data.GetTileData(horizontalPosition);
            TileData verticalTileData   = NavTileManager.Instance.SurfaceManager.Data.GetTileData(verticalPosition);

            NavTileAgent obstructingAgent;

            // Check whether there is an agent which is walking across the two relevant tiles.
            if (horizontalTileData.IsObstructed(this, out obstructingAgent) && obstructingAgent.GetPreviousPositionInPath() == verticalPosition ||
                verticalTileData.IsObstructed(this, out obstructingAgent) && obstructingAgent.GetPreviousPositionInPath() == horizontalPosition)
            {
                outObstructingAgent = obstructingAgent;

                return(true);
            }

            return(false);
        }
Exemplo n.º 6
0
        private void OnEnable()
        {
            // Fields.
            _autoTraversePathProperty  = serializedObject.FindProperty("AutoTraversePath");
            _areaMaskProperty          = serializedObject.FindProperty("_areaMask");
            _agentTypeProperty         = serializedObject.FindProperty("_agentType");
            _speedProperty             = serializedObject.FindProperty("_speed");
            _diagonalAllowedProperty   = serializedObject.FindProperty("_diagonalAllowed");
            _cutCornersProperty        = serializedObject.FindProperty("_cutCorners");
            _ignoreTileCostProperty    = serializedObject.FindProperty("_ignoreTileCost");
            _conflictOptionProperty    = serializedObject.FindProperty("_conflictOption");
            _waitAfterFreeTileProperty = serializedObject.FindProperty("_waitAfterFreeTile");
            _debugEnabledProperty      = serializedObject.FindProperty("_debugEnabled");
            _debugLineColorProperty    = serializedObject.FindProperty("_debugLineColor");

            // Animation settings.
            _animatorProperty = serializedObject.FindProperty("LinkedAnimator");
            _preserveAnimDirectionProperty = serializedObject.FindProperty("_preserveAnimDirection");
            _horizontalAnimParamProperty   = serializedObject.FindProperty("_animationHorizontalParameter");
            _verticalAnimParamProperty     = serializedObject.FindProperty("_animationVerticalParameter");
            _speedAnimParamProperty        = serializedObject.FindProperty("_animationSpeedParameter");

            // Area settings.
            _onAreaChangeUnityEvent   = serializedObject.FindProperty("OnAreaChangeUnityEvent");
            _areaSettingsListProperty = serializedObject.FindProperty("_areaSettingsList");

            // Path callbacks.
            _onPathFoundUnityEventProperty    = serializedObject.FindProperty("OnPathFoundUnityEvent");
            _onPathNotFoundUnityEventProperty = serializedObject.FindProperty("OnPathNotFoundUnityEvent");
            _onPathAbortedUnityEventProperty  = serializedObject.FindProperty("OnPathAbortedUnityEvent");
            _onPathFinishedUnityEventProperty = serializedObject.FindProperty("OnPathFinishedUnityEvent");

            _areaAnimationsReorderableList = new ReorderableList(serializedObject, _areaSettingsListProperty, false, false, false, false)
            {
                drawHeaderCallback  = DrawAreaAnimationsListHeader,
                drawElementCallback = DrawAreaAnimationsListElement,
                elementHeight       = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing,
                footerHeight        = 0
            };

            _areaSpeedsReorderableList = new ReorderableList(serializedObject, _areaSettingsListProperty, false, false, false, false)
            {
                drawHeaderCallback  = DrawAreaSpeedsListHeader,
                drawElementCallback = DrawAreaSpeedsListElement,
                elementHeight       = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing,
                footerHeight        = 0
            };

            // Default animator to self if possible.
            for (int i = 0; i < targets.Length; i++)
            {
                NavTileAgent anAgent = (NavTileAgent)targets[i];

                if (anAgent.LinkedAnimator == null)
                {
                    anAgent.LinkedAnimator = anAgent.GetComponent <Animator>();
                }
            }

            UpdateAreaSettingsList();
            LoadEditorPrefs();
        }