// 可以A*搜索生成plan,也可以手动配置plan void BuildPlan(GOAPGoal goal) { int maxOverLoad = 100; AStarResultCode ret = _astar.FindPath(goal, CurWorldState, ref _path, maxOverLoad); switch (ret) { case AStarResultCode.SUCCESS: foreach (var action in _path) { steps.Enqueue(action); } break; case AStarResultCode.FAIL_NO_WAY: Debug.Log(string.Format("寻路失败!无法获得goalType = {0}的路径。", goal.GetType())); break; case AStarResultCode.FAIL_OVERLOAD: Debug.Log(string.Format("寻路失败!在寻找goalType = {0}的路径时open列表元素个数超过上限{1}。", goal.GetType(), maxOverLoad)); break; default: break; } }
public void OnUpdate() { if (_curGoal != null) { if (_curGoal.IsAborted() || _curGoal.IsFinished(WorldState) || _plan.IsAborted()) { _curGoal.OnExit(WorldState); if (onGoalExit != null) { onGoalExit.Invoke(false); } _curGoal = null; } } GOAPGoal topGoal = FindTopGoal(); if (topGoal == null /*|| topGoal.IsAborted()*/ || topGoal.IsFinished(WorldState)) { // 如果topGoal不合理 if (_curGoal != null) { _plan.OnUpdate(); } return; } // 如果是新的topGoal if (_curGoal != topGoal) { if (_curGoal != null) { _curGoal.OnExit(WorldState); if (onGoalExit != null) { onGoalExit.Invoke(true); } } _curGoal = topGoal; foreach (var action in _actions) { action.BeforeBuildPlan(_curGoal); } _plan.Build(WorldState, _curGoal); _curGoal.OnEnter(WorldState); } else if (_plan.IsEmpty()) // TopGoal不变 { _plan.Build(WorldState, _curGoal); } _plan.OnUpdate(); }
public GOAP(WorldState ws, List <GOAPGoal> goals, List <GOAPAction> actions, GOAPAStarBase astar) { WorldState = ws; _goals = goals; _actions = actions; _plan = new GOAPPlan(astar); _curGoal = null; foreach (var goal in goals) { goalsMap.Add(goal.GOAPGoalType, goal); } }
public void Build(WorldState curWS, GOAPGoal goal) { CurWorldState = curWS; while (steps.Count > 0) { steps.Dequeue().OnExit(curWS); } BuildPlan(goal); if (steps.Count > 0) { steps.Peek().OnEnter(); } }
protected virtual GOAPGoal FindTopGoal() { float max = -1; GOAPGoal ret = null; foreach (var goal in _goals) { if (goal.InCD()) { continue; } float weight = goal.GetWeight(WorldState); if (weight > max) { max = weight; ret = goal; } } return(ret); }
public AStarResultCode FindPath(GOAPGoal goal, WorldState curWorldState, ref List <GOAPAction> path, int maxOverload = 0) { path.Clear(); _goal = goal; _nodes.Shuffle(); curWorldState.CopyTo(ref _start.nodeWS); AStarResultCode ret = FindPath(_start, null, ref _nodePath, maxOverload); if (AStarResultCode.SUCCESS == ret) { foreach (var node in _nodePath) { path.Add(node.goapAction); } } return(ret); }
public void Reset() { if (WorldState != null) { WorldState.Clear(); } if (_plan != null) { _plan.Reset(); } _curGoal = null; foreach (var goal in _goals) { goal.Reset(); } foreach (var action in _actions) { action.Reset(); } }
public virtual void BeforeBuildPlan(GOAPGoal goal) { }
protected virtual float GetH(GOAPAction action, GOAPGoal goal) { return(0); }
protected virtual float GetCost(GOAPAction action, GOAPGoal goal) { return(1); }