#include "Components/GameObject.h" #include "Components/TransformComponent.h" #include "Scene/Scene.h" namespace XCEngine { namespace Components { GameObject::ID GameObject::s_nextID = 1; GameObject::GameObject() : m_name("GameObject") { m_id = s_nextID++; m_transform = new TransformComponent(); m_transform->m_gameObject = this; } GameObject::GameObject(const std::string& name) : m_name(name) { m_id = s_nextID++; m_transform = new TransformComponent(); m_transform->m_gameObject = this; } GameObject::~GameObject() { if (m_transform) { delete m_transform; m_transform = nullptr; } m_components.clear(); } std::unordered_map& GameObject::GetGlobalRegistry() { static std::unordered_map registry; return registry; } void GameObject::SetParent(GameObject* parent) { SetParent(parent, true); } void GameObject::SetParent(GameObject* parent, bool worldPositionStays) { if (m_parent == parent) { return; } Math::Vector3 worldPos = worldPositionStays ? GetTransform()->GetPosition() : GetTransform()->GetLocalPosition(); Math::Quaternion worldRot = worldPositionStays ? GetTransform()->GetRotation() : GetTransform()->GetLocalRotation(); Math::Vector3 worldScale = worldPositionStays ? GetTransform()->GetScale() : GetTransform()->GetLocalScale(); if (m_parent) { auto& siblings = m_parent->m_children; siblings.erase(std::remove(siblings.begin(), siblings.end(), this), siblings.end()); } m_parent = parent; if (m_parent) { m_parent->m_children.push_back(this); } if (worldPositionStays) { GetTransform()->SetPosition(worldPos); GetTransform()->SetRotation(worldRot); GetTransform()->SetScale(worldScale); } GetTransform()->SetDirty(); } GameObject* GameObject::GetChild(size_t index) const { if (index < m_children.size()) { return m_children[index]; } return nullptr; } std::vector GameObject::GetChildren() const { return m_children; } void GameObject::DetachChildren() { for (auto* child : m_children) { if (child) { child->m_parent = nullptr; } } m_children.clear(); } void GameObject::SetActive(bool active) { if (m_activeSelf != active) { m_activeSelf = active; if (m_parent == nullptr || m_parent->IsActiveInHierarchy()) { } } } bool GameObject::IsActiveInHierarchy() const { if (!m_activeSelf) { return false; } if (m_parent) { return m_parent->IsActiveInHierarchy(); } return true; } GameObject* GameObject::Find(const std::string& name) { auto& registry = GetGlobalRegistry(); for (auto& pair : registry) { if (pair.second->GetName() == name) { return pair.second; } } return nullptr; } std::vector GameObject::FindObjectsOfType() { auto& registry = GetGlobalRegistry(); std::vector result; for (auto& pair : registry) { result.push_back(pair.second); } return result; } std::vector GameObject::FindGameObjectsWithTag(const std::string& tag) { auto& registry = GetGlobalRegistry(); std::vector result; for (auto& pair : registry) { if (pair.second->GetName() == tag) { result.push_back(pair.second); } } return result; } void GameObject::Awake() { for (auto& comp : m_components) { comp->Awake(); } } void GameObject::Start() { for (auto& comp : m_components) { if (comp->IsEnabled()) { comp->Start(); } } } void GameObject::Update(float deltaTime) { for (auto& comp : m_components) { if (comp->IsEnabled()) { comp->Update(deltaTime); } } } void GameObject::FixedUpdate() { for (auto& comp : m_components) { if (comp->IsEnabled()) { comp->FixedUpdate(); } } } void GameObject::LateUpdate(float deltaTime) { for (auto& comp : m_components) { if (comp->IsEnabled()) { comp->LateUpdate(deltaTime); } } } void GameObject::OnDestroy() { for (auto& comp : m_components) { comp->OnDestroy(); } } void GameObject::Destroy() { OnDestroy(); if (m_scene) { m_scene->DestroyGameObject(this); } } } // namespace Components } // namespace XCEngine