[DX] Component

vector·2025년 11월 15일

유니티 엔진과 비슷하게 기존의 코드를 수정하고 새로운 클래스 추가

추후 GameObject는 보여주는 기능 뿐 아니라 다양한 기능을 가지게 될 것이기에 GameObject에 구현되어 있는 렌더링 부분을 Component로 이동할 예정

Component

Component란

  • 모든 게임 오브젝트 기능의 최소 단위
  • 유니티/언리얼의 컴포넌트 모델과 동일
    -> 이동, 렌더링, 카메라, 에니메이션 등 모든 기능은 Component로 구성
  • GameObject가 여러 Component를 붙여서 "행동 + 시각적 기능"을 가짐
  • 관련 클래스 : GameObject, Transform, Camera, MeshRenderer, Animator, MonoBehaviour 등

코드

  • Component에 유니티 엔진 방식대로 Awake, Start, Update등의 기본 함수 추가 및 상속 받는 모든 클래스에서 사용할 수 있도록 가상함수 사용
  • 오브젝트당 하나씩만 추가할 수 있는 고정적인 개수의 ComponentEnum 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;
};

MonoBehaviour

  • 개발자가 직접 작성하는 스크립트의 기반 클래스
  • 컴포넌트지만 "사용자 로직 용도"
  • Unity의 MonoBehaviour과 동일한 개념
  • 현재는 별다른 기능은 없고 기본적인 함수만 사용
  • 스크립트 추가시 GameObject의 Update 루프에 자동 포함
#pragma once
#include "Component.h"
class MonoBehaviour : public Component
{
	using Super = Component;

public:
	MonoBehaviour();
	~MonoBehaviour();

	virtual void Awake() override;
	virtual void Update() override;
};

알아두면 좋은 포인트

  • 게임 오브젝트의 "행동/로직"은 대부분 MonoBehaviour 상속으로 구현
  • Transform, Animator, MeshRenderer는 "엔진 기능" / MonoBehaviour는 "유저 로직 기능"
  • Transform = 위치 / MeshRenderer = 그리는 기능 / Animator = 애니메이션 재생 / MonoBehaviour = 스크립트 (움직임, 공격, AI등)

Camera

  • 씬을 렌더링할 때 기준점이 되는 시점/행렬을 제공
  • View 행렬(카메라 위치/회전)rhk Proejction행렬(투영방식)을 계신하 RenderManager에 전달
  • 3D 엔진 필수 요소
#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);
	}
}
profile
게임 클라이언트 프로그래머 준비중 (공부 및 기록용)

0개의 댓글