public virtual void CopyValues(Action_GS copy)
 {
     _agent = copy._agent;
     _name  = copy._name;
     _cost  = copy._cost;
     _state = copy._state;
 }
Exemple #2
0
 //Constructors ================
 public BehaviourSelectMenu_GS(Agent_GS new_target_agent)
 {
     //Set the target agent
     _target_agent = new_target_agent;
     //Get dropdown slot for behaviour select
     _behaviour_dropdown_slot = ProTools.GetDropdownSlot();
 }
Exemple #3
0
        static void ClearAgentPlanning()
        {
            //Clear agent planning
            Agent_GS agent = Selection.activeGameObject.GetComponent <Agent_GS>();

            agent.ClearPlanning();
            //Clear node editor planning
            NodeEditor_GS editor = (NodeEditor_GS)EditorWindow.GetWindow(typeof(NodeEditor_GS));

            editor.ClearPlanning();
        }
 //Constructors ================
 public Action_GS()
 {
     //Set action target agent to null
     _agent = null;
 }
        //Planning Methods ================
        public Stack <ActionNode_GS> GeneratePlan(Agent_GS agent)
        {
            //First get the world state states
            //Current
            WorldState_GS current_world_state        = agent.blackboard.GenerateWorldState();
            WorldState_GS current_global_world_state = GlobalBlackboard_GS.blackboard.GenerateWorldState();

            current_world_state.MixGoals(current_global_world_state);

            //Goal
            //Get current as base world state
            WorldState_GS goal_world_state = new WorldState_GS(current_world_state);

            //Apply the goals on the current to get the goal world state
            goal_world_state.MixGoals(agent.goal_world_state);

            //Check if the current world state and the goal world state coincide
            float start_goal_distance = current_world_state.DistanceTo(goal_world_state);

            if (start_goal_distance < ProTools.MIN_PROPERTY_DISTANCE)
            {
                Debug.LogWarning("The current world state coincides with the goal world state: " + goal_world_state.name + " !");
                return(new Stack <ActionNode_GS>());
            }

            //Allocate plan start node
            PlannerNode_GS start_node = new PlannerNode_GS(0, start_goal_distance, new_id_number, 0, current_world_state, null);

            //Clear open and close dictionaries
            _open.Clear();
            _closed.Clear();
            //Reset iterations count
            _current_iterations = 0;

            //Add start node to the open list
            _open.Add(start_node.f, new List <PlannerNode_GS> {
                start_node
            });

            //Iterate open list till there are no nodes to check
            while (_open.Count > 0)
            {
                //Check and update iterations count
                if (ProTools.ITERATION_LIMIT < _current_iterations)
                {
                    Debug.LogWarning("Planning generation for agent: " + agent.name + " failed");
                    break;
                }
                else
                {
                    _current_iterations += 1;
                }

                //Current closed node
                PlannerNode_GS current_node = CloseNode();

                //Check if the resultant world state of the current node is the goal world state
                if (current_node.resultant_world_state.DistanceTo(goal_world_state) < ProTools.MIN_PROPERTY_DISTANCE)
                {
                    //Allocate a new queue of actions to store the plan
                    Stack <ActionNode_GS> action_plan = new Stack <ActionNode_GS>();
                    //Enqueue the goal action
                    action_plan.Push(new ActionNode_GS(current_node.action));
                    //Iterate goal node "childs" to start node using the parent id
                    while (current_node.parent_id != 0)
                    {
                        //Update current node
                        current_node = _closed[current_node.parent_id];
                        //Check if the node has an action assigned
                        if (current_node.action != null)
                        {
                            //Enqueue the new current node
                            action_plan.Push(new ActionNode_GS(current_node.action));
                        }
                    }

                    //Flip the generated queue

                    //Return the generated actions queue
                    return(action_plan);
                }

                //Iterate all the avaliable actions
                for (int k = 0; k < agent.action_nodes_num; k++)
                {
                    if (agent.action_nodes[k].action == null)
                    {
                        continue;
                    }

                    //Scoped action
                    ActionNode_GS scoped_action = agent.action_nodes[k];

                    //Check if this action is reachable from the current world state
                    if (scoped_action.ValidateWorldState(current_node.resultant_world_state) == false)
                    {
                        //If the current world state is not valid for this actions we discard it and keep iterating the others
                        continue;
                    }

                    //If this action can be executed in the current world state, action effects are applied in the current world state
                    WorldState_GS new_current_world_state = scoped_action.EffectWorldState(current_node.resultant_world_state);

                    //Check if there is an action in the open list that can also reach the new current world state
                    PlannerNode_GS in_open_node = null;
                    if (IsInOpen(new_current_world_state, out in_open_node) == true)
                    {
                        //In true case check if the new node is better
                        if (current_node.g + scoped_action.action_cost > in_open_node.g)
                        {
                            //The old node is better than this new one
                            continue;
                        }

                        //The new node is better than the old, lets update the node data
                        in_open_node.parent_id = current_node.id;
                        in_open_node.g         = current_node.g + scoped_action.action_cost;
                        in_open_node.h         = new_current_world_state.DistanceTo(goal_world_state);
                        in_open_node.action    = scoped_action;
                    }
                    else
                    {
                        //In false case generate a new open node
                        PlannerNode_GS new_node = new PlannerNode_GS(current_node.g + scoped_action.action_cost, new_current_world_state.DistanceTo(goal_world_state), new_id_number, current_node.id, new_current_world_state, scoped_action);
                        //Add the new node to the open list
                        AddToOpen(new_node);
                    }
                }
            }

            //In no plan found case we return an empty plan
            return(new Stack <ActionNode_GS>());
        }
        //Loop Methods ================
        public override void OnGUI(Rect rect)
        {
            editorWindow.minSize = new Vector2(200.0f, 100.0f);
            editorWindow.maxSize = new Vector2(200.0f, 100.0f);

            GUILayout.BeginVertical();

            //Menu title
            GUILayout.BeginHorizontal("Box");
            GUILayout.FlexibleSpace();
            GUILayout.Label("Action Select", UIConfig_GS.Instance.select_menu_title_style, GUILayout.ExpandWidth(true));
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            //Separator
            EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

            //Action select dropdown button
            ProTools.GenerateButtonDropdownMenu(ref _selected_action_index, ResourcesTool.action_paths, "Select", false, 200.0f, _action_dropdown_slot);
            if (_selected_action_index != -1)
            {
                //Get selected action script value
                Object script = null;
                ResourcesTool.action_scripts.TryGetValue(ResourcesTool.action_paths[_selected_action_index], out script);
                //Allocate a class with the same type of script value
                Action_GS new_script = ProTools.AllocateClass <Action_GS>(script);
                //Action node case
                if (_target_action_node != null)
                {
                    //Check if the selected action is different to the node action
                    if (_target_action_node.action == null || _target_action_node.action.GetType() != new_script.GetType())
                    {
                        //Set the class name to the new allocated action
                        new_script.name = ResourcesTool.action_paths[_selected_action_index].PathToName();
                        //Set the allocated class to the action node
                        _target_action_node.action = new_script;
                        //Set new action agent
                        new_script.agent = _target_action_node.agent;
                        //Set target action node editor action editor
                        _target_action_node_editor.action_editor = new Action_GS_Editor(_target_action_node_editor);
                        //Mark scene dirty
                        EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
                        //Repaint the node editor to update the UI
                        NodeEditor_GS.Instance.Repaint();
                    }
                }
                //Agent idle action case
                else
                {
                    Agent_GS target_agent = NodeEditor_GS.Instance.selected_agent;
                    //Check if the selected agent is different to the agent idle action
                    if (target_agent.idle_action == null || target_agent.idle_action.GetType() != new_script.GetType())
                    {
                        //Set the class name to the new allocated action
                        new_script.name = ResourcesTool.action_paths[_selected_action_index].PathToName();
                        //Set new action agent
                        new_script.agent = NodeEditor_GS.Instance.selected_agent;
                        //Set the agent idle action
                        target_agent.idle_action = new_script;
                        //Mark scene dirty
                        EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
                        //Repaint the node editor to update the UI
                        NodePlanning_GS.Instance.Repaint();
                    }
                }
                //Close the pop window at the end of the process
                editorWindow.Close();
            }

            //Action create button
            if (GUILayout.Button("Create New", GUILayout.ExpandWidth(true)))
            {
                //Get mouse current position
                Vector2 mousePos = Event.current.mousePosition;
                //Open script creation menu
                PopupWindow.Show(new Rect(mousePos.x, mousePos.y, 0, 0), new ScriptCreationMenu_GS(ScriptCreationMenu_GS.ScriptCreationType.ScriptC_action, _target_action_node.index));
            }

            GUILayout.EndVertical();
        }
Exemple #7
0
        private string _id             = null; //Window UUID

        //Constructor =================
        public AgentBehaviour_GS_Editor(Agent_GS _agent)
        {
            //Set target agent
            _target_agent = _agent;
        }