유니티 엔진과 비슷하게 기존의 코드를 수정하고 새로운 클래스 추가
추후 GameObject는 보여주는 기능 뿐 아니라 다양한 기능을 가지게 될 것이기에 GameObject에 구현되어 있는 렌더링 부분을 Component로 이동할 예정
Component를 Enum Class(Transform, MeshRenderer, Camera, Animator, Script, ...)로 선언해주고 개수를 enum(FIXED_COMPONENT_COUNT)으로 저장Component.h
#pragma once
class GameObject;
class Transform;
enum class ComponentType : uint8
{
Transform,
MeshRenderer,
Camera,
Animator,
// ...
Script,
End,
};
enum
{
FIXED_COMPONENT_COUNT = static_cast<uint8>(ComponentType::End) - 1
};
class Component
{
public:
Component(ComponentType type);
virtual ~Component();
// 컴포넌트 라이프사이클(Unity 형식)
virtual void Awake() { } // 생성 직후 1회
virtual void Start() { } // 모든 Awake가 끝난 후 1회
virtual void Update() { } // 프레임 마다
virtual void LateUpdate() { } // 프레임 마다
virtual void FixedUpdate() { } // 고정 주기 (물리)
public:
// 소유 GameObject 접근
shared_ptr<GameObject> GetGameObject(); {return _gameObject.lock();}
// 편리함을 위한 헬퍼
shared_ptr<Transform> GetTransform(); { return _gameObject.lock()->GetTransform(); }
ComponentType GetType() { return _type; }
private:
friend class GameObject;
void SetGameObject(shared_ptr<GameObject> gameObject) { _gameObject = gameObject; }
protected:
ComponentType _type;
weak_ptr<GameObject> _gameObject;
};
#pragma once
#include "Component.h"
class MonoBehaviour : public Component
{
using Super = Component;
public:
MonoBehaviour();
~MonoBehaviour();
virtual void Awake() override;
virtual void Update() override;
};
#pragma once
#include "Component.h"
enum class ProjectionType
{
Perspective, // 원근 투형 (3d, 원근법에 따라 크기 차이)
Orthographic, // 직교 투영 (2d, 화면에 들어온 모든 오브젝트는 같은 크기)
};
class Camera : public Component
{
using Super = Component;
public:
Camera();
~Camera();
virtual void Update() override;
void SetProjectionType(ProjectionType type) { _type = type; }
ProjectionType GetProjetctionType() { return _type; }
void UpdateMatrix();
private:
ProjectionType _type = ProjectionType::Orthographic;
public:
static Matrix S_MatView;
static Matrix S_MatProjection;
};
#include "pch.h"
#include "Camera.h"
Matrix Camera::S_MatView = Matrix::Identity;
Matrix Camera::S_MatProjection = Matrix::Identity;
Camera::Camera() : Super(ComponentType::Camera) { }
Camera::~Camera() { }
void Camera::Update()
{
UpdateMatrix();
}
void Camera::UpdateMatrix()
{
Vec3 eyePosition = GetTransform()->GetPosition();
Vec3 focusPosition = eyePosition + GetTransform()->GetLook();
Vec3 upDirection = GetTransform()->GetUp();
S_MatView = ::XMMatrixLookAtLH(eyePosition, focusPosition, upDirection);
//S_MatView = GetTransform()->GetWorldMatrix().Invert();
if (_type == ProjectionType::Perspective)
{
S_MatProjection = ::XMMatrixPerspectiveFovLH(XM_PI / 4.f, 800.f / 600.f, 1.f, 100.f);
}
else
{
S_MatProjection = XMMatrixOrthographicLH(8, 6, 0.f, 1.f);
}
}