그럼 게임 Object를 관리하는 클래스는 없나? -> Scene을 통해서 관리한다.
Unity도 보면 Scene을 통해서 게임 Object를 관리하게된다.
Singleton
// EnginePch.h
// ...
#define DECLARE_SINGLE(type) \
// private로 생성자/소멸자를 선언해 외부에서 new로 새롭게 생성하는 것을 막는다
private: \
type() {} \
~type() {} \
public: \
static type* GetInstance() \
{ \
static type instance; \
return &instance; \
} \
#define GET_SINGLE(type) type::GetInstance()
// ...
SceneManager 클래스
#pragma once
class Scene;
class SceneManager
{
// 싱글톤 선언
DECLARE_SINGLE(SceneManager);
public:
void Update();
void LoadScene(wstring sceneName);
public:
shared_ptr<Scene> GetActiveScene() { return _activeScene; }
private:
shared_ptr<Scene> LoadTestScene();
private:
shared_ptr<Scene> _activeScene;
};
#include "pch.h"
#include "SceneManager.h"
#include "Scene.h"
#include "Engine.h"
#include "Material.h"
#include "GameObject.h"
#include "MeshRenderer.h"
void SceneManager::Update()
{
if (_activeScene == nullptr)
return;
_activeScene->Update();
_activeScene->LateUpdate();
}
void SceneManager::LoadScene(wstring sceneName)
{
// TODO : 기존 Scene 정리
// TODO : 파일에서 Scene 정보 로드
_activeScene = LoadTestScene();
_activeScene->Awake();
_activeScene->Start();
}
shared_ptr<Scene> SceneManager::LoadTestScene()
{
shared_ptr<Scene> scene = make_shared<Scene>();
// TestObject
shared_ptr<GameObject> gameObject = make_shared<GameObject>();
vector<Vertex> vec(4);
vec[0].pos = Vec3(-0.5f, 0.5f, 0.5f);
vec[0].color = Vec4(1.f, 0.f, 0.f, 1.f);
vec[0].uv = Vec2(0.f, 0.f);
vec[1].pos = Vec3(0.5f, 0.5f, 0.5f);
vec[1].color = Vec4(0.f, 1.f, 0.f, 1.f);
vec[1].uv = Vec2(1.f, 0.f);
vec[2].pos = Vec3(0.5f, -0.5f, 0.5f);
vec[2].color = Vec4(0.f, 0.f, 1.f, 1.f);
vec[2].uv = Vec2(1.f, 1.f);
vec[3].pos = Vec3(-0.5f, -0.5f, 0.5f);
vec[3].color = Vec4(0.f, 1.f, 0.f, 1.f);
vec[3].uv = Vec2(0.f, 1.f);
vector<uint32> indexVec;
{
indexVec.push_back(0);
indexVec.push_back(1);
indexVec.push_back(2);
}
{
indexVec.push_back(0);
indexVec.push_back(2);
indexVec.push_back(3);
}
gameObject->Init(); // Transform
shared_ptr<MeshRenderer> meshRenderer = make_shared<MeshRenderer>();
{
shared_ptr<Mesh> mesh = make_shared<Mesh>();
mesh->Init(vec, indexVec);
meshRenderer->SetMesh(mesh);
}
{
shared_ptr<Shader> shader = make_shared<Shader>();
shared_ptr<Texture> texture = make_shared<Texture>();
shader->Init(L"..\\Resources\\Shader\\default.hlsli");
texture->Init(L"..\\Resources\\Texture\\veigar.jpg");
shared_ptr<Material> material = make_shared<Material>();
material->SetShader(shader);
material->SetFloat(0, 0.3f);
material->SetFloat(1, 0.4f);
material->SetFloat(2, 0.3f);
material->SetTexture(0, texture);
meshRenderer->SetMaterial(material);
}
gameObject->AddComponent(meshRenderer);
scene->AddGameObject(gameObject);
return scene;
}
Scene 클래스
#pragma once
class GameObject;
class Scene
{
public:
void Awake();
void Start();
void Update();
void LateUpdate();
void AddGameObject(shared_ptr<GameObject> gameObject);
void RemoveGameObject(shared_ptr<GameObject> gameObject);
private:
vector<shared_ptr<GameObject>> _gameObjects;
};
#include "pch.h"
#include "Scene.h"
#include "GameObject.h"
void Scene::Awake()
{
// const shared_ptr<GameObject>&
// &로 받으면 shared_ptr 레퍼런스 카운트가 증가하지 않아 성능에 효율적이다.
for (const shared_ptr<GameObject>& gameObject : _gameObjects)
{
gameObject->Awake();
}
}
void Scene::Start()
{
for (const shared_ptr<GameObject>& gameObject : _gameObjects)
{
gameObject->Start();
}
}
void Scene::Update()
{
for (const shared_ptr<GameObject>& gameObject : _gameObjects)
{
gameObject->Update();
}
}
void Scene::LateUpdate()
{
for (const shared_ptr<GameObject>& gameObject : _gameObjects)
{
gameObject->LateUpdate();
}
}
void Scene::AddGameObject(shared_ptr<GameObject> gameObject)
{
_gameObjects.push_back(gameObject);
}
void Scene::RemoveGameObject(shared_ptr<GameObject> gameObject)
{
auto findIt = std::find(_gameObjects.begin(), _gameObjects.end(), gameObject);
if (findIt != _gameObjects.end())
{
_gameObjects.erase(findIt);
}
}
Timer, Input 모두 Singlton 처리
class Timer
{
DECLARE_SINGLE(Timer);
// ...
// ...
class Input
{
DECLARE_SINGLE(Input);
// ...