BehaviorNode.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. ---
  2. --- Generated by EmmyLua(https://github.com/EmmyLua)
  3. --- Created by xxn.
  4. --- DateTime: 2021/1/7 13:25
  5. ---
  6. -- 行为树各类节点
  7. --[[
  8. 行为树节点主要分为:
  9. 1、组合节点(序列节点、选择节点、并行节点等)
  10. 2、装饰节点(且只能有一个子节点)
  11. 3、条件节点
  12. 4、动作节点
  13. 只有条件节点和动作节点能做完行为树的叶子节点,
  14. 而组合、装饰节点控制行为树的决策走向,所以,
  15. 条件和动作节点称为行为节点(Behavior Node),
  16. 组合和装饰节点称为决策节点(Decider Node)。
  17. 只有叶子节点才需要特别定制。
  18. --]]
  19. -- 行为树节点父类
  20. ---@class BehaviorNode
  21. BehaviorNode = class()
  22. ---@param children BehaviorNode[]
  23. function BehaviorNode:ctor(children)
  24. self.parent = nil
  25. self.kind = BehaviorNodeEnum.BehaviourNode --行为树节点种类
  26. self.children = children --子节点列表(数组)
  27. self.owner = nil --行为树拥有者
  28. self.status = BehaviorStatusEnum.READY --当前状态
  29. self.lastResult = BehaviorStatusEnum.READY --上一次结果
  30. if children then
  31. for _,child in ipairs(children) do
  32. child.parent = self
  33. end
  34. end
  35. end
  36. function BehaviorNode:SetOwner(owner)
  37. self.owner = owner
  38. if self.children then
  39. for k, child in ipairs(self.children) do
  40. child:SetOwner(owner)
  41. end
  42. end
  43. end
  44. function BehaviorNode:IsKindOf(k)
  45. return self.kind == k
  46. end
  47. function BehaviorNode:Visit()
  48. end
  49. -- 步进
  50. -- 如果该处于运行中并且有子节点,则步进子节点; 否则,重置该节点以及子节点
  51. function BehaviorNode:Step()
  52. if self.status ~= BehaviorStatusEnum.RUNNING then
  53. self:Reset()
  54. elseif self.children then
  55. for k, v in ipairs(self.children) do
  56. v:Step()
  57. end
  58. end
  59. end
  60. -- 重置节点为ready状态
  61. function BehaviorNode:Reset()
  62. if self.status ~= BehaviorStatusEnum.READY then
  63. self.status = BehaviorStatusEnum.READY
  64. if self.children then
  65. for _, child in ipairs(self.children) do
  66. child:Reset()
  67. end
  68. end
  69. end
  70. end
  71. function BehaviorNode:Stop()
  72. if self.children then
  73. for _, child in ipairs(self.children) do
  74. child:Stop()
  75. end
  76. end
  77. end
  78. -- 保存上一次update的状态
  79. function BehaviorNode:SaveStatus()
  80. self.lastResult = self.status
  81. if self.children then
  82. for k,v in ipairs(self.children) do
  83. v:SaveStatus()
  84. end
  85. end
  86. end
  87. ---@param nodeEnum BehaviorNodeEnum
  88. function BehaviorNode:FindNode(nodeEnum)
  89. if self.kind == nodeEnum then
  90. return self
  91. end
  92. if self.children then
  93. for k, v in pairs(self.children) do
  94. local f = v:FindNode(v)
  95. if f then
  96. return f
  97. end
  98. end
  99. end
  100. end
  101. ------------------------------------- 条件节点 -------------------------------------
  102. --[[
  103. 条件节点根据比较结果返回成功或失败,但永远不会返回正在执行(Running)
  104. --]]
  105. ---@class ConditionNode:BehaviorNode
  106. ConditionNode = class(BehaviorNode)
  107. function ConditionNode:ctor(func)
  108. BehaviorNode.ctor(self)
  109. self.kind = BehaviorNodeEnum.ConditionNode
  110. self.func = func
  111. end
  112. -- 条件为true则返回成功
  113. function ConditionNode:Visit()
  114. if self.func and self.func() then
  115. self.status = BehaviorStatusEnum.SUCCESS
  116. else
  117. self.status = BehaviorStatusEnum.FAILED
  118. end
  119. end
  120. ------------------------------------- 动作节点 -------------------------------------
  121. -- 通常对应owner的某个方法,一般是个瞬间动作,比如放个技能
  122. ---@class ActionNode:BehaviorNode
  123. ActionNode = class(BehaviorNode)
  124. function ActionNode:ctor(action, resetFnc)
  125. BehaviorNode.ctor(self)
  126. self.kind = BehaviorNodeEnum.ActionNode
  127. self.action = action
  128. self.resetFnc = resetFnc
  129. end
  130. function ActionNode:Reset()
  131. BehaviorNode.Reset(self)
  132. if self.resetFnc then
  133. self.resetFnc()
  134. end
  135. end
  136. function ActionNode:Visit()
  137. if self.action then
  138. self.action()
  139. end
  140. self.status = BehaviorStatusEnum.SUCCESS
  141. end
  142. ------------------------------------- 组合节点 -------------------------------------
  143. -- 序列节点
  144. --[[
  145. 它实现的是and的逻辑,例如:r = x and y and z,则先执行x,如果x为true,则继续执行y,如果x为false,则直接返回false,以此类推
  146. 执行该节点时,它会一个接一个运行,
  147. 如果子节点状态为success,则执行下一个子节点;
  148. 如果子节点状态为running,则把自身设置为running,并等待返回其他结果(success或failed);
  149. 如果子节点状态为failed,则把自身设置为failed,并返回;
  150. 如果所有节点都为success,则把自身设置为success并返回。
  151. 原则:只要一个子节点返回"失败"或"运行中",则返回;若返回"成功",则执行下一个子节点。
  152. --]]
  153. ---@class SequenceNode:BehaviorNode
  154. SequenceNode = class(BehaviorNode)
  155. function SequenceNode:ctor(children)
  156. BehaviorNode.ctor(self, children)
  157. self.kind = BehaviorNodeEnum.SequenceNode
  158. self.index = 1 -- 运行的是第几个节点
  159. end
  160. function SequenceNode:Reset()
  161. self.index = 1
  162. BehaviorNode.Reset(self)
  163. end
  164. function SequenceNode:Visit()
  165. if self.status ~= BehaviorStatusEnum.RUNNING then --如果没有运行的子节点,则从头开始执行
  166. self.index = 1
  167. end
  168. local count = #self.children
  169. local child
  170. local status
  171. while self.index <= count do
  172. child = self.children[self.index]
  173. child:Visit()
  174. status = child.status
  175. if status == BehaviorStatusEnum.RUNNING or status == BehaviorStatusEnum.FAILED then
  176. self.status = status
  177. if BTMgr.IsDebug == true then
  178. if child.nodeName == nil then
  179. -- 这些是中间节点,非叶子节点
  180. else
  181. logError(child.nodeName .. ' ' .. child.status)
  182. end
  183. end
  184. return
  185. end
  186. self.index = self.index + 1
  187. end
  188. self.status = BehaviorStatusEnum.SUCCESS --所有子节点都返回success
  189. end
  190. -- 选择节点
  191. --[[
  192. 它实现的是or的逻辑,例如:r = x or y or z,则先执行x,如果x为false,则继续执行y,如果x为true,则直接返回true,以此类推
  193. 执行该节点时,它会一个接一个运行,
  194. 如果子节点状态为success,则把自身设置为success并返回;
  195. 如果子节点状态为running,则把自身设置为running,并等待返回其他结果(success或failed);
  196. 如果子节点状态为failed,则会执行下一个子节点;
  197. 如果所有没子节点都不为success,则把自身设置为failed并返回。
  198. 原则:只要一个子节点返回"成功"或"运行中",则返回;若返回"失败",则执行下一个子节点。
  199. --]]
  200. ---@class SelectorNode:BehaviorNode
  201. SelectorNode = class(BehaviorNode)
  202. function SelectorNode:ctor(children)
  203. BehaviorNode.ctor(self, children)
  204. self.kind = BehaviorNodeEnum.SelectorNode
  205. self.index = 1 -- 运行的是第几个节点
  206. end
  207. function SelectorNode:Reset()
  208. self.index = 1
  209. BehaviorNode.Reset(self)
  210. end
  211. function SelectorNode:Visit()
  212. if self.status ~= BehaviorStatusEnum.RUNNING then --如果没有运行的子节点,则从头开始执行
  213. self.index = 1
  214. end
  215. local count = #self.children
  216. local child
  217. local status
  218. while self.index <= count do
  219. child = self.children[self.index]
  220. child:Visit()
  221. status = child.status
  222. if status == BehaviorStatusEnum.SUCCESS or status == BehaviorStatusEnum.RUNNING then
  223. self.status = status
  224. if BTMgr.IsDebug == true then
  225. if child.nodeName == nil then
  226. -- 这些是中间节点,非叶子节点
  227. else
  228. logError(child.nodeName .. ' ' .. child.status)
  229. end
  230. end
  231. return
  232. end
  233. self.index = self.index + 1
  234. end
  235. self.status = BehaviorStatusEnum.FAILED --所有子节点都返回failed
  236. end
  237. -- 并行节点
  238. --[[
  239. 看上去是同时执行所有的子节点,但是真正的逻辑还是一个一个执行子节点。
  240. 它实现的是and的逻辑,例如:r = x and y and z,则先执行x,如果x为true或者runing,则继续执行y,如果x为false,则直接返回false,以此类推
  241. 如果子节点的状态是failed,则将自身设置为failed,并返回;
  242. 如果子节点是success或者running,则运行下一个子节点;
  243. 如果所有子节点都为success,则将自身设置为success并返回,否则设置自身为running。
  244. 在运行到该节点时,要对部分节点(ConditionNode、NotDecorator)做重置,重启判断。
  245. ps:这里的实现的其实是Parallel Sequence Node,如果子节点failed,则返回。
  246. 并行节点可以设置退出条件
  247. 和序列节点不同的是,序列节点子节点返回runing状态的时候就返回不执行后面的节点
  248. 并行节点是返回runing状态的时候就返回继续执行后面的节点
  249. 他们遇到子节点false时都返回,不执行后面的节点
  250. --]]
  251. ---@class ParallelNode:BehaviorNode
  252. ParallelNode = class(BehaviorNode)
  253. function ParallelNode:ctor(children)
  254. BehaviorNode.ctor(self, children)
  255. self.kind = BehaviorNodeEnum.ParallelNode
  256. self.stopOnAnyComplete = nil
  257. end
  258. function ParallelNode:Step()
  259. if self.status ~= BehaviorStatusEnum.RUNNING then
  260. self:Reset()
  261. else
  262. --只重置条件子节点
  263. if self.children then
  264. for i,child in ipairs(self.children) do
  265. if self:IsKindOf(BehaviorNodeEnum.ConditionNode)
  266. and child.status == BehaviorStatusEnum.SUCCESS then
  267. child:Reset()
  268. end
  269. end
  270. end
  271. end
  272. end
  273. function ParallelNode:Visit()
  274. local done = true --是否所有子节点都success
  275. local any_done = false
  276. for _, child in ipairs(self.children) do
  277. if child:IsKindOf(BehaviorNodeEnum.ConditionNode) then --重启条件节点
  278. child:Reset()
  279. end
  280. if child.status ~= BehaviorStatusEnum.SUCCESS then
  281. child:Visit()
  282. if child.status == BehaviorStatusEnum.FAILED then
  283. self.status = BehaviorStatusEnum.FAILED
  284. return
  285. end
  286. end
  287. if child.status == BehaviorStatusEnum.RUNNING then
  288. done = false
  289. else -- success
  290. any_done = true
  291. end
  292. end
  293. if done or (self.stopOnAnyComplete and any_done) then
  294. self.status = BehaviorStatusEnum.SUCCESS
  295. else
  296. self.status = BehaviorStatusEnum.RUNNING
  297. end
  298. end
  299. --if 节点
  300. --实现了if操作,只有cond为success时,node才会被执行
  301. --注意:如果node处于运行中,则会在下一次思考时,继续执行node节点,直到node返回成功或失败,该节点才会退出
  302. --如果node节点有可能出现运行中状态,则该节点不适用
  303. ---@class IfNode:BehaviorNode
  304. IfNode = class(SequenceNode)
  305. function IfNode:ctor(condFunc, node)
  306. local children = {ConditionNode(condFunc),node}
  307. SequenceNode.ctor(self, children)
  308. self.kind = BehaviorNodeEnum.IfNode
  309. end
  310. ---status值由node或者elseNode决定,node和elseNode可以再套IfElseNode
  311. ---@class IfElseNode:BehaviorNode
  312. IfElseNode = class(BehaviorNode)
  313. ---@param node BehaviorNode
  314. ---@param elseNode BehaviorNode
  315. function IfElseNode:ctor(condFunc, node,elseNode)
  316. local children = {node,elseNode}
  317. BehaviorNode.ctor(self, children)
  318. self.kind = BehaviorNodeEnum.IfElseNode
  319. self.condFunc = condFunc
  320. self.node = node
  321. self.elseNode = elseNode
  322. self.runingNode = nil
  323. end
  324. function IfElseNode:Visit()
  325. if self.lastVisitNode then
  326. self.lastVisitNode:Visit()
  327. self.status = self.lastVisitNode.status
  328. if self.status ~= BehaviorStatusEnum.RUNNING then
  329. self.lastVisitNode = nil
  330. end
  331. return
  332. end
  333. if self.condFunc() then
  334. self.node:Visit()
  335. self.lastVisitNode = self.node
  336. self.status = self.node.status
  337. else
  338. self.elseNode:Visit()
  339. self.lastVisitNode = self.elseNode
  340. self.status = self.elseNode.status
  341. end
  342. if self.status ~= BehaviorStatusEnum.RUNNING then
  343. self.lastVisitNode = nil
  344. end
  345. end
  346. --- wait 节点
  347. --等待条件达成继续运行
  348. ---@class WaitNode : BehaviorNode
  349. WaitNode = class(BehaviorNode)
  350. ---@param waitFun function @等待判定方法
  351. function WaitNode:ctor(waitFun)
  352. BehaviorNode.ctor(self, nil)
  353. self.waitFun = waitFun
  354. end
  355. function WaitNode:Reset()
  356. BehaviorNode.Reset(self)
  357. end
  358. function WaitNode:Visit()
  359. if not self.waitFun then
  360. self.status = BehaviorStatusEnum.SUCCESS
  361. return
  362. end
  363. if self.waitFun() then
  364. self.status = BehaviorStatusEnum.SUCCESS
  365. else
  366. self.status = BehaviorStatusEnum.RUNNING
  367. end
  368. end