게임제작기법연구

게임제작기법연구 6주차

ckhyeok 2020. 5. 19. 15:23

GameEngine 구조를 구성하기 위해 각각 GameObject, Resource라는 필수 핵심 클래스를 관리하는 해당 컨테이너를 선택하십시오. 그 이유는 전체 게임 엔진 프로세스 중에 각 중요한 함수 호출에서 발생한 실제 작업 (단일 항목 검색, 삽입 / 삭제, 트래버스)을 기반으로해야합니다.

STL map, unordered_map, Vector의 장단점 및 특징은 지난 포스팅에 블로깅 되어있습니다.

에디터작업(삽입삭제 빈번) -> 저장 -> 씬로딩-> 리소스로딩 -> 루프 (Update, Drawcall)

 

게임오브젝트 : Vector를 선택했습니다. 그 이유는 렌더링 처리를 하려면 다 돌아야 하는데 특정 물체를 집어서 가는게 아니라 처음부터 끝까지 다 돌아야 하기 때문입니다. 그렇기 때문에 삽입, 삭제, 탐색이 모두 O(n) 인 벡터를 골랐습니다.

 

리소스 : unodered_map을 선택했습니다. 그 이유는 씬로딩은 게임오브젝트를 로딩하는것이며 그것들은 위에서 말했듯

Vector로 관리가 될 것입니다. 또한, 그것들을 하나씩 순차적으로 로딩할 때 그것들이 가지고 있는 리소스가 무엇인지를 판단 한 후 그 안에 있는 포인트 정보(Key값)만 로딩하면 됩니다. 그러므로 에디터가 아닌 한 Key값이 정렬되어야 할 필요가 없기 때문에  비정렬에서 빠른 unordered_map을 선택했습니다. 

 

Tip) 에디터에선 정렬되서 보여야하기 때문에 map이 최고의 성능을 발휘하지만 굳이 정렬 될 필요가 없다면       

      unordered_map을 써도 문제는 없다.

C ++ 언어에서 구조체와 클래스의 차이점에 대한 간단한 보고서를 작성하십시오.

구조체와 클래스의 차이점은 바로 접근법의 차이입니다. C++에서는 접근제어 지시자가 3가지 존재합니다.

어디서든 허용하는 public, 상속관계에서 허용하는 protected, 클래스 내에서만 허용하는 private가 있습니다.

구조체의 경우는 위 3가지를 따로 선언하지 않으면 모두 public으로 선언되며,

클래스의 경우는 위 3가지를 따로 선언하지 않으면 모두 private으로 선언됩니다.

 

Tip) C# 기준 Struct는 value type으로 stack memory에 생성되며, Class는 reference type으로 heep memory에 생성됨.

Math 라이브러리가 클래스 대신 struct를 사용하여 객체를 정의하는 이유를 생각하십시오.

제 생각에는 Class가 Struct 보다 더 우월하며 참조 타입인 클래스는 힙에 생성돼서 스택도 덜 차지하고 또한 상속과 다형성도 지원하기 때문에 Class를 쓰는것이 더 좋다고 생각이 듭니다. 하지만 Math Library에서는 Class대신 Struct를 사용했는데 그 이유유를 생각해보자면, Class의 장점들인 상속과 다형성이 필요없기 때문이 아닐까? 라고 생각합니다. 또한 매번 생성자를 정의하고 변수가 필요할 떄 마다 new를 호출하는 것은 매우 번거롭기 때문이지 않을까?라고 추측합니다.

다음 링크를 참조하여 프로그래밍 로직을 구현하십시오. https://www.notion.so/ideugu/6-fd8fa5b2889848fcbd9b8b77e71de7d1

#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>

struct Vector2
{
	Vector2() = default;
	float X = 0.f;
	float Y = 0.f;
};

struct GameObjectMock
{
	GameObjectMock(const std::string& InName) : Name(InName)
	{
		Hash = std::hash<std::string>()(Name);
	}
	std::size_t Hash;
	std::string Name;
	Vector2 v;
		
	// 비교 연산자 ==, != 추가
	inline bool operator==(const GameObjectMock& hs)
	{
		return Hash == hs.Hash;
	}
	inline bool operator!=(const GameObjectMock& hs)
	{
		return Hash != hs.Hash;
	}
};

struct OrderByHash
{
	inline bool operator () (const GameObjectMock& _left, const GameObjectMock& _right)
	{
		return _left.Hash < _right.Hash;
	}

	inline bool operator () (const GameObjectMock& _left, const std::hash<std::string>::result_type& _right) const
	{
		return _left.Hash < _right;
	}
};

int main()
{
	const auto startTime = std::chrono::high_resolution_clock::now();

	std::vector<GameObjectMock> sorted;
	std::vector<GameObjectMock> sizeCheck = { GameObjectMock("11"), GameObjectMock("111"), GameObjectMock("11111"), GameObjectMock("10"), GameObjectMock("1111") };
	for (const GameObjectMock& n : sizeCheck)
	{
		auto it = std::lower_bound(sorted.begin(), sorted.end(), n, OrderByHash());

		if (it != sorted.end() && *it != n)
		{
			sorted.insert(it, n);
		}
		else if (it != sorted.end() && *it == n)
		{
			// dup!!
			continue;
		}
		else if (it == sorted.end())
		{
			sorted.push_back(n);
		}
	}

	std::chrono::high_resolution_clock::duration elapsedTime = std::chrono::high_resolution_clock::now() - startTime;
	std::cout << std::endl;
	std::cout << "sorted_vector Time: " << std::chrono::duration_cast<std::chrono::nanoseconds>(elapsedTime).count() << " ns" << std::endl;

	for_each(sorted.begin(), sorted.end(), [](GameObjectMock x) { std::cout << std::hex << x.Name << " "; });
	std::cout << std::endl;
}

Notion에 있는 기존 코드에서 int로 sort 된 vector를 GameObjectMock으로 바꾸는 과정에서 아래와 같은 문제가 발생하여 비교연산자를 추가해주었습니다.

 

 

결과창

'게임제작기법연구' 카테고리의 다른 글

게임제작기법연구 8주차  (0) 2020.06.02
게임제작기법연구 7주차  (0) 2020.05.26
게임제작기법연구 5주차  (0) 2020.05.12
게임제작기법연구 4주차  (0) 2020.05.05
게임제작기법연구 2주차  (0) 2020.04.09