For me
[DirectX12] 7) Component 본문
Unity 에서는 각종 Component를 통해 오브젝트의 성질을 추가해줄 수 있다. ex) Mesh, Collider etc..
Unreal 에서는 빈 깡통의 오브젝트가 아닌 부모클래스의 상속을 받는 오브젝트로 생성을한다.
GameObject
GameObject.h
더보기
#pragma once
#include "Component.h"
#include "Object.h"
class Transform;
class MeshRenderer;
class Camera;
class Light;
class MonoBehaviour;
class ParticleSystem;
class BaseCollider;
class Terrain;
class Animator;
class GameObject : public Object, public enable_shared_from_this<GameObject>
{
public:
GameObject();
virtual ~GameObject();
void Awake();
void Start();
void Update();
void LateUpdate();
void FinalUpdate();
shared_ptr<Component> GetFixedComponent(COMPONENT_TYPE type);
shared_ptr<Transform> GetTransform();
shared_ptr<MeshRenderer> GetMeshRenderer();
shared_ptr<Camera> GetCamera();
shared_ptr<Light> GetLight();
shared_ptr<ParticleSystem> GetParticleSystem();
shared_ptr<Terrain> GetTerrain();
shared_ptr<BaseCollider> GetCollider();
shared_ptr<Animator> GetAnimator();
void AddComponent(shared_ptr<Component> component);
void SetCheckFrustum(bool checkFrustum) { _checkFrustum = checkFrustum; }
bool GetCheckFrustum() { return _checkFrustum; }
void SetLayerIndex(uint8 layer) { _layerIndex = layer; }
uint8 GetLayerIndex() { return _layerIndex; }
void SetStatic(bool flag) { _static = flag; }
bool IsStatic() { return _static; }
private:
array<shared_ptr<Component>, FIXED_COMPONENT_COUNT> _components;
vector<shared_ptr<MonoBehaviour>> _scripts;
bool _checkFrustum = true;
uint8 _layerIndex = 0;
bool _static = true;
};
GameObject.cpp
더보기
#include "pch.h"
#include "GameObject.h"
#include "Transform.h"
#include "MeshRenderer.h"
#include "Camera.h"
#include "Light.h"
#include "MonoBehaviour.h"
#include "ParticleSystem.h"
#include "Terrain.h"
#include "BaseCollider.h"
#include "Animator.h"
GameObject::GameObject() : Object(OBJECT_TYPE::GAMEOBJECT)
{
}
GameObject::~GameObject()
{
}
void GameObject::Awake()
{
for (shared_ptr<Component>& component : _components)
{
if (component)
component->Awake();
}
for (shared_ptr<MonoBehaviour>& script : _scripts)
{
script->Awake();
}
}
void GameObject::Start()
{
for (shared_ptr<Component>& component : _components)
{
if (component)
component->Start();
}
for (shared_ptr<MonoBehaviour>& script : _scripts)
{
script->Start();
}
}
void GameObject::Update()
{
for (shared_ptr<Component>& component : _components)
{
if (component)
component->Update();
}
for (shared_ptr<MonoBehaviour>& script : _scripts)
{
script->Update();
}
}
void GameObject::LateUpdate()
{
for (shared_ptr<Component>& component : _components)
{
if (component)
component->LateUpdate();
}
for (shared_ptr<MonoBehaviour>& script : _scripts)
{
script->LateUpdate();
}
}
void GameObject::FinalUpdate()
{
for (shared_ptr<Component>& component : _components)
{
if (component)
component->FinalUpdate();
}
}
shared_ptr<Component> GameObject::GetFixedComponent(COMPONENT_TYPE type)
{
uint8 index = static_cast<uint8>(type);
assert(index < FIXED_COMPONENT_COUNT);
return _components[index];
}
shared_ptr<Transform> GameObject::GetTransform()
{
shared_ptr<Component> component = GetFixedComponent(COMPONENT_TYPE::TRANSFORM);
return static_pointer_cast<Transform>(component);
}
void GameObject::AddComponent(shared_ptr<Component> component)
{
component->SetGameObject(shared_from_this());
uint8 index = static_cast<uint8>(component->GetType());
if (index < FIXED_COMPONENT_COUNT)
{
_components[index] = component;
}
else
{
_scripts.push_back(dynamic_pointer_cast<MonoBehaviour>(component));
}
}
각종 Get 함수들은 Transform을 제외하곤 생략
일반적인 컴포넌트는 _components[] 에 넣고
monobehaviour는 _scripts에 들어가게 됨.
AddComponent에 SetGameObject(make_shared<GameObject>(game)) 으로 넘긴다면?
새로운 스마터 포인터를 만들게 되면서 make_shared<GameObject>(game)의 레퍼런스가 0이되어 사라지면 문제 발생
따라서, 헤더파일에서 public enabled_shared_from_this<GameObject> 를 추가함
(자기 자신의 weak_ptr 가짐)
이후, 자신에 대한 shared pointer을 넘기고 싶을 때 shared_from_this() 를 넘김
Component
Light, Camera, Transform ... 등 많은 컴포넌트를 관리하는 컴포넌트 클래스 생성
Component.h
더보기
enum class COMPONENT_TYPE : uint8
{
TRANSFORM,
MESH_RENDERER,
CAMERA,
LIGHT,
PARTICLE_SYSTEM,
TERRAIN,
COLLIDER,
ANIMATOR,
// ...
MONO_BEHAVIOUR,
END,
};
enum
{
FIXED_COMPONENT_COUNT = static_cast<uint8>(COMPONENT_TYPE::END) - 1
};
class GameObject;
class Transform;
class Animator;
class MeshRenderer;
class Component : public Object
{
public:
Component(COMPONENT_TYPE type);
virtual ~Component();
public:
virtual void Awake() { }
virtual void Start() { }
virtual void Update() { }
virtual void LateUpdate() { }
virtual void FinalUpdate() { }
public:
COMPONENT_TYPE GetType() { return _type; }
bool IsValid() { return _gameObject.expired() == false; }
shared_ptr<GameObject> GetGameObject();
shared_ptr<Transform> GetTransform();
shared_ptr<MeshRenderer> GetMeshRenderer();
shared_ptr<Animator> GetAnimator();
private:
friend class GameObject;
void SetGameObject(shared_ptr<GameObject> gameObject) { _gameObject = gameObject; }
protected:
COMPONENT_TYPE _type;
weak_ptr<GameObject> _gameObject;
};
COMPONENT_TYPE 이라는 enum class 생성하여 기본적인 컴포넌트 종류 관리
Component.cpp - 간단한 Get 메소드만 구현
더보기
#include "pch.h"
#include "Component.h"
#include "GameObject.h"
#include "MeshRenderer.h"
#include "Animator.h"
Component::Component(COMPONENT_TYPE type) : Object(OBJECT_TYPE::COMPONENT), _type(type)
{
}
Component::~Component()
{
}
shared_ptr<GameObject> Component::GetGameObject()
{
return _gameObject.lock();
}
shared_ptr<Transform> Component::GetTransform()
{
return _gameObject.lock()->GetTransform();
}
shared_ptr<MeshRenderer> Component::GetMeshRenderer()
{
return _gameObject.lock()->GetMeshRenderer();
}
shared_ptr<Animator> Component::GetAnimator()
{
return _gameObject.lock()->GetAnimator();
}
'DirectX12' 카테고리의 다른 글
[DirectX12] 9) Scene (0) | 2023.01.16 |
---|---|
[DirectX12] 8) Material (0) | 2023.01.16 |
[DirectX12] 6) Timer (0) | 2023.01.15 |
[DirectX12] 5) Input (0) | 2023.01.15 |
[DirectX12] 4) Texture Mapping (0) | 2023.01.15 |