Files
XCEngine/docs/plan/XCGameEngine架构设计.md

6026 lines
188 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# XCEngine - 仿Unity引擎架构设计文档
> **⚠️ 重要声明(严禁修改!)**
> 下文出现矛盾时永远以开头声明为准!!!!!!!!
> 本架构**1:1参考传统Unity引擎架构**GameObject + MonoBehaviour模式**不是Unity DOTS**
>
> - 组件是**类**(引用类型),包含数据和行为
> - 实体是GameObject容器
> - 系统是OOP风格的类
> - 不是纯数据组件 + 纯函数系统的DOTS模式
> - 不是SoA内存布局**除粒子系统性能关键路径外**
> - 不要被"ECS"这个词误导这里是传统Unity的Component模式
> - TransformComponent继承自Component与Unity的GetComponent\<Transform\>() API行为一致
---
## 文档信息
- **版本**: 1.0
- **日期**: 2026-03-12
- **状态**: 架构设计文档
- **目标**: 构建类Unity的专业游戏引擎
---
## 第一章 整体架构概览
### 1.1 架构设计原则
本引擎采用**分层架构**结合**模块化设计**,遵循以下核心原则:
1. **关注点分离 (Separation of Concerns)**: 各系统独立演化,通过明确定义的接口通信
2. **依赖倒置 (Dependency Inversion)**: 上层模块依赖抽象接口,不依赖具体实现
3. **开闭原则 (Open-Closed)**: 对扩展开放,对修改封闭
4. **单一职责 (Single Responsibility)**: 每个模块只负责一项职责
5. **数据驱动 (Data-Driven)**: 引擎行为由数据(组件、资源、配置)驱动
6. **组件化架构**: 采用类Unity的组件模式组件挂载在实体上
7. **渲染抽象**: 跨 API 的渲染接口,便于多平台支持
### 1.2 整体架构图
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ XCGameEngine │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐│
│ │ Editor │ │ Runtime │ │ Toolchain ││
│ │ (编辑器) │ │ (运行时) │ │ (工具链) ││
│ ├─────────────────┤ ├─────────────────┤ ├─────────────────────────┤│
│ │ • UI Framework │ │ • Game Loop │ │ • Asset Processor ││
│ │ • Scene View │ │ • Component Update │ │ • Shader Compiler ││
│ │ • Inspector │ │ • Physics Sim │ │ • Mesh Optimizer ││
│ │ • Hierarchy │ │ • Audio Engine │ │ • Texture Compressor ││
│ │ • Project │ │ • Script VM │ │ • Build Pipeline ││
│ │ • Console │ │ • Networking │ │ • Profiler ││
│ └────────┬────────┘ └────────┬────────┘ └────────────┬────────────┘│
│ │ │ │ │
│ └───────────────────────┼──────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Engine Core │ │
│ ├────────────────────────────────────────────────────────────────────────┤ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐│ │
│ │ │ Renderer │ │ Scene │ │ Resource │ │ Components ││ │
│ │ │ (渲染) │ │ (场景) │ │ (资源) │ │ (组件系统) ││ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘│ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐│ │
│ │ │ Physics │ │ Audio │ │ Script │ │ Math ││ │
│ │ │ (物理) │ │ (音频) │ │ (脚本) │ │ (数学) ││ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘│ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐│ │
│ │ │ Memory │ │ Thread │ │ Network │ │ File ││ │
│ │ │ (内存) │ │ (线程) │ │ (网络) │ │ (文件) ││ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘│ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Platform Layer │ │
│ ├────────────────────────────────────────────────────────────────────────┤ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │ │
│ │ │ D3D12 │ │ Vulkan │ │ Metal │ │ OpenGL │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 1.3 目录结构设计
```
XCVolumeRenderer/
├── engine/ # 引擎核心库(静态库)
│ ├── CMakeLists.txt
│ ├── include/
│ │ └── XCGameEngine/
│ │ ├── Core/ # 核心基础
│ │ │ ├── Assert.h
│ │ │ ├── Enum.h
│ │ │ ├── Flags.h
│ │ │ ├── TypeTraits.h
│ │ │ ├── Variant.h
│ │ │ └── UniquePtr.h
│ │ ├── Math/ # 数学库
│ │ │ ├── Vector2.h
│ │ │ ├── Vector3.h
│ │ │ ├── Vector4.h
│ │ │ ├── Matrix2.h
│ │ │ ├── Matrix3.h
│ │ │ ├── Matrix4.h
│ │ │ ├── Quaternion.h
│ │ │ ├── Transform.h
│ │ │ ├── Color.h
│ │ │ ├── MathUtils.h
│ │ │ ├── Ray.h
│ │ │ ├── Plane.h
│ │ │ ├── Sphere.h
│ │ │ ├── Box.h
│ │ │ └── Frustum.h
│ │ ├── Containers/ # 容器
│ │ │ ├── Array.h
│ │ │ ├── FixedArray.h
│ │ │ ├── Vector.h
│ │ │ ├── Map.h
│ │ │ ├── Set.h
│ │ │ ├── HashMap.h
│ │ │ ├── String.h
│ │ │ └── RingBuffer.h
│ │ ├── Memory/ # 内存管理
│ │ │ ├── Allocator.h
│ │ │ ├── StackAllocator.h
│ │ │ ├── PoolAllocator.h
│ │ │ ├── FreeListAllocator.h
│ │ │ ├── ProxyAllocator.h
│ │ │ └── MemoryUtils.h
│ │ ├── Threading/ # 线程
│ │ │ ├── Thread.h
│ │ │ ├── Mutex.h
│ │ │ ├── RWLock.h
│ │ │ ├── Semaphore.h
│ │ │ ├── ThreadPool.h
│ │ │ ├── TaskSystem.h
│ │ │ ├── SpinLock.h
│ │ │ └── Atomic.h
│ │ ├── IO/ # 文件IO
│ │ │ ├── FileSystem.h
│ │ │ ├── Path.h
│ │ │ ├── Stream.h
│ │ │ ├── FileReader.h
│ │ │ ├── FileWriter.h
│ │ │ ├── Archive.h
│ │ │ └── Compression.h
│ │ ├── Debug/ # 调试
│ │ │ ├── Logger.h
│ │ │ ├── Profiler.h
│ │ │ ├── DebugDraw.h
│ │ │ ├── Assertion.h
│ │ │ └── Traces.h
│ │ ├── Components/ # 组件系统类Unity GameObject模式
│ │ │ ├── GameObject.h # 游戏对象
│ │ │ ├── Component.h # 组件基类
│ │ │ └── System.h # 系统基类
│ │ ├── Scene/ # 场景系统
│ │ │ ├── Scene.h
│ │ │ ├── SceneLoader.h
│ │ │ ├── SceneSerializer.h
│ │ │ ├── SubScene.h
│ │ │ └── SceneManager.h
│ │ ├── Renderer/ # 渲染系统
│ │ │ ├── ForwardDeclarations.h
│ │ │ ├── Device.h
│ │ │ ├── Context.h
│ │ │ ├── SwapChain.h
│ │ │ ├── Buffer.h
│ │ │ ├── Texture.h
│ │ │ ├── Shader.h
│ │ │ ├── Pipeline.h
│ │ │ ├── RenderPass.h
│ │ │ ├── RenderTarget.h
│ │ │ ├── CommandList.h
│ │ │ ├── CommandQueue.h
│ │ │ ├── Descriptor.h
│ │ │ ├── Fence.h
│ │ │ ├── QueryHeap.h
│ │ │ ├── GpuResource.h
│ │ │ ├── GpuAllocator.h
│ │ │ ├── GpuEvent.h
│ │ │ ├── RenderModule.h
│ │ │ ├── RenderGraph.h
│ │ │ ├── Light.h
│ │ │ ├── Camera.h
│ │ │ ├── Material.h
│ │ │ ├── Mesh.h
│ │ │ ├── Skybox.h
│ │ │ ├── DebugRenderer.h
│ │ │ └── PostProcess.h
│ │ ├── Resources/ # 资源系统
│ │ │ ├── Resource.h
│ │ │ ├── ResourceManager.h
│ │ │ ├── ResourceLoader.h
│ │ │ ├── ResourceCache.h
│ │ │ ├── AssetDatabase.h
│ │ │ ├── ImportSettings.h
│ │ │ ├── ResourceCooker.h
│ │ │ └── Bundle.h
│ │ ├── Physics/ # 物理系统
│ │ │ ├── PhysicsWorld.h
│ │ │ ├── RigidBody.h
│ │ │ ├── Collider.h
│ │ │ ├── Joint.h
│ │ │ ├── CharacterController.h
│ │ │ ├── Trigger.h
│ │ │ ├── Raycast.h
│ │ │ ├── ForceField.h
│ │ │ └── PhysicsMaterial.h
│ │ ├── Audio/ # 音频系统
│ │ │ ├── AudioEngine.h
│ │ │ ├── AudioSource.h
│ │ │ ├── AudioListener.h
│ │ │ ├── AudioClip.h
│ │ │ ├── AudioMixer.h
│ │ │ ├── AudioEffect.h
│ │ │ └── AudioBanks.h
│ │ ├── Scripting/ # 脚本系统
│ │ │ ├── ScriptEngine.h
│ │ │ ├── ScriptClass.h
│ │ │ ├── ScriptObject.h
│ │ │ ├── ScriptMethod.h
│ │ │ ├── MonoBridge.h
│ │ │ ├── LuaBridge.h
│ │ │ └── AngelScript.h
│ │ ├── Animation/ # 动画系统
│ │ │ ├── Animator.h
│ │ │ ├── AnimationClip.h
│ │ │ ├── AnimationCurve.h
│ │ │ ├── AnimationState.h
│ │ │ ├── AnimationBlendTree.h
│ │ │ ├── Skeleton.h
│ │ │ ├── Bone.h
│ │ │ ├── Skinning.h
│ │ │ └── BlendShape.h
│ │ ├── Particles/ # 粒子系统
│ │ │ ├── ParticleSystem.h
│ │ │ ├── ParticleEmitter.h
│ │ │ ├── ParticleRenderer.h
│ │ │ ├── ParticleForce.h
│ │ │ ├── GPUParticles.h
│ │ │ └── VFXGraph.h
│ │ ├── Networking/ # 网络系统
│ │ │ ├── NetworkManager.h
│ │ │ ├── NetworkClient.h
│ │ │ ├── NetworkServer.h
│ │ │ ├── NetworkPeer.h
│ │ │ ├── Packet.h
│ │ │ ├── Serializer.h
│ │ │ ├── RPC.h
│ │ │ ├── NetworkTransform.h
│ │ │ └── NetcodeProtocol.h
│ │ ├── UI/ # UI系统
│ │ │ ├── Canvas.h
│ │ │ ├── Element.h
│ │ │ ├── Image.h
│ │ │ ├── Text.h
│ │ │ ├── Button.h
│ │ │ ├── ScrollView.h
│ │ │ ├── LayoutGroup.h
│ │ │ ├── UIRenderer.h
│ │ │ └── Font.h
│ │ ├── Navigation/ # 导航系统
│ │ │ ├── NavMesh.h
│ │ │ ├── NavMeshAgent.h
│ │ │ ├── NavMeshQuery.h
│ │ │ ├── Obstacle.h
│ │ │ └── CrowdSystem.h
│ │ ├── Platforms/ # 平台层
│ │ │ ├── Platform.h
│ │ │ ├── Windows.h
│ │ │ ├── Linux.h
│ │ │ ├── MacOS.h
│ │ │ ├── Android.h
│ │ │ ├── IOS.h
│ │ │ └── Web.h
│ │ └── XCGameEngine.h # 主头文件
│ ├── src/
│ │ ├── Core/
│ │ ├── Math/
│ │ ├── Components/ # 组件系统
│ │ ├── Scene/
│ │ ├── Renderer/
│ │ ├── Resources/
│ │ ├── Physics/
│ │ ├── Audio/
│ │ ├── Scripting/
│ │ └── ...
│ └── third_party/ # 第三方库
│ ├── stb/
│ ├── json/
│ ├── lua/
│ ├── physx/
│ └── etc.
├── editor/ # 编辑器项目你的UI
│ ├── CMakeLists.txt
│ ├── src/
│ │ ├── Application.h/cpp
│ │ ├── main.cpp
│ │ ├── Theme.h/cpp
│ │ ├── Core/
│ │ │ ├── Event.h
│ │ │ ├── AssetItem.h
│ │ │ └── LogEntry.h
│ │ ├── Managers/
│ │ │ ├── SelectionManager.h
│ │ │ ├── LogSystem.h/cpp
│ │ │ ├── ProjectManager.h/cpp
│ │ │ └── EditorSceneManager.h/cpp
│ │ ├── Panels/
│ │ │ ├── Panel.h/cpp
│ │ │ ├── MenuBar.h/cpp
│ │ │ ├── HierarchyPanel.h/cpp
│ │ │ ├── InspectorPanel.h/cpp
│ │ │ ├── SceneViewPanel.h/cpp
│ │ │ ├── GameViewPanel.h/cpp
│ │ │ ├── ProjectPanel.h/cpp
│ │ │ ├── ConsolePanel.h/cpp
│ │ │ ├── AssetsBrowserPanel.h/cpp
│ │ │ ├── AnimationPanel.h/cpp
│ │ │ ├── ProfilerPanel.h/cpp
│ │ │ └── SettingsPanel.h/cpp
│ │ ├── Windows/
│ │ │ ├── AssetImporter.h/cpp
│ │ │ ├── SceneHierarchyWindow.h/cpp
│ │ │ ├── ShaderEditor.h/cpp
│ │ │ ├── MaterialEditor.h/cpp
│ │ │ ├── AnimationEditor.h/cpp
│ │ │ └── PreferenceWindow.h/cpp
│ │ ├── Tools/
│ │ │ ├── Gizmo.h/cpp
│ │ │ ├── SelectionTool.h/cpp
│ │ │ ├── MoveTool.h/cpp
│ │ │ ├── RotateTool.h/cpp
│ │ │ ├── ScaleTool.h/cpp
│ │ │ └── EditorCamera.h/cpp
│ │ ├── Editor/
│ │ │ ├── EditorEngineLink.h/cpp
│ │ │ ├── EditorRenderView.h/cpp
│ │ │ ├── EditorModes.h
│ │ │ └── UndoRedo.h/cpp
│ │ └── ImGui/
│ │ ├── ImGuiRenderer.h/cpp
│ │ ├── ImGuiTheme.h/cpp
│ │ └── ImGuiWidgets.h/cpp
│ └── assets/
│ ├── fonts/
│ ├── icons/
│ └── themes/
├── runtime/ # 游戏运行时(独立可执行文件)
│ ├── CMakeLists.txt
│ ├── src/
│ │ ├── GameMain.cpp
│ │ ├── RuntimeConfig.h
│ │ └── EntryPoint.cpp
│ └── resources/
│ └── (烘焙后的场景和资源)
├── tools/ # 工具链
│ ├── AssetProcessor/ # 资源处理器
│ ├── ShaderCompiler/ # 着色器编译器
│ ├── SceneCooker/ # 场景烘焙工具
│ ├── TextureConverter/ # 纹理转换工具
│ ├── MeshOptimizer/ # 网格优化工具
│ ├── AudioImporter/ # 音频导入工具
│ ├── BuildTool/ # 构建打包工具
│ └── ShaderDebugger/ # 着色器调试工具
├── content/ # 资源内容
│ ├── Assets/
│ │ ├── Scenes/
│ │ ├── Materials/
│ │ ├── Meshes/
│ │ ├── Textures/
│ │ ├── Audio/
│ │ ├── Scripts/
│ │ ├── Shaders/
│ │ ├── Animations/
│ │ ├── Prefabs/
│ │ └── UI/
│ ├── Packages/ # 包管理
│ └── Library/ # 引擎库缓存
│ ├── ShaderLibrary/
│ ├── ShaderCache/
│ ├── AssetDatabase/
│ ├── SourceAssets/
│ └── ImportCache/
└── docs/ # 文档
├── Architecture.md
├── ComponentReference.md
├── ShaderGuide.md
└── APIReference.md
```
---
## 第二章 核心层 (Core Layer)
核心层提供引擎所有其他部分依赖的基础功能,是整个引擎的基石。
### 2.1 数学库 (Math Library)
#### 2.1.1 设计目标
- **高性能**: SIMD 优化,支持 SSE/AVX/NEON
- **精确性**: 满足游戏精度需求,避免浮点误差
- **完整性**: 覆盖游戏开发所需的所有数学类型
- **可读性**: 简洁清晰的 API 设计
#### 2.1.2 核心类型
```cpp
namespace XCEngine {
namespace Math {
// 向量类型
struct Vector2 { float x, y; };
struct Vector3 { float x, y, z; };
struct Vector4 { float x, y, z, w; };
// 矩阵类型
struct Matrix3x3; // 3D变换
struct Matrix4x4; // 4D变换
struct Matrix2x2; // 2D变换
// 四元数 - 避免欧拉角万向节锁
struct Quaternion {
float x, y, z, w;
// 旋转变换
static Quaternion FromAxisAngle(const Vector3& axis, float radians);
static Quaternion FromEulerAngles(float pitch, float yaw, float roll);
static Quaternion FromRotationMatrix(const Matrix4x4& matrix);
static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float t);
Vector3 ToEulerAngles() const;
Matrix4x4 ToMatrix4x4() const;
Vector3 operator*(const Vector3& v) const; // 旋转向量
};
// 变换 - 组合位置、旋转、缩放
struct Transform {
Vector3 position = Vector3::Zero();
Quaternion rotation = Quaternion::Identity();
Vector3 scale = Vector3::One();
Matrix4x4 ToMatrix() const;
Transform Inverse() const;
Transform operator*(const Transform& other) const; // 组合变换
Vector3 TransformPoint(const Vector3& point) const;
Vector3 TransformDirection(const Vector3& direction) const;
};
// 空间参照
enum class Space {
Self, // 自身局部空间
World // 世界空间
};
// 颜色
struct Color { float r, g, b, a; };
struct LinearColor; // 线性空间颜色
struct HDRColor; // HDR颜色
// 射线 - 用于射线检测和选择
struct Ray {
Vector3 origin;
Vector3 direction;
Vector3 GetPoint(float t) const;
bool Intersects(const Sphere& sphere, float& t) const;
bool Intersects(const Box& box, float& t) const;
bool Intersects(const Plane& plane, float& t) const;
};
// 包围体
struct Sphere { Vector3 center; float radius; };
struct Box { Vector3 center; Vector3 extents; Matrix4x4 transform; };
struct Frustum; // 视锥体
struct OBB; // 定向包围盒
struct AABB; // 轴对齐包围盒
} // namespace Math
} // namespace XCEngine
```
#### 2.1.3 SIMD 优化示例
```cpp
// 使用 SIMD 进行向量运算
struct alignas(16) Vector3_SIMD {
union {
__m128 simd;
struct { float x, y, z, w; };
};
Vector3_SIMD operator+(const Vector3_SIMD& other) const {
Vector3_SIMD result;
result.simd = _mm_add_ps(simd, other.simd);
return result;
}
float Dot(const Vector3_SIMD& other) const {
__m128 dot = _mm_mul_ps(simd, other.simd);
__m128 temp = _mm_movehl_ps(dot, dot);
dot = _mm_add_ss(dot, temp);
return _mm_cvtss_f32(dot);
}
Vector3_SIMD Cross(const Vector3_SIMD& other) const {
Vector3_SIMD result;
__m128 a = _mm_shuffle_ps(simd, simd, _MM_SHUFFLE(3,0,2,1));
__m128 b = _mm_shuffle_ps(other.simd, other.simd, _MM_SHUFFLE(3,1,0,2));
result.simd = _mm_sub_ps(_mm_mul_ps(simd, a), _mm_mul_ps(other.simd, b));
result.simd = _mm_shuffle_ps(result.simd, result.simd, _MM_SHUFFLE(3,0,2,1));
return result;
}
};
```
### 2.2 内存管理 (Memory Management)
```cpp
namespace XCEngine {
namespace Memory {
// 分配器基类
class IAllocator {
public:
virtual ~IAllocator() = default;
virtual void* Allocate(size_t size, size_t alignment = 0) = 0;
virtual void Free(void* ptr) = 0;
virtual void* Reallocate(void* ptr, size_t newSize) = 0;
virtual size_t GetTotalAllocated() const = 0;
virtual size_t GetTotalFreed() const = 0;
virtual size_t GetPeakAllocated() const = 0;
virtual size_t GetAllocationCount() const = 0;
virtual const char* GetName() const = 0;
};
// 线性分配器 - 快速分配和批量释放
class LinearAllocator : public IAllocator {
public:
explicit LinearAllocator(size_t size, IAllocator* parent = nullptr);
~LinearAllocator();
void* Allocate(size_t size, size_t alignment = 8) override;
void Free(void* ptr) override; // 只重置,不真正释放
void Clear(); // 清空所有内存
void* GetMarker() const;
void SetMarker(void* marker);
private:
byte* m_buffer = nullptr;
size_t m_capacity = 0;
size_t m_offset = 0;
IAllocator* m_parent = nullptr;
};
// 池分配器 - 高频小对象分配
class PoolAllocator : public IAllocator {
public:
PoolAllocator(size_t blockSize, size_t poolSize, size_t alignment = 8);
~PoolAllocator();
void* Allocate(size_t size, size_t alignment = 0) override;
void Free(void* ptr) override;
bool Contains(void* ptr) const;
size_t GetBlockSize() const { return m_blockSize; }
size_t GetFreeBlockCount() const;
private:
struct FreeNode {
FreeNode* next;
};
size_t m_blockSize = 0;
size_t m_alignment = 0;
void* m_memory = nullptr;
FreeNode* m_freeList = nullptr;
size_t m_totalBlocks = 0;
size_t m_freeBlocks = 0;
};
// 代理分配器 - 用于追踪和调试
class ProxyAllocator : public IAllocator {
public:
ProxyAllocator(IAllocator* underlying, const char* name);
void* Allocate(size_t size, size_t alignment = 0) override;
void Free(void* ptr) override;
void* Reallocate(void* ptr, size_t newSize) override;
struct Stats {
size_t totalAllocated;
size_t totalFreed;
size_t peakAllocated;
size_t allocationCount;
size_t memoryOverhead;
};
const Stats& GetStats() const;
private:
IAllocator* m_underlying;
const char* m_name;
Stats m_stats;
Mutex m_mutex;
};
// 全局内存管理器
class MemoryManager {
public:
static MemoryManager& Get();
void Initialize();
void Shutdown();
IAllocator* GetSystemAllocator();
IAllocator* GetPhysicsAllocator();
IAllocator* GetRenderingAllocator();
IAllocator* GetAudioAllocator();
std::unique_ptr<LinearAllocator> CreateLinearAllocator(size_t size);
std::unique_ptr<PoolAllocator> CreatePoolAllocator(size_t blockSize, size_t count);
std::unique_ptr<ProxyAllocator> CreateProxyAllocator(const char* name);
void SetTrackAllocations(bool track);
void DumpMemoryLeaks();
void GenerateMemoryReport();
};
#define XE_ALLOC(allocator, size, ...) allocator->Allocate(size, ##__VA_ARGS__)
#define XE_FREE(allocator, ptr) allocator->Free(ptr)
}
}
```
### 2.3 线程系统 (Threading)
```cpp
namespace XCEngine {
namespace Threading {
enum class TaskPriority : uint8_t {
Critical = 0,
High = 1,
Normal = 2,
Low = 3,
Idle = 4
};
enum class TaskStatus : uint8_t {
Pending,
Scheduled,
Running,
Completed,
Failed,
Canceled
};
template<typename T = void()>
using Func = std::function<T>;
// 任务接口
class ITask {
public:
virtual ~ITask() = default;
virtual void Execute() = 0;
virtual void OnComplete() {}
virtual void OnCancel() {}
TaskPriority GetPriority() const { return m_priority; }
TaskStatus GetStatus() const { return m_status; }
uint64 GetId() const { return m_id; }
protected:
TaskPriority m_priority = TaskPriority::Normal;
TaskStatus m_status = TaskStatus::Pending;
uint64 m_id = 0;
std::atomic<uint32> m_refCount{1};
};
// Lambda 任务包装器
template<typename Func>
class LambdaTask : public ITask {
public:
explicit LambdaTask(Func&& func, TaskPriority priority = TaskPriority::Normal)
: m_func(std::move(func)), m_priority(priority) {}
void Execute() override {
m_func();
}
private:
Func m_func;
};
// 任务组 - 用于批量管理任务
class TaskGroup {
public:
using Callback = std::function<void()>;
TaskGroup();
~TaskGroup();
uint64 AddTask(std::unique_ptr<ITask> task);
uint64 AddTask(Func&& func, TaskPriority priority = TaskPriority::Normal);
void AddDependency(uint64 taskId, uint64 dependsOn);
void Wait();
bool WaitFor(std::chrono::milliseconds timeout);
void SetCompleteCallback(Callback&& callback);
bool IsComplete() const;
float GetProgress() const;
};
// 任务系统主类
class TaskSystem {
public:
static TaskSystem& Get();
void Initialize(const TaskSystemConfig& config);
void Shutdown();
uint64 Submit(std::unique_ptr<ITask> task);
uint64 Submit(Func&& func, TaskPriority priority = TaskPriority::Normal);
TaskGroup* CreateTaskGroup();
void DestroyTaskGroup(TaskGroup* group);
void Wait(uint64 taskId);
uint32 GetWorkerThreadCount() const;
void Update();
// 并行 For 循环
template<typename Func>
void ParallelFor(int32 start, int32 end, Func&& func);
void RunOnMainThread(Func&& func);
};
}
}
```
### 2.4 容器库 (Containers)
```cpp
namespace XCEngine {
namespace Containers {
// 动态数组
template<typename T>
class Array {
public:
using Iterator = T*;
using ConstIterator = const T*;
Array() = default;
explicit Array(size_t capacity);
Array(size_t count, const T& value);
Array(std::initializer_list<T> init);
~Array();
Array(const Array& other);
Array(Array&& other) noexcept;
Array& operator=(const Array& other);
Array& operator=(Array&& other) noexcept;
T& operator[](size_t index);
const T& operator[](size_t index) const;
T* Data() { return m_data; }
const T* Data() const { return m_data; }
size_t Size() const { return m_size; }
size_t Capacity() const { return m_capacity; }
void Clear();
void PushBack(const T& value);
void PushBack(T&& value);
template<typename... Args>
T& EmplaceBack(Args&&... args);
void PopBack();
private:
T* m_data = nullptr;
size_t m_size = 0;
size_t m_capacity = 0;
IAllocator* m_allocator = nullptr;
};
// 字符串
class String {
public:
String();
String(const char* str);
String(const char* str, size_t len);
~String();
String& operator+=(const String& other);
String& operator+=(const char* str);
String Substring(size_t pos, size_t len = npos) const;
String Trim() const;
String ToLower() const;
String ToUpper() const;
size_t Find(const char* str, size_t pos = 0) const;
bool StartsWith(const String& prefix) const;
bool EndsWith(const String& suffix) const;
const char* CStr() const { return m_data; }
size_t Length() const { return m_length; }
private:
char* m_data = nullptr;
size_t m_length = 0;
size_t m_capacity = 0;
};
// 哈希映射
template<typename Key, typename Value>
class HashMap {
public:
struct Pair {
Key first;
Value second;
};
HashMap() = default;
explicit HashMap(size_t bucketCount, IAllocator* allocator = nullptr);
Value& operator[](const Key& key);
Value* Find(const Key& key);
const Value* Find(const Key& key) const;
bool Contains(const Key& key) const;
bool Insert(const Key& key, const Value& value);
bool Erase(const Key& key);
void Clear();
size_t Size() const { return m_size; }
private:
size_t GetBucketIndex(const Key& key) const;
void Resize();
struct Bucket {
Array<Pair> pairs;
};
Array<Bucket> m_buckets;
size_t m_bucketCount = 0;
size_t m_size = 0;
float m_loadFactor = 0.75f;
IAllocator* m_allocator = nullptr;
};
} // namespace Containers
} // namespace XCEngine
```
### 2.5 日志与调试系统
```cpp
namespace XCEngine {
namespace Core {
// 事件系统 - 基础事件系统(线程安全版本)
template<typename... Args>
class Event {
public:
using Callback = std::function<void(Args...)>;
using Listener = std::pair<uint64_t, Callback>;
using Iterator = typename std::vector<Listener>::iterator;
uint64_t Subscribe(Callback callback) {
std::lock_guard<std::mutex> lock(m_mutex);
uint64_t id = ++m_nextId;
m_listeners.emplace_back(id, std::move(callback));
return id;
}
void Unsubscribe(uint64_t id) {
std::lock_guard<std::mutex> lock(m_mutex);
m_pendingUnsubscribes.push_back(id);
}
void ProcessUnsubscribes() {
std::lock_guard<std::mutex> lock(m_mutex);
for (uint64_t id : m_pendingUnsubscribes) {
m_listeners.erase(
std::remove_if(m_listeners.begin(), m_listeners.end(),
[id](const auto& pair) { return pair.first == id; }),
m_listeners.end()
);
}
m_pendingUnsubscribes.clear();
}
void Invoke(Args... args) const {
// 注意这里不加锁以避免回调中调用Unsubscribe导致的死锁
// 实际使用时应在调用前确保没有并发的Unsubscribe
// 或者使用副本进行调用
if (!m_pendingUnsubscribes.empty()) {
std::vector<Listener> listenersCopy;
{
std::lock_guard<std::mutex> lock(m_mutex);
listenersCopy = m_listeners;
m_pendingUnsubscribes.clear();
}
for (const auto& [id, callback] : listenersCopy) {
callback(args...);
}
} else {
for (const auto& [id, callback] : m_listeners) {
callback(args...);
}
}
}
void Clear() {
std::lock_guard<std::mutex> lock(m_mutex);
m_listeners.clear();
}
Iterator begin() { return m_listeners.begin(); }
Iterator end() { return m_listeners.end(); }
private:
mutable std::mutex m_mutex;
std::vector<Listener> m_listeners;
std::vector<uint64_t> m_pendingUnsubscribes;
uint64_t m_nextId = 0;
};
// 基础类型定义
// 注意String 定义在 Containers 命名空间中,避免与 Core::String 冲突
using int8 = int8_t;
using int16 = int16_t;
using int32 = int32_t;
using int64 = int64_t;
using uint8 = uint8_t;
using uint16 = uint16_t;
using uint32 = uint32_t;
using uint64 = uint64_t;
using byte = uint8_t;
// 引用计数基类
class RefCounted {
public:
RefCounted() : m_refCount(1) {}
virtual ~RefCounted() = default;
void AddRef() { ++m_refCount; }
void Release() {
if (--m_refCount == 0) {
delete this;
}
}
uint32_t GetRefCount() const { return m_refCount.load(); }
protected:
std::atomic<uint32_t> m_refCount;
};
// 智能指针别名
template<typename T>
using Ref = std::shared_ptr<T>;
template<typename T>
using UniqueRef = std::unique_ptr<T>;
} // namespace Core
}
namespace XCEngine {
namespace Debug {
enum class LogLevel : uint8_t {
Verbose = 0,
Debug = 1,
Info = 2,
Warning = 3,
Error = 4,
Fatal = 5
};
enum class LogCategory {
General,
Rendering,
Physics,
Audio,
Scripting,
Network,
Memory,
Threading,
FileSystem,
Custom
};
struct LogEntry {
LogLevel level;
LogCategory category;
String message;
String file;
int32 line;
String function;
uint64 timestamp;
uint32 threadId;
};
class ILogSink {
public:
virtual ~ILogSink() = default;
virtual void Log(const LogEntry& entry) = 0;
virtual void Flush() = 0;
};
class ConsoleLogSink : public ILogSink {
public:
void Log(const LogEntry& entry) override;
void Flush() override;
void SetColorOutput(bool enable);
void SetMinimumLevel(LogLevel level);
};
class FileLogSink : public ILogSink {
public:
explicit FileLogSink(const String& filePath);
~FileLogSink();
void Log(const LogEntry& entry) override;
void Flush() override;
private:
String m_filePath;
FileWriter m_writer;
};
class Logger {
public:
static Logger& Get();
void Initialize();
void Shutdown();
void AddSink(std::unique_ptr<ILogSink> sink);
void RemoveSink(ILogSink* sink);
void Log(LogLevel level, LogCategory category,
const String& message, const char* file = nullptr,
int32 line = 0, const char* function = nullptr);
void Verbose(LogCategory category, const String& message);
void Debug(LogCategory category, const String& message);
void Info(LogCategory category, const String& message);
void Warning(LogCategory category, const String& message);
void Error(LogCategory category, const String& message);
void Fatal(LogCategory category, const String& message);
void SetMinimumLevel(LogLevel level);
void SetCategoryEnabled(LogCategory category, bool enabled);
};
#define XE_LOG(category, level, message) \
XCEngine::Debug::Logger::Get().Log(level, category, message, __FILE__, __LINE__, __FUNCTION__)
#define XE_ASSERT(condition, message) \
if (!(condition)) { \
XCEngine::Debug::Logger::Get().Fatal(XCEngine::Debug::LogCategory::General, message); \
__debugbreak(); \
}
// 性能分析器
class Profiler {
public:
static Profiler& Get();
void Initialize();
void Shutdown();
void BeginProfile(const char* name);
void EndProfile();
void BeginFrame();
void EndFrame();
void MarkEvent(const char* name, uint64_t timestamp, uint32_t threadId);
void SetMarker(const char* name, uint32_t color);
void ExportChromeTracing(const String& filePath);
};
#define XE_PROFILE_BEGIN(name) XCEngine::Debug::Profiler::Get().BeginProfile(name)
#define XE_PROFILE_END() XCEngine::Debug::Profiler::Get().EndProfile()
#define XE_PROFILE_FUNCTION() XE_PROFILE_BEGIN(__FUNCTION__)
}
}
```
---
## 第三章 组件系统 (GameObject + Component)
> 本架构参考**传统Unity的GameObject + Component模式**。
> - GameObject是实体容器包含Transform等内置组件
> - Component是挂载在GameObject上的class引用类型包含数据和行为
> - Component有完整的生命周期Awake, Start, Update, OnDestroy等
> - Scene直接管理GameObject列表没有World中间层
### 3.1 组件系统架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ GameObject + Component Architecture │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ Scene (场景) │ │
│ │ ┌─────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Scene │ │
│ │ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ │ GameObject List │ │ │
│ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │
│ │ │ │ │ GameObject │ │ GameObject │ │ GameObject │ │ │ │
│ │ │ │ │ - name │ │ - name │ │ - name │ │ │ │
│ │ │ │ │ - transform│ │ - transform│ │ - transform│ │ │ │
│ │ │ │ │ - components│ │ - components│ │ - components│ │ │ │
│ │ │ │ │ └ Renderer│ │ └ Camera │ │ └ Script │ │ │ │
│ │ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ │
│ │ │ └─────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 3.2 游戏对象 (GameObject)
```cpp
namespace XCEngine {
class Scene;
class Transform;
class Component;
// GameObject: 游戏对象类Unity GameObject
// 传统Unity风格的GameObject包含内置组件和用户组件
// 生命周期由 Scene 的 unique_ptr 管理,不需要引用计数
class GameObject {
public:
GameObject();
~GameObject();
// 内部构造 - 用于Scene创建GameObject时设置初始属性
struct ConstructParams {
String name = "GameObject";
GameObject* parent = nullptr;
bool active = true;
};
// 工厂方法(替代公有构造函数)
static GameObject* Create(const ConstructParams& params = {});
static void Destroy(GameObject* obj);
String name; // 对象名称
bool active = true; // 激活状态
TransformComponent& GetTransform() { return m_transform; }
const TransformComponent& GetTransform() const { return m_transform; }
Scene* GetScene() const { return m_scene; }
// 组件管理
template<typename T>
T* AddComponent();
template<typename T>
void RemoveComponent();
template<typename T>
T* GetComponent() const;
template<typename T>
std::vector<T*> GetComponents() const;
template<typename T>
T* GetComponentInChildren() const;
template<typename T>
std::vector<T*> GetComponentsInChildren() const;
template<typename T>
T* GetComponentInParent() const;
// 层级管理
GameObject* GetParent() const;
void SetParent(GameObject* parent);
void SetParent(GameObject* parent, bool worldPositionStays);
const std::vector<GameObject*>& GetChildren() const;
GameObject* GetChild(int index) const;
int GetChildCount() const;
int GetSiblingIndex() const;
void SetSiblingIndex(int index);
// 激活状态
void SetActive(bool active);
bool IsActive() const;
bool IsActiveInHierarchy() const;
// 场景查找静态方法内部使用SceneManager::GetActiveScene
static GameObject* Find(const String& name);
static std::vector<GameObject*> FindObjectsOfType();
static std::vector<GameObject*> FindGameObjectsWithTag(const String& tag);
// 生命周期
void Destroy();
private:
void AddComponentInternal(Component* component);
void RemoveComponentInternal(Component* component);
std::vector<std::unique_ptr<Component>> m_components;
// 组件类型索引 - 用于O(1)查询类型ID -> 组件索引)
// 每个 AddComponent/RemoveComponent 时更新
std::unordered_map<uint32_t, size_t> m_componentTypeIndex;
std::vector<GameObject*> m_children;
GameObject* m_parent = nullptr;
Scene* m_scene = nullptr;
// TransformComponent是GameObject的内置组件
// 注意TransformComponent继承自Component需要在构造后设置m_gameObject
TransformComponent m_transform;
void Initialize(const ConstructParams& params);
friend class Scene;
friend class TransformComponent;
};
// GameObject实现
inline GameObject::GameObject() {
// m_transform需要在构造后初始化m_gameObject
}
inline GameObject::~GameObject() {
// 销毁所有子对象
for (auto* child : m_children) {
delete child;
}
}
inline GameObject* GameObject::Create(const ConstructParams& params) {
GameObject* obj = new GameObject();
obj->Initialize(params);
return obj;
}
inline void GameObject::Destroy(GameObject* obj) {
delete obj;
}
inline void GameObject::Initialize(const ConstructParams& params) {
name = params.name;
active = params.active;
// 设置TransformComponent的m_gameObject指针
m_transform.m_gameObject = this;
// 设置父子关系
if (params.parent) {
params.parent->m_children.push_back(this);
m_parent = params.parent;
}
}
inline void GameObject::Destroy() {
if (m_scene) {
m_scene->DestroyGameObject(this);
} else {
delete this;
}
}
// 静态方法实现
inline GameObject* GameObject::Find(const String& name) {
return SceneManager::Get().GetActiveScene()->Find(name);
}
inline std::vector<GameObject*> GameObject::FindObjectsOfType() {
return SceneManager::Get().GetActiveScene()->FindObjectsOfType<GameObject>();
}
inline std::vector<GameObject*> GameObject::FindGameObjectsWithTag(const String& tag) {
return SceneManager::Get().GetActiveScene()->FindGameObjectsWithTag(tag);
}
// GameObject创建辅助类
class GameObjectBuilder {
public:
explicit GameObjectBuilder(const String& name = "GameObject");
~GameObjectBuilder() = default;
template<typename T, typename... Args>
GameObjectBuilder& AddComponent(Args&&... args);
GameObject* Build();
private:
String m_name;
std::vector<std::function<void(GameObject*)>> m_components;
};
}
```
### 3.3 组件 (Component)
```cpp
namespace XCEngine {
class GameObject;
// 组件基类类Unity MonoBehaviour
// 包含完整的生命周期方法,用户组件继承此类
// 注意组件由GameObject拥有和管理生命周期不需要引用计数
class Component {
public:
Component();
virtual ~Component();
// 所属GameObject
GameObject* gameObject() const { return m_gameObject; }
TransformComponent& transform() const { return m_gameObject->GetTransform(); }
// 激活状态
bool IsEnabled() const { return m_enabled; }
void SetEnabled(bool enabled) { m_enabled = enabled; }
// 场景引用
Scene* GetScene() const;
// 组件查找
template<typename T>
T* GetComponent() const { return m_gameObject->GetComponent<T>(); }
template<typename T>
std::vector<T*> GetComponents() const { return m_gameObject->GetComponents<T>(); }
// ========================================
// 生命周期类Unity MonoBehaviour
// ========================================
// 创建时调用(即使组件被禁用也会调用)
virtual void Awake() {}
// 首次启用时调用(当对象和组件都被启用时)
virtual void Start() {}
// 每帧调用(当组件启用时)
virtual void Update(float deltaTime) {}
// 物理更新(固定时间间隔)
virtual void FixedUpdate() {}
// 在Update之后每帧调用
virtual void LateUpdate(float deltaTime) {}
// 销毁时调用
virtual void OnDestroy() {}
// 当组件被启用时调用
virtual void OnEnable() {}
// 当组件被禁用时调用
virtual void OnDisable() {}
// ========================================
// 物理回调类Unity
// ========================================
virtual void OnCollisionEnter(const Collision& collision) {}
virtual void OnCollisionStay(const Collision& collision) {}
virtual void OnCollisionExit(const Collision& collision) {}
virtual void OnTriggerEnter(Collider* other) {}
virtual void OnTriggerStay(Collider* other) {}
virtual void OnTriggerExit(Collider* other) {}
virtual void OnMouseDown() {}
virtual void OnMouseDrag() {}
virtual void OnMouseEnter() {}
virtual void OnMouseExit() {}
virtual void OnMouseOver() {}
virtual void OnMouseUp() {}
virtual void OnMouseUpAsButton() {}
virtual void OnTriggerEnter2D(Collider2D* other) {}
virtual void OnTriggerExit2D(Collider2D* other) {}
virtual void OnCollisionEnter2D(Collision2D* collision) {}
virtual void OnCollisionExit2D(Collision2D* collision) {}
// ========================================
// 消息发送
// ========================================
// 发送消息到同GameObject上的其他组件
void SendMessage(const String& methodName, const void* value = nullptr);
void SendMessageUpwards(const String& methodName, const void* value = nullptr);
void BroadcastMessage(const String& methodName, const void* value = nullptr);
protected:
GameObject* m_gameObject = nullptr;
bool m_enabled = true;
friend class GameObject;
};
// 组件类型注册(用于运行时类型识别)
class ComponentTypeRegistry {
public:
static ComponentTypeRegistry& Get();
template<typename T>
static uint32_t GetTypeId() {
static uint32_t id = Get().Register(typeid(T).name(), static_cast<uint32_t>(-1));
return id;
}
template<typename T>
static uint32_t GetTypeId(const char* typeName) {
static uint32_t id = Get().Register(typeName, static_cast<uint32_t>(-1));
return id;
}
static uint32_t GetTypeIdFromName(const char* typeName) {
return Get().GetIdByName(typeName);
}
static const char* GetTypeName(uint32_t typeId) {
return Get().GetNameById(typeId);
}
private:
uint32_t Register(const char* typeName, uint32_t suggestedId);
uint32_t GetIdByName(const char* typeName) const;
const char* GetNameById(uint32_t typeId) const;
std::atomic<uint32_t> m_nextTypeId{0};
std::unordered_map<uint32_t, String> m_idToName;
std::unordered_map<String, uint32_t> m_nameToId;
Mutex m_mutex;
};
// ============================================================================
// ============================================================================
// TransformComponent - GameObject的内置组件类Unity Transform
// 继承自 Component包含父子层级关系
// ============================================================================
class TransformComponent : public Component {
public:
// 局部变换
Vector3 GetLocalPosition() const { return m_localPosition; }
void SetLocalPosition(const Vector3& position) { m_localPosition = position; SetDirty(); }
Quaternion GetLocalRotation() const { return m_localRotation; }
void SetLocalRotation(const Quaternion& rotation) { m_localRotation = rotation; SetDirty(); }
Vector3 GetLocalScale() const { return m_localScale; }
void SetLocalScale(const Vector3& scale) { m_localScale = scale; SetDirty(); }
// 世界变换(通过计算得出)
Vector3 GetPosition() const;
void SetPosition(const Vector3& position);
Quaternion GetRotation() const;
void SetRotation(const Quaternion& rotation);
Vector3 GetScale() const;
void SetScale(const Vector3& scale);
// 方向向量
Vector3 GetForward() const { return GetRotation() * Vector3::Forward(); }
Vector3 GetRight() const { return GetRotation() * Vector3::Right(); }
Vector3 GetUp() const { return GetRotation() * Vector3::Up(); }
// 矩阵
const Matrix4x4& GetLocalToWorldMatrix() const;
Matrix4x4 GetWorldToLocalMatrix() const;
// 层级操作
TransformComponent* GetParent() const { return m_parent; }
void SetParent(TransformComponent* parent, bool worldPositionStays = true);
int GetChildCount() const { return static_cast<int>(m_children.size()); }
TransformComponent* GetChild(int index) const;
TransformComponent* Find(const String& name) const;
void DetachChildren();
void SetAsFirstSibling();
void SetAsLastSibling();
void SetSiblingIndex(int index);
int GetSiblingIndex() const;
// 变换操作
void LookAt(const Vector3& target);
void LookAt(const Vector3& target, const Vector3& up);
void Rotate(const Vector3& eulers);
void Rotate(const Vector3& axis, float angle);
void Translate(const Vector3& translation);
void Translate(const Vector3& translation, Math::Space relativeTo);
// 点变换
Vector3 TransformPoint(const Vector3& point) const;
Vector3 InverseTransformPoint(const Vector3& point) const;
Vector3 TransformDirection(const Vector3& direction) const;
Vector3 InverseTransformDirection(const Vector3& direction) const;
// 设为脏(需要重新计算世界变换)
void SetDirty() { m_dirty = true; }
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;
friend class GameObject;
};
// 渲染组件继承Component
class RenderMeshComponent : public Component {
public:
void Awake() override;
void Start() override;
void Update(float deltaTime) override;
ResourceGUID GetMesh() const { return m_meshGuid; }
void SetMesh(const ResourceGUID& guid);
ResourceGUID GetMaterial() const { return m_materialGuid; }
void SetMaterial(const ResourceGUID& guid);
bool GetCastShadows() const { return m_castShadows; }
void SetCastShadows(bool cast) { m_castShadows = cast; }
bool GetReceiveShadows() const { return m_receiveShadows; }
void SetReceiveShadows(bool receive) { m_receiveShadows = receive; }
private:
ResourceGUID m_meshGuid;
ResourceGUID m_materialGuid;
bool m_castShadows = true;
bool m_receiveShadows = true;
};
// 光源组件 - 继承Component类Unity Light
class RenderLightComponent : public Component {
public:
void Awake() override;
void Update(float deltaTime) override;
enum class LightType : uint8_t {
Directional,
Point,
Spot,
Area
};
void SetLightType(LightType type) { m_type = type; }
LightType GetLightType() const { return m_type; }
void SetColor(const Vector3& color) { m_color = color; }
Vector3 GetColor() const { return m_color; }
void SetIntensity(float intensity) { m_intensity = intensity; }
float GetIntensity() const { return m_intensity; }
void SetRange(float range) { m_range = range; }
float GetRange() const { return m_range; }
void SetSpotAngle(float angle) { m_spotAngle = angle; }
float GetSpotAngle() const { return m_spotAngle; }
void SetCastShadows(bool cast) { m_castShadows = cast; }
bool GetCastShadows() const { return m_castShadows; }
void SetShadowResolution(uint32_t resolution) { m_shadowResolution = resolution; }
uint32_t GetShadowResolution() const { return m_shadowResolution; }
void SetCullingMask(int32_t mask) { m_cullingMask = mask; }
int32_t GetCullingMask() const { return m_cullingMask; }
private:
LightType m_type = LightType::Point;
Vector3 m_color = Vector3::One();
float m_intensity = 1.0f;
float m_range = 10.0f;
float m_spotAngle = 30.0f;
float m_penumbraAngle = 5.0f;
bool m_castShadows = true;
uint32_t m_shadowResolution = 1024;
float m_shadowBias = 0.005f;
float m_normalOffsetBias = 0.001f;
float m_nearPlane = 0.1f;
int32_t m_cullingMask = -1;
float m_intensityVariation = 0.0f;
ResourceGUID m_cookieTextureGuid = ResourceGUID::Invalid;
float m_cookieSize = 5.0f;
};
// 相机组件 - 继承Component类Unity Camera
class CameraComponent : public Component {
public:
void Awake() override;
void Start() override;
void Update(float deltaTime) override;
enum class ProjectionType : uint8_t {
Perspective,
Orthographic
};
void SetProjectionType(ProjectionType type) { m_projectionType = type; }
ProjectionType GetProjectionType() const { return m_projectionType; }
void SetFieldOfView(float fov) { m_fieldOfView = fov; }
float GetFieldOfView() const { return m_fieldOfView; }
void SetOrthographicSize(float size) { m_orthographicSize = size; }
float GetOrthographicSize() const { return m_orthographicSize; }
void SetNearClipPlane(float near) { m_nearPlane = near; }
float GetNearClipPlane() const { return m_nearPlane; }
void SetFarClipPlane(float far) { m_farPlane = far; }
float GetFarClipPlane() const { return m_farPlane; }
void SetViewport(const Rect& rect) { m_viewportRect = rect; }
const Rect& GetViewport() const { return m_viewportRect; }
void SetCullingMask(int32_t mask) { m_cullingMask = mask; }
int32_t GetCullingMask() const { return m_cullingMask; }
void SetDepth(float depth) { m_depth = depth; }
float GetDepth() const { return m_depth; }
Matrix4x4 GetViewMatrix() const;
Matrix4x4 GetProjectionMatrix() const;
Matrix4x4 GetViewProjectionMatrix() const;
Vector3 ScreenToWorldPoint(const Vector3& screenPoint) const;
Vector3 WorldToScreenPoint(const Vector3& worldPoint) const;
Ray ScreenPointToRay(const Vector2& screenPoint) const;
Frustum& GetFrustum() { return m_frustum; }
private:
ProjectionType m_projectionType = ProjectionType::Perspective;
float m_fieldOfView = 60.0f;
float m_orthographicSize = 5.0f;
float m_nearPlane = 0.1f;
float m_farPlane = 1000.0f;
float m_aspectRatio = 16.0f / 9.0f;
Rect m_viewportRect = Rect(0, 0, 1, 1);
float m_depth = 0.0f;
int32_t m_cullingMask = -1;
Frustum m_frustum;
};
// 物理组件 - 继承Component类Unity Rigidbody
class RigidBodyComponent : public Component {
public:
void Awake() override;
void Start() override;
void FixedUpdate() override;
void OnEnable() override;
void OnDisable() override;
void OnDestroy() override;
// 物理回调类Unity
void OnCollisionEnter(const Collision& collision) override;
void OnCollisionStay(const Collision& collision) override;
void OnCollisionExit(const Collision& collision) override;
void OnTriggerEnter(Collider* other) override;
void OnTriggerStay(Collider* other) override;
void OnTriggerExit(Collider* other) override;
enum class BodyType : uint8_t {
Dynamic,
Kinematic,
Static
};
void SetBodyType(BodyType type) { m_bodyType = type; }
BodyType GetBodyType() const { return m_bodyType; }
void SetMass(float mass) { m_mass = mass; }
float GetMass() const { return m_mass; }
void SetLinearDamping(float damping) { m_linearDamping = damping; }
float GetLinearDamping() const { return m_linearDamping; }
void SetAngularDamping(float damping) { m_angularDamping = damping; }
float GetAngularDamping() const { return m_angularDamping; }
void AddForce(const Vector3& force, ForceMode mode = ForceMode::Force);
void AddForceAtPosition(const Vector3& force, const Vector3& position, ForceMode mode = ForceMode::Force);
void AddTorque(const Vector3& torque, ForceMode mode = ForceMode::Force);
void SetVelocity(const Vector3& velocity);
Vector3 GetVelocity() const;
void SetAngularVelocity(const Vector3& velocity);
Vector3 GetAngularVelocity() const;
void SetUseGravity(bool use) { m_useGravity = use; }
bool IsUsingGravity() const { return m_useGravity; }
void SetIsKinematic(bool kinematic);
bool IsKinematic() const;
enum class InterpolateMode : uint8_t {
None,
Interpolate,
Extrapolate
};
void SetInterpolate(InterpolateMode mode);
InterpolateMode GetInterpolate() const { return m_interpolateMode; }
// 获取物理引擎内部句柄(用于 PhysicsWorld 调用,避免 GameObject* 悬空指针)
void* GetPhysicsHandle() const { return m_physicsHandle; }
void SetPhysicsHandle(void* handle) { m_physicsHandle = handle; }
private:
BodyType m_bodyType = BodyType::Dynamic;
float m_mass = 1.0f;
float m_linearDamping = 0.0f;
float m_angularDamping = 0.05f;
Vector3 m_velocity;
Vector3 m_angularVelocity;
bool m_useGravity = true;
InterpolateMode m_interpolateMode = InterpolateMode::None;
// 物理引擎内部句柄(由 PhysicsWorld 设置)
void* m_physicsHandle = nullptr;
};
// 碰撞组件 - 继承Component类Unity Collider
class ColliderComponent : public Component {
public:
void Awake() override;
void Start() override;
enum class ShapeType : uint8_t {
Box,
Sphere,
Capsule,
Mesh,
ConvexHull
};
void SetShapeType(ShapeType type) { m_shapeType = type; }
ShapeType GetShapeType() const { return m_shapeType; }
void SetCenter(const Vector3& center) { m_center = center; }
Vector3 GetCenter() const { return m_center; }
void SetSize(const Vector3& size) { m_boxSize = size; }
Vector3 GetSize() const { return m_boxSize; }
void SetRadius(float radius) { m_sphereRadius = radius; }
float GetRadius() const { return m_sphereRadius; }
void SetIsTrigger(bool trigger) { m_isTrigger = trigger; }
bool IsTrigger() const { return m_isTrigger; }
void SetMaterial(const ResourceGUID& guid);
ResourceGUID GetMaterial() const { return m_materialGuid; }
private:
ShapeType m_shapeType = ShapeType::Box;
Vector3 m_boxSize = Vector3::One();
float m_sphereRadius = 0.5f;
float m_capsuleRadius = 0.5f;
float m_capsuleHeight = 2.0f;
Vector3 m_center = Vector3::Zero();
Quaternion m_rotation = Quaternion::Identity();
int32_t m_layer = 0;
int32_t m_mask = -1;
float m_friction = 0.5f;
float m_restitution = 0.0f;
bool m_isTrigger = false;
bool m_convex = true;
ResourceGUID m_materialGuid = ResourceGUID::Invalid;
ResourceGUID m_meshGuid = ResourceGUID::Invalid;
// 物理引擎内部句柄(由 PhysicsWorld 设置)
void* m_physicsHandle = nullptr;
};
// 关节组件 - 继承Component类Unity Joint
class JointComponent : public Component {
public:
void Awake() override;
void OnDestroy() override;
enum class Type : uint8_t {
Hinge, // 铰链关节
Slider, // 滑块关节
Spring, // 弹簧关节
Fixed, // 固定关节
Configurable, // 可配置关节
Character // 角色关节
};
enum class Axis {
X, Y, Z
};
void SetJointType(Type type) { m_jointType = type; }
Type GetJointType() const { return m_jointType; }
void SetConnectedBody(GameObject* body) { m_connectedBody = body; }
GameObject* GetConnectedBody() const { return m_connectedBody; }
void SetAnchor(const Vector3& anchor) { m_anchor = anchor; }
Vector3 GetAnchor() const { return m_anchor; }
void SetAxis(const Vector3& axis) { m_axis = axis; }
Vector3 GetAxis() const { return m_axis; }
void SetBreakForce(float force) { m_breakForce = force; }
float GetBreakForce() const { return m_breakForce; }
void SetBreakTorque(float torque) { m_breakTorque = torque; }
float GetBreakTorque() const { return m_breakTorque; }
void SetEnableCollision(bool enable) { m_enableCollision = enable; }
bool GetEnableCollision() const { return m_enableCollision; }
bool IsBroken() const { return m_broken; }
private:
Type m_jointType = Type::Fixed;
GameObject* m_connectedBody = nullptr;
Vector3 m_anchor = Vector3::Zero();
Vector3 m_axis = Vector3::Up();
Vector3 m_secondaryAxis = Vector3::Right();
float m_breakForce = INFINITY;
float m_breakTorque = INFINITY;
bool m_enableCollision = false;
bool m_broken = false;
void* m_physicsJoint = nullptr;
};
// 音频源组件继承Component
class AudioSourceComponent : public Component {
public:
void Awake() override;
void Start() override;
void Update(float deltaTime) override;
void OnEnable() override;
void OnDisable() override;
void OnDestroy() override;
void Play();
void Stop();
void Pause();
bool IsPlaying() const;
bool IsPaused() const;
void SetClip(const ResourceGUID& guid);
ResourceGUID GetClip() const { return m_clipGuid; }
void SetLoop(bool loop) { m_loop = loop; }
bool GetLoop() const { return m_loop; }
void SetVolume(float volume) { m_volume = volume; }
float GetVolume() const { return m_volume; }
void SetPitch(float pitch) { m_pitch = pitch; }
float GetPitch() const { return m_pitch; }
void SetSpatialBlend(float blend) { m_spatialBlend = blend; }
float GetSpatialBlend() const { return m_spatialBlend; }
private:
ResourceGUID m_clipGuid;
bool m_playOnAwake = false;
bool m_loop = false;
bool m_isPlaying = false;
bool m_isPaused = false;
float m_volume = 1.0f;
float m_pitch = 1.0f;
float m_spatialBlend = 1.0f;
float m_minDistance = 1.0f;
float m_maxDistance = 500.0f;
};
// 音频监听器组件继承Component
class AudioListenerComponent : public Component {
public:
void Awake() override;
void SetDopplerFactor(float factor) { m_dopplerFactor = factor; }
float GetDopplerFactor() const { return m_dopplerFactor; }
void SetMasterVolume(float volume) { m_masterVolume = volume; }
float GetMasterVolume() const { return m_masterVolume; }
private:
float m_dopplerFactor = 1.0f;
float m_masterVolume = 1.0f;
};
} // namespace XCEngine
```
### 3.5 场景 (Scene)
> 说明传统Unity的Scene直接管理GameObject列表没有World中间层。
```cpp
namespace XCEngine {
// 场景类Unity Scene
// 直接管理GameObject列表不需要World
class Scene {
public:
Scene();
~Scene();
// 场景名称
const String& GetName() const { return m_name; }
void SetName(const String& name) { m_name = name; }
// GameObject管理类Unity Scene API
GameObject* CreateGameObject(const String& name = "GameObject") {
GameObject::ConstructParams params;
params.name = name;
params.parent = nullptr;
params.active = true;
GameObject* obj = GameObject::Create(params);
obj->m_scene = this;
AddGameObject(obj);
return obj;
}
GameObject* CreateGameObject(const String& name, GameObject* parent) {
GameObject::ConstructParams params;
params.name = name;
params.parent = parent;
params.active = true;
GameObject* obj = GameObject::Create(params);
obj->m_scene = this;
AddGameObject(obj);
return obj;
}
void DestroyGameObject(GameObject* obj);
// 根GameObject没有父对象的顶层GameObject从所有GameObject中筛选
// 注意此方法为O(n)复杂度与Unity的Scene.GetRootGameObjects行为一致
// Unity也不缓存根对象因为GameObject层级变化频繁缓存维护成本可能更高
std::vector<GameObject*> GetRootGameObjects() const {
std::vector<GameObject*> roots;
roots.reserve(m_gameObjects.size() / 2); // 预分配合理容量
for (auto& obj : m_gameObjects) {
if (obj->GetParent() == nullptr) {
roots.push_back(obj.get());
}
}
return roots;
}
// 查找
GameObject* Find(const String& name) const;
GameObject* FindGameObjectWithTag(const String& tag) const;
std::vector<GameObject*> FindGameObjectsWithTag(const String& tag) const;
template<typename T>
std::vector<T*> FindObjectsOfType() const;
T* FindObjectOfType() const;
// 激活状态
bool IsActive() const { return m_isActive; }
void SetActive(bool active);
// 生命周期
void Load(const String& filePath);
void LoadAsync(const String& filePath, std::function<void()> callback);
void Save(const String& filePath);
// 更新(内部调用)
void Update(float deltaTime);
void FixedUpdate(float fixedDeltaTime);
void LateUpdate(float deltaTime);
// 调试
void DebugDraw();
int GetObjectCount() const { return m_gameObjects.size(); }
private:
void AddGameObject(GameObject* obj);
void RemoveGameObject(GameObject* obj);
String m_name;
std::vector<std::unique_ptr<GameObject>> m_gameObjects;
bool m_isActive = true;
friend class GameObject;
friend class SceneManager;
};
// 场景管理器
class SceneManager {
public:
static SceneManager& Get();
void Initialize();
void Shutdown();
// 场景操作
Scene* CreateScene(const String& name);
void LoadScene(const String& filePath);
void LoadSceneAsync(const String& filePath, std::function<void(Scene*)> callback);
void UnloadScene(Scene* scene);
void UnloadScene(const String& sceneName);
// 活动场景
void SetActiveScene(Scene* scene);
void SetActiveScene(const String& sceneName);
Scene* GetActiveScene() const;
// 查找
Scene* GetScene(const String& name) const;
std::vector<Scene*> GetAllScenes() const;
// 更新
void Update(float deltaTime);
void FixedUpdate(float fixedDeltaTime);
void LateUpdate(float deltaTime);
// 事件
Event<Scene*> OnSceneLoaded;
Event<Scene*> OnSceneUnloaded;
Event<Scene*> OnActiveSceneChanged;
private:
SceneManager() = default;
std::vector<std::unique_ptr<Scene>> m_scenes;
Scene* m_activeScene = nullptr;
Scene* m_loadingScene = nullptr;
std::unordered_map<String, Scene*> m_sceneNameMap;
std::function<void(Scene*)> m_loadCallback;
bool m_loading = false;
};
} // namespace XCEngine
```
---
## 第四章 渲染系统 (Renderer)
> **架构说明**:
> - **RenderGraph** - 高级渲染管线抽象,定义 Pass 之间的依赖关系和资源流
> - **RenderContext** - 低级渲染上下文,管理 GPU 资源和执行具体的渲染命令
> - 关系RenderGraph 是声明式的渲染描述RenderContext 是执行层
### 4.1 渲染系统架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Rendering Pipeline │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ Render Pipeline Manager │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Render Graph Builder │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Pass 1 │ │ Pass 2 │ │ Pass 3 │ │ Pass N │ │ │
│ │ │ G-Buffer │ │ Lighting │ │ Shadow │ │ Post │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Render Passes │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ GBuffer │→ │ Shadow │→ │ Deferred │→ │ Forward │ │ │
│ │ │ Pass │ │ Pass │ │ Lighting │ │ Pass │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ ↓ ↓ ↓ ↓ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Depth │ │ Shadow │ │ SSAO │ │ Alpha │ │ │
│ │ │ Pre-Pass │ │ Update │ │ Pass │ │ Blend │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ ↓ │ │
│ │ ┌────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Post-Processing │ │ │
│ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │
│ │ │ │ SSAO │ │ SSR │ │ Bloom │ │ Tone │ │ FXAA │ │ │ │
│ │ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │ │
│ │ └────────────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ GPU Resources │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Vertex │ │ Index │ │ Uniform │ │ Texture │ │ Render │ │ │
│ │ │ Buffer │ │ Buffer │ │ Buffer │ │ Sampler │ │ Target │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 4.2 渲染抽象层
```cpp
namespace XCEngine {
namespace Rendering {
enum class ResourceState {
Undefined,
RenderTarget,
DepthStencil,
ShaderResource,
UnorderedAccess,
CopySrc,
CopyDst,
Present
};
struct ResourceDesc {
ResourceType type;
uint32_t width = 1;
uint32_t height = 1;
uint32_t depth = 1;
uint32_t mipLevels = 1;
uint32_t arraySize = 1;
Format format = Format::Unknown;
SampleCount sampleCount = SampleCount::Count1;
ResourceState initialState = ResourceState::Undefined;
bool cpuAccessible = false;
bool randomAccess = false;
MemoryUsage memoryUsage = MemoryUsage::Default;
String name;
};
class IRenderDevice {
public:
virtual ~IRenderDevice() = default;
virtual const char* GetApiName() const = 0;
virtual const char* GetDriverVersion() const = 0;
virtual uint64_t GetDeviceId() const = 0;
virtual uint64_t GetVendorId() const = 0;
virtual bool SupportsRaytracing() const = 0;
virtual bool SupportsMeshShaders() const = 0;
virtual bool SupportsVariableRateShading() const = 0;
virtual bool SupportsSamplerFeedback() const = 0;
virtual uint32_t GetMaxTextureSize() const = 0;
virtual uint32_t GetMaxUBOSize() const = 0;
virtual uint32_t GetMaxMSAA() const = 0;
virtual std::unique_ptr<RenderTexture> CreateTexture(const ResourceDesc& desc) = 0;
virtual std::unique_ptr<RenderBuffer> CreateBuffer(const ResourceDesc& desc, const void* initialData = nullptr) = 0;
virtual std::unique_ptr<Shader> CreateShader(const ShaderDesc& desc) = 0;
virtual std::unique_ptr<Pipeline> CreatePipeline(const PipelineDesc& desc) = 0;
virtual std::unique_ptr<RenderPass> CreateRenderPass(const RenderPassDesc& desc) = 0;
virtual ICommandQueue* GetGraphicsQueue() = 0;
virtual ICommandQueue* GetComputeQueue() = 0;
virtual ICommandQueue* GetCopyQueue() = 0;
virtual std::unique_ptr<IFence> CreateFence() = 0;
virtual IDescriptorHeap* CreateDescriptorHeap(const DescriptorHeapDesc& desc) = 0;
virtual std::unique_ptr<IQueryHeap> CreateQueryHeap(const QueryHeapDesc& desc) = 0;
};
class ICommandList {
public:
virtual ~ICommandList() = default;
virtual void TransitionBarrier(const IResource* resource, ResourceState newState) = 0;
virtual void UAVBarrier(const IResource* resource) = 0;
virtual void FlushBarriers() = 0;
virtual void SetPipeline(const IPipeline* pipeline) = 0;
virtual void SetVertexBuffer(uint32_t slot, const IBuffer* buffer, uint64_t offset = 0) = 0;
virtual void SetIndexBuffer(const IBuffer* buffer, IndexType indexType, uint64_t offset = 0) = 0;
virtual void SetConstantBuffer(uint32_t slot, const IBuffer* buffer, uint64_t offset = 0) = 0;
virtual void SetShaderResource(uint32_t slot, const IResource* resource) = 0;
virtual void SetSampler(uint32_t slot, const ISampler* sampler) = 0;
virtual void Draw(uint32_t vertexCount, uint32_t firstVertex = 0) = 0;
virtual void DrawIndexed(uint32_t indexCount, uint32_t firstIndex = 0, int32_t baseVertex = 0) = 0;
virtual void DrawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount,
uint32_t firstVertex = 0, uint32_t firstInstance = 0) = 0;
virtual void DrawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount,
uint32_t firstIndex = 0, int32_t baseVertex = 0, uint32_t firstInstance = 0) = 0;
virtual void Dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) = 0;
virtual void BuildAccelerationStructure(const RaytracingBuildDesc& desc) = 0;
virtual void SetRaytracingPipeline(const IPipeline* pipeline) = 0;
virtual void DispatchRays(const DispatchRaysDesc& desc) = 0;
virtual void BeginRenderPass(const RenderPassBeginDesc& desc) = 0;
virtual void EndRenderPass() = 0;
virtual void CopyResource(IResource* dst, const IResource* src) = 0;
virtual void CopyBuffer(IBuffer* dst, uint64_t dstOffset, const IBuffer* src, uint64_t srcOffset, uint64_t size) = 0;
virtual void BeginQuery(IQueryHeap* heap, uint32_t index) = 0;
virtual void EndQuery(IQueryHeap* heap, uint32_t index) = 0;
virtual void SetMarker(const char* name, uint32_t color) = 0;
virtual void BeginEvent(const char* name, uint32_t color) = 0;
virtual void EndEvent() = 0;
};
class RenderContext {
public:
// 前向声明
class GBufferPass;
class LightingPass;
class ShadowPass;
class PostProcessPass;
// 创建和销毁(支持多实例)
static RenderContext* Create(const RenderContextDesc& desc);
static void Destroy(RenderContext* context);
// 获取主上下文(默认上下文,用于单窗口场景)
static RenderContext* GetMain();
void Initialize(const RenderContextDesc& desc);
void Shutdown();
IRenderDevice* GetDevice() { return m_device.get(); }
void BeginFrame();
void EndFrame();
ICommandList* GetMainCommandList() { return m_mainCommandList.get(); }
void SetRenderTarget(const RenderTarget& target);
void SetViewport(const Viewport& viewport);
void SetScissorRect(const Rect& rect);
void RenderScene(const SceneRenderDesc& desc);
void ApplyPostProcessing(const PostProcessDesc& desc);
void CaptureFrame(const String& filePath);
void ToggleDebugView();
private:
std::unique_ptr<IRenderDevice> m_device;
std::unique_ptr<ICommandList> m_mainCommandList;
std::unique_ptr<ISwapChain> m_swapChain;
std::unique_ptr<GBufferPass> m_gBufferPass;
std::unique_ptr<LightingPass> m_lightingPass;
std::unique_ptr<ShadowPass> m_shadowPass;
std::unique_ptr<PostProcessPass> m_postProcessPass;
uint32_t m_frameIndex = 0;
uint64_t m_frameCount = 0;
// 静态主上下文(用于 GetMain()
static RenderContext* s_mainContext;
};
class RenderTexture : public IResource {
public:
uint32_t GetWidth() const { return m_width; }
uint32_t GetHeight() const { return m_height; }
uint32_t GetMipLevels() const { return m_mipLevels; }
Format GetFormat() const { return m_format; }
void* GetNativeHandle() const { return m_nativeHandle; }
IShaderResourceView* GetSRV() { return m_srv.get(); }
IRenderTargetView* GetRTV() { return m_rtv.get(); }
IDepthStencilView* GetDSV() { return m_dsv.get(); }
void* Map();
void Unmap();
private:
uint32_t m_width, m_height;
uint32_t m_mipLevels;
Format m_format;
void* m_nativeHandle = nullptr;
std::unique_ptr<IShaderResourceView> m_srv;
std::unique_ptr<IRenderTargetView> m_rtv;
std::unique_ptr<IDepthStencilView> m_dsv;
};
class RenderBuffer : public IResource {
public:
uint64_t GetSize() const { return m_size; }
BufferUsage GetUsage() const { return m_usage; }
void* GetNativeHandle() const { return m_nativeHandle; }
void SetData(const void* data, uint64_t size, uint64_t offset = 0);
void* Map();
void Unmap();
private:
uint64_t m_size;
BufferUsage m_usage;
void* m_nativeHandle = nullptr;
};
}
}
```
### 4.3 渲染图 (Render Graph)
```cpp
namespace XCEngine {
namespace Rendering {
class RenderGraphResource {
public:
RenderGraphResource() = default;
RenderGraphResource(const String& name);
const String& GetName() const { return m_name; }
uint32_t GetIndex() const { return m_index; }
bool IsValid() const { return m_index != UINT32_MAX; }
operator bool() const { return IsValid(); }
private:
String m_name;
uint32_t m_index = UINT32_MAX;
friend class RenderGraph;
};
class RenderGraphPass {
public:
using ExecuteFn = std::function<void(RenderGraphPass&, ICommandList&)>;
RenderGraphPass(const String& name, PassType type);
RenderGraphResource Read(const String& resourceName);
RenderGraphResource Write(const String& resourceName);
RenderGraphResource ReadWrite(const String& resourceName, ResourceState initialState, ResourceState finalState);
void Execute(ExecuteFn&& fn);
void Execute() const;
void SetDebugColor(const Color& color);
const String& GetName() const { return m_name; }
PassType GetType() const { return m_type; }
const std::vector<RenderGraphResource>& GetReads() const { return m_reads; }
const std::vector<RenderGraphResource>& GetWrites() const { return m_writes; }
private:
String m_name;
PassType m_type;
std::vector<RenderGraphResource> m_reads;
std::vector<RenderGraphResource> m_writes;
ExecuteFn m_executeFn;
Color m_debugColor;
friend class RenderGraph;
};
class RenderGraph {
public:
RenderGraph();
~RenderGraph();
RenderGraphResource CreateTexture(const String& name, const TextureDesc& desc);
RenderGraphResource CreateBuffer(const String& name, const BufferDesc& desc);
RenderGraphPass& AddPass(const String& name, PassType type);
void Build();
void Execute(ICommandList* commandList);
void SetName(const String& name);
void Print() const;
void ExportToDot(const String& filePath) const;
void Clear();
private:
void Compile();
void Validate();
void SortPasses();
void AllocateResources();
struct ResourceInfo {
String name;
ResourceDesc desc;
ResourceState currentState;
uint32_t firstPassWrite = UINT32_MAX;
uint32_t lastPassRead = UINT32_MAX;
bool imported = false;
};
struct PassInfo {
String name;
PassType type;
std::vector<uint32_t> reads;
std::vector<uint32_t> writes;
std::function<void(RenderGraphPass&, ICommandList&)> executeFn;
};
std::vector<ResourceInfo> m_resources;
std::vector<PassInfo> m_passes;
std::unordered_map<String, uint32_t> m_resourceIndex;
bool m_built = false;
};
}
}
```
---
## 第五章 资源系统 (Resource System)
### 5.1 资源管理架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Resource Management │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ Asset Database │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ GUID │ │ Path │ │ Meta │ │ │
│ │ │ 映射表 │ │ 索引 │ │ 数据 │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Resource Manager │ │
│ │ ┌───────────────────────────────────────────────────────────────┐ │ │
│ │ │ Resource Loader Registry │ │ │
│ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │
│ │ │ │ Mesh │ │ Texture│ │ Audio │ │ Material│ │ Shader │ │ │ │
│ │ │ │ Loader │ │ Loader │ │ Loader │ │ Loader │ │ Loader │ │ │ │
│ │ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │ │
│ │ └───────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────────────────▼────────────────────────────────────┐ │ │
│ │ │ Resource Cache │ │ │
│ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ LRU Cache │ │ │ │
│ │ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ │
│ │ │ │ │ Resource│ │ Resource│ │ Resource│ │ Resource│ │ │ │ │
│ │ │ │ │ 1 │ │ 2 │ │ 3 │ │ N │ │ │ │ │
│ │ │ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │ │ │
│ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │
│ │ └───────────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Import Pipeline │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Import │→ │ Process │→ │ Cook │→ │ Package │→ │ Index │ │ │
│ │ │ 导入 │ │ 处理 │ │ 烘焙 │ │ 打包 │ │ 索引 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 5.2 资源系统实现
```cpp
namespace XCEngine {
namespace Resources {
enum class ResourceType {
Unknown,
Mesh,
Texture,
Material,
Shader,
Audio,
Animation,
Skeleton,
Font,
Prefab,
Scene,
Script,
PhysicsMaterial,
NavMesh,
Video,
Custom
};
struct ResourceGUID {
static constexpr uint64_t INVALID = 0;
uint64_t value = INVALID;
bool IsValid() const { return value != INVALID; }
bool operator==(const ResourceGUID& other) const { return value == other.value; }
bool operator!=(const ResourceGUID& other) const { return value != other.value; }
String ToString() const;
static ResourceGUID FromString(const String& str);
struct Hash {
size_t operator()(const ResourceGUID& guid) const {
return std::hash<uint64_t>{}(guid.value);
}
};
};
class IResource {
public:
virtual ~IResource() = default;
virtual ResourceType GetType() const = 0;
virtual const String& GetName() const = 0;
virtual ResourceGUID GetGUID() const = 0;
virtual bool IsLoaded() const = 0;
virtual bool IsLoading() const = 0;
virtual float GetLoadingProgress() const = 0;
virtual void AddRef() = 0;
virtual void Release() = 0;
virtual uint32_t GetRefCount() const = 0;
virtual void Unload() = 0;
};
struct LoadRequest {
ResourceGUID guid;
ResourceType type;
std::function<void(IResource*)> callback;
std::function<void(float)> progressCallback;
bool async = true;
uint32_t priority = 0;
};
class IResourceLoader {
public:
virtual ~IResourceLoader() = default;
virtual ResourceType GetResourceType() const = 0;
virtual std::vector<String> GetSupportedExtensions() const = 0;
virtual bool CanLoad(const String& filePath) const = 0;
virtual bool Load(const String& filePath, IResource* resource) = 0;
virtual bool Save(const String& filePath, const IResource* resource) = 0;
virtual std::unique_ptr<IResource> CreateResource() = 0;
};
class ResourceRepository {
public:
void Initialize(const String& basePath);
void Shutdown();
std::unique_ptr<uint8_t[]> LoadRaw(const String& filePath, size_t& outSize);
std::unique_ptr<IStream> OpenStream(const String& filePath);
bool FileExists(const String& filePath);
bool DirectoryExists(const String& dirPath);
std::vector<String> GetFiles(const String& dirPath, const String& extension = "");
String GetFullPath(const String& relativePath);
String GetCachePath();
String GetSourcePath();
private:
String m_basePath;
String m_cachePath;
String m_sourcePath;
};
class ResourceCache {
public:
explicit ResourceCache(size_t maxMemory);
~ResourceCache();
void Initialize();
void Shutdown();
void Add(const ResourceGUID& guid, IResource* resource);
IResource* Find(const ResourceGUID& guid);
void Remove(const ResourceGUID& guid);
void Clear();
void SetMaxMemory(size_t bytes);
size_t GetCurrentMemory() const;
size_t GetMaxMemory() const;
void Touch(const ResourceGUID& guid);
void Evict(size_t bytesToFree);
struct Stats {
uint32_t hitCount;
uint32_t missCount;
size_t memoryUsed;
size_t memoryReserved;
};
const Stats& GetStats() const;
private:
struct CacheEntry {
IResource* resource;
size_t memorySize;
uint64_t lastAccess;
};
std::unordered_map<ResourceGUID, CacheEntry, ResourceGUID::Hash> m_cache;
size_t m_maxMemory;
size_t m_currentMemory;
Stats m_stats;
};
class ResourceManager {
public:
static ResourceManager& Get();
void Initialize(const ResourceManagerConfig& config);
void Shutdown();
void RegisterLoader(std::unique_ptr<IResourceLoader> loader);
IResourceLoader* GetLoader(ResourceType type) const;
IResourceLoader* GetLoaderForFile(const String& filePath) const;
ResourceGUID Load(const String& filePath);
ResourceGUID LoadAsync(const String& filePath, const std::function<void(IResource*)>& callback);
template<typename T>
std::shared_ptr<T> Get(const ResourceGUID& guid);
template<typename T>
std::shared_ptr<T> Get(const String& filePath);
void AddRef(const ResourceGUID& guid);
void Release(const ResourceGUID& guid);
ResourceGUID FindByPath(const String& path) const;
String GetPath(const ResourceGUID& guid) const;
bool Reload(const ResourceGUID& guid);
void Unload(const ResourceGUID& guid);
void UnloadUnused();
void PrintStatistics();
void RebuildDatabase();
void ScanDirectory(const String& dirPath);
private:
ResourceManager() = default;
std::unordered_map<ResourceType, std::unique_ptr<IResourceLoader>> m_loaders;
std::unordered_map<ResourceGUID, std::shared_ptr<IResource>, ResourceGUID::Hash> m_resources;
std::unordered_map<String, ResourceGUID> m_pathToGUID;
std::unordered_map<ResourceGUID, String, ResourceGUID::Hash> m_guidToPath;
std::unique_ptr<ResourceCache> m_cache;
std::unique_ptr<ResourceRepository> m_repository;
std::unique_ptr<AssetDatabase> m_assetDatabase;
std::atomic<uint64_t> m_nextGuid{1};
};
template<typename T>
class ResourcePtr {
public:
ResourcePtr() = default;
explicit ResourcePtr(const ResourceGUID& guid)
: m_guid(guid), m_resource(ResourceManager::Get().Get<T>(guid)) {}
ResourcePtr(const ResourcePtr& other)
: m_guid(other.m_guid), m_resource(other.m_resource) {}
~ResourcePtr() {
if (m_guid.IsValid()) {
ResourceManager::Get().Release(m_guid);
}
}
T* Get() const { return m_resource.get(); }
T* operator->() const { return m_resource.get(); }
T& operator*() const { return *m_resource; }
bool IsValid() const { return m_resource != nullptr; }
explicit operator bool() const { return IsValid(); }
const ResourceGUID& GetGUID() const { return m_guid; }
private:
ResourceGUID m_guid;
std::shared_ptr<T> m_resource;
};
}
}
```
---
## 第六章 场景系统 (Scene System)
> **架构说明**: Scene是Unity风格的场景直接管理GameObject列表没有World中间层负责场景生命周期管理、资源加载和序列化。
### 6.1 场景管理
```cpp
namespace XCEngine {
namespace Scene {
// 注意GameObject和Transform定义在Components命名空间中
// Transform是GameObject的内置组件包含父子层级关系
enum class SceneLoadFlags {
None = 0,
Async = 1 << 0,
Additive = 1 << 1,
Single = 1 << 2,
DontLoadAudio = 1 << 3,
DontCreatePhysics = 1 << 4,
SubScene = 1 << 5
};
inline SceneLoadFlags operator|(SceneLoadFlags a, SceneLoadFlags b) {
return static_cast<SceneLoadFlags>(static_cast<int>(a) | static_cast<int>(b));
}
inline SceneLoadFlags& operator|=(SceneLoadFlags& a, SceneLoadFlags b) {
a = a | b;
return a;
}
inline SceneLoadFlags operator&(SceneLoadFlags a, SceneLoadFlags b) {
return static_cast<SceneLoadFlags>(static_cast<int>(a) & static_cast<int>(b));
}
inline SceneLoadFlags& operator&=(SceneLoadFlags& a, SceneLoadFlags b) {
a = a & b;
return a;
}
inline bool HasFlag(SceneLoadFlags flags, SceneLoadFlags flag) {
return (static_cast<int>(flags) & static_cast<int>(flag)) != 0;
}
// 注意SceneManager 定义在 XCEngine 命名空间中(第三章 3.5 节)
// 此处只保留场景相关的辅助类型和序列化器
// 场景序列化器
// 支持 JSON 和 Binary 两种格式
class SceneSerializer {
public:
// 序列化格式
enum class Format {
JSON,
Binary
};
// 序列化到文件
static void Serialize(const Scene& scene, const String& filePath, Format format = Format::JSON);
static std::unique_ptr<Scene> Deserialize(const String& filePath);
// JSON 序列化 (使用已存在的 Core 命名空间中的 JSON 库)
static void SerializeToJson(const Scene& scene, Core::JsonDocument& doc);
static void DeserializeFromJson(Scene& scene, const Core::JsonDocument& doc);
// Binary 序列化 (使用 Core::IStream)
static void SerializeToBinary(const Scene& scene, Core::IStream& stream);
static std::unique_ptr<Scene> DeserializeFromBinary(Core::IStream& stream);
private:
static void SerializeGameObject(const GameObject& gameObject, Core::JsonValue& parent);
static void DeserializeGameObject(GameObject& gameObject, const Core::JsonValue& data);
static void SerializeComponent(uint32_t componentTypeId, const void* component, Core::JsonValue& parent);
static void DeserializeComponent(uint32_t componentTypeId, const GameObject& gameObject, const Core::JsonValue& data);
};
// ============================================================================
// 序列化辅助类型 (需要在 Core 命名空间中定义)
// ============================================================================
namespace Core {
// 流接口
class IStream {
public:
virtual ~IStream() = default;
virtual bool IsValid() const = 0;
virtual size_t GetPosition() const = 0;
virtual size_t GetSize() const = 0;
virtual size_t Read(void* buffer, size_t size) = 0;
virtual size_t Write(const void* buffer, size_t size) = 0;
virtual void Seek(size_t position) = 0;
virtual void Skip(size_t bytes) = 0;
virtual void Flush() = 0;
virtual bool IsReading() const = 0;
virtual bool IsWriting() const = 0;
};
// JSON 文档
class JsonDocument {
public:
JsonDocument();
~JsonDocument();
void Parse(const String& json);
void Parse(const char* json, size_t length);
JsonValue& GetRoot();
const JsonValue& GetRoot() const;
String ToString() const;
bool HasParseError() const;
String GetParseError() const;
};
// JSON 值
class JsonValue {
public:
enum class Type {
Null,
Bool,
Int,
Float,
String,
Array,
Object
};
JsonValue();
JsonValue(bool value);
JsonValue(int32_t value);
JsonValue(int64_t value);
JsonValue(float value);
JsonValue(double value);
JsonValue(const String& value);
JsonValue(const char* value);
~JsonValue();
Type GetType() const { return m_type; }
// 值的获取
bool GetBool() const;
int32_t GetInt() const;
int64_t GetInt64() const;
float GetFloat() const;
double GetDouble() const;
const String& GetString() const;
// 数组/对象访问
size_t GetSize() const;
JsonValue& operator[](size_t index);
const JsonValue& operator[](size_t index) const;
JsonValue& operator[](const String& key);
const JsonValue& operator[](const String& key) const;
bool Has(const String& key) const;
// 修改
JsonValue& SetBool(bool value);
JsonValue& SetInt(int32_t value);
JsonValue& SetFloat(float value);
JsonValue& SetString(const String& value);
JsonValue& AddArrayElement();
JsonValue& AddObjectMember(const String& key);
void Clear();
private:
Type m_type = Type::Null;
// ... 具体成员
};
} // namespace Core
}
}
```
---
## 第七章 物理系统 (Physics)
### 7.1 物理系统
```cpp
namespace XCEngine {
namespace Physics {
// 碰撞检测查询标志
enum class QueryFlags : uint32_t {
None = 0,
Colliders = 1 << 0,
Rigidodies = 1 << 1,
Transforms = 1 << 2,
All = Colliders | Rigidodies | Transforms
};
// 力学模式 (类Unity ForceMode)
enum class ForceMode : uint8_t {
Force = 0, // 持续力 (质量单位)
Acceleration = 1, // 加速度 (无质量单位)
Impulse = 2, // 瞬时冲量 (质量单位)
VelocityChange = 3 // 速度变化 (无质量单位)
};
enum class CollisionShapeType {
Sphere,
Box,
Capsule,
ConvexMesh,
ConcaveMesh,
Heightfield,
Compound
};
struct CollisionLayer {
static constexpr uint32_t MaxLayers = 32;
static constexpr uint32_t Default = 0;
uint32_t id;
String name;
uint32_t mask;
};
struct PhysicsMaterial {
float friction = 0.5f;
float restitution = 0.0f;
float frictionCombine = 0;
float restitutionCombine = 0;
bool isTrigger = false;
float staticFriction = 0.5f;
float dynamicFriction = 0.5f;
};
struct RaycastHit {
GameObject* gameObject;
Vector3 point;
Vector3 normal;
float distance;
Vector2 uv;
int32_t faceIndex;
float fraction;
ColliderComponent* collider = nullptr;
};
// 碰撞信息 (类Unity Collision)
struct Collision {
GameObject* gameObject = nullptr;
ColliderComponent* collider = nullptr;
RigidBodyComponent* rigidBody = nullptr;
Vector3 relativeVelocity;
Vector3 contactPoint;
Vector3 contactNormal;
std::vector<Vector3> contacts;
std::vector<Vector3> normals;
};
// 2D碰撞信息 (类Unity Collision2D)
struct Collision2D {
GameObject* gameObject = nullptr;
Collider2DComponent* collider = nullptr;
RigidBody2DComponent* rigidBody = nullptr;
Vector2 relativeVelocity;
Vector2 contactPoint;
Vector2 contactNormal;
std::vector<Vector2> contacts;
std::vector<Vector2> normals;
float fraction = 0.0f;
int32_t faceID = 0;
};
// 2D碰撞体组件 (类Unity Collider2D)
class Collider2DComponent : public Component {
public:
void Awake() override;
void Start() override;
enum class ShapeType : uint8_t {
Box,
Circle,
Capsule,
Polygon,
Edge
};
void SetShapeType(ShapeType type) { m_shapeType = type; }
ShapeType GetShapeType() const { return m_shapeType; }
void SetOffset(const Vector2& offset) { m_offset = offset; }
Vector2 GetOffset() const { return m_offset; }
void SetDensity(float density) { m_density = density; }
float GetDensity() const { return m_density; }
void SetIsTrigger(bool trigger) { m_isTrigger = trigger; }
bool IsTrigger() const { return m_isTrigger; }
void SetUsedByEffector(bool use) { m_usedByEffector = use; }
bool IsUsedByEffector() const { return m_usedByEffector; }
private:
ShapeType m_shapeType = ShapeType::Box;
Vector2 m_offset = Vector2::Zero();
float m_density = 1.0f;
bool m_isTrigger = false;
bool m_usedByEffector = false;
void* m_physicsHandle = nullptr;
};
// 2D刚体组件 (类Unity Rigidbody2D)
class RigidBody2DComponent : public Component {
public:
void Awake() override;
void Start() override;
void FixedUpdate() override;
enum class BodyType : uint8_t {
Dynamic,
Kinematic,
Static
};
enum class InterpolateMode : uint8_t {
None,
Interpolate,
Extrapolate
};
void SetBodyType(BodyType type) { m_bodyType = type; }
BodyType GetBodyType() const { return m_bodyType; }
void SetMass(float mass) { m_mass = mass; }
float GetMass() const { return m_mass; }
void SetLinearVelocity(const Vector2& velocity);
Vector2 GetLinearVelocity() const;
void SetAngularVelocity(float velocity);
float GetAngularVelocity() const;
void AddForce(const Vector2& force, ForceMode mode = ForceMode::Force);
void AddForceAtPosition(const Vector2& force, const Vector2& position, ForceMode mode = ForceMode::Force);
void SetGravityScale(float scale) { m_gravityScale = scale; }
float GetGravityScale() const { return m_gravityScale; }
void SetIsKinematic(bool kinematic) { m_kinematic = kinematic; }
bool IsKinematic() const { return m_kinematic; }
void SetInterpolateMode(InterpolateMode mode) { m_interpolateMode = mode; }
InterpolateMode GetInterpolateMode() const { return m_interpolateMode; }
void* GetPhysicsHandle() const { return m_physicsHandle; }
void SetPhysicsHandle(void* handle) { m_physicsHandle = handle; }
private:
BodyType m_bodyType = BodyType::Dynamic;
float m_mass = 1.0f;
Vector2 m_linearVelocity;
float m_angularVelocity = 0.0f;
float m_gravityScale = 1.0f;
bool m_kinematic = false;
InterpolateMode m_interpolateMode = InterpolateMode::None;
void* m_physicsHandle = nullptr;
};
struct CollisionEvent {
GameObject* gameObjectA;
GameObject* gameObjectB;
Vector3 point;
Vector3 normal;
Vector3 relativeVelocity;
enum class Type {
Enter,
Stay,
Exit
};
Type type;
};
class PhysicsWorld {
public:
PhysicsWorld();
~PhysicsWorld();
void Initialize(const PhysicsWorldDesc& desc);
void Shutdown();
void Simulate(float deltaTime);
void SetGravity(const Vector3& gravity);
Vector3 GetGravity() const { return m_gravity; }
// 物理组件注册(替代直接 SyncWithScene通过组件系统同步
void RegisterRigidBody(RigidBodyComponent* component);
void UnregisterRigidBody(RigidBodyComponent* component);
void RegisterCollider(ColliderComponent* component);
void UnregisterCollider(ColliderComponent* component);
bool Raycast(const Ray& ray, float maxDistance, RaycastHit& hit,
uint32_t layerMask = 0xFFFFFFFF, QueryFlags flags = QueryFlags::None);
bool RaycastMultiple(const Ray& ray, float maxDistance, std::vector<RaycastHit>& hits,
uint32_t layerMask = 0xFFFFFFFF, QueryFlags flags = QueryFlags::None);
bool CheckSphere(const Sphere& sphere, uint32_t layerMask = 0xFFFFFFFF);
bool CheckBox(const Box& box, uint32_t layerMask = 0xFFFFFFFF);
bool CheckCapsule(const Vector3& start, const Vector3& end, float radius,
uint32_t layerMask = 0xFFFFFFFF);
bool SphereCast(const Sphere& sphere, const Vector3& direction, float maxDistance,
RaycastHit& hit, uint32_t layerMask = 0xFFFFFFFF);
std::vector<GameObject*> OverlapSphere(const Sphere& sphere, uint32_t layerMask = 0xFFFFFFFF);
std::vector<GameObject*> OverlapBox(const Box& box, uint32_t layerMask = 0xFFFFFFFF);
// 使用 RigidBodyComponent* 代替 GameObject*,通过组件内部的句柄操作,避免悬空指针
void AddForce(RigidBodyComponent* component, const Vector3& force, ForceMode mode = ForceMode::Force);
void AddForceAtPosition(RigidBodyComponent* component, const Vector3& force, const Vector3& position,
ForceMode mode = ForceMode::Force);
void AddTorque(RigidBodyComponent* component, const Vector3& torque, ForceMode mode = ForceMode::Force);
void SetLinearVelocity(RigidBodyComponent* component, const Vector3& velocity);
void SetAngularVelocity(RigidBodyComponent* component, const Vector3& velocity);
Vector3 GetLinearVelocity(RigidBodyComponent* component) const;
Vector3 GetAngularVelocity(RigidBodyComponent* component) const;
void SetKinematic(RigidBodyComponent* component, bool kinematic);
// Joint 由 JointComponent 组件管理,不再由 PhysicsWorld 直接创建
Event<const CollisionEvent&> OnCollisionEnter;
Event<const CollisionEvent&> OnCollisionStay;
Event<const CollisionEvent&> OnCollisionExit;
Event<const CollisionEvent&> OnTriggerEnter;
Event<const CollisionEvent&> OnTriggerStay;
Event<const CollisionEvent&> OnTriggerExit;
void DebugDraw();
void SetDebugDrawEnabled(bool enabled);
private:
void* m_physicsBackend = nullptr;
Vector3 m_gravity = Vector3(0, -9.81f, 0);
std::vector<CollisionEvent> m_collisionEvents;
std::vector<CollisionEvent> m_triggerEvents;
bool m_debugDrawEnabled = false;
};
class CharacterControllerComponent : public Component {
public:
void Awake() override;
void Update(float deltaTime) override;
void OnDestroy() override;
void Initialize(const CharacterControllerDesc& desc);
void Move(const Vector3& displacement);
void SetVelocity(const Vector3& velocity);
Vector3 GetVelocity() const { return m_velocity; }
bool IsGrounded() const { return m_grounded; }
Vector3 GetGroundNormal() const { return m_groundNormal; }
GameObject* GetGroundObject() const { return m_groundObject; }
void Jump(const Vector3& jumpForce);
void SetJumpEnabled(bool enabled);
void SetSlopeLimit(float angle);
void SetStepOffset(float height);
void SetSkinWidth(float width);
bool DetectCollision(const Vector3& position, const Vector3& direction, float distance);
private:
void UpdateGroundStatus();
void HandleCollision();
Vector3 m_velocity = Vector3::Zero();
Vector3 m_pendingForces = Vector3::Zero();
float m_slopeLimit = 45.0f;
float m_stepOffset = 0.5f;
float m_skinWidth = 0.02f;
float m_minDistance = 0.1f;
bool m_grounded = false;
bool m_jumpEnabled = true;
Vector3 m_groundNormal = Vector3::Up();
GameObject* m_groundObject = nullptr;
uint32_t m_layer = 0;
uint32_t m_collisionMask = 0xFFFFFFFF;
};
}
}
```
---
## 第八章 音频系统 (Audio)
> **架构说明**: Unity风格的音频系统。音频源和监听器都是挂载在GameObject上的组件。
> AudioEngine是底层实现提供音频解码、混音、空间化等功能。
### 8.1 音频系统
```cpp
namespace XCEngine {
namespace Audio {
// 音频格式
enum class AudioFormat {
Unknown,
WAV,
OGG,
MP3,
FLAC,
AAC
};
// 音频片段 (资源)
class AudioClip : public IResource {
public:
AudioClip();
~AudioClip();
const String& GetName() const override { return m_name; }
ResourceType GetType() const override { return ResourceType::Audio; }
ResourceGUID GetGUID() const override { return m_guid; }
bool IsLoaded() const override { return m_loaded; }
bool IsLoading() const override { return m_loading; }
float GetLoadingProgress() const override { return m_loadProgress; }
const uint8_t* GetData() const { return m_data.get(); }
size_t GetDataSize() const { return m_dataSize; }
uint32_t GetSampleRate() const { return m_sampleRate; }
uint32_t GetChannels() const { return m_channels; }
uint32_t GetBitsPerSample() const { return m_bitsPerSample; }
float GetDuration() const { return m_duration; }
AudioFormat GetFormat() const { return m_format; }
private:
String m_name;
ResourceGUID m_guid;
std::unique_ptr<uint8_t[]> m_data;
size_t m_dataSize = 0;
uint32_t m_sampleRate = 44100;
uint32_t m_channels = 2;
uint32_t m_bitsPerSample = 16;
float m_duration = 0.0f;
AudioFormat m_format = AudioFormat::Unknown;
bool m_loaded = false;
bool m_loading = false;
float m_loadProgress = 0.0f;
friend class AudioEngine;
};
// 音频总线 (混音器)
class AudioBus {
public:
AudioBus(const String& name, AudioBus* parent = nullptr);
void SetVolume(float volume);
float GetVolume() const { return m_volume; }
void SetMute(bool mute);
bool IsMuted() const { return m_muted; }
void SetBypassEffects(bool bypass);
bool IsBypassingEffects() const { return m_bypassEffects; }
void AddEffect(AudioEffect* effect);
void RemoveEffect(AudioEffect* effect);
private:
String m_name;
AudioBus* m_parent = nullptr;
std::vector<AudioBus*> m_children;
std::vector<std::unique_ptr<AudioEffect>> m_effects;
float m_volume = 1.0f;
bool m_muted = false;
bool m_bypassEffects = false;
};
// 音频引擎 - 底层实现 (不对外直接使用)
class AudioEngine {
public:
static AudioEngine& Get();
void Initialize(const AudioEngineConfig& config);
void Shutdown();
const char* GetDeviceName() const;
uint32_t GetSpeakerCount() const;
void Update(float deltaTime);
// 资源管理
std::shared_ptr<AudioClip> LoadClip(const String& filePath);
void UnloadClip(AudioClip* clip);
// 混音器
AudioBus* GetMasterBus() { return m_masterBus.get(); }
AudioBus* GetBus(const String& path);
AudioBus* CreateBus(const String& path);
// 内部音频源管理 (由 AudioSystem 使用)
struct InternalSource {
uint64_t id = 0;
void* handle = nullptr; // 底层音频引擎句柄
};
InternalSource CreateInternalSource();
void DestroyInternalSource(InternalSource source);
void SetSourceClip(InternalSource source, AudioClip* clip);
void PlaySource(InternalSource source);
void StopSource(InternalSource source);
void PauseSource(InternalSource source);
void SetSourceVolume(InternalSource source, float volume);
void SetSourcePitch(InternalSource source, float pitch);
void SetSourcePosition(InternalSource source, const Vector3& position);
void SetSourceLoop(InternalSource source, bool loop);
bool IsSourcePlaying(InternalSource source);
// 监听器管理 - Unity 限制只能有一个 AudioListener
void SetListenerComponent(AudioListenerComponent* listener);
AudioListenerComponent* GetListenerComponent() const { return m_listenerComponent; }
void SetListenerPosition(const Vector3& position);
void SetListenerVelocity(const Vector3& velocity);
void SetListenerOrientation(const Vector3& forward, const Vector3& up);
void SetListenerDopplerFactor(float factor);
struct Stats {
uint32_t activeVoices;
uint32_t totalVoices;
uint32_t playingSources;
uint32_t cpuUsage;
size_t memoryUsage;
};
const Stats& GetStats() const { return m_stats; }
private:
AudioEngine() = default;
std::unique_ptr<AudioBus> m_masterBus;
std::unordered_map<uint64_t, std::shared_ptr<AudioClip>> m_loadedClips;
std::vector<InternalSource> m_activeSources;
uint64_t m_nextSourceId = 1;
// 监听器状态
Vector3 m_listenerPosition;
Vector3 m_listenerVelocity;
Vector3 m_listenerForward = Vector3::Forward();
Vector3 m_listenerUp = Vector3::Up();
float m_listenerDopplerFactor = 1.0f;
// 限制只能有一个 AudioListener
AudioListenerComponent* m_listenerComponent = nullptr;
Stats m_stats;
void* m_backend = nullptr; // FMOD / Wwise / OpenAL
};
} // namespace Audio
} // namespace XCEngine
```
---
## 第十章 动画系统 (Animation)
### 10.1 动画系统架构
```cpp
namespace XCEngine {
namespace Animation {
// 动画曲线
struct AnimationCurve {
std::vector<Keyframe<float>> floatKeys;
std::vector<Keyframe<Vector3>> vector3Keys;
std::vector<Keyframe<Quaternion>> quaternionKeys;
std::vector<Keyframe<Color>> colorKeys;
// 具体类型的求值方法
float EvaluateFloat(float time, float defaultValue = 0.0f) const;
Vector3 EvaluateVector3(float time, const Vector3& defaultValue = Vector3::Zero()) const;
Quaternion EvaluateQuaternion(float time, const Quaternion& defaultValue = Quaternion::Identity()) const;
Color EvaluateColor(float time, const Color& defaultValue = Color::White) const;
// 具体类型的 Key 操作
void AddKeyFloat(float time, float value);
void AddKeyVector3(float time, const Vector3& value);
void AddKeyQuaternion(float time, const Quaternion& value);
void AddKeyColor(float time, const Color& value);
void RemoveKeyFloat(float time);
void RemoveKeyVector3(float time);
void RemoveKeyQuaternion(float time);
void RemoveKeyColor(float time);
};
// 动画片段
struct AnimationClip : public IResource {
float duration = 0.0f;
float sampleRate = 30.0f;
bool loop = false;
// 轨道
struct Track {
String path; // 目标路径 e.g., "Root/Child/Arm"
enum Type { Position, Rotation, Scale, Float, Int, Bool, Trigger } type;
AnimationCurve curve;
};
std::vector<Track> tracks;
// 事件
struct Event {
float time;
String functionName;
String stringParameter;
float floatParameter;
int intParameter;
};
std::vector<Event> events;
};
// 骨骼
struct Bone {
String name;
int32 parentIndex = -1;
Matrix4x4 localMatrix;
Matrix4x4 worldMatrix;
Vector3 position;
Quaternion rotation;
Vector3 scale;
};
// 骨架
struct Skeleton : public IResource {
std::vector<Bone> bones;
int32 rootBoneIndex = -1;
int32 FindBone(const String& name) const;
const Bone& GetBone(int32 index) const;
Matrix4x4 GetBoneMatrix(int32 index) const;
};
// 蒙皮数据
struct SkinningData {
std::vector<Matrix4x4> bindPoses;
std::vector<uint32_t> boneIndices;
std::vector<float> boneWeights;
};
// 动画状态机
class AnimatorStateMachine {
public:
struct State {
String name;
AnimationClip* clip = nullptr;
float speed = 1.0f;
float cycleOffset = 0.0f;
std::vector<Transition> transitions;
};
struct Transition {
String targetState;
float exitTime = 0.0f;
float duration = 0.0f;
enum class ConditionMode {
If,
IfNot,
Greater,
Less,
Equals
};
struct Condition {
String parameter;
ConditionMode mode;
float threshold;
};
std::vector<Condition> conditions;
};
struct Parameter {
enum Type { Float, Int, Bool, Trigger } type;
String name;
};
// 状态管理
void AddState(const String& name);
void AddTransition(const String& from, const String& to, const Transition& transition);
void AddParameter(const Parameter& param);
// 播放控制
void Play(const String& stateName);
void CrossFade(const String& stateName, float duration);
void Stop();
// 参数
void SetFloat(const String& name, float value);
void SetInt(const String& name, int32 value);
void SetBool(const String& name, bool value);
void SetTrigger(const String& name);
float GetFloat(const String& name) const;
int32 GetInt(const String& name) const;
bool GetBool(const String& name) const;
// 动画层级
void AddLayer(const String& name, float weight = 1.0f);
void SetLayerWeight(const String& name, float weight);
private:
std::vector<State> m_states;
std::vector<Parameter> m_parameters;
std::unordered_map<String, int32> m_stateIndices;
String m_currentState;
String m_previousState;
float m_currentTime = 0.0f;
};
// 动画器组件 - 继承Component类Unity Animator
class AnimatorComponent : public Component {
public:
void Awake() override;
void Start() override;
void Update(float deltaTime) override;
void OnDestroy() override;
void SetSkeleton(Skeleton* skeleton);
Skeleton* GetSkeleton() const { return m_skeleton; }
// 播放控制
void Play(const String& stateName);
void CrossFade(const String& stateName, float duration);
void PlayInFixedTime(const String& stateName, float normalizedTime);
bool IsPlaying() const;
float GetCurrentAnimationTime() const;
float GetCurrentAnimationLength() const;
// 层
void AddLayer(const String& name, float weight);
void SetLayerWeight(const String& name, float weight);
// 参数
void SetFloat(const String& name, float value);
void SetInteger(const String& name, int32 value);
void SetBool(const String& name, bool value);
void SetTrigger(const String& name);
// 根运动
void SetApplyRootMotion(bool apply) { m_applyRootMotion = apply; }
bool GetApplyRootMotion() const { return m_applyRootMotion; }
Vector3 GetRootPosition() const { return m_rootPosition; }
Quaternion GetRootRotation() const { return m_rootRotation; }
private:
Skeleton* m_skeleton = nullptr;
std::unique_ptr<AnimatorStateMachine> m_stateMachine;
bool m_useGPUAnimation = false;
Buffer* m_boneMatricesBuffer = nullptr;
bool m_applyRootMotion = false;
Vector3 m_rootPosition;
Quaternion m_rootRotation;
};
// 动画系统管理器 (处理GPU蒙皮、事件等)
class AnimationSystem {
public:
static AnimationSystem& Get();
void Initialize();
void Shutdown();
void Update(float deltaTime);
void UpdateGPUBuffers(AnimatorComponent* animator);
void ProcessAnimationEvents(AnimatorComponent* animator, float prevTime, float currentTime);
private:
void EvaluateState(AnimatorComponent* animator, float time,
std::vector<Matrix4x4>& boneMatrices);
void BlendStates(AnimatorComponent* animator, float blendWeight,
const std::vector<Matrix4x4>& from,
const std::vector<Matrix4x4>& to,
std::vector<Matrix4x4>& output);
};
// GPU 蒙皮
void UpdateGPUBuffers(AnimatorComponent* animator);
// 事件触发
void ProcessAnimationEvents(AnimatorComponent* animator, float prevTime, float currentTime);
private:
void EvaluateState(AnimatorComponent* animator, float time,
std::vector<Matrix4x4>& boneMatrices);
void BlendStates(AnimatorComponent* animator, float blendWeight,
const std::vector<Matrix4x4>& from,
const std::vector<Matrix4x4>& to,
std::vector<Matrix4x4>& output);
};
// Blend Shape
struct BlendShape {
String name;
std::vector<Vector3> vertices;
std::vector<Vector3> normals;
std::vector<Vector3> tangents;
};
struct BlendShapeFrame {
float weight = 0.0f;
std::vector<Vector3> deltaVertices;
std::vector<Vector3> deltaNormals;
std::vector<Vector3> deltaTangents;
};
struct BlendShapeData {
std::vector<BlendShape> shapes;
std::vector<BlendShapeFrame> frames;
};
// 程序化动画
namespace ProceduralAnimation {
class IKChain {
public:
void SetJoints(const std::vector<TransformComponent*>& joints);
void Solve(const Vector3& target);
void SetPoleVector(const Vector3& pole);
void SetIterations(int32 iterations);
private:
std::vector<TransformComponent*> m_joints;
Vector3 m_poleVector;
int32_t m_iterations = 10;
};
class CCDIK : public IKChain {
public:
void Solve(const Vector3& target) override;
};
class FABRIK : public IKChain {
public:
void Solve(const Vector3& target) override;
private:
void ForwardReach(const Vector3& target);
void BackwardReach(const Vector3& base);
void SolveConstraints();
};
} // namespace ProceduralAnimation
} // namespace Animation
} // namespace XCEngine
```
---
## 第十一章 粒子系统 (Particle System)
### 11.1 粒子系统架构
```cpp
namespace XCEngine {
namespace Particles {
// 粒子数据 - 粒子系统使用SoA布局以优化SIMD性能这是性能关键路径的例外
struct Particle {
Vector3 position;
Vector3 velocity;
Vector3 acceleration;
Quaternion rotation;
float rotationSpeed;
float size;
float lifetime;
float age;
Color color;
float alpha;
uint32_t seed;
bool alive;
};
// 粒子发射器
class ParticleEmitter {
public:
// 发射模式
enum class EmitMode {
Continuous,
Burst,
Distance
};
// 形状
enum class ShapeType {
Sphere,
Box,
Cone,
Circle,
Edge,
MeshSurface,
MeshVolume
};
// 发射参数
float rate = 10.0f;
int maxParticles = 1000;
float lifetime = 5.0f;
// 初始速度
Vector3 velocityMin = Vector3(-1, 1, -1);
Vector3 velocityMax = Vector3(1, 1, 1);
float speedMin = 1.0f;
float speedMax = 5.0f;
// 初始变换
float startSizeMin = 0.1f;
float startSizeMax = 0.5f;
float startRotationMin = 0.0f;
float startRotationMax = 360.0f;
Color startColor = Color::White;
// 形状
ShapeType shape = ShapeType::Sphere;
float shapeRadius = 1.0f;
float shapeAngle = 25.0f;
Vector3 shapeBoxSize = Vector3::One();
// 发射
EmitMode emitMode = EmitMode::Continuous;
int burstCount = 10;
float burstInterval = 1.0f;
};
// 粒子系统组件 - 继承Component类Unity ParticleSystem
class ParticleSystemComponent : public Component {
public:
void Awake() override;
void Start() override;
void Update(float deltaTime) override;
void OnDestroy() override;
// 播放控制Unity 风格)
void Play();
void Stop();
void Pause();
void Resume();
void Clear();
bool IsPlaying() const { return m_isPlaying && !m_isPaused; }
bool IsPaused() const { return m_isPaused; }
bool IsStopped() const { return !m_isPlaying; }
void SetLoop(bool loop) { m_loop = loop; }
bool GetLoop() const { return m_loop; }
void SetEmitRate(float rate) { m_emitter.rate = rate; }
float GetEmitRate() const { return m_emitter.rate; }
void SetLifetime(float lifetime) { m_emitter.lifetime = lifetime; }
float GetLifetime() const { return m_emitter.lifetime; }
void SetStartSpeed(float speed) { m_emitter.speedMin = m_emitter.speedMax = speed; }
float GetStartSpeed() const { return m_emitter.speedMin; }
void SetStartSize(float size) { m_emitter.startSizeMin = m_emitter.startSizeMax = size; }
float GetStartSize() const { return m_emitter.startSizeMin; }
void SetStartColor(const Color& color) { m_emitter.startColor = color; }
Color GetStartColor() const { return m_emitter.startColor; }
private:
ParticleEmitter m_emitter;
bool m_isPlaying = false;
bool m_isPaused = false;
bool m_loop = true;
float m_simulationSpeed = 1.0f;
float m_startDelay = 0.0f;
uint32_t m_randomSeed = 0;
};
// GPU 粒子系统
class GPUParticleSystem {
public:
void Initialize(uint32_t maxParticles);
void Shutdown();
void Update(float deltaTime, const ParticleSystemComponent& config);
void Render(RenderContext& context);
// GPU 缓冲区
Buffer* GetPositionBuffer() { return m_positionBuffer.get(); }
Buffer* GetVelocityBuffer() { return m_velocityBuffer.get(); }
Buffer* GetColorBuffer() { return m_colorBuffer.get(); }
private:
struct GPUParticle {
Vector4 position; // w = size
Vector4 velocity; // w = lifetime
Vector4 color; // w = rotation
};
uint32_t m_maxParticles = 0;
std::unique_ptr<Buffer> m_positionBuffer;
std::unique_ptr<Buffer> m_velocityBuffer;
std::unique_ptr<Buffer> m_colorBuffer;
std::unique_ptr<Buffer> m_indexBuffer;
ComputePipeline m_updatePipeline;
};
// 粒子系统管理器
class ParticleSystemManager {
public:
static ParticleSystemManager& Get();
void Initialize();
void Shutdown();
void Update(float deltaTime);
void Render(RenderContext& context);
// 发射器
ParticleEmitter* CreateEmitter();
void DestroyEmitter(ParticleEmitter* emitter);
// GPU 粒子
GPUParticleSystem* GetGPUParticleSystem() { return &m_gpuSystem; }
private:
std::vector<std::unique_ptr<ParticleEmitter>> m_emitters;
GPUParticleSystem m_gpuSystem;
};
// VFX Graph 集成
namespace VFXGraph {
class VFXGraphAsset : public IResource {
public:
// VFX Graph 描述
};
class VFXGraphComponent : public Component {
public:
void Update(float deltaTime) override;
VFXGraphAsset* asset = nullptr;
std::unordered_map<String, float> floatParameters;
std::unordered_map<String, Vector3> vector3Parameters;
std::unordered_map<String, Color> colorParameters;
std::unordered_map<String, bool> boolParameters;
void SetFloat(const String& name, float value);
void SetVector3(const String& name, const Vector3& value);
void SetColor(const String& name, const Color& value);
void SetBool(const String& name, bool value);
void Play();
void Stop();
void Pause();
void SetSeed(uint32_t seed);
};
} // namespace VFXGraph
} // namespace Particles
} // namespace XCEngine
```
---
## 第十二章 网络系统 (Networking)
### 12.1 网络系统架构
```cpp
namespace XCEngine {
namespace Networking {
// 网络模式
enum class NetworkMode {
Offline,
Host,
Client,
Server
};
// 传输层
enum class TransportProtocol {
UDP,
TCP,
WebSocket
};
// 网络消息
struct NetworkMessage {
uint32_t type;
uint32_t channel;
uint32_t senderId;
uint64_t sequence;
uint64_t timestamp;
std::vector<uint8_t> data;
};
// 消息类型
enum class MessageType : uint32_t {
// 内置
Connect = 1,
Disconnect = 2,
Heartbeat = 3,
Ack = 4,
// 游戏
Spawn = 100,
Despawn = 101,
TransformUpdate = 102,
ComponentUpdate = 103,
RPC = 104,
SceneChange = 105,
};
// 网络通道
enum class NetworkChannel {
Reliable,
Unreliable,
Voice,
Raw
};
// 网络连接
class NetworkConnection {
public:
uint32_t GetId() const { return m_id; }
const String& GetAddress() const { return m_address; }
float GetRoundTripTime() const { return m_rtt; }
bool IsConnected() const { return m_connected; }
void Send(uint32_t type, const void* data, size_t size, NetworkChannel channel);
void Disconnect();
private:
uint32_t m_id = 0;
String m_address;
bool m_connected = false;
float m_rtt = 0.0f;
};
// 网络玩家
struct NetworkPlayer {
uint32_t id;
String name;
NetworkConnection* connection = nullptr;
GameObject* avatar = nullptr;
bool isLocal = false;
bool isReady = false;
};
// 网络管理器
class NetworkManager {
public:
static NetworkManager& Get();
void Initialize(const NetworkConfig& config);
void Shutdown();
// 模式
NetworkMode GetMode() const { return m_mode; }
// 主机
bool StartHost(uint16_t port);
void StopHost();
// 客户端
bool Connect(const String& address, uint16_t port);
void Disconnect();
// 玩家
uint32_t GetLocalPlayerId() const { return m_localPlayerId; }
NetworkPlayer* GetPlayer(uint32_t id);
const std::vector<NetworkPlayer*>& GetPlayers();
// 消息
void Send(uint32_t playerId, uint32_t type, const void* data, size_t size,
NetworkChannel channel = NetworkChannel::Reliable);
void SendToAll(uint32_t type, const void* data, size_t size,
NetworkChannel channel = NetworkChannel::Reliable);
// RPC
template<typename T>
void RegisterRPC(const String& name, T* obj, void (T::*func)(NetworkReader&));
// 场景同步
void SetNetworkedScene(Scene* scene);
void AddNetworkedObject(GameObject* gameObject);
void RemoveNetworkedObject(GameObject* gameObject);
// 同步
void Update(float deltaTime);
// 事件
Event<uint32_t> OnPlayerConnected;
Event<uint32_t> OnPlayerDisconnected;
Event<NetworkMessage&> OnMessageReceived;
private:
NetworkMode m_mode = NetworkMode::Offline;
uint32_t m_localPlayerId = 0;
std::vector<NetworkPlayer> m_players;
void* m_transport = nullptr; // ENet / LiteNetLib / custom
};
// 网络组件
class NetworkIdentityComponent : public Component {
public:
void Update(float deltaTime) override;
uint32_t networkId = 0;
bool isLocalPlayer = false;
bool isOwnedByClient = false;
bool canSpawn = true;
bool syncTransform = true;
bool syncComponents = true;
};
class NetworkTransformComponent : public Component {
public:
void Update(float deltaTime) override;
enum class SyncMode {
None,
SyncTransform,
SyncPosition,
SyncPositionAndRotation,
SyncPositionRotationScale
};
SyncMode syncMode = SyncMode::SyncPositionRotationScale;
float snapThreshold = 0.5f;
float interpolationDelay = 0.1f;
float syncInterval = 0.05f;
bool enablePrediction = true;
float predictionTime = 0.1f;
bool quantizePosition = true;
int positionPrecision = 0.01f;
bool quantizeRotation = true;
int rotationPrecision = 1;
};
// 远程过程调用
namespace RPC {
// RPC 属性
enum class RpcTarget {
Server,
Others,
All,
Specific
};
enum class RpcMode {
Normal,
Buffered,
Unbuffered
};
// RPC 调用
struct RpcCall {
String methodName;
std::vector<uint8_t> args;
RpcTarget target;
uint32_t targetPlayer;
float timestamp;
};
// 注册 RPC
#define XE_RPC(methodName, target) \
void methodName(NetworkReader& reader); \
static void _RPC_##methodName(NetworkIdentityComponent* identity, NetworkReader& reader) { \
auto* comp = identity->GetComponent<NetworkIdentityComponent>(); \
if (comp && comp->isOwnedByClient) { \
auto* obj = static_cast<MyClass*>(identity); \
obj->methodName(reader); \
} \
}
// 服务器/客户端 RPC
class RpcHandler {
public:
void Register(uint32_t hash, std::function<void(NetworkIdentityComponent*, NetworkReader&)> handler);
void Call(NetworkIdentityComponent* identity, uint32_t methodHash, NetworkWriter& writer,
RpcTarget target, uint32_t targetPlayer = 0);
void Handle(NetworkMessage& msg);
};
} // namespace RPC
// 网络序列化
class NetworkSerializer {
public:
void Serialize(NetworkWriter& writer, const GameObject& gameObject);
void Deserialize(NetworkReader& reader, GameObject& gameObject);
void SerializeTransform(NetworkWriter& writer, const TransformComponent& transform);
void DeserializeTransform(NetworkReader& reader, TransformComponent& transform);
// 组件同步
void SerializeComponent(NetworkWriter& writer, uint32_t componentTypeId, const void* component);
void* DeserializeComponent(NetworkReader& reader, uint32_t componentTypeId, GameObject* gameObject);
};
// 网络预测
class ClientPrediction {
public:
struct PredictedState {
Vector3 position;
Quaternion rotation;
Vector3 velocity;
float timestamp;
};
void StorePredictedState(const Vector3& position, const Quaternion& rotation,
const Vector3& velocity);
void ApplyServerCorrection(const Vector3& serverPosition, const Quaternion& serverRotation);
bool HasPredictionError() const;
void Reconcile();
private:
std::deque<PredictedState> m_predictedStates;
std::deque<PredictedState> m_unconfirmedStates;
Vector3 m_lastServerPosition;
Quaternion m_lastServerRotation;
};
// 延迟补偿
class LagCompensation {
public:
struct ServerFrame {
float timestamp;
std::vector<EntitySnapshot> entities;
};
void RecordFrame(const std::vector<EntitySnapshot>& entities);
EntitySnapshot GetInterpolatedSnapshot(float timestamp);
bool Raycast(Ray& ray, float maxDistance, RaycastHit& hit);
private:
std::deque<ServerFrame> m_frames;
float m_recordDuration = 1.0f; // 记录1秒
};
} // namespace Networking
} // namespace XCEngine
```
---
## 第十三章 UI 系统 (In-Game UI / UGUI)
> **架构说明**: Unity UGUI风格的UI系统。UI元素作为组件挂载在GameObject上。
> 每个UI元素GameObject必须挂载RectTransform组件。
### 13.1 UI 系统架构
```cpp
namespace XCEngine {
namespace UI {
// ============================================================================
// UI 组件 (Unity UGUI风格)
// ============================================================================
// 矩形变换组件 (Unity RectTransform继承 Transform)
class RectTransformComponent : public TransformComponent {
public:
void Update(float deltaTime) override;
// 锚点
Vector2 anchorMin = Vector2(0, 0);
Vector2 anchorMax = Vector2(0, 0);
Vector2 pivot = Vector2(0.5f, 0.5f);
// 位置和大小
Vector2 anchoredPosition = Vector2::Zero();
Vector2 sizeDelta = Vector2(100, 100);
// 偏移 (相对于锚点)
Vector2 offsetMin = Vector2::Zero();
Vector2 offsetMax = Vector2::Zero();
// 计算属性
Vector3 GetWorldPosition() const;
Vector2 GetWorldSize() const;
void SetSize(const Vector2& size);
private:
// 父子层级由基类 TransformComponent 管理
mutable Matrix4x4 m_worldMatrix;
mutable bool m_dirty = true;
};
// 图像组件 (Unity Image)
class ImageComponent : public Component {
public:
void Update(float deltaTime) override;
ResourceGUID spriteGuid;
enum class Type {
Simple,
Sliced,
Tiled,
Filled
};
Type type = Type::Simple;
float fillAmount = 1.0f;
enum class FillMethod { Horizontal, Vertical, Radial90, Radial180, Radial360 };
FillMethod fillMethod = FillMethod::Horizontal;
bool fillClockwise = true;
int fillOrigin = 0;
Color color = Color::White;
bool raycastTarget = true;
Event<> OnSpriteChanged;
};
// 文本组件 (Unity Text / TextMeshPro)
class TextComponent : public Component {
public:
void Update(float deltaTime) override;
String text;
ResourceGUID fontGuid;
int fontSize = 14;
enum class FontStyle { Normal, Bold, Italic, BoldAndItalic };
FontStyle fontStyle = FontStyle::Normal;
Color color = Color::White;
Color outlineColor = Color::Black;
float outlineWidth = 0.0f;
enum class Alignment {
UpperLeft, UpperCenter, UpperRight,
MiddleLeft, MiddleCenter, MiddleRight,
LowerLeft, LowerCenter, LowerRight
};
Alignment alignment = Alignment::MiddleCenter;
float lineSpacing = 1.0f;
bool richText = true;
bool horizontalOverflow = false;
bool verticalOverflow = true;
bool raycastTarget = true;
};
// 按钮组件 (Unity Button)
class ButtonComponent : public Component {
public:
void Update(float deltaTime) override;
enum class Transition {
None,
ColorTint,
SpriteSwap,
Animation
};
Transition transition = Transition::ColorTint;
// 颜色状态
Color normalColor = Color::White;
Color highlightedColor = Color(1, 1, 1, 0.8f);
Color pressedColor = Color(1, 1, 1, 0.6f);
Color disabledColor = Color(1, 1, 1, 0.5f);
// 精灵状态
ResourceGUID normalSpriteGuid;
ResourceGUID highlightedSpriteGuid;
ResourceGUID pressedSpriteGuid;
ResourceGUID disabledSpriteGuid;
// 事件
Event<> OnClick;
Event<> OnPointerDown;
Event<> OnPointerUp;
Event<> OnPointerEnter;
Event<> OnPointerExit;
};
// 输入字段组件 (Unity InputField / TMP_InputField)
class InputFieldComponent : public Component {
public:
void Update(float deltaTime) override;
String text;
String placeholder;
int characterLimit = 0;
bool multiLine = false;
bool isPassword = false;
char passwordChar = '*';
enum class ContentType {
Standard,
Autocorrected,
DecimalNumber,
IntegerNumber,
Name,
EmailAddress,
Password,
PIN,
MobileTelephoneNumber,
TelephoneNumber,
URL,
Alphabet
};
ContentType contentType = ContentType::Standard;
Color color = Color::White;
bool raycastTarget = true;
// 事件
Event<String> OnValueChanged;
Event<String> OnEndEdit;
Event<> OnSubmit;
};
// 滑动条组件 (Unity Slider)
class SliderComponent : public Component {
public:
void Update(float deltaTime) override;
float value = 0.5f;
float minValue = 0.0f;
float maxValue = 1.0f;
bool wholeNumbers = false;
enum class Direction {
LeftToRight,
RightToLeft,
BottomToTop,
TopToBottom
};
Direction direction = Direction::LeftToRight;
Color color = Color::White;
bool raycastTarget = true;
// 事件
Event<float> OnValueChanged;
Event<float> OnPointerDown;
Event<float> OnPointerUp;
};
// 滚动视图组件 (Unity ScrollRect)
class ScrollViewComponent : public Component {
public:
void Update(float deltaTime) override;
GameObject* contentGameObject = nullptr;
enum class MovementType {
Elastic,
Clamped,
Unrestricted
};
MovementType movementType = MovementType::Elastic;
float elasticity = 0.1f;
float decelerationRate = 0.135f;
GameObject* horizontalScrollbar = nullptr;
GameObject* verticalScrollbar = nullptr;
bool enabled = true;
bool raycastTarget = true;
};
// 画布组件 (Unity Canvas)
class CanvasComponent : public Component {
public:
void Update(float deltaTime) override;
enum class RenderMode {
ScreenSpaceOverlay,
ScreenSpaceCamera,
WorldSpace
};
RenderMode renderMode = RenderMode::ScreenSpaceOverlay;
GameObject* targetCamera = nullptr;
float planeDistance = 100.0f;
float scaleFactor = 1.0f;
int32_t renderOrder = 0;
};
// 画布缩放器组件 (Unity CanvasScaler)
class CanvasScalerComponent : public Component {
public:
void Update(float deltaTime) override;
enum class ScaleMode {
ConstantPixelSize,
ScaleWithScreenSize,
ConstantPhysicalSize
};
ScaleMode uiScaleMode = ScaleMode::ScaleWithScreenSize;
Vector2 referenceResolution = Vector2(800, 600);
float referencePixelsPerUnit = 100.0f;
enum class ScreenMatchMode {
Width,
Height,
Expand,
Shrink
};
ScreenMatchMode screenMatchMode = ScreenMatchMode::Expand;
float matchWidthOrHeight = 0.0f;
};
// 布局元素组件 (用于布局组)
class LayoutElementComponent : public Component {
public:
void Update(float deltaTime) override;
float minWidth = 0.0f;
float minHeight = 0.0f;
float preferredWidth = 0.0f;
float preferredHeight = 0.0f;
float flexibleWidth = 0.0f;
float flexibleHeight = 0.0f;
int32_t layoutPriority = 0;
};
// 水平布局组组件 (Unity HorizontalLayoutGroupComponent)
class HorizontalLayoutGroupComponent : public Component {
public:
void Update(float deltaTime) override;
float spacing = 0.0f;
bool childForceExpandWidth = true;
bool childForceExpandHeight = false;
bool childControlWidth = true;
bool childControlHeight = true;
int32_t childAlignment = 4;
};
// 垂直布局组组件 (Unity VerticalLayoutGroupComponent)
class VerticalLayoutGroupComponent : public Component {
public:
void Update(float deltaTime) override;
float spacing = 0.0f;
bool childForceExpandWidth = false;
bool childForceExpandHeight = true;
bool childControlWidth = true;
bool childControlHeight = true;
int32_t childAlignment = 4;
};
// 网格布局组组件 (Unity GridLayoutGroupComponent)
class GridLayoutGroupComponent : public Component {
public:
void Update(float deltaTime) override;
Vector2 cellSize = Vector2(100, 100);
Vector2 spacing = Vector2::Zero();
int32_t startCorner = 0;
int32_t startAxis = 0;
int32_t constraint = 0;
int32_t constraintCount = 2;
};
// ============================================================================
// UI 系统 (处理布局、事件等 - 传统Unity风格)
// ============================================================================
class UISystem {
public:
void Initialize();
void Shutdown();
void Update(float deltaTime);
// 射线检测
GameObject* Raycast(const Vector2& screenPosition);
std::vector<GameObject*> RaycastAll(const Vector2& screenPosition);
// 焦点管理
void SetFocus(GameObject* element);
GameObject* GetFocusedElement();
void ClearFocus();
private:
void ProcessLayoutGroups();
void ProcessRaycasts();
void ProcessEvents();
GameObject* m_focusedElement = nullptr;
GameObject* m_hoveredElement = nullptr;
};
// ============================================================================
// UI 渲染器 (底层实现)
// ============================================================================
class UIRenderer {
public:
void Initialize();
void Shutdown();
void Render(Scene& scene);
// 批处理
void BeginBatch();
void AddToBatch(GameObject* gameObject, const Matrix4x4& transform, const Mesh* mesh, const Material* material);
void EndBatch();
// 默认材质
Material* defaultMaterial = nullptr;
Material* defaultSpriteMaterial = nullptr;
};
// ============================================================================
// 画布渲染器组件 (挂载在 Canvas 上)
class CanvasRendererComponent : public Component {
public:
void Update(float deltaTime) override;
bool renderMode = true;
uint32_t vertexCount = 0;
uint32_t indexCount = 0;
bool hasPopulateMesh = false;
std::function<void(Mesh*)> onPopulateMesh;
};
// ============================================================================
// UI 事件系统
// ============================================================================
class UIEventSystem {
public:
static UIEventSystem& Get();
// 指针事件
void OnPointerDown(PointerEvent& event);
void OnPointerUp(PointerEvent& event);
void OnPointerMove(PointerEvent& event);
void OnPointerClick(PointerEvent& event);
// 键盘事件
void OnKeyDown(KeyEvent& event);
void OnKeyUp(KeyEvent& event);
void OnTextInput(TextInputEvent& event);
// 拖放事件
void OnDragStart(DragEvent& event);
void OnDrag(DragEvent& event);
void OnDragEnd(DragEvent& event);
private:
GameObject* m_currentPointerOver = nullptr;
GameObject* m_draggedElement = nullptr;
GameObject* m_focusedElement = nullptr;
};
} // namespace UI
} // namespace XCEngine
```
---
## 第十四章 编辑器架构 (Editor)
### 14.1 编辑器整体架构
```cpp
namespace XCEngine {
namespace Editor {
// 编辑器应用
class EditorApplication {
public:
static EditorApplication& Get();
void Initialize();
void Shutdown();
void Run();
// 主循环
void Update();
void Render();
// 项目
Project* GetCurrentProject() { return m_currentProject.get(); }
void NewProject(const String& path);
void OpenProject(const String& path);
void SaveProject();
void CloseProject();
// 编辑器状态
enum class Mode {
Stopped,
Playing,
Paused,
Step
};
Mode GetMode() const { return m_mode; }
void Play();
void Pause();
void Stop();
void Step();
// 场景操作
void NewScene();
void OpenScene(const String& path);
void SaveScene();
void SaveSceneAs(const String& path);
// 窗口
void RegisterWindow(EditorWindow* window);
void UnregisterWindow(EditorWindow* window);
private:
std::unique_ptr<Project> m_currentProject;
Mode m_mode = Mode::Stopped;
std::vector<std::unique_ptr<EditorWindow>> m_windows;
};
// 编辑器窗口基类
class EditorWindow {
public:
virtual ~EditorWindow() = default;
virtual void OnOpen() {}
virtual void OnClose() {}
virtual void Update(float deltaTime) {}
virtual void OnGUI() {}
virtual bool IsOpen() const { return m_open; }
void SetOpen(bool open) { m_open = open; }
virtual ImVec2 GetSize() const { return ImVec2(400, 300); }
virtual ImVec2 GetPosition() const { return ImVec2(0, 0); }
protected:
String m_title;
bool m_open = true;
};
// 项目
class Project {
public:
String name;
String path;
String assemblyName;
// 设置
ProjectSettings settings;
// 资源(使用编辑器专用的资源数据库)
EditorAssetDatabase* GetAssetDatabase() { return m_assetDatabase.get(); }
// 场景
std::vector<String> GetScenes();
void AddScene(const String& scenePath);
void RemoveScene(const String& scenePath);
// 构建
void Build(const BuildSettings& settings);
private:
std::unique_ptr<EditorAssetDatabase> m_assetDatabase;
std::vector<String> m_scenes;
};
// 编辑器资源数据库(继承自 Resources::AssetDatabase
class EditorAssetDatabase {
public:
void Initialize(const String& projectPath);
void Shutdown();
// 资源查找
Resources::ResourceGUID FindAsset(const String& guid) const;
Resources::ResourceGUID FindAssetByPath(const String& path) const;
String GetAssetPath(const Resources::ResourceGUID& guid) const;
// 资源操作
void ImportAsset(const String& sourcePath);
void ReimportAsset(const Resources::ResourceGUID& guid);
void DeleteAsset(const Resources::ResourceGUID& guid);
// 刷新
void Refresh();
// GUID 生成
Resources::ResourceGUID GenerateGUID();
// 编辑器特定功能
void SelectAsset(const Resources::ResourceGUID& guid);
std::vector<Resources::ResourceGUID> GetSelectedAssets() const;
void OpenInExternalEditor(const Resources::ResourceGUID& guid);
// 资源变换监听
Core::Event<const String&> OnAssetRenamed;
Core::Event<const Resources::ResourceGUID&> OnAssetDeleted;
private:
void ScanDirectory(const String& dirPath);
void ImportAssetInternal(const String& sourcePath, const String& destPath);
struct AssetMetadata {
Resources::ResourceGUID guid;
String path;
String extension;
int64_t fileSize;
int64_t lastModified;
String importerType;
JsonObject metadata;
};
std::unordered_map<String, AssetMetadata> m_guidToAsset;
std::unordered_map<String, Resources::ResourceGUID> m_pathToGuid;
std::vector<Resources::ResourceGUID> m_selectedAssets;
};
// 资源导入器
class AssetImporter {
public:
virtual ~AssetImporter() = default;
virtual bool CanImport(const String& extension) const = 0;
virtual void Import(const String& sourcePath, const ResourceGUID& guid,
const ImportSettings& settings) = 0;
virtual ImportSettings* GetDefaultSettings() const = 0;
protected:
String GetOutputPath(const String& sourcePath, const ResourceGUID& guid);
};
// 具体导入器
class TextureImporter : public AssetImporter {
public:
bool CanImport(const String& extension) const override;
void Import(const String& sourcePath, const ResourceGUID& guid,
const ImportSettings& settings) override;
struct Settings : ImportSettings {
TextureType textureType = TextureType::Texture2D;
int maxSize = 2048;
TextureFormat format = TextureFormat::RGBA;
bool generateMipmaps = true;
bool sRGB = true;
FilterMode filterMode = FilterMode::Bilinear;
WrapMode wrapMode = WrapMode::Repeat;
};
};
class MeshImporter : public AssetImporter {
public:
bool CanImport(const String& extension) const override;
void Import(const String& sourcePath, const ResourceGUID& guid,
const ImportSettings& settings) override;
};
class MaterialImporter : public AssetImporter {
public:
bool CanImport(const String& extension) const override;
void Import(const String& sourcePath, const ResourceGUID& guid,
const ImportSettings& settings) override;
};
// 编辑器场景管理 (Unity Editor 风格)
//
// 编辑器/运行时模式切换机制:
// - Stop (编辑模式): 编辑器直接操作 m_editingScene
// - Play (运行模式):
// 1. 深拷贝 m_editingScene -> m_runtimeScene (包括所有Entity和Component)
// 2. 运行 m_runtimeScene
// 3. 用户在运行时对Scene的修改都在 m_runtimeScene 中
// - Stop -> Play 循环:
// 1. 销毁旧的 m_runtimeScene (如果存在)
// 2. 深拷贝 m_editingScene -> m_runtimeScene
// - Play -> Stop:
// 1. 销毁 m_runtimeScene
// 2. 如果用户选择了 "Apply Changes",将 runtime 改动的 GameObject 同步回 editing
// 3. 恢复编辑模式
class EditorSceneManager {
public:
static EditorSceneManager& Get();
// 编辑场景 (编辑模式下使用)
Scene* GetEditingScene() { return m_editingScene.get(); }
// 运行时场景 (Play 模式下使用)
// 注意:运行时场景是编辑场景的副本,不是同一个对象
Scene* GetRuntimeScene() { return m_runtimeScene.get(); }
// Play/Stop 控制
enum class Mode {
Stopped, // 编辑模式
Playing, // 播放模式
Paused // 暂停模式
};
void Play(); // 开始播放:从 editing 拷贝到 runtime
void Pause(); // 暂停
void Unpause(); // 继续
void Stop(); // 停止播放:销毁 runtime可选 Apply Changes
void Step(); // 单步执行一帧
Mode GetMode() const { return m_mode; }
// Apply Changes (Play -> Stop 时可选)
// 将 runtime 场景中的运行时数据同步回 editing 场景
enum class ApplyChangesMode {
None, // 不应用任何更改
All, // 应用所有更改
Selected // 只应用选中的GameObject
};
void SetApplyChangesMode(ApplyChangesMode mode);
void ApplyRuntimeChanges();
// 场景操作
void CreateNewScene();
void OpenScene(const String& path);
void SaveScene(const String& path);
// 撤销/重做
void Undo();
void Redo();
bool CanUndo() const;
bool CanRedo() const;
// GameObject操作
void DuplicateGameObject(GameObject* gameObject);
void DeleteGameObject(GameObject* gameObject);
void PasteGameObject();
void CopyGameObject(GameObject* gameObject);
// 预制件
void CreatePrefab(GameObject* gameObject, const String& path);
GameObject* InstantiatePrefab(const String& path);
void UnpackPrefab(GameObject* gameObject);
private:
void CopySceneToRuntime(); // 深拷贝编辑场景到运行时场景
void SyncRuntimeToEditing(); // 同步运行时更改回编辑场景
std::unique_ptr<Scene> m_editingScene;
std::unique_ptr<Scene> m_runtimeScene;
Mode m_mode = Mode::Stopped;
ApplyChangesMode m_applyChangesMode = ApplyChangesMode::None;
std::deque<UndoRedoAction> m_undoStack;
std::deque<UndoRedoAction> m_redoStack;
};
// 撤销/重做
class UndoRedoSystem {
public:
void PushAction(std::unique_ptr<IUndoRedoAction> action);
void Undo();
void Redo();
bool CanUndo() const { return !m_undoStack.empty(); }
bool CanRedo() const { return !m_redoStack.empty(); }
void Clear();
private:
std::deque<std::unique_ptr<IUndoRedoAction>> m_undoStack;
std::deque<std::unique_ptr<IUndoRedoAction>> m_redoStack;
size_t m_maxStackSize = 100;
};
// 编辑器工具
namespace Tools {
class EditorTool {
public:
virtual ~EditorTool() = default;
virtual void OnActivate() {}
virtual void OnDeactivate() {}
virtual void Update(float deltaTime) {}
virtual void OnSceneGUI() {}
virtual void OnObjectGUI(GameObject* gameObject) {}
virtual const char* GetName() const = 0;
virtual const char* GetIcon() const = 0;
protected:
bool m_active = false;
};
class SelectionTool : public EditorTool {
public:
const char* GetName() const override { return "Select"; }
void Update(float deltaTime) override;
void OnSceneGUI() override;
};
class MoveTool : public EditorTool {
public:
const char* GetName() const override { return "Move"; }
void Update(float deltaTime) override;
void OnSceneGUI() override;
};
class RotateTool : public EditorTool {
public:
const char* GetName() const override { return "Rotate"; }
void Update(float deltaTime) override;
void OnSceneGUI() override;
};
class ScaleTool : public EditorTool {
public:
const char* GetName() const override { return "Scale"; }
void Update(float deltaTime) override;
void OnSceneGUI() override;
};
class Gizmo {
public:
enum class Mode {
Translate,
Rotate,
Scale,
Rect,
Transform
};
enum class Space {
World,
Local
};
enum class PivotMode {
Center,
Pivot
};
void SetMode(Mode mode);
void SetSpace(Space space);
void SetPivot(PivotMode pivot);
void BeginManipulation(GameObject* gameObject);
void Draw(GameObject* gameObject);
void EndManipulation();
bool IsManipulating() const { return m_manipulating; }
Matrix4x4 GetManipulationDelta() const;
private:
Mode m_mode = Mode::Translate;
Space m_space = Space::World;
PivotMode m_pivot = PivotMode::Center;
bool m_manipulating = false;
GameObject* m_selectedGameObject = nullptr;
Matrix4x4 m_startMatrix;
};
// 编辑器相机
class EditorCamera {
public:
void Initialize();
void Shutdown();
void Update(float deltaTime);
void SetProjection(float fov, float aspect, float near, float far);
void SetOrthographic(float size, float near, float far);
Matrix4x4 GetViewMatrix() const;
Matrix4x4 GetProjectionMatrix() const;
// 控制
void Orbit(const Vector2& delta);
void Pan(const Vector2& delta);
void Zoom(float delta);
void FocusOn(GameObject* gameObject);
void FocusOn(const BoundingBox& bounds);
// 状态
float GetDistance() const { return m_distance; }
void SetDistance(float distance);
Vector3 GetPosition() const;
Vector3 GetForward() const;
Vector3 GetTarget() const { return m_target; }
private:
Vector3 m_target = Vector3::Zero();
float m_distance = 10.0f;
float m_pitch = 0.0f;
float m_yaw = 0.0f;
float m_fov = 60.0f;
float m_near = 0.1f;
float m_far = 1000.0f;
bool m_orthographic = false;
// 交互
bool m_isOrbiting = false;
bool m_isPanning = false;
};
} // namespace Tools
// 编辑器面板
namespace Panels {
class HierarchyPanel {
public:
void OnGUI();
void SetSearchFilter(const String& filter);
void DrawGameObjectTree(GameObject* parent, int& idCounter);
private:
String m_searchFilter;
GameObject* m_contextMenuGameObject = nullptr;
};
class InspectorPanel {
public:
void OnGUI();
void DrawGameObject(GameObject* gameObject);
void DrawComponent(uint32_t componentTypeId, void* component);
void DrawAddComponentMenu();
private:
GameObject* m_selectedGameObject = nullptr;
};
class SceneViewPanel {
public:
void OnGUI();
void Render();
Tools::EditorCamera& GetCamera() { return m_camera; }
private:
Tools::EditorCamera m_camera;
bool m_gridVisible = true;
bool m_gizmosVisible = true;
};
class GameViewPanel {
public:
void OnGUI();
void Render();
void SetResolution(int width, int height);
void SetFullscreen(bool fullscreen);
private:
int m_width = 1280;
int m_height = 720;
bool m_fullscreen = false;
bool m_vsync = true;
};
class ProjectPanel {
public:
void OnGUI();
void DrawAssetBrowser();
void DrawFolderTree();
void OnAssetSelected(ResourceGUID guid);
private:
String m_currentPath;
std::vector<ResourceGUID> m_selectedAssets;
ViewMode m_viewMode = ViewMode::Grid;
};
class ConsolePanel {
public:
void OnGUI();
void Log(const String& message, LogLevel level);
void Clear();
void Filter(LogLevel minLevel);
private:
struct LogEntry {
String message;
LogLevel level;
String source;
int64_t timestamp;
};
std::vector<LogEntry> m_logs;
LogLevel m_filterLevel = LogLevel::Info;
};
// 动画曲线编辑器
class AnimationCurveEditor {
public:
void OnGUI();
void SetCurve(AnimationCurve* curve);
void AddKey(float time, float value);
void RemoveKey(int index);
private:
AnimationCurve* m_curve = nullptr;
int m_selectedKey = -1;
};
// 着色器编辑器
class ShaderEditor {
public:
void OnGUI();
void OpenShader(const String& path);
void SaveShader();
void CompileShader();
void SetPreviewMesh(Mesh* mesh);
void SetPreviewRotation(const Vector3& rotation);
private:
String m_shaderPath;
bool m_compileErrors = false;
String m_errorMessage;
};
// 材质编辑器
class MaterialEditor {
public:
void OnGUI();
void OpenMaterial(Material* material);
void SaveMaterial();
void DrawProperty(MaterialProperty* property);
private:
Material* m_material = nullptr;
};
// 偏好设置
class PreferencesWindow : public EditorWindow {
public:
void OnGUI() override;
private:
void DrawGeneralSettings();
void DrawThemeSettings();
void DrawInputSettings();
void DrawShortcutSettings();
};
} // namespace Panels
// 编辑器渲染
class EditorRenderView {
public:
void Initialize();
void Shutdown();
void RenderSceneView(Panels::SceneViewPanel* panel);
void RenderGameView(Panels::GameViewPanel* panel);
void SetRenderTarget(RenderTexture* target);
private:
void SetupCamera(EditorCamera& camera);
void RenderGizmos();
RenderTexture* m_renderTarget = nullptr;
};
} // namespace Editor
} // namespace XCEngine
```
---
## 第十五章 工具链 (Toolchain)
### 15.1 资源处理管道
```cpp
namespace XCEngine {
namespace Tools {
// 资源处理器
class AssetProcessor {
public:
static AssetProcessor& Get();
void Initialize(const String& projectPath);
void Shutdown();
// 导入
void ImportAsset(const String& sourcePath);
void ImportAllAssets();
// 烘焙
void CookScene(Scene* scene, const String& outputPath);
void CookMaterial(Material* material, const String& outputPath);
void CookTexture(Texture* texture, const String& outputPath);
// 构建
void BuildProject(const BuildSettings& settings);
private:
void ProcessImportQueue();
void WriteCookedData(const String& path, const void* data, size_t size);
std::queue<String> m_importQueue;
};
// 着色器编译器
class ShaderCompiler {
public:
void Initialize();
void Shutdown();
// 编译
CompiledShader Compile(const ShaderSource& source, const ShaderCompileOptions& options);
bool CompileFile(const String& inputPath, const String& outputPath,
const ShaderCompileOptions& options);
// 工具
void GenerateShaderIncludes();
void StripDebugInfo(CompiledShader& shader);
// 工具链
enum class ShaderProfile {
DXIL, // DirectX 12
SPIRV, // Vulkan
MSL, // Metal
GLSL, // OpenGL
WGSL // WebGPU
};
void SetProfile(ShaderProfile profile);
void AddPreprocessorDefine(const String& define);
private:
struct CompilerConfig {
ShaderProfile profile;
std::vector<String> defines;
bool generateDebugInfo = false;
bool optimize = true;
int optimizationLevel = 3;
};
CompilerConfig m_config;
};
// 场景烘焙器
class SceneCooker {
public:
void Cook(Scene* scene, const CookSettings& settings);
// 灯光烘焙
void BakeLightmaps(Scene* scene);
void BakeReflectionProbes(Scene* scene);
void BakeAmbientOcclusion(Scene* scene);
// 导航烘焙
void BakeNavigationMesh(Scene* scene);
// 遮挡剔除
void BakeOcclusionCulling(Scene* scene);
// 静态批处理
void BakeStaticBatches(Scene* scene);
private:
void CookGameObject(GameObject* gameObject);
void WriteCookedScene(const String& path, const CookedScene& data);
};
// 构建工具
class BuildTool {
public:
struct BuildSettings {
String outputPath;
String projectName;
// 平台
BuildPlatform platform;
BuildConfiguration config = BuildConfiguration::Release;
// 脚本
bool compileScripts = true;
bool generateDebugSymbols = false;
// 资源
bool compressAssets = true;
bool stripUnusedResources = true;
// 目标
bool buildExe = true;
bool buildDLC = false;
bool bundleResources = true;
};
void Build(const BuildSettings& settings);
void BuildPlayer(const BuildSettings& settings);
void BuildAssetBundle(const BuildSettings& settings);
private:
void PrepareBuildDirectory(const BuildSettings& settings);
void CompileScripts(const BuildSettings& settings);
void CookResources(const BuildSettings& settings);
void CopyEngineFiles(const BuildSettings& settings);
void LinkExecutable(const BuildSettings& settings);
};
// 性能分析器工具
class ProfilerCapture {
public:
void StartCapture();
void StopCapture();
void SaveCapture(const String& path);
void LoadCapture(const String& path);
// 分析
void GenerateReport();
float GetTotalFrameTime() const;
float GetCPUFrameTime() const;
float GetGPUFrameTime() const;
private:
struct FrameData {
uint64_t timestamp;
std::vector<ProfilerEvent> events;
};
std::vector<FrameData> m_frames;
bool m_capturing = false;
};
} // namespace Tools
} // namespace XCEngine
```
---
## 第十六章 平台层 (Platform)
### 16.1 跨平台抽象
```cpp
namespace XCEngine {
namespace Platform {
// 平台类型
enum class PlatformType {
Windows,
Linux,
macOS,
Android,
iOS,
Web,
PlayStation,
Xbox,
Nintendo
};
// 键码
enum class KeyCode {
None = 0,
A = 4, B = 5, C = 6, D = 7, E = 8, F = 9, G = 10,
H = 11, I = 12, J = 13, K = 14, L = 15, M = 16, N = 17,
O = 18, P = 19, Q = 20, R = 21, S = 22, T = 23, U = 24,
V = 25, W = 26, X = 27, Y = 28, Z = 29,
F1 = 122, F2 = 120, F3 = 99, F4 = 118, F5 = 96, F6 = 97,
F7 = 98, F8 = 100, F9 = 101, F10 = 109, F11 = 103, F12 = 111,
Space = 49, Tab = 48, Enter = 36, Escape = 53,
LeftShift = 56, RightShift = 60, LeftCtrl = 59, RightCtrl = 62,
LeftAlt = 58, RightAlt = 61,
Up = 126, Down = 125, Left = 123, Right = 124,
Home = 115, End = 119, PageUp = 116, PageDown = 121,
Delete = 51, Backspace = 51
};
// 鼠标按钮
enum class MouseButton {
Left = 0,
Right = 1,
Middle = 2,
Button4 = 3,
Button5 = 4
};
// 触摸状态
struct TouchState {
int touchId;
Vector2 position;
Vector2 deltaPosition;
float deltaTime;
int tapCount;
enum Phase { Began, Moved, Stationary, Ended, Canceled } phase;
};
// 指针事件
struct PointerEvent {
int pointerId;
Vector2 position;
Vector2 deltaPosition;
float pressure;
MouseButton button;
enum Type { Pressed, Released, Moved, Wheel, Hover } type;
};
// 按键事件
struct KeyEvent {
KeyCode keyCode;
bool alt;
bool ctrl;
bool shift;
bool meta;
enum Type { Down, Up, Repeat } type;
};
// 文本输入事件
struct TextInputEvent {
char character;
String text;
};
// 拖放事件
struct DragEvent {
Vector2 position;
Vector2 delta;
int pointerId;
};
// 文件变化事件
struct FileChangeEvent {
String path;
enum Type { Created, Modified, Deleted, Renamed } type;
};
// 手势事件
struct GestureEvent {
Vector2 position;
float deltaScale;
float deltaRotation;
int tapCount;
enum Type { None, Tap, DoubleTap, Pinch, Rotate, Pan } type;
};
// 窗口
class Window {
public:
virtual ~Window() = default;
virtual void Create(const WindowDesc& desc) = 0;
virtual void Destroy() = 0;
virtual void Show() = 0;
virtual void Hide() = 0;
virtual void Minimize() = 0;
virtual void Maximize() = 0;
virtual void Restore() = 0;
virtual void SetFullscreen(bool fullscreen) = 0;
virtual void SetTitle(const String& title) = 0;
virtual void SetSize(int width, int height) = 0;
virtual void SetPosition(int x, int y) = 0;
virtual bool IsClosed() const = 0;
virtual bool IsFocused() const = 0;
virtual bool IsMinimized() const = 0;
virtual bool IsMaximized() const = 0;
virtual bool IsFullscreen() const = 0;
virtual void* GetNativeHandle() const = 0;
// 事件
Event<int, int> OnResize;
Event<int, int> OnMove;
Event<> OnClose;
Event<> OnFocus;
Event<> OnBlur;
Event<> OnMinimize;
Event<> OnMaximize;
Event<> OnRestore;
};
// 输入
class InputSystem {
public:
// 键盘
bool IsKeyDown(KeyCode key) const;
bool IsKeyUp(KeyCode key) const;
bool IsKeyPressed(KeyCode key) const;
// 鼠标
Vector2 GetMousePosition() const;
Vector2 GetMouseDelta() const;
float GetMouseScrollDelta() const;
bool IsMouseButtonDown(MouseButton button) const;
bool IsMouseButtonUp(MouseButton button) const;
bool IsMouseButtonClicked(MouseButton button) const;
// 手柄
int GetJoystickCount() const;
bool IsJoystickConnected(int joystick) const;
Vector2 GetJoystickAxis(int joystick, int axis) const;
bool IsJoystickButtonDown(int joystick, int button) const;
// 触摸
int GetTouchCount() const;
TouchState GetTouch(int index) const;
// 手势
Event<GestureEvent&> OnGesture;
};
// 注意FileSystem 定义在 Platform 命名空间中
// Core::IO 只保留流抽象 (IStream, FileReader, FileWriter)
}
namespace XCEngine {
namespace Platform {
// 文件系统 - 统一的跨平台文件系统抽象
class FileSystem {
public:
static FileSystem& Get();
// 路径操作
String GetWorkingDirectory();
String GetExecutablePath();
String GetUserDirectory();
String GetAppDataDirectory();
String GetTempDirectory();
// 文件操作
bool FileExists(const String& path);
bool DirectoryExists(const String& path);
bool CreateDirectory(const String& path);
bool DeleteFile(const String& path);
bool DeleteDirectory(const String& path);
// 读写
std::unique_ptr<IStream> OpenRead(const String& path);
std::unique_ptr<IStream> OpenWrite(const String& path);
std::unique_ptr<IStream> OpenAppend(const String& path);
// 遍历
void EnumerateFiles(const String& directory, const String& pattern,
std::vector<String>& results);
void EnumerateDirectories(const String& directory,
std::vector<String>& results);
// 观察
void WatchDirectory(const String& directory,
std::function<void(const FileChangeEvent&)> callback);
};
// 时间
// 时间
class Time {
public:
static float GetTime();
static float GetUnscaledTime();
static float GetDeltaTime();
static float GetUnscaledDeltaTime();
static void SetTimeScale(float scale);
static float GetTimeScale() { return m_timeScale; }
static uint64_t GetFrameCount() { return m_frameCount; }
static int GetFrameRate() { return m_frameRate; }
static void SetTargetFrameRate(int rate);
static void BeginFrame();
static void EndFrame();
private:
static float m_timeScale;
static uint64_t m_frameCount;
static int m_frameRate;
};
// 内存映射文件
class MemoryMappedFile {
public:
bool Open(const String& path);
void Close();
void* GetData() const { return m_data; }
size_t GetSize() const { return m_size; }
private:
void* m_handle = nullptr;
void* m_data = nullptr;
size_t m_size = 0;
};
// 进程
class Process {
public:
bool Launch(const String& command, const std::vector<String>& args);
void Terminate();
bool IsRunning() const;
int GetExitCode() const;
int WaitForExit();
void Write(const void* data, size_t size);
String ReadOutput();
String ReadError();
private:
void* m_handle = nullptr;
};
// 动态库
class DynamicLibrary {
public:
bool Load(const String& path);
void Unload();
void* GetFunction(const String& name);
bool IsLoaded() const;
private:
void* m_handle = nullptr;
};
// 系统信息
class SystemInfo {
public:
static String GetOSName();
static String GetOSVersion();
static String GetMachineName();
static String GetUserName();
static int GetProcessorCount();
static int GetProcessorCoreCount();
static int GetThreadCount();
static uint64_t GetTotalMemory();
static uint64_t GetAvailableMemory();
static String GetGPUName();
static uint64_t GetGPUMemory();
static int GetGPUMonitorCount();
static bool HasNvidiaGPU();
static bool HasAmdGPU();
static bool HasIntelGPU();
};
} // namespace Platform
} // namespace XCEngine
```
---
## 第十七章 构建与部署
### 17.1 CMake 项目结构
```
XCVolumeRenderer/
├── CMakeLists.txt # 根 CMake 配置
├── cmake/
│ ├── FindXXX.cmake # 第三方库查找
│ ├── XCEngineDefaults.cmake # 默认设置
│ └── Utils.cmake # 工具宏
├── engine/ # 引擎核心
│ ├── CMakeLists.txt
│ ├── include/
│ └── src/
├── editor/ # 编辑器
│ ├── CMakeLists.txt
│ └── src/
├── runtime/ # 运行时
│ ├── CMakeLists.txt
│ └── src/
├── tools/ # 工具链
│ ├── AssetProcessor/
│ ├── ShaderCompiler/
│ └── SceneCooker/
└── third_party/ # 第三方库
├── CMakeLists.txt
├── imgui/
├── stb/
└── ...
```
### 17.2 CMake 配置示例
```cmake
# 根 CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(XCGameEngine VERSION 1.0.0)
# 选项
option(BUILD_EDITOR "Build editor" ON)
option(BUILD_RUNTIME "Build runtime" ON)
option(BUILD_TOOLS "Build tools" ON)
option(BUILD_SHADERS "Build shaders" ON)
# 加载工具
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(XCEngineDefaults)
# 依赖
find_package(Threads REQUIRED)
find_package(D3D12 REQUIRED)
find_package(Vulkan REQUIRED)
# 子目录
add_subdirectory(third_party)
add_subdirectory(engine)
if(BUILD_EDITOR)
add_subdirectory(editor)
endif()
if(BUILD_RUNTIME)
add_subdirectory(runtime)
endif()
if(BUILD_TOOLS)
add_subdirectory(tools)
endif()
```
### 17.3 构建流程
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Build Pipeline │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Source Code ──► Compile ──► Link ──► Engine Library │
│ │ │
│ │ │
│ ▼ │
│ Assets ──► Import ──► Cook ──► Pack ──► Resource Bundle │
│ │
│ │ │
│ │ │
│ ▼ │
│ Shaders ──► Compile ──► Pack ──► Shader Cache │
│ │
│ │ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Final Output │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │ │
│ │ │ Executable │ │ Resources │ │ Engine Libraries │ │ │
│ │ │ (EXE/DLL) │ │ (.pak) │ │ (.lib/.dll) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 第十八章 总结与实现建议
### 18.1 架构核心要点
1. **分层设计**: Platform → Core → Engine → Editor/Runtime
2. **组件系统**: 类Unity的GameObject+Component模式
3. **渲染抽象**: 跨 API 的渲染接口,便于扩展
4. **资源管理**: 完整的导入→处理→缓存→加载管道
5. **工具链**: 从源代码到最终产品的完整构建系统
### 18.2 实现优先级建议
#### 第一阶段 (基础框架)
- [ ] 数学库 (Vector, Matrix, Quaternion, Transform)
- [ ] 基础容器 (Array, String, HashMap)
- [ ] 内存管理 (Allocator, Pool)
- [ ] 线程系统 (Thread, Mutex, TaskSystem)
- [ ] 日志系统
- [ ] 文件系统抽象
#### 第二阶段 (组件系统 + 渲染)
- [ ] 组件系统核心 (GameObject, Component)
- [ ] 基础组件 (Transform, RenderMesh)
- [ ] 渲染抽象层 (Device, CommandList)
- [ ] D3D12/Vulkan 后端
- [ ] 基础渲染管线 (GBuffer, Lighting)
#### 第三阶段 (功能系统)
- [ ] 资源系统 (ResourceManager, AssetDatabase)
- [ ] 场景系统 (Scene, SceneManager)
- [ ] 物理系统 (基础碰撞检测)
- [ ] 输入系统
- [ ] UI 框架
#### 第四阶段 (编辑器)
- [ ] 编辑器 UI (ImGui)
- [ ] 场景视图/游戏视图
- [ ] 层级面板/检视面板
- [ ] 资源浏览器
- [ ] 工具 (Gizmo, 编辑器相机)
#### 第五阶段 (高级功能)
- [ ] 动画系统
- [ ] 粒子系统
- [ ] 音频系统
- [ ] 网络系统
- [ ] 脚本系统
### 18.3 代码组织建议
```
engine/src/
├── Core/ # 1-2周
│ ├── Math/
│ ├── Containers/
│ ├── Memory/
│ ├── Threading/
│ └── Debug/
├── Components/ # 2-3周
│ ├── GameObject.cpp
│ ├── Component.cpp
│ └── System.cpp
├── Renderer/ # 3-4周
│ ├── Device.cpp
│ ├── CommandList.cpp
│ ├── Pipeline.cpp
│ └── Passes/
├── Resources/ # 2周
│ ├── ResourceManager.cpp
│ ├── AssetDatabase.cpp
│ └── Loaders/
├── Scene/ # 1周
├── Physics/ # 2-3周
├── Scripting/ # 3-4周 (可选)
└── Platform/ # 1周
├── Windows.cpp
└── ...
editor/src/
├── Application.cpp # 1周
├── Panels/ # 2周
├── Tools/ # 2周
├── Windows/ # 2周
└── ImGui/ # 1周
```
### 18.4 技术选型建议
| 子系统 | 推荐方案 | 备选 |
|--------|----------|------|
| 图形 API | D3D12 + Vulkan | Metal, OpenGL |
| 物理 | PhysX | Bullet, Box2D |
| 脚本 | C# (Mono/.NET) | Lua, AngelScript |
| UI (编辑器) | ImGui | Qt, Custom |
| UI (运行时) | 自研 Canvas | DearImgui, RmlUI |
| 资源格式 | 自研 Binary + JSON | glTF, USD |
| 压缩 | LZ4 + ZSTD | LZMA, LZHAM |
| 网络 | 自研 / ENet | LiteNetLib |
### 18.5 性能目标
- 60 FPS 稳定运行 (1080p, 中等画质)
- 10000+ 实体同屏
- 加载时间 < 3秒 (典型场景)
- 编辑器响应 < 16ms
---
*文档版本: 1.15*
*最后更新: 2026-03-13*