Beispiel #1
0
        /// <summary>
        /// Создает новую ноду описывающую конкретное действие из плана ИИ.
        /// </summary>
        private AntAIDebuggerNode CreatePlanNode(AntAIAction aAction, AntAICondition aConditions,
                                                 AntAICondition aPrevConditions, ref Vector2 aNodePosition)
        {
            AntAICondition condCopy = aConditions.Clone();

            condCopy.name = aAction.name;

            int    numLines;
            string desc = DescribePlanAction(condCopy, aPrevConditions, out numLines);

            GUIStyle style;

            if (_currentPlan.isSuccess)
            {
                style = (aAction.name.Equals(_agent.currentPlan[0])) ? _activePlanStyle : _planStyle;
            }
            else
            {
                style = (aAction.name.Equals(_agent.currentPlan[0])) ? _activeFailedPlanStyle : _failedPlanStyle;
            }

            var node = AddNode(desc, 220.0f, CalcHeight(numLines), style, style, ref aNodePosition, false);

            node.value = aAction.state;
            node.SetOutput(node.rect.width - 10.0f, node.rect.height * 0.5f);
            node.SetInput(10.0f, node.rect.height * 0.5f);

            if (_genericNodes.Count > 0)
            {
                _genericNodes[_genericNodes.Count - 1].LinkTo(node, new Color(0.3f, 0.7f, 0.4f));
            }

            _genericNodes.Add(node);
            return(node);
        }
Beispiel #2
0
        private void UpdatePlan(Vector2 aNodePosition, out float aMaxHeight)
        {
            for (int i = 0, n = _genericNodes.Count; i < n; i++)
            {
                _genericNodes[i].isActive = false;
            }

            aMaxHeight = 0.0f;
            int curIndex = 0;
            AntAIDebuggerNode node;

            if (_genericNodes.Count > 0)
            {
                node = _genericNodes[curIndex];
                UpdateWorldStateNode(_agent.planner.debugConditions, node);
                node.isActive    = true;
                node.rect.x      = aNodePosition.x;
                aNodePosition.x += node.rect.width;
            }
            else
            {
                node = CreateWorldStateNode(_agent.planner.debugConditions, ref aNodePosition);
            }

            curIndex++;
            AntAIAction    action;
            AntAICondition conditions = _agent.planner.debugConditions;
            AntAICondition prevConditions;

            for (int i = 0, n = _currentPlan.Count; i < n; i++)
            {
                action         = _agent.planner.GetAction(_currentPlan[i]);
                prevConditions = conditions.Clone();
                conditions.Act(action.post);
                if (curIndex < _genericNodes.Count)
                {
                    node = _genericNodes[curIndex];
                    UpdatePlanNode(action, conditions, prevConditions, node);
                    node.isActive    = true;
                    node.rect.x      = aNodePosition.x;
                    aNodePosition.x += node.rect.width;
                }
                else
                {
                    node = CreatePlanNode(action, conditions, prevConditions, ref aNodePosition);
                }

                aMaxHeight = (node.rect.height > aMaxHeight)
                                        ? node.rect.height
                                        : aMaxHeight;
                curIndex++;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Обновляет ноду описывающую конкретное действие из плана ИИ.
        /// </summary>
        private void UpdatePlanNode(AntAIAction aAction, AntAICondition aConditions,
                                    AntAICondition aPrevConditions, AntAIDebuggerNode aNode)
        {
            AntAICondition condCopy = aConditions.Clone();

            condCopy.name = aAction.name;
            aNode.value   = aAction.state;

            int numLines;

            aNode.title       = DescribePlanAction(condCopy, aPrevConditions, out numLines);
            aNode.rect.height = CalcHeight(numLines);

            if (_currentPlan.isSuccess)
            {
                aNode.defaultNodeStyle = (aAction.name.Equals(_agent.currentPlan[0])) ? _activePlanStyle : _planStyle;
            }
            else
            {
                aNode.defaultNodeStyle = (aAction.name.Equals(_agent.currentPlan[0])) ? _activeFailedPlanStyle : _failedPlanStyle;
            }
        }
        /// <summary>
        /// Builds the plan.
        /// </summary>
        /// <param name="aPlan">Reference to the result Plan.</param>
        /// <param name="aCurrent">Current World State.</param>
        /// <param name="aGoal">Goal World State that we want reach.</param>
        public void MakePlan(ref AntAIPlan aPlan, AntAICondition aCurrent, AntAICondition aGoal)
        {
#if UNITY_EDITOR
            DebugConditions = aCurrent.Clone();
#endif
            var opened = new List <AntAINode>();
            var closed = new List <AntAINode>();

            opened.Add(new AntAINode
            {
                world     = aCurrent,
                parent    = null,
                cost      = 0,
                heuristic = aCurrent.Heuristic(aGoal),
                sum       = aCurrent.Heuristic(aGoal),
                action    = string.Empty
            });

            AntAINode current = opened[0];
            while (opened.Count > 0)
            {
                // Find lowest rank.
                current = opened[0];
                for (int i = 1, n = opened.Count; i < n; i++)
                {
                    if (opened[i].sum < current.sum)
                    {
                        current = opened[i];
                    }
                }

                opened.Remove(current);

                if (current.world.Match(aGoal))
                {
                    // Plan is found!
                    ReconstructPlan(ref aPlan, closed, current);
                    aPlan.isSuccess = true;
                    if (EventPlanUpdated != null)
                    {
                        EventPlanUpdated(aPlan);
                    }

                    return;
                }

                closed.Add(current);

                // Get neighbors.
                List <AntAIAction> neighbors = GetPossibleTransitions(current.world);
                AntAICondition     neighbor;
                int openedIndex = -1;
                int closedIndex = -1;
                int cost        = -1;
                for (int i = 0, n = neighbors.Count; i < n; i++)
                {
                    cost = current.cost + neighbors[i].cost;

                    neighbor = current.world.Clone();
                    neighbor.Act(neighbors[i].post);

                    openedIndex = FindEqual(opened, neighbor);
                    closedIndex = FindEqual(closed, neighbor);

                    if (openedIndex > -1 && cost < opened[openedIndex].cost)
                    {
                        opened.RemoveAt(openedIndex);
                        openedIndex = -1;
                    }

                    if (closedIndex > -1 && cost < closed[closedIndex].cost)
                    {
                        closed.RemoveAt(closedIndex);
                        closedIndex = -1;
                    }

                    if (openedIndex == -1 && closedIndex == -1)
                    {
                        opened.Add(new AntAINode
                        {
                            world     = neighbor,
                            cost      = cost,
                            heuristic = neighbor.Heuristic(aGoal),
                            sum       = cost + neighbor.Heuristic(aGoal),
                            action    = neighbors[i].name,
                            parent    = current.world
                        });
                    }
                }
            }

            // Failed plan.
            ReconstructPlan(ref aPlan, closed, current);
            aPlan.isSuccess = false;

            if (EventPlanUpdated != null)
            {
                EventPlanUpdated(aPlan);
            }
        }