Skip to content

Commit

Permalink
Add Node Constraint
Browse files Browse the repository at this point in the history
  • Loading branch information
AkiKurisu committed Sep 4, 2023
1 parent a8c1218 commit 9501152
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 97 deletions.
12 changes: 8 additions & 4 deletions Editor/Core/GOAPPlannerProEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,19 @@ public override VisualElement CreateInspectorGUI()
UIUtility.GetLabel("Normal Setting", 14, color: UIUtility.AkiBlue, anchor: TextAnchor.MiddleLeft).AddTo(myInspector);
myInspector.Q<PropertyField>("PropertyField:logType").MoveToEnd(myInspector);
myInspector.Q<PropertyField>("PropertyField:tickType").MoveToEnd(myInspector);
var isActive = new Toggle("Is Active");
isActive.tooltip = SkilSearchTooltip;
var isActive = new Toggle("Is Active")
{
tooltip = SkilSearchTooltip
};
isActive.BindProperty(serializedObject.FindProperty("isActive"));
isActive.AddTo(myInspector);
myInspector.AddSpace();
UIUtility.GetLabel("Pro Setting", 14, color: UIUtility.AkiBlue, anchor: TextAnchor.MiddleLeft).AddTo(myInspector);
var skipSearchProperty = serializedObject.FindProperty("skipSearchWhenActionRunning");
var skipSearchToggle = new Toggle("Skip Search When Action Running");
skipSearchToggle.tooltip = SkilSearchTooltip;
var skipSearchToggle = new Toggle("Skip Search When Action Running")
{
tooltip = SkilSearchTooltip
};
skipSearchToggle.BindProperty(skipSearchProperty);
skipSearchToggle.AddTo(myInspector);
//SnapShot
Expand Down
24 changes: 19 additions & 5 deletions Editor/Node/GOAPNodeStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,25 @@ public class GOAPNodeStack : StackNode
{
public GOAPNodeStack()
{
capabilities&=~Capabilities.Copiable;
capabilities &=~Capabilities.Deletable;//不可删除
capabilities &=~Capabilities.Movable;//不可删除
headerContainer.style.flexDirection=FlexDirection.Row;
headerContainer.style.justifyContent=Justify.Center;
capabilities &= ~Capabilities.Copiable;
capabilities &= ~Capabilities.Deletable;
capabilities &= ~Capabilities.Movable;
headerContainer.style.flexDirection = FlexDirection.Row;
headerContainer.style.justifyContent = Justify.Center;
}
}
public class GOAPActionStack : GOAPNodeStack
{
protected override bool AcceptsElement(GraphElement element, ref int proposedIndex, int maxIndex)
{
return element is GOAPActionNode;
}
}
public class GOAPGoalStack : GOAPNodeStack
{
protected override bool AcceptsElement(GraphElement element, ref int proposedIndex, int maxIndex)
{
return element is GOAPGoalNode;
}
}
}
28 changes: 14 additions & 14 deletions Editor/Window/GOAPEditorWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ namespace Kurisu.GOAP.Editor
{
public class GOAPEditorWindow : EditorWindow
{
private static readonly Dictionary<int,GOAPEditorWindow> cache = new Dictionary<int, GOAPEditorWindow>();
private UnityEngine.Object key { get; set; }
private static readonly Dictionary<int, GOAPEditorWindow> cache = new Dictionary<int, GOAPEditorWindow>();
private UnityEngine.Object Key { get; set; }
private GOAPView graphView;
public static void ShowEditorWindow(IGOAPSet set)
{
Expand All @@ -18,21 +18,21 @@ public static void ShowEditorWindow(IGOAPSet set)
cache[key].Focus();
return;
}
var window = ScriptableObject.CreateInstance<GOAPEditorWindow>();
var window = CreateInstance<GOAPEditorWindow>();
window.titleContent = new GUIContent($"GOAP Editor ({set._Object.name})");
window.Show();
window.Focus();
window.key = set._Object;
window.Key = set._Object;
cache[key] = window;
window.StructGraphView(set);
}
private void StructGraphView(IGOAPSet set)
{
rootVisualElement.Clear();
graphView=new GOAPView(this,set);
graphView = new GOAPView(this, set);
graphView.Restore();
rootVisualElement.Add(CreateToolBar(graphView));
rootVisualElement.Add(graphView);
rootVisualElement.Add(graphView);
}
private VisualElement CreateToolBar(GOAPView graphView)
{
Expand All @@ -41,15 +41,15 @@ private VisualElement CreateToolBar(GOAPView graphView)
{
GUILayout.BeginHorizontal(EditorStyles.toolbar);

GUI.enabled=!Application.isPlaying;
GUI.enabled = !Application.isPlaying;
if (GUILayout.Button($"Save", EditorStyles.toolbarButton))
{
var guiContent = new GUIContent();
graphView.Save();
guiContent.text = $"Update Succeed !";
this.ShowNotification(guiContent);
ShowNotification(guiContent);
}
GUI.enabled=true;
GUI.enabled = true;
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
Expand Down Expand Up @@ -86,17 +86,17 @@ private void OnDisable()
}
private void Reload()
{
if (key != null)
if (Key != null)
{
if(key is GameObject)StructGraphView((key as GameObject).GetComponent<IGOAPSet>());
else StructGraphView((key as IGOAPSet));
if (Key is GameObject) StructGraphView((Key as GameObject).GetComponent<IGOAPSet>());
else StructGraphView(Key as IGOAPSet);
Repaint();
}
}
private void OnDestroy()
{
int code=key.GetHashCode();
if (key != null && cache.ContainsKey(code))
int code = Key.GetHashCode();
if (Key != null && cache.ContainsKey(code))
{
cache.Remove(code);
}
Expand Down
118 changes: 58 additions & 60 deletions Editor/Window/GOAPView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ namespace Kurisu.GOAP.Editor
{
public class GOAPView : GraphView
{
private const string GraphStyleSheetPath="AkiGOAP/Graph";
private const string GoalIconPath="Icons/goal_icon";
private const string ActionIconPath="Icons/action_icon";
private const string GraphStyleSheetPath = "AkiGOAP/Graph";
private const string GoalIconPath = "Icons/goal_icon";
private const string ActionIconPath = "Icons/action_icon";
private readonly EditorWindow editorWindow;
internal System.Action<GOAPNode> onSelectAction;
private IGOAPSet set;
public IGOAPSet Set=>set;
internal System.Action<GOAPNode> onSelectAction;
private readonly IGOAPSet set;
public IGOAPSet Set => set;
private readonly NodeResolver nodeResolver = new NodeResolver();
private GOAPNodeStack goalStack;
private GOAPNodeStack actionStack;
public GOAPView(EditorWindow editor,IGOAPSet set)
public GOAPView(EditorWindow editor, IGOAPSet set)
{
this.set=set;
editorWindow=editor;
this.set = set;
editorWindow = editor;
style.flexGrow = 1;
style.flexShrink = 1;
styleSheets.Add(Resources.Load<StyleSheet>(GraphStyleSheetPath));
Expand All @@ -39,34 +39,34 @@ public GOAPView(EditorWindow editor,IGOAPSet set)
this.AddManipulator(new RectangleSelector());
this.AddManipulator(new FreehandSelector());
this.AddManipulator(contentDragger);
if(set is GOAPActionSet)
if (set is GOAPActionSet)
{
var searchWindow=ScriptableObject.CreateInstance<ActionSearchWindowProvider>();
searchWindow.Init(editorWindow,this);
var searchWindow = ScriptableObject.CreateInstance<ActionSearchWindowProvider>();
searchWindow.Init(editorWindow, this);
nodeCreationRequest += context =>
{
SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), searchWindow);
};
}
else if(set is GOAPGoalSet)
else if (set is GOAPGoalSet)
{
var searchWindow=ScriptableObject.CreateInstance<GoalSearchWindowProvider>();
searchWindow.Init(editorWindow,this);
var searchWindow = ScriptableObject.CreateInstance<GoalSearchWindowProvider>();
searchWindow.Init(editorWindow, this);
nodeCreationRequest += context =>
{
SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), searchWindow);
};
}
else
{
var searchWindow=ScriptableObject.CreateInstance<GOAPNodeSearchWindow>();
searchWindow.Init(editorWindow,this);
var searchWindow = ScriptableObject.CreateInstance<GOAPNodeSearchWindow>();
searchWindow.Init(editorWindow, this);
nodeCreationRequest += context =>
{
SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), searchWindow);
};
}

}
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
Expand All @@ -85,82 +85,80 @@ public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
}
internal void Restore()
{
goalStack=new GOAPNodeStack();
goalStack.SetPosition (new Rect(100,300,100,100));
goalStack.headerContainer.Add(new Image(){image=Resources.Load<Texture2D>(GoalIconPath)});
goalStack = new GOAPGoalStack();
goalStack.SetPosition(new Rect(100, 300, 100, 100));
goalStack.headerContainer.Add(new Image() { image = Resources.Load<Texture2D>(GoalIconPath) });
goalStack.headerContainer.Add(new Label(" GOAP Goal Stack"));
actionStack=new GOAPNodeStack();
actionStack.SetPosition (new Rect(600,300,100,100));
actionStack.headerContainer.Add(new Image(){image=Resources.Load<Texture2D>(ActionIconPath)});
actionStack = new GOAPActionStack();
actionStack.SetPosition(new Rect(600, 300, 100, 100));
actionStack.headerContainer.Add(new Image() { image = Resources.Load<Texture2D>(ActionIconPath) });
actionStack.headerContainer.Add(new Label(" GOAP Action Stack"));
AddElement(goalStack);
AddElement(actionStack);
if(set is GOAPActionSet)
if (set is GOAPActionSet)
{
goalStack.SetEnabled(false);
}
if(set is GOAPGoalSet)
if (set is GOAPGoalSet)
{
actionStack.SetEnabled(false);
}
foreach(var behavior in set.Behaviors)
foreach (var behavior in set.Behaviors)
{
if(behavior==null)continue;
var node = nodeResolver.CreateNodeInstance(behavior.GetType(),this);
if (behavior == null) continue;
var node = nodeResolver.CreateNodeInstance(behavior.GetType(), this);
node.Restore(behavior);
if(node is GOAPActionNode)actionStack.AddElement(node);
if (node is GOAPActionNode) actionStack.AddElement(node);
else goalStack.AddElement(node);
node.onSelectAction=onSelectAction;
node.onSelectAction = onSelectAction;
}
if(set is IPlanner)
if (set is IPlanner)
{
IPlanner planner=set as IPlanner;
planner.OnUpdatePlanEvent+=UpdateView;
IPlanner planner = set as IPlanner;
planner.OnUpdatePlanEvent += UpdateView;
}
}
private void UpdateView(IPlanner planner)
{
var actions=actionStack.Query<GOAPNode>().ToList();
actions.ForEach(x=>x.CleanUp());
var goals=goalStack.Query<GOAPNode>().ToList();
goals.ForEach(x=>x.CleanUp());
var activePlans=planner.ActivatePlan;
var activeGoal=planner.ActivateGoal;
foreach(var action in activePlans)
var actions = actionStack.Query<GOAPNode>().ToList();
actions.ForEach(x => x.CleanUp());
var goals = goalStack.Query<GOAPNode>().ToList();
goals.ForEach(x => x.CleanUp());
var activePlans = planner.ActivatePlan;
var activeGoal = planner.ActivateGoal;
foreach (var action in activePlans)
{
var goapAction=action as GOAPAction;
if(goapAction==null)continue;
var t_Action=actions.First(x=>x.GUID==goapAction.GUID);
if (action is not GOAPAction goapAction) continue;
var t_Action = actions.First(x => x.GUID == goapAction.GUID);
(t_Action as GOAPActionNode).SetUp(goapAction.GetCost());
}
var goapGoal=activeGoal as GOAPGoal;
if(goapGoal==null)return;
var t_Goal=goals.First(x=>x.GUID==goapGoal.GUID);
(t_Goal as GOAPGoalNode).SetUp(goapGoal.GetPriority(),goapGoal.PreconditionsSatisfied(planner.WorldState),true);
foreach(var goal in goals)
if (activeGoal is not GOAPGoal goapGoal) return;
var t_Goal = goals.First(x => x.GUID == goapGoal.GUID);
(t_Goal as GOAPGoalNode).SetUp(goapGoal.GetPriority(), goapGoal.PreconditionsSatisfied(planner.WorldState), true);
foreach (var goal in goals)
{
if(goal==t_Goal)continue;
var goalBehavior=planner.Behaviors.First(x=>x.GUID==goal.GUID) as GOAPGoal;
(goal as GOAPGoalNode).SetUp(goalBehavior.GetPriority(),goalBehavior.PreconditionsSatisfied(planner.WorldState),false);
if (goal == t_Goal) continue;
var goalBehavior = planner.Behaviors.First(x => x.GUID == goal.GUID) as GOAPGoal;
(goal as GOAPGoalNode).SetUp(goalBehavior.GetPriority(), goalBehavior.PreconditionsSatisfied(planner.WorldState), false);
}
}
internal void Save()
{
if(Application.isPlaying)return;
if (Application.isPlaying) return;
set.Behaviors.Clear();
IEnumerable<GOAPNode> list;
if(set is GOAPActionSet)
if (set is GOAPActionSet)
{
list=actionStack.Query<GOAPNode>().ToList();
list = actionStack.Query<GOAPNode>().ToList();
}
else if(set is GOAPGoalSet)
else if (set is GOAPGoalSet)
{
list=goalStack.Query<GOAPNode>().ToList();
list = goalStack.Query<GOAPNode>().ToList();
}
else list=goalStack.Query<GOAPNode>().ToList().Concat(actionStack.Query<GOAPNode>().ToList());
foreach(var node in list)
else list = goalStack.Query<GOAPNode>().ToList().Concat(actionStack.Query<GOAPNode>().ToList());
foreach (var node in list)
{
node.Commit();
node.Commit();
set.Behaviors.Add(node.NodeBehavior);
}
EditorUtility.SetDirty(set._Object);
Expand Down
29 changes: 15 additions & 14 deletions Example/Scripts/Agent/AgentFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class AgentFactory : MonoBehaviour
[SerializeField]
private GameObject agentPrefab;
[SerializeField]
private int maxAmount=1000;
private int maxAmount = 1000;
[SerializeField]
private Transform player;
[SerializeField]
Expand All @@ -15,33 +15,34 @@ public class AgentFactory : MonoBehaviour
private Transform tent;
[SerializeField]
private GOAPSet dataSet;
[SerializeField]
private ExampleAgent[] agents;
private void Awake() {
agents=new ExampleAgent[maxAmount];
for(int i=0;i<maxAmount;i++)
private void Awake()
{
agents = new ExampleAgent[maxAmount];
for (int i = 0; i < maxAmount; i++)
{
var prefab= Instantiate(agentPrefab,GetRandomPosition(),Quaternion.identity);
agents[i]=new ExampleAgent(dataSet){
_Transform=prefab.transform,
Home=home,
Tent=tent,
Player=player
var prefab = Instantiate(agentPrefab, GetRandomPosition(), Quaternion.identity);
agents[i] = new ExampleAgent(dataSet)
{
_Transform = prefab.transform,
Home = home,
Tent = tent,
Player = player
};
agents[i].Init();
}
InvokeRepeating("LossEnergy",0.2f,0.2f);
InvokeRepeating(nameof(LossEnergy), 0.2f, 0.2f);
}
private void LossEnergy()
{
for(int i=0;i<agents.Length;i++)
for (int i = 0; i < agents.Length; i++)
{
agents[i].LossEnergy();
}
}
private Vector3 GetRandomPosition()
{
return transform.position+new Vector3(Random.Range(-10f,10f),0,Random.Range(-10f,10f));
return transform.position + new Vector3(Random.Range(-10f, 10f), 0, Random.Range(-10f, 10f));
}
}
}

0 comments on commit 9501152

Please sign in to comment.