Scene

 

  • 인게임 - 로비 - 로그인과 같이 서로 겹치지 않는 Object를 사용하는 경우 Scene을 통해 구분하여 관리한다.
  • Scene에 포함된 Object들의 초기화와 갱신은 Scene에서 관리한다.
  • 싱글톤 패턴을 사용하여 SceneManager을 호출해 어디서든 사용이 가능하도록 설계한다.

 

 


 

 

<Game.cpp>

 

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "pch.h"
#include "Game.h"
#include "Engine.h"
#include "SceneManager.h"
 
void Game::Init(const WindowInfo& info)
{
    GEngine->Init(info);
 
    GET_SINGLE(SceneManager)->LoadScene(L"TestScene");
}
 
void Game::Update()
{
    GEngine->Update();
}
 
cs

 

 

  • 여태와는 달리 Game.cpp가 상당히 깔끔해진 것을 확인할 수 있다.
  • 여태 Game.cpp에서 하던 것들을 모두 Load한 Scene에게 넘겨주어 수행하고 있기 때문이다.
  • Render를 하는 부분 또한 Engine에게 넘겨주었으며 gameObject의 Update를 하는 부분도 Engine에서 Render를 실행할 때 같이 해주게 된다.

 

 

<Engine.cpp 일부>

 

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
void Engine::Update()
{
    GET_SINGLE(Input)->Update();
    GET_SINGLE(Timer)->Update();
 
    Render();
 
    ShowFps();
}
 
void Engine::Render()
{
    RenderBegin();
 
    GET_SINGLE(SceneManager)->Update();
 
    RenderEnd();
}
cs

 

 

  • Update() 함수는 싱글톤을 통하여 Input과 Timer를 받아서 Update 해주는 부분을 확인할 수 있다.
  • 또한 Render() 부분에서 기존에 Game.cpp에서 담당하던 부분을 맡아줬다는 것을 확인할 수 있으며 
  • SceneManager의 싱글톤 객체를 통해 Update()를 실행하고 있음을 확인 가능하다.

 

 

<싱글톤 DECLARE_SINGLE(type)>

 

더보기
1
2
3
4
5
6
7
8
9
10
11
12
#define DECLARE_SINGLE(type)        \
private:                            \
    type() {}                        \
    ~type() {}                        \
public:                                \
    static type* GetInstance()        \
    {                                \
        static type instance;        \
        return &instance;            \
    }                                \
 
#define GET_SINGLE(type)    type::GetInstance()
cs

 

  • Type에 따른 싱글톤을 생성하기 위한 매크로를 생성하는 부분이다.
  • GetInstance() 함수는 Instance를 생성한 뒤 주소를 반환해주는 함수이다.
  • 아래의 GET_SINGLE(type) 매크로는 Type의 GetInstance()를 호출해주는 함수이다.

 

 

<Scene.h>

 

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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;
};
 
 
cs

 

 

  • 기본적인 함수 4가지(Awake, Start, Update, LateUpdate)를 지니고 있다.
  • 또 GameObject를 추가하거나 제거하는 함수를 지니고 있다.
  • Scene에 존재할 GameObject들을 관리하는 Class이기 때문에 GameObject Vector를 지니고 있는것을 확인할 수 있다.

 

 

<Scene.cpp>

 

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "pch.h"
#include "Scene.h"
#include "GameObject.h"
 
void Scene::Awake()
{
    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);
    }
}
cs

 

 

  • GameObject의 기본함수 4가지(Awake, Start, Update, LateUpdate)를 실행시켜주는 함수가 있다.
  • gameObject를 매개변수로 받아 추가와 제거를 수행한다.
  • 제거의 부분에선 Iterator를 사용하여 gameObject Vector 안에 목표 Object를 탐색하고 만약 존재한다면 그것을 제거해주게 된다.

 

<SceneManager.h>

 

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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;
};
 
 
cs

 

 

  • Scene을 세팅하거나 Load,Update 해주기 위한 Class.
  • 단 하나만 존재하면 되기 때문에 싱글톤 객체이다.
  • 어떤 Scene이 활성화 되어있는지를 확인하기 위한 _activeScene이 존재한다.

 

<SceneManager.cpp>

 

더보기

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#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(00.3f);
        material->SetFloat(10.4f);
        material->SetFloat(20.3f);
        material->SetTexture(0, texture);
        meshRenderer->SetMaterial(material);
    }
 
    gameObject->AddComponent(meshRenderer);
 
    scene->AddGameObject(gameObject);
 
    return scene;
}
cs

 

 

  • Update() 함수는 활성화 되어있는 Scene의 Update와 LateUpdate를 호출해주는 역할을 한다.
  • LoadScene은 목표 Scene을 전달받아 그 Scene을 Load 해줌과 동시에 Awake와 Start 함수를 호출해준다.
  • LoadTestScene은 여태까지 Game.cpp가 해주던 것과 동일하며, GameObject를 생성하여 Scene에 Add 해준 뒤 세팅 된 Scene을 반환한다.

 

+ Recent posts