카테고리 없음

Lua, C++ behavior tree 최적화3

denny 2025. 4. 3. 16:53

현재 구조에서는 부모 노드(Parent Node)로 이동하는 기능이 없습니다.
이제 각 노드가 부모 정보를 저장하도록 변경하고,
필요할 때 부모 노드로 이동 가능하도록 개선해보겠습니다! 🚀


📌 개선 사항

1️⃣ 각 노드에 parent 포인터 추가
2️⃣ 부모로 이동하는 기능 (getParent()) 추가
3️⃣ Lua에서 정의한 트리 구조를 유지하면서, 부모 정보를 자동으로 설정


🔹 수정된 C++ 코드

1️⃣ Node 클래스 (부모 정보 추가)

class Node {
protected:
    Node* parent = nullptr;  // 부모 노드 포인터

public:
    virtual ~Node() = default;
    virtual bool execute() = 0;

    void setParent(Node* p) { parent = p; }
    Node* getParent() { return parent; }
};

2️⃣ CompositeNode (부모 설정)

class CompositeNode : public Node {
protected:
    std::vector<std::unique_ptr<Node>> children;
    NodeType type;

public:
    explicit CompositeNode(NodeType type) : type(type) {}

    void addChild(std::unique_ptr<Node> child) {
        child->setParent(this);  // 부모 설정
        children.push_back(std::move(child));
    }

    bool execute() override {
        if (type == NodeType::Sequence) {
            for (auto& child : children) {
                if (!child->execute()) return false;
            }
            return true;
        } else {  // Selector
            for (auto& child : children) {
                if (child->execute()) return true;
            }
            return false;
        }
    }
};

3️⃣ Leaf 노드 (부모 설정)

class Leaf : public Node {
protected:
    Monster* monster;

public:
    explicit Leaf(Monster* monster) : monster(monster) {}
    virtual ~Leaf() = default;
    virtual bool execute() override = 0;
};

4️⃣ Lua에서 트리 생성 시 부모 설정

std::unique_ptr<Node> parseNode(lua_State* L, int index, Monster* monster, Node* parent = nullptr) {
    lua_getfield(L, index, "type");
    std::string typeStr = lua_tostring(L, -1);
    lua_pop(L, 1);

    std::unique_ptr<Node> node;

    if (typeStr == "Leaf") {
        lua_getfield(L, index, "name");
        std::string name = lua_tostring(L, -1);
        lua_pop(L, 1);
        node = LeafFactory::createLeaf(name, monster);
    } 
    else if (typeStr == "Sequence" || typeStr == "Selector") {
        lua_getfield(L, index, "children");
        auto compositeNode = std::make_unique<CompositeNode>(
            (typeStr == "Sequence") ? NodeType::Sequence : NodeType::Selector
        );

        if (lua_istable(L, -1)) {
            int len = luaL_len(L, -1);
            for (int i = 1; i <= len; ++i) {
                lua_rawgeti(L, -1, i);
                auto child = parseNode(L, lua_gettop(L), monster, compositeNode.get());
                compositeNode->addChild(std::move(child));
                lua_pop(L, 1);
            }
        }
        lua_pop(L, 1);
        node = std::move(compositeNode);
    }

    if (node) {
        node->setParent(parent);  // 부모 설정
    }

    return node;
}

5️⃣ 부모로 이동하는 예제 코드

class CheckEnemyLeaf : public Leaf {
public:
    using Leaf::Leaf;

    bool execute() override {
        if (monster) {
            std::cout << monster->getName() << " is checking for enemies...\n";

            // 부모 노드로 이동
            if (Node* parent = getParent()) {
                std::cout << "Moving up to parent node!\n";
            }
        }
        return true;
    }
};

🔹 주요 개선점

기능 기존 변경

부모 이동 가능 여부 ❌ 부모 노드 정보 없음 ✅ Node* parent 추가
부모 노드로 이동 ❌ 불가능 ✅ getParent() 로 가능
트리 생성 시 부모 설정 ❌ 자동 설정 없음 ✅ setParent() 활용

🎯 최종 결과

이제 각 노드에서 부모 노드로 이동 가능하고,
트리에서 상위 노드의 로직을 활용할 수 있습니다! 🚀🔥