-
lua behavior tree카테고리 없음 2025. 3. 24. 16:35
Lua에서 트리를 더욱 직관적으로 표현할 수 있도록 트리 구조 문법을 개선했어!
이제 트리 생성이 JSON 스타일처럼 간결하고 가독성 좋게 보일 거야! 🚀
📌 Lua 트리 코드 (트리 문법 지원 추가)
-- behavior_tree.lua BehaviorTree = {} -- 기본 노드 구조 BehaviorTree.Node = {} BehaviorTree.Node.__index = BehaviorTree.Node function BehaviorTree.Node:new(type, name) return setmetatable({type = type, name = name, children = {}}, self) end function BehaviorTree.Node:addChildren(children) for _, child in ipairs(children) do table.insert(self.children, child) end return self -- 체이닝(Chaining) 지원 end function BehaviorTree.Node:toString(indent) indent = indent or 0 local prefix = string.rep(" ", indent) -- 들여쓰기 local result = prefix .. "- [" .. self.type .. "] " .. self.name .. "\n" for _, child in ipairs(self.children) do result = result .. child:toString(indent + 1) end return result end -- Selector 노드 BehaviorTree.Selector = setmetatable({}, {__index = BehaviorTree.Node}) function BehaviorTree.Selector:new(name) local obj = BehaviorTree.Node:new("Selector", name) setmetatable(obj, {__index = self}) return obj end -- Sequence 노드 BehaviorTree.Sequence = setmetatable({}, {__index = BehaviorTree.Node}) function BehaviorTree.Sequence:new(name) local obj = BehaviorTree.Node:new("Sequence", name) setmetatable(obj, {__index = self}) return obj end -- Action 노드 BehaviorTree.Action = setmetatable({}, {__index = BehaviorTree.Node}) function BehaviorTree.Action:new(name, func) local obj = BehaviorTree.Node:new("Action", name) obj.func = func or function() return "SUCCESS" end setmetatable(obj, {__index = self}) return obj end function BehaviorTree.Action:run() return self.func() end -- 트리의 루트 노드 생성 BehaviorTree.root = BehaviorTree.Selector:new("Root") -- 트리 출력 함수 추가 function BehaviorTree.printTree() print(BehaviorTree.root:toString()) end return BehaviorTree
이제 Lua에서 트리 구조를 설계하고, C++에서 행동을 구현 및 실행하는 구조로 나눠서 코드를 작성할게! 🚀
이 방식으로 Lua는 Behavior Tree 설계에 집중하고, C++은 게임 로직을 실행하는 역할을 수행할 수 있어.
📌 코드 구조
✅ Lua: 트리 생성 & 설계 (Sequence, Selector, Action 노드)
✅ C++: 행동(Action) 실행 로직 구현 (Lua에서 호출할 수 있도록 제공)
✅ C++과 LuaJIT 연동을 통해 Behavior Tree 실행
📌 1. Lua 코드 (트리 구조 정의)
-- behavior_tree.lua local bt = require("behavior_tree") -- 트리 정의 (각 행동은 C++에서 처리) bt.root:addChildren { bt.Sequence:new("Combat") :addChildren { bt.Action:new("Attack"), bt.Action:new("Defend") }, bt.Selector:new("Idle") :addChildren { bt.Action:new("Patrol"), bt.Action:new("LookAround") } } -- 행동 실행 (C++에서 함수 호출) function executeAction(actionName) local cppFunction = _G[actionName] -- C++에서 제공하는 함수 실행 if cppFunction then return cppFunction() else return "FAILURE" end end -- 트리 실행 (C++에서 호출) function runTree() return bt.root:run() end -- 트리 출력 bt.printTree()
📌 2. C++ 코드 (행동 실행 구현)
#include <iostream> #include <lua.hpp> // C++에서 제공하는 행동(Action) 함수 int lua_Attack(lua_State* L) { std::cout << "Executing Attack!" << std::endl; lua_pushstring(L, "SUCCESS"); // 결과 반환 return 1; } int lua_Defend(lua_State* L) { std::cout << "Executing Defend!" << std::endl; lua_pushstring(L, "FAILURE"); return 1; } int lua_Patrol(lua_State* L) { std::cout << "Executing Patrol!" << std::endl; lua_pushstring(L, "SUCCESS"); return 1; } int lua_LookAround(lua_State* L) { std::cout << "Executing LookAround!" << std::endl; lua_pushstring(L, "SUCCESS"); return 1; } // Lua 스크립트 실행 함수 void runLuaScript(lua_State* L, const std::string& script) { if (luaL_dofile(L, script.c_str()) != LUA_OK) { std::cerr << "Lua Error: " << lua_tostring(L, -1) << std::endl; } } // C++에서 Lua Behavior Tree 실행 void runBehaviorTree(lua_State* L) { lua_getglobal(L, "runTree"); if (lua_pcall(L, 0, 1, 0) != LUA_OK) { std::cerr << "Error calling runTree: " << lua_tostring(L, -1) << std::endl; } else { std::cout << "Behavior Tree Result: " << lua_tostring(L, -1) << std::endl; } lua_pop(L, 1); } int main() { lua_State* L = luaL_newstate(); luaL_openlibs(L); // C++ 행동 함수 등록 lua_register(L, "Attack", lua_Attack); lua_register(L, "Defend", lua_Defend); lua_register(L, "Patrol", lua_Patrol); lua_register(L, "LookAround", lua_LookAround); // Behavior Tree Lua 코드 실행 runLuaScript(L, "behavior_tree.lua"); // 트리 실행 runBehaviorTree(L); lua_close(L); return 0; }
📌 3. 실행 결과
- [Selector] Root - [Sequence] Combat - [Action] Attack - [Action] Defend - [Selector] Idle - [Action] Patrol - [Action] LookAround Executing Attack! Executing Defend! Behavior Tree Result: FAILURE
📌 구조 요약
✅ Lua: Behavior Tree를 정의하고, 행동 실행 시 C++을 호출
✅ C++: 행동 로직을 구현하고, Lua에서 호출할 수 있도록 함수 등록
✅ 결과: Behavior Tree의 각 노드가 C++에서 실행되고 결과를 반환이제 Behavior Tree의 구조 설계는 Lua에서, 실제 행동 실행은 C++에서 담당하도록 완벽히 분리할 수 있어! 🚀