Scene Graph의 부모-자식 관계 연결하기

지난 글에서는 Scene Graph를 구성하는 가장 작은 단위인 SceneNode 클래스를 만들었습니다.
하지만 아직은 단순히 이름만 가진 객체일 뿐이었습니다.
각 노드는 서로 아무런 관계도 맺고 있지 않았습니다.
이번 글에서는 Scene Graph의 핵심인 부모-자식(Parent-Child) 관계를 직접 구현해보겠습니다.
World
└─ Player
├─ Camera
└─ Weapon
```
이제부터는 단순한 객체 목록이 아니라, 계층 구조를 가진 Scene Graph를 만들기 시작합니다.
부모-자식 관계가 필요한 이유
게임에서는 서로 연관된 오브젝트가 매우 많습니다.
- 플레이어와 카메라
- 플레이어와 무기
- 무기와 총구 이펙트
- 자동차와 바퀴
- 캐릭터와 모자
이들은 각각 독립적인 객체이지만, 실제로는 서로 연결되어 함께 움직입니다.
이 관계를 가장 자연스럽게 표현하는 방법이 바로 부모-자식 구조입니다.
SceneNode에 필요한 멤버
부모-자식 관계를 만들기 위해서는 다음 두 가지 정보가 필요합니다.
- 부모 노드
- 자식 노드 목록
SceneNode를 아래와 같이 수정합니다.
#pragma once
#include <string>
#include <vector>
class SceneNode
{
public:
SceneNode(const std::string& name);
void AddChild(SceneNode* child);
void Print() const;
private:
std::string name;
SceneNode* parent = nullptr;
std::vector<SceneNode*> children;
};
parent는 자신의 부모를 가리키고, children은 자신의 자식 노드들을 저장합니다.
AddChild 구현하기
부모 노드에 자식을 추가하는 함수는 생각보다 단순합니다.
void SceneNode::AddChild(SceneNode* child)
{
child->_parent = this;
children.emplace_back(child);
}
이 함수는 두 가지 작업만 수행합니다.
- 자식의 부모를 현재 노드로 설정
- 현재 노드의 자식 목록에 추가
이 두 줄만으로 노드 간의 관계가 만들어집니다.
계층 구조 만들기
이제 main.cpp에서 Scene Graph를 구성해보겠습니다.
SceneNode world("World");
SceneNode player("Player");
SceneNode camera("Camera");
SceneNode weapon("Weapon");
world.AddChild(&player);
player.AddChild(&camera);
player.AddChild(&weapon);
메모리 안에서는 다음과 같은 관계가 만들어집니다.
World
└─ Player
├─ Camera
└─ Weapon
아직 콘솔에는 이렇게 출력되지 않지만, 객체들 사이의 관계는 이미 완성되었습니다.
객체 목록과 무엇이 다를까?
기존 방식에서는 모든 객체를 하나의 배열에 넣었습니다.
std::vector<SceneNode*> nodes;
이 경우 Player와 Camera의 관계를 배열만 보고는 알 수 없습니다.
반면 Scene Graph에서는 Player가 Camera의 부모라는 사실을 객체 자체가 알고 있습니다.
이것이 가장 큰 차이입니다.
부모 포인터도 필요한 이유
자식 목록만 있어도 될 것처럼 보일 수 있습니다.
하지만 게임에서는 부모를 알아야 하는 경우도 매우 많습니다.
- 월드 위치 계산
- 부모 제거
- 루트 노드 찾기
- 상위 오브젝트 정보 접근
그래서 대부분의 게임 엔진은 부모와 자식을 모두 저장합니다.
아직 부족한 점
지금 만든 Scene Graph도 아직 완성은 아닙니다.
- 계층 구조 출력
- Transform 계산
- 재귀 탐색
- Tick 전파
이 기능들은 모두 부모-자식 관계를 기반으로 구현됩니다.
다음 단계
현재는 노드를 연결하기만 했습니다.
하지만 실제 Scene Graph는 아래처럼 계층 구조를 한눈에 볼 수 있어야 합니다.
World
└─ Player
├─ Camera
└─ Weapon
다음 글에서는 재귀(Recursive) 탐색을 이용하여 Scene Graph 전체를 콘솔에 출력하는 기능을 구현해보겠습니다.
마무리
이번 글에서는 Scene Graph의 핵심인 부모-자식 관계를 구현했습니다.
추가한 코드는 많지 않지만,
이 작은 변화만으로 단순한 객체 목록이 계층 구조를 가진 Scene Graph로 발전하기 시작했습니다.
다음 글에서는 재귀 탐색을 이용해 Scene Graph를 트리 형태로 출력하고, 이후 Transform 상속으로 자연스럽게 확장해보겠습니다.