462 lines
18 KiB
Markdown
462 lines
18 KiB
Markdown
|
|
# UI-Editor GameObject 缺口分析
|
|||
|
|
|
|||
|
|
> **基于**:XCEngine渲染引擎架构设计.md
|
|||
|
|
> **目标**:识别 UI 编辑器 GameObject.h 相对于 Engine 架构设计文档的缺失功能
|
|||
|
|
> **日期**:2026-03-20
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、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()` | `Vector3 GetPosition() const` | ❌ 缺失 | 获取世界坐标 |
|
|||
|
|
| `SetPosition()` | `void SetPosition(const Vector3& position)` | ❌ 缺失 | 设置世界坐标 |
|
|||
|
|
| `GetRotation()` | `Quaternion GetRotation() const` | ❌ 缺失 | 获取世界旋转 |
|
|||
|
|
| `SetRotation()` | `void SetRotation(const Quaternion& rotation)` | ❌ 缺失 | 设置世界旋转 |
|
|||
|
|
| `GetScale()` | `Vector3 GetScale() const` | ❌ 缺失 | 获取世界缩放 |
|
|||
|
|
| `SetScale()` | `void SetScale(const Vector3& scale)` | ❌ 缺失 | 设置世界缩放 |
|
|||
|
|
|
|||
|
|
### 2.2 方向向量
|
|||
|
|
|
|||
|
|
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
|||
|
|
|------------|---------|------|------|
|
|||
|
|
| `GetForward()` | `Vector3 GetForward() const` | ❌ 缺失 | 获取前向向量 |
|
|||
|
|
| `GetRight()` | `Vector3 GetRight() const` | ❌ 缺失 | 获取右向量 |
|
|||
|
|
| `GetUp()` | `Vector3 GetUp() const` | ❌ 缺失 | 获取上向量 |
|
|||
|
|
|
|||
|
|
### 2.3 矩阵变换
|
|||
|
|
|
|||
|
|
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
|||
|
|
|------------|---------|------|------|
|
|||
|
|
| `GetLocalToWorldMatrix()` | `const Matrix4x4& GetLocalToWorldMatrix() const` | ❌ 缺失 | 本地到世界矩阵(含缓存) |
|
|||
|
|
| `GetWorldToLocalMatrix()` | `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 Vector3& target)` | ❌ 缺失 | 朝向目标点 |
|
|||
|
|
| `LookAt(target, up)` | `void LookAt(const Vector3& target, const Vector3& up)` | ❌ 缺失 | 朝向目标点(指定上向量) |
|
|||
|
|
| `Rotate(eulers)` | `void Rotate(const Vector3& eulers)` | ❌ 缺失 | 欧拉角旋转 |
|
|||
|
|
| `Rotate(axis, angle)` | `void Rotate(const Vector3& axis, float angle)` | ❌ 缺失 | 轴角旋转 |
|
|||
|
|
| `Translate(translation)` | `void Translate(const Vector3& translation)` | ❌ 缺失 | 平移(世界空间) |
|
|||
|
|
| `Translate(translation, relativeTo)` | `void Translate(const Vector3& translation, Space relativeTo)` | ❌ 缺失 | 平移(指定空间) |
|
|||
|
|
|
|||
|
|
### 2.6 点/方向变换
|
|||
|
|
|
|||
|
|
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
|||
|
|
|------------|---------|------|------|
|
|||
|
|
| `TransformPoint()` | `Vector3 TransformPoint(const Vector3& point) const` | ❌ 缺失 | 变换点(含平移旋转) |
|
|||
|
|
| `InverseTransformPoint()` | `Vector3 InverseTransformPoint(const Vector3& point) const` | ❌ 缺失 | 逆变换点 |
|
|||
|
|
| `TransformDirection()` | `Vector3 TransformDirection(const Vector3& direction) const` | ❌ 缺失 | 变换方向(仅旋转) |
|
|||
|
|
| `InverseTransformDirection()` | `Vector3 InverseTransformDirection(const Vector3& direction) const` | ❌ 缺失 | 逆变换方向 |
|
|||
|
|
|
|||
|
|
### 2.7 脏标记与缓存
|
|||
|
|
|
|||
|
|
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|
|||
|
|
|------------|---------|------|------|
|
|||
|
|
| `SetDirty()` | `void SetDirty()` | ⚠️ 局部 | UI Editor 只有简单 flag,缺少完整缓存机制 |
|
|||
|
|
| 缓存成员 | `mutable 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}; // 仅有本地缩放
|
|||
|
|
// 缺少世界空间方法、矩阵缓存、父子指针等
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**架构设计要求**:
|
|||
|
|
```cpp
|
|||
|
|
class TransformComponent : public Component {
|
|||
|
|
private:
|
|||
|
|
Vector3 m_localPosition = Vector3::Zero();
|
|||
|
|
Quaternion m_localRotation = Quaternion::Identity();
|
|||
|
|
Vector3 m_localScale = Vector3::One();
|
|||
|
|
|
|||
|
|
TransformComponent* m_parent = nullptr;
|
|||
|
|
std::vector<TransformComponent*> m_children;
|
|||
|
|
|
|||
|
|
mutable Matrix4x4 m_localToWorldMatrix;
|
|||
|
|
mutable Matrix4x4 m_worldToLocalMatrix;
|
|||
|
|
mutable Vector3 m_worldPosition;
|
|||
|
|
mutable Quaternion m_worldRotation;
|
|||
|
|
mutable Vector3 m_worldScale;
|
|||
|
|
mutable bool m_dirty = true;
|
|||
|
|
|
|||
|
|
void UpdateWorldTransform() const;
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、Entity(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(GameObject* parent)` | ❌ 缺失 | 2参数版本(含 worldPositionStays) |
|
|||
|
|
| `GetChildren()` | `const std::vector<GameObject*>& GetChildren() const` | ❌ 缺失 | 获取子实体列表 |
|
|||
|
|
| `GetChild()` | `GameObject* 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 GameObject* Find(const String& name)` | ❌ 缺失 | 按名称查找实体 |
|
|||
|
|
| `FindObjectsOfType()` | `static std::vector<GameObject*> FindObjectsOfType()` | ❌ 缺失 | 查找所有实体 |
|
|||
|
|
| `FindGameObjectsWithTag()` | `static std::vector<GameObject*> 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)` | `GameObject* CreateGameObject(const String& name, GameObject* parent)` | ❌ 缺失 | 带父实体创建 |
|
|||
|
|
| `GetRootGameObjects()` | `std::vector<GameObject*> GetRootGameObjects() const` | ❌ 缺失 | 获取根实体列表 |
|
|||
|
|
| `Find()` | `GameObject* Find(const String& name) const` | ❌ 缺失 | 查找实体 |
|
|||
|
|
| `FindGameObjectWithTag()` | `GameObject* 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 |
|
|||
|
|
|
|||
|
|
### 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]` 数组 | `Vector3` / `Quaternion` | ⚠️ UI Editor 自行实现,接口对齐即可 |
|
|||
|
|
| 父子关系 | `EntityID` (uint64) | `GameObject*` 指针 | ⚠️ 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` | 功能相似,命名不同 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、依赖关系分析
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
实现优先级 - 依赖链:
|
|||
|
|
|
|||
|
|
P0: TransformComponent 世界空间
|
|||
|
|
│
|
|||
|
|
├── 需要: Vector3/Quaternion 数学类型
|
|||
|
|
├── 需要: 矩阵计算方法
|
|||
|
|
└── 影响: 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 重构
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、附录:当前 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
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**文档结束**
|