- Created EditorConsoleSink (implements ILogSink interface) - EditorConsoleSink stores logs in memory buffer (max 1000 entries) - Added to Debug::Logger in Application::Initialize() - ConsolePanel now reads from EditorConsoleSink via static GetInstance() - Removed separate LogSystem singleton - Removed editor/src/Core/LogEntry.h (no longer needed) Now Editor and Engine share the same Debug::Logger, with ConsolePanel displaying logs via EditorConsoleSink.
551 lines
22 KiB
Markdown
551 lines
22 KiB
Markdown
# UI-Editor GameObject 缺口分析
|
||
|
||
> **基于**:XCEngine渲染引擎架构设计.md
|
||
> **目标**:识别 UI 编辑器 GameObject.h 相对于 Engine 架构设计文档的缺失功能
|
||
> **日期**:2026-03-20
|
||
|
||
---
|
||
|
||
## 架构参考
|
||
|
||
XCEngine 组件系统参考 **Unity 传统架构 (GameObject-Component Pattern)**:
|
||
|
||
- **GameObject**:场景中的实体(UI Editor 中称 `Entity`)
|
||
- **Component**:挂载到 GameObject 的功能模块(变换、渲染器等)
|
||
- **TransformComponent**:每个 GameObject 都有的变换组件,管理位置/旋转/缩放
|
||
- **Scene/SceneManager**:场景管理和场景切换
|
||
|
||
---
|
||
|
||
## Engine 模块现状
|
||
|
||
| 模块 | 状态 | UI Editor 对齐情况 |
|
||
|-----|------|------------------|
|
||
| Core (Event, Types) | ✅ 已实现 | UI 编辑器已复用 `XCEngine::Core::Event<T>` |
|
||
| Debug (Logger, LogLevel, LogEntry) | ✅ 已实现 | UI 编辑器已复用 `XCEngine::Debug::LogLevel` |
|
||
| **Math (Vector3, Quaternion, Matrix4x4, Transform, Color)** | ✅ **已实现** | **可直接复用 Engine Math 类型** |
|
||
| Memory | ✅ 已实现 | |
|
||
| Threading | ✅ 已实现 | |
|
||
| Containers | ✅ 已实现 | |
|
||
| RHI / D3D12 | ✅ 已实现 | UI 编辑器自行实现(与 Engine 技术栈一致) |
|
||
| Resources | ✅ 已实现 | |
|
||
| **Components (GameObject, Component, System)** | ❌ **缺失** | UI 编辑器自行实现,待 Engine 实现后迁移 |
|
||
| **Scene (Scene, SceneManager, SceneLoader, SceneSerializer)** | ❌ **缺失** | UI 编辑器自行实现,待 Engine 实现后迁移 |
|
||
|
||
---
|
||
|
||
## 一、Component 基类缺口
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `transform()` | `TransformComponent& transform() const` | ❌ 缺失 | 返回所在实体的 TransformComponent 引用 |
|
||
| `GetScene()` | `Scene* GetScene() const` | ❌ 缺失 | 返回所属 Scene 指针 |
|
||
| `FixedUpdate()` | `virtual void FixedUpdate()` | ❌ 缺失 | 物理更新(每固定帧) |
|
||
| `LateUpdate()` | `virtual void LateUpdate(float deltaTime)` | ❌ 缺失 | 晚于 Update 执行 |
|
||
| `OnEnable()` | `virtual void OnEnable()` | ❌ 缺失 | 组件启用时调用 |
|
||
| `OnDisable()` | `virtual void OnDisable()` | ❌ 缺失 | 组件禁用时调用 |
|
||
| `friend class` | `friend class GameObject` | ⚠️ 差异 | UI Editor 是 `friend class Entity` |
|
||
|
||
**补充说明**:
|
||
- UI Editor 的 `Component` 需要增加 `TransformComponent*` 获取方法以支持 Inspector 面板的变换编辑
|
||
- Engine 的 `m_gameObject` 在 UI Editor 中对应 `m_entity`
|
||
|
||
---
|
||
|
||
## 二、TransformComponent 缺口
|
||
|
||
### 2.1 World 空间方法
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `GetPosition()` | `XCEngine::Math::Vector3 GetPosition() const` | ❌ 缺失 | 获取世界坐标 |
|
||
| `SetPosition()` | `void SetPosition(const XCEngine::Math::Vector3& position)` | ❌ 缺失 | 设置世界坐标 |
|
||
| `GetRotation()` | `XCEngine::Math::Quaternion GetRotation() const` | ❌ 缺失 | 获取世界旋转 |
|
||
| `SetRotation()` | `void SetRotation(const XCEngine::Math::Quaternion& rotation)` | ❌ 缺失 | 设置世界旋转 |
|
||
| `GetScale()` | `XCEngine::Math::Vector3 GetScale() const` | ❌ 缺失 | 获取世界缩放 |
|
||
| `SetScale()` | `void SetScale(const XCEngine::Math::Vector3& scale)` | ❌ 缺失 | 设置世界缩放 |
|
||
|
||
### 2.2 方向向量
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `GetForward()` | `XCEngine::Math::Vector3 GetForward() const` | ❌ 缺失 | 获取前向向量 |
|
||
| `GetRight()` | `XCEngine::Math::Vector3 GetRight() const` | ❌ 缺失 | 获取右向量 |
|
||
| `GetUp()` | `XCEngine::Math::Vector3 GetUp() const` | ❌ 缺失 | 获取上向量 |
|
||
|
||
### 2.3 矩阵变换
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `GetLocalToWorldMatrix()` | `const XCEngine::Math::Matrix4x4& GetLocalToWorldMatrix() const` | ❌ 缺失 | 本地到世界矩阵(含缓存) |
|
||
| `GetWorldToLocalMatrix()` | `XCEngine::Math::Matrix4x4 GetWorldToLocalMatrix() const` | ❌ 缺失 | 世界到本地矩阵 |
|
||
|
||
### 2.4 父子层级
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `GetParent()` | `TransformComponent* GetParent() const` | ❌ 缺失 | 获取父变换 |
|
||
| `SetParent()` | `void SetParent(TransformComponent* parent, bool worldPositionStays = true)` | ❌ 缺失 | 设置父变换 |
|
||
| `GetChild()` | `TransformComponent* GetChild(int index) const` | ❌ 缺失 | 按索引获取子变换 |
|
||
| `Find()` | `TransformComponent* Find(const String& name) const` | ❌ 缺失 | 按名称查找子变换 |
|
||
| `DetachChildren()` | `void DetachChildren()` | ❌ 缺失 | 断开所有子节点 |
|
||
| `SetAsFirstSibling()` | `void SetAsFirstSibling()` | ❌ 缺失 | 设为第一个同级 |
|
||
| `SetAsLastSibling()` | `void SetAsLastSibling()` | ❌ 缺失 | 设为最后一个同级 |
|
||
| `GetSiblingIndex()` | `int GetSiblingIndex() const` | ❌ 缺失 | 获取同级索引 |
|
||
| `SetSiblingIndex()` | `void SetSiblingIndex(int index)` | ❌ 缺失 | 设置同级索引 |
|
||
|
||
### 2.5 变换操作
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `LookAt(target)` | `void LookAt(const XCEngine::Math::Vector3& target)` | ❌ 缺失 | 朝向目标点 |
|
||
| `LookAt(target, up)` | `void LookAt(const XCEngine::Math::Vector3& target, const XCEngine::Math::Vector3& up)` | ❌ 缺失 | 朝向目标点(指定上向量) |
|
||
| `Rotate(eulers)` | `void Rotate(const XCEngine::Math::Vector3& eulers)` | ❌ 缺失 | 欧拉角旋转 |
|
||
| `Rotate(axis, angle)` | `void Rotate(const XCEngine::Math::Vector3& axis, float angle)` | ❌ 缺失 | 轴角旋转 |
|
||
| `Translate(translation)` | `void Translate(const XCEngine::Math::Vector3& translation)` | ❌ 缺失 | 平移(世界空间) |
|
||
| `Translate(translation, relativeTo)` | `void Translate(const XCEngine::Math::Vector3& translation, Space relativeTo)` | ❌ 缺失 | 平移(指定空间) |
|
||
|
||
### 2.6 点/方向变换
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `TransformPoint()` | `XCEngine::Math::Vector3 TransformPoint(const XCEngine::Math::Vector3& point) const` | ❌ 缺失 | 变换点(含平移旋转) |
|
||
| `InverseTransformPoint()` | `XCEngine::Math::Vector3 InverseTransformPoint(const XCEngine::Math::Vector3& point) const` | ❌ 缺失 | 逆变换点 |
|
||
| `TransformDirection()` | `XCEngine::Math::Vector3 TransformDirection(const XCEngine::Math::Vector3& direction) const` | ❌ 缺失 | 变换方向(仅旋转) |
|
||
| `InverseTransformDirection()` | `XCEngine::Math::Vector3 InverseTransformDirection(const XCEngine::Math::Vector3& direction) const` | ❌ 缺失 | 逆变换方向 |
|
||
|
||
### 2.7 脏标记与缓存
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `SetDirty()` | `void SetDirty()` | ⚠️ 局部 | UI Editor 只有简单 flag,缺少完整缓存机制 |
|
||
| 缓存成员 | `mutable XCEngine::Math::Matrix4x4 m_localToWorldMatrix` 等 | ❌ 缺失 | 矩阵缓存 |
|
||
| 更新方法 | `void UpdateWorldTransform() const` | ❌ 缺失 | 缓存失效时重新计算 |
|
||
|
||
**当前 UI Editor 实现**:
|
||
```cpp
|
||
class TransformComponent : public Component {
|
||
public:
|
||
float position[3] = {0.0f, 0.0f, 0.0f}; // 仅有本地坐标
|
||
float rotation[3] = {0.0f, 0.0f, 0.0f}; // 欧拉角
|
||
float scale[3] = {1.0f, 1.0f, 1.0f}; // 仅有本地缩放
|
||
// 缺少世界空间方法、矩阵缓存、父子指针等
|
||
};
|
||
```
|
||
|
||
**架构设计要求**(应使用 Engine Math 类型):
|
||
```cpp
|
||
class TransformComponent : public Component {
|
||
public:
|
||
// 使用 Engine Math 类型
|
||
XCEngine::Math::Vector3 GetLocalPosition() const { return m_localPosition; }
|
||
void SetLocalPosition(const XCEngine::Math::Vector3& pos) { m_localPosition = pos; SetDirty(); }
|
||
|
||
XCEngine::Math::Quaternion GetLocalRotation() const { return m_localRotation; }
|
||
void SetLocalRotation(const XCEngine::Math::Quaternion& rot) { m_localRotation = rot; SetDirty(); }
|
||
|
||
XCEngine::Math::Vector3 GetLocalScale() const { return m_localScale; }
|
||
void SetLocalScale(const XCEngine::Math::Vector3& sc) { m_localScale = sc; SetDirty(); }
|
||
|
||
private:
|
||
XCEngine::Math::Vector3 m_localPosition = XCEngine::Math::Vector3::Zero();
|
||
XCEngine::Math::Quaternion m_localRotation = XCEngine::Math::Quaternion::Identity();
|
||
XCEngine::Math::Vector3 m_localScale = XCEngine::Math::Vector3::One();
|
||
|
||
TransformComponent* m_parent = nullptr;
|
||
std::vector<TransformComponent*> m_children;
|
||
|
||
mutable XCEngine::Math::Matrix4x4 m_localToWorldMatrix;
|
||
mutable XCEngine::Math::Matrix4x4 m_worldToLocalMatrix;
|
||
mutable XCEngine::Math::Vector3 m_worldPosition;
|
||
mutable XCEngine::Math::Quaternion m_worldRotation;
|
||
mutable XCEngine::Math::Vector3 m_worldScale;
|
||
mutable bool m_dirty = true;
|
||
|
||
void UpdateWorldTransform() const;
|
||
};
|
||
```
|
||
|
||
---
|
||
|
||
## 三、GameObject缺口
|
||
|
||
### 3.1 基础方法
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `GetTransform()` | `TransformComponent& GetTransform()` | ❌ 缺失 | 获取变换组件引用 |
|
||
| `GetScene()` | `Scene* GetScene() const` | ❌ 缺失 | 获取所属场景 |
|
||
|
||
### 3.2 组件查找
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `GetComponentInChildren<T>()` | `T* GetComponentInChildren() const` | ❌ 缺失 | 在子实体中查找组件 |
|
||
| `GetComponentsInChildren<T>()` | `std::vector<T*> GetComponentsInChildren() const` | ❌ 缺失 | 获取所有子实体中的组件 |
|
||
| `GetComponentInParent<T>()` | `T* GetComponentInParent() const` | ❌ 缺失 | 在父实体中查找组件 |
|
||
|
||
### 3.3 父子层级
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `SetParent(parent)` | `void SetParent(Entity* parent)` | ❌ 缺失 | 2参数版本(含 worldPositionStays) |
|
||
| `GetChildren()` | `const std::vector<Entity*>& GetChildren() const` | ❌ 缺失 | 获取子实体列表 |
|
||
| `GetChild()` | `Entity* GetChild(int index) const` | ❌ 缺失 | 按索引获取子实体 |
|
||
|
||
### 3.4 激活状态
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `active` 成员 | `bool active = true` | ❌ 缺失 | 实体激活状态 |
|
||
| `SetActive()` | `void SetActive(bool active)` | ❌ 缺失 | 设置激活状态 |
|
||
| `IsActive()` | `bool IsActive() const` | ❌ 缺失 | 检查激活状态 |
|
||
| `IsActiveInHierarchy()` | `bool IsActiveInHierarchy() const` | ❌ 缺失 | 检查层级中的激活状态 |
|
||
|
||
### 3.5 静态查找
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `Find()` | `static Entity* Find(const String& name)` | ❌ 缺失 | 按名称查找实体 |
|
||
| `FindObjectsOfType()` | `static std::vector<Entity*> FindObjectsOfType()` | ❌ 缺失 | 查找所有实体 |
|
||
| `FindGameObjectsWithTag()` | `static std::vector<Entity*> FindGameObjectsWithTag(const String& tag)` | ❌ 缺失 | 按标签查找 |
|
||
|
||
### 3.6 销毁
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `Destroy()` | `void Destroy()` | ❌ 缺失 | 实例方法销毁(通过 Scene) |
|
||
|
||
---
|
||
|
||
## 四、Scene / SceneManager 缺口
|
||
|
||
### 4.1 Scene 类
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `GetName()` | `const String& GetName() const` | ❌ 缺失 | 获取场景名称 |
|
||
| `SetName()` | `void SetName(const String& name)` | ❌ 缺失 | 设置场景名称 |
|
||
| `CreateGameObject(name, parent)` | `Entity* CreateGameObject(const String& name, Entity* parent)` | ❌ 缺失 | 带父实体创建 |
|
||
| `GetRootGameObjects()` | `std::vector<Entity*> GetRootGameObjects() const` | ❌ 缺失 | 获取根实体列表 |
|
||
| `Find()` | `Entity* Find(const String& name) const` | ❌ 缺失 | 查找实体 |
|
||
| `FindGameObjectWithTag()` | `Entity* FindGameObjectWithTag(const String& tag) const` | ❌ 缺失 | 按标签查找 |
|
||
| `FindObjectsOfType<T>()` | `std::vector<T*> FindObjectsOfType() const` | ❌ 缺失 | 模板查找 |
|
||
| `FindObjectOfType<T>()` | `T* FindObjectOfType() const` | ❌ 缺失 | 查找单个 |
|
||
| `IsActive()` | `bool IsActive() const` | ❌ 缺失 | 场景激活状态 |
|
||
| `SetActive()` | `void SetActive(bool active)` | ❌ 缺失 | 设置激活状态 |
|
||
| `Load()` | `void Load(const String& filePath)` | ❌ 缺失 | 加载场景 |
|
||
| `Save()` | `void Save(const String& filePath)` | ❌ 缺失 | 保存场景 |
|
||
| `Update()` | `void Update(float deltaTime)` | ❌ 缺失 | 场景更新 |
|
||
| `FixedUpdate()` | `void FixedUpdate(float fixedDeltaTime)` | ❌ 缺失 | 物理更新 |
|
||
| `LateUpdate()` | `void LateUpdate(float deltaTime)` | ❌ 缺失 | 晚更新 |
|
||
|
||
**当前 UI Editor 缺失 Scene 概念**,所有实体都在 SceneManager 全局管理。
|
||
|
||
### 4.2 SceneManager 类
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| `CreateScene()` | `Scene* CreateScene(const String& name)` | ❌ 缺失 | 创建场景 |
|
||
| `LoadScene()` | `void LoadScene(const String& filePath)` | ❌ 缺失 | 同步加载 |
|
||
| `LoadSceneAsync()` | `void LoadSceneAsync(const String& filePath, std::function<void(Scene*)> callback)` | ❌ 缺失 | 异步加载 |
|
||
| `UnloadScene(scene)` | `void UnloadScene(Scene* scene)` | ❌ 缺失 | 卸载场景 |
|
||
| `UnloadScene(name)` | `void UnloadScene(const String& sceneName)` | ❌ 缺失 | 按名称卸载 |
|
||
| `SetActiveScene(scene)` | `void SetActiveScene(Scene* scene)` | ❌ 缺失 | 设置激活场景 |
|
||
| `SetActiveScene(name)` | `void SetActiveScene(const String& sceneName)` | ❌ 缺失 | 按名称设置 |
|
||
| `GetActiveScene()` | `Scene* GetActiveScene() const` | ❌ 缺失 | 获取激活场景 |
|
||
| `GetScene(name)` | `Scene* GetScene(const String& name) const` | ❌ 缺失 | 按名称获取场景 |
|
||
| `GetAllScenes()` | `std::vector<Scene*> GetAllScenes() const` | ❌ 缺失 | 获取所有场景 |
|
||
| `OnSceneLoaded` | `Event<Scene*>` | ⚠️ 差异 | UI Editor 是 `OnSceneChanged` |
|
||
| `OnSceneUnloaded` | `Event<Scene*>` | ❌ 缺失 | 场景卸载事件 |
|
||
| `OnActiveSceneChanged` | `Event<Scene*>` | ❌ 缺失 | 激活场景变更事件 |
|
||
|
||
### 4.3 GameObjectBuilder 类
|
||
|
||
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
||
|------------|---------|------|------|
|
||
| 完整类 | `class GameObjectBuilder` | ❌ 缺失 | 实体创建辅助类 |
|
||
|
||
---
|
||
|
||
## 五、实现优先级
|
||
|
||
### P0 - 核心缺失(必须实现)
|
||
|
||
| 模块 | 原因 | 涉及文件 |
|
||
|-----|------|---------|
|
||
| TransformComponent 世界空间方法 | Editor 变换编辑基础 | GameObject.h |
|
||
| Entity `GetTransform()` | Inspector 面板需要 | GameObject.h |
|
||
| Component `transform()` | 组件访问变换 | GameObject.h |
|
||
|
||
**依赖**:Engine Math 模块 ✅ 已实现,可直接使用 `XCEngine::Math::Vector3` / `Quaternion` / `Matrix4x4`。
|
||
|
||
### P1 - 功能完整(应该实现)
|
||
|
||
| 模块 | 原因 | 涉及文件 |
|
||
|-----|------|---------|
|
||
| TransformComponent 矩阵缓存 | 性能优化 | GameObject.h |
|
||
| TransformComponent 父子指针 | 层级操作 | GameObject.h |
|
||
| Entity 激活状态 | 运行时状态 | GameObject.h |
|
||
| Entity 父子层级操作 | 层级编辑 | GameObject.h |
|
||
| Scene 概念 | 多场景支持 | SceneManager.h |
|
||
| SceneManager 多场景管理 | 场景隔离 | SceneManager.h |
|
||
|
||
### P2 - 高级功能(可选实现)
|
||
|
||
| 模块 | 原因 | 涉及文件 |
|
||
|-----|------|---------|
|
||
| Scene 序列化/反序列化 | 持久化 | SceneManager.h |
|
||
| TransformComponent 点/方向变换 | Gizmos 操作 | GameObject.h |
|
||
| SceneManager 异步加载 | 体验优化 | SceneManager.h |
|
||
| Entity 静态查找 | Editor 操作 | GameObject.h |
|
||
|
||
---
|
||
|
||
## 六、数据结构对齐表
|
||
|
||
### 6.1 当前 UI Editor vs 架构设计
|
||
|
||
| 项目 | UI Editor 当前 | 架构设计 | 对齐建议 |
|
||
|-----|--------------|---------|---------|
|
||
| 实体内组件存储 | `vector<unique_ptr<Component>>` | `vector<unique_ptr<Component>>` | ✅ 已对齐 |
|
||
| 变换类型 | `float[3]` 数组 | `XCEngine::Math::Vector3` / `Quaternion` | ⚠️ **应改用 Engine Math** |
|
||
| 父子关系 | `EntityID` (uint64) | `Entity*` 指针 | ⚠️ UI 用 ID,Engine 用指针 |
|
||
| 场景管理 | 全局单例 SceneManager | 多 Scene + SceneManager | ❌ 需要重构 |
|
||
|
||
### 6.2 命名差异
|
||
|
||
| UI Editor | Engine 架构设计 | 说明 |
|
||
|-----------|---------------|------|
|
||
| `Entity` | `GameObject` | UI Editor 使用 Entity 避免与 std 冲突 |
|
||
| `EntityID` | `uint64_t` | UI Editor 自定义类型别名 |
|
||
| `INVALID_ENTITY_ID` | N/A | UI Editor 自定义常量 |
|
||
| `ComponentRegistry` | `ComponentTypeRegistry` | 功能相似,命名不同 |
|
||
|
||
### 6.3 类型复用情况
|
||
|
||
| Engine 类型 | UI Editor 现状 | 建议 |
|
||
|-----------|--------------|------|
|
||
| `XCEngine::Math::Vector3` | UI Editor 用 `float[3]` | **直接复用** |
|
||
| `XCEngine::Math::Quaternion` | UI Editor 用 `float[3]` (欧拉角) | **直接复用**,但欧拉角存储可保留 |
|
||
| `XCEngine::Math::Matrix4x4` | 无 | **直接复用** |
|
||
| `XCEngine::Core::Event<T>` | ✅ 已复用 | 保持 |
|
||
| `XCEngine::Debug::LogLevel` | ✅ 已复用 | 保持 |
|
||
|
||
---
|
||
|
||
## 七、依赖关系分析
|
||
|
||
```
|
||
实现优先级 - 依赖链:
|
||
|
||
P0: TransformComponent 世界空间
|
||
│
|
||
├── 需要: XCEngine::Math::Vector3 ✅ 已实现
|
||
├── 需要: XCEngine::Math::Quaternion ✅ 已实现
|
||
├── 需要: XCEngine::Math::Matrix4x4 ✅ 已实现
|
||
└── 影响: Entity::GetTransform()
|
||
|
||
P0: Component::transform()
|
||
│
|
||
└── 依赖: Entity::GetTransform()
|
||
|
||
P1: TransformComponent 父子指针
|
||
│
|
||
├── 需要: TransformComponent* parent
|
||
├── 需要: vector<TransformComponent*> children
|
||
└── 影响: Entity 父子操作
|
||
|
||
P1: Entity 激活状态
|
||
│
|
||
├── 需要: active 成员
|
||
└── 影响: IsActiveInHierarchy()
|
||
|
||
P1: Scene 多场景
|
||
│
|
||
├── 需要: Scene 类
|
||
├── 需要: Scene::CreateGameObject()
|
||
└── 影响: SceneManager 重构
|
||
```
|
||
|
||
---
|
||
|
||
## 八、与 Unity 架构的对照
|
||
|
||
### Unity 传统架构 (GameObject-Component)
|
||
|
||
```
|
||
Scene
|
||
└── GameObject ("MyEntity")
|
||
├── Transform
|
||
├── MeshRenderer
|
||
└── (其他组件...)
|
||
|
||
GameObject.GetComponent<T>() → Entity.GetComponent<T>()
|
||
GameObject.transform → Entity.GetTransform()
|
||
GameObject.SetActive(bool) → 缺失
|
||
GameObject.Find("name") → 缺失
|
||
Scene.GetRootGameObjects() → 缺失
|
||
SceneManager.GetActiveScene() → 缺失
|
||
```
|
||
|
||
### UI Editor 当前实现
|
||
|
||
```
|
||
SceneManager (全局单例)
|
||
└── m_entities (unordered_map<EntityID, Entity>)
|
||
└── Entity ("MyEntity")
|
||
├── id, name, parent, children
|
||
├── components (vector<unique_ptr<Component>>)
|
||
└── selected
|
||
|
||
Entity.AddComponent<T>() → ✅ 已实现
|
||
Entity.GetComponent<T>() → ✅ 已实现
|
||
Entity.GetTransform() → ❌ 缺失
|
||
TransformComponent 世界空间方法 → ❌ 缺失
|
||
```
|
||
|
||
---
|
||
|
||
## 九、附录:当前 GameObject.h 完整内容
|
||
|
||
```cpp
|
||
// ui_editor/src/Core/GameObject.h 当前实现
|
||
|
||
#pragma once
|
||
|
||
#include <string>
|
||
#include <vector>
|
||
#include <memory>
|
||
#include <unordered_map>
|
||
#include <functional>
|
||
#include <cstdint>
|
||
|
||
#include <XCEngine/Core/Event.h>
|
||
|
||
namespace UI {
|
||
|
||
using EntityID = uint64_t;
|
||
constexpr EntityID INVALID_ENTITY_ID = 0;
|
||
|
||
class Component {
|
||
public:
|
||
virtual ~Component() = default;
|
||
virtual std::string GetName() const = 0;
|
||
|
||
virtual void Awake() {}
|
||
virtual void Start() {}
|
||
virtual void Update(float deltaTime) {}
|
||
virtual void OnDestroy() {}
|
||
|
||
class Entity* GetEntity() const { return m_entity; }
|
||
bool IsEnabled() const { return m_enabled; }
|
||
void SetEnabled(bool enabled) { m_enabled = enabled; }
|
||
|
||
protected:
|
||
class Entity* m_entity = nullptr;
|
||
bool m_enabled = true;
|
||
|
||
friend class Entity;
|
||
};
|
||
|
||
class TransformComponent : public Component {
|
||
public:
|
||
float position[3] = {0.0f, 0.0f, 0.0f};
|
||
float rotation[3] = {0.0f, 0.0f, 0.0f};
|
||
float scale[3] = {1.0f, 1.0f, 1.0f};
|
||
|
||
std::string GetName() const override { return "Transform"; }
|
||
};
|
||
|
||
class MeshRendererComponent : public Component {
|
||
public:
|
||
std::string materialName = "Default-Material";
|
||
std::string meshName = "";
|
||
|
||
std::string GetName() const override { return "Mesh Renderer"; }
|
||
};
|
||
|
||
class Entity {
|
||
public:
|
||
EntityID id = INVALID_ENTITY_ID;
|
||
std::string name;
|
||
EntityID parent = INVALID_ENTITY_ID;
|
||
std::vector<EntityID> children;
|
||
std::vector<std::unique_ptr<Component>> components;
|
||
bool selected = false;
|
||
|
||
template<typename T, typename... Args>
|
||
T* AddComponent(Args&&... args) {
|
||
auto comp = std::make_unique<T>(std::forward<Args>(args)...);
|
||
comp->m_entity = this;
|
||
T* ptr = comp.get();
|
||
components.push_back(std::move(comp));
|
||
return ptr;
|
||
}
|
||
|
||
template<typename T>
|
||
T* GetComponent() {
|
||
for (auto& comp : components) {
|
||
if (auto casted = dynamic_cast<T*>(comp.get())) {
|
||
return casted;
|
||
}
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
template<typename T>
|
||
std::vector<T*> GetComponents() {
|
||
std::vector<T*> result;
|
||
for (auto& comp : components) {
|
||
if (auto casted = dynamic_cast<T*>(comp.get())) {
|
||
result.push_back(casted);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
};
|
||
|
||
using ComponentInspectorFn = std::function<void(Component*)>;
|
||
|
||
struct ComponentInspectorInfo {
|
||
std::string name;
|
||
ComponentInspectorFn renderFn;
|
||
};
|
||
|
||
class ComponentRegistry {
|
||
public:
|
||
static ComponentRegistry& Get() {
|
||
static ComponentRegistry instance;
|
||
return instance;
|
||
}
|
||
|
||
template<typename T>
|
||
void RegisterComponent(const std::string& name, ComponentInspectorFn inspectorFn) {
|
||
m_inspectors[name] = {name, inspectorFn};
|
||
m_factories[name] = []() -> std::unique_ptr<Component> {
|
||
return std::make_unique<T>();
|
||
};
|
||
}
|
||
|
||
ComponentInspectorInfo* GetInspector(const std::string& name) {
|
||
auto it = m_inspectors.find(name);
|
||
if (it != m_inspectors.end()) {
|
||
return &it->second;
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
private:
|
||
ComponentRegistry() = default;
|
||
std::unordered_map<std::string, ComponentInspectorInfo> m_inspectors;
|
||
std::unordered_map<std::string, std::function<std::unique_ptr<Component>()>> m_factories;
|
||
};
|
||
|
||
} // namespace UI
|
||
```
|
||
|
||
---
|
||
|
||
**文档结束**
|