188 KiB
188 KiB
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 架构设计原则
本引擎采用分层架构结合模块化设计,遵循以下核心原则:
- 关注点分离 (Separation of Concerns): 各系统独立演化,通过明确定义的接口通信
- 依赖倒置 (Dependency Inversion): 上层模块依赖抽象接口,不依赖具体实现
- 开闭原则 (Open-Closed): 对扩展开放,对修改封闭
- 单一职责 (Single Responsibility): 每个模块只负责一项职责
- 数据驱动 (Data-Driven): 引擎行为由数据(组件、资源、配置)驱动
- 组件化架构: 采用类Unity的组件模式,组件挂载在实体上
- 渲染抽象: 跨 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 核心类型
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 优化示例
// 使用 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)
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)
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)
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 日志与调试系统
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)
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)
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中间层。
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 渲染抽象层
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)
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 资源系统实现
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 场景管理
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 物理系统
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 音频系统
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 动画系统架构
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 粒子系统架构
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 网络系统架构
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 系统架构
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 编辑器整体架构
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 资源处理管道
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 跨平台抽象
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 配置示例
# 根 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 架构核心要点
- 分层设计: Platform → Core → Engine → Editor/Runtime
- 组件系统: 类Unity的GameObject+Component模式
- 渲染抽象: 跨 API 的渲染接口,便于扩展
- 资源管理: 完整的导入→处理→缓存→加载管道
- 工具链: 从源代码到最终产品的完整构建系统
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