diff --git a/docs/document/FAQ/FAQ.md b/docs/document/FAQ/FAQ.md index 661ef79..46ad318 100644 --- a/docs/document/FAQ/FAQ.md +++ b/docs/document/FAQ/FAQ.md @@ -1,9 +1,191 @@ --- -description: "" -hide_title: true +title: ❓ 常见问题 +description: 使用 UnrealCSharp 过程中的常见问题与解决方案 +hide_title: false custom_edit_url: null --- -# FAQ +# ❓ 常见问题 (FAQ) + +
+

+ 💡 快速解决您在使用过程中遇到的问题 +

+
+ +--- + +## 🔧 安装相关 + +### Q: 插件安装后编辑器无法启动? + +
+ 🔍 常见原因: +
+ +- **检查 .NET 版本**:确保安装了 .NET 8 或更高版本 +- **检查插件完整性**:确认所有依赖文件都已正确放置 +- **清理临时文件**:删除 `Binaries/` 和 `Intermediate/` 文件夹后重新编译 + +### Q: 无法生成 C# 项目? + +
+ 💡 解决步骤: +
+ +1. 确认插件已正确启用 +2. 检查 `Generator Code` 按钮是否可见 +3. 尝试使用命令行:`UnrealCSharp.Editor.Generator` +4. 查看输出日志中的错误信息 + +--- + +## 💻 开发相关 + +### Q: C# 代码修改后不生效? + +
+ 🔥 热重载功能: +
+ +- **自动重载**:编辑器会自动检测 C# 代码变更 +- **手动重载**:使用 `UnrealCSharp.Editor.Compile` 命令 +- **完整重新生成**:使用 `UnrealCSharp.Editor.Generator` 命令 + +### Q: 调试断点不生效? + +
+ 🐛 调试设置: +
+ +1. 确认使用 Debug 配置编译 +2. 检查调试器是否正确附加到进程 +3. 验证断点设置在可执行的代码行上 + +--- + +## 🌍 平台相关 + +### Q: Android 平台打包失败? + +
+ 📱 Android 特殊设置: +
+ +- 确保 Android NDK 版本兼容 +- 检查 ARM64 架构支持 +- 验证 Mono 运行时正确打包 + +### Q: iOS 平台是否支持? + +
+ ✅ 完全支持: +
+ +- iOS 平台已完全支持 +- 支持真机调试 +- 支持 App Store 发布 + +--- + +## 🔄 热更新相关 + +### Q: 如何实现代码热更新? + +
+ 📦 热更新流程: +
+ +1. 将 C# 程序集打包到 Pak 文件 +2. 运行时下载新的 Pak 文件 +3. 调用热更新 API 加载新代码 +4. 无需重启应用即可生效 + +### Q: 热更新有哪些限制? + +
+ ⚠️ 注意事项: +
+ +- 不能修改已存在的静态绑定类结构 +- 动态类可以完全替换 +- 建议设计时考虑热更新友好的架构 + +--- + +## 🚀 性能相关 + +### Q: C# 性能是否足够好? + +
+ 📊 性能数据: +
+ +- 基于 .NET 8 运行时,性能优异 +- 与原生 C++ 性能差距极小 +- 已在商业项目中验证 + +### Q: 如何优化 C# 代码性能? + +
+ 💡 优化建议: +
+ +- 避免频繁的装箱/拆箱操作 +- 合理使用对象池 +- 减少跨语言调用频率 +- 使用 `Span` 等高性能类型 + +--- + +## 📚 学习资源 + +### Q: 有哪些学习资料? + +
+
+
+
+

📖 官方文档

+
+
+ +
+
+
+
+
+
+

🎮 示例项目

+
+
+
    +
  • StackOBot 游戏示例
  • +
  • Cropout 游戏示例
  • +
  • 社区项目案例
  • +
+
+
+
+
+ +--- + +## 🤝 获取帮助 + +
+

找不到您问题的答案?我们来帮助您!

+ + 💬 联系社区 + + {' '} + + 🐛 报告问题 + +
--- diff --git a/docs/document/advanced/compile.md b/docs/document/advanced/compile.md index 08427ac..2dfded5 100644 --- a/docs/document/advanced/compile.md +++ b/docs/document/advanced/compile.md @@ -7,187 +7,504 @@ sidebar_position: 3 custom_edit_url: null --- -## +# 编译Mono -### 源码 - - [runtime](https://github.com/dotnet/runtime) +本文档详细介绍了如何在不同平台上编译Mono运行时,包括环境配置、编译步骤和产物说明。 ---- +## 概述 -### Windows - 1. 环境:[Requirements to build dotnet/runtime on Windows](https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/windows-requirements.md) - 2. 编译 - - Debug:`build.cmd mono+libs` - - Release:`build.cmd mono+libs -c release` - 3. include - - `artifacts/bin/mono/windows.x64.Debug/include` - 4. dll - - [Microsoft.NETCore.App.Runtime.Mono.win-x64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.win-x64/8.0.5),修改后缀为.zip,并解压 - - 根据`runtimes/win-x64/lib/net8.0`筛选`artifacts/bin/runtime/net8.0-windows-Debug-x64`中的dll - - `artifacts/bin/mono/windows.x64.Debug/System.Private.CoreLib.dll` - 5. lib - - `artifacts/obj/mono/windows.x64.Debug/out/lib` - - `coreclr.dll` - - `coreclr.import.lib` - - `mono-component-debugger-static.lib` - - `mono-component-debugger-stub-static.lib` - - `mono-component-diagnostics_tracing-static.lib` - - `mono-component-diagnostics_tracing-stub-static.lib` - - `mono-component-hot_reload-static.lib` - - `mono-component-hot_reload-stub-static.lib` - - `mono-component-marshal-ilgen-static.lib` - - `mono-component-marshal-ilgen-stub-static.lib` - - `mono-profiler-aot.lib` - - `monosgen-2.0.lib` +Mono是.NET运行时的开源实现,支持多平台部署。本文档涵盖以下平台的编译流程: ---- +- **Windows** - 使用Visual Studio构建工具 +- **Linux** - 使用GCC/Clang工具链 +- **macOS** - 使用Xcode命令行工具 +- **Android** - 交叉编译支持ARM64 +- **iOS** - 包含AOT编译和Framework打包 -### Linux - 1. 环境:[Requirements to build dotnet/runtime on Linux](https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/linux-requirements.md) - 2. 编译选项:[v8.0.5-Linux](https://github.com/crazytuzi/runtime/commit/0458ead883ddb88e269fc14d1937d95f77279031) - 3. 编译 - - Debug:`./build.sh mono+libs` - - Release:`./build.sh mono+libs -c release` - 4. include - - `artifacts/bin/mono/linux.x64.Debug/include` - 5. dll - - [Microsoft.NETCore.App.Runtime.Mono.linux-x64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.linux-x64/8.0.5),修改后缀为.zip,并解压 - - 根据`runtimes/linux-x64/lib/net8.0`筛选`artifacts/bin/runtime/net8.0-linux-Debug-x64`中的dll - - `artifacts/bin/mono/linux.x64.Debug/System.Private.CoreLib.dll` - 6. lib - - `artifacts/obj/mono/linux.x64.Debug/out/lib` - - `libcoreclr.so` - - `libmono-component-debugger-static.a` - - `libmono-component-debugger-stub-static.a` - - `libmono-component-diagnostics_tracing-static.a` - - `libmono-component-diagnostics_tracing-stub-static.a` - - `libmono-component-hot_reload-static.a` - - `libmono-component-hot_reload-stub-static.a` - - `libmono-component-marshal-ilgen-static.a` - - `libmono-component-marshal-ilgen-stub-static.a` - - `libmono-profiler-aot.a` - - `libmonosgen-2.0.a` - - `artifacts/bin/runtime/net8.0-linux-Debug-x64` - - `libSystem.Globalization.Native.a` - - `libSystem.Native.so` - ---- - -### macOS - 1. 环境:[Requirements to build dotnet/runtime on macOS](https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/macos-requirements.md) - 2. 编译 - - Debug:`./build.sh mono+libs` - - Release:`./build.sh mono+libs -c release` - 3. include - - `artifacts/bin/mono/osx.x64.Debug/include` - 4. dll - - [Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64/8.0.5),修改后缀为.zip,并解压 - - 根据`runtimes/maccatalyst-x64/lib/net8.0`筛选`artifacts/bin/runtime/net8.0-osx-Debug-x64`中的dll - - `artifacts/bin/mono/osx.x64.Debug/System.Private.CoreLib.dll` - 5. lib - - `artifacts/obj/mono/osx.x64.Debug/out/lib` - - `libmono-component-debugger-static.a` - - `libmono-component-debugger-stub-static.a` - - `libmono-component-diagnostics_tracing-static.a` - - `libmono-component-diagnostics_tracing-stub-static.a` - - `libmono-component-hot_reload-static.a` - - `libmono-component-hot_reload-stub-static.a` - - `libmono-component-marshal-ilgen-static.a` - - `libmono-component-marshal-ilgen-stub-static.a` - - `libmono-profiler-aot.a` - - `libmonosgen-2.0.a` - - `artifacts/bin/mono/osx.x64.Debug` - - `libcoreclr.dylib` - - `artifacts/bin/runtime/net8.0-osx-Debug-x64` - - `libSystem.Globalization.Native.a` - - `libSystem.Globalization.Native.dylib` - - `libSystem.IO.Compression.Native.dylib` - - `libSystem.IO.Ports.Native.dylib` - - `libSystem.Native.dylib` - - `libSystem.Net.Security.Native.dylib` - - `libSystem.Security.Cryptography.Native.Apple.dylib` - - `libSystem.Security.Cryptography.Native.OpenSsl.dylib` +## 源码仓库 ---- +- **主仓库**: [dotnet/runtime](https://github.com/dotnet/runtime) +- **版本**: 推荐使用v8.0.5或更高版本 +- **分支**: `main` 或对应的发布分支 -### Android - 1. 环境:[Testing Libraries on Android](https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/libraries/testing-android.md) - 2. 编译 - - Debug:`./build.sh mono+libs -os android -arch arm64` - - Release:`./build.sh mono+libs -os android -arch arm64 -c release` - 3. include - - `artifacts/bin/mono/android.arm64.Debug/include` - 4. dll - - [Microsoft.NETCore.App.Runtime.Mono.android-arm64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.android-arm64/8.0.5),修改后缀为.zip,并解压 - - 根据`runtimes/android-arm64/lib/net8.0`筛选`artifacts/bin/runtime/net8.0-android-Debug-arm64`中的dll - - `artifacts/bin/mono/android.arm64.Debug/System.Private.CoreLib.dll` - 5. lib - - `artifacts/obj/mono/android.arm64.Debug/out/lib` - - `libmono-component-debugger-static.a` - - `libmono-component-debugger-stub-static.a` - - `libmono-component-diagnostics_tracing-static.a` - - `libmono-component-diagnostics_tracing-stub-static.a` - - `libmono-component-hot_reload-static.a` - - `libmono-component-hot_reload-stub-static.a` - - `libmono-component-marshal-ilgen-static.a` - - `libmono-component-marshal-ilgen-stub-static.a` - - `libmonosgen-2.0.a` - - `libmonosgen-2.0.so` - - `artifacts/bin/runtime/net8.0-android-Debug-arm64` - - `libSystem.Native.so` +## 文档导航 ---- +本文档按照以下结构组织: -### IOS - 1. 环境:[Testing Libraries on iOS, tvOS, and MacCatalyst](https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/libraries/testing-apple.md) - 2. 编译选项:[v8.0.5-IOS](https://github.com/crazytuzi/runtime/commit/511b15e287bbb5eb084911da3218f9466b8950e0) - 3. 编译 - - Debug:`./build.sh mono+libs -os ios -arch arm64` - - Release:`./build.sh mono+libs -os ios -arch arm64 -c release` - - 拷贝`artifacts/obj/mono/System.Private.CoreLib/arm64/Debug/PreTrim/System.Private.CoreLib.dll`到`artifacts/obj/mono/ios.arm64.Debug/cross/mono/mini/mono-aot-cross` - - `./mono-aot-cross --aot=asmonly,static,interp System.Private.CoreLib.dll` - - `xcrun -sdk iphoneos clang -arch arm64 -o System.Private.CoreLib.dll.o -c System.Private.CoreLib.dll.s` - - `ar rcs System.Private.CoreLib.dll.a System.Private.CoreLib.dll.o` - 4. include - - `artifacts/bin/mono/ios.arm64.Debug/include` - 5. dll - - [Microsoft.NETCore.App.Runtime.Mono.ios-arm64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.ios-arm64/8.0.5),修改后缀为.zip,并解压 - - 根据`runtimes/ios-arm64/lib/net8.0`筛选`artifacts/bin/runtime/net8.0-ios-Debug-arm64`中的dll - - `artifacts/obj/mono/System.Private.CoreLib/arm64/Debug/PreTrim/System.Private.CoreLib.dll` - 6. lib - - `artifacts/obj/mono/ios.arm64.Debug/out/lib` - - `libmono-component-debugger-static.a` - - `libmono-component-debugger-stub-static.a` - - `libmono-component-diagnostics_tracing-static.a` - - `libmono-component-diagnostics_tracing-stub-static.a` - - `libmono-component-hot_reload-static.a` - - `libmono-component-hot_reload-stub-static.a` - - `libmono-component-marshal-ilgen-static.a` - - `libmono-component-marshal-ilgen-stub-static.a` - - `libmonosgen-2.0.a` - - `artifacts/bin/runtime/net8.0-ios-Debug-arm64` - - `libicudata.a` - - `libicui18n.a` - - `libicuuc.a` - - `libSystem.Globalization.Native.a` - - `libSystem.Globalization.Native.dylib` - - `libSystem.IO.Compression.Native.dylib` - - `libSystem.Native.dylib` - - `libSystem.Net.Security.Native.dylib` - - `libSystem.Security.Cryptography.Native.Apple.dylib` - - `artifacts/obj/mono/ios.arm64.Debug/cross/mono/mini/mono-aot-cross` - - `System.Private.CoreLib.dll.a` - 7. Framework - 1. 新建`IOS`-`Framework` - 2. `Product`填写`Mono` - 3. `Language`选择`Objective-C` - 4. 不勾选`Include Tests`和`Include Documentation` - 5. `Minmum Deployments`选择`14.0` - 6. `Build Settings`-`Library Search Paths`-`Debug`选择`*dylib`目录 - 7. `Build Phases`-`Link Binary With Libraries`添加`*dylib` - 8. `General`-`Frameworks and Libraries`-`Embed`选择`Embed & Sign` - 9. `Build`选择`Any IOS Device(arm64)` - 10. `File`-`Project Setting`-`Advanced`-`Custom`选择`Relative to Workspace` - 11. `Build/Products/Debug-iphones`新建`Mono.embeddendframework`文件夹,拷贝`Mono.framework`到`Mono.embeddendframework`,压缩`Mono.embeddendframework` +1. [Windows编译](#windows) - Visual Studio环境编译 +2. [Linux编译](#linux) - GCC/Clang工具链编译 +3. [macOS编译](#macos) - Xcode命令行工具编译 +4. [Android编译](#android) - NDK交叉编译 +5. [iOS编译](#ios) - 包含AOT和Framework打包 +6. [常见问题](#常见问题-faq) - 故障排除和解决方案 +7. [最佳实践](#最佳实践) - 性能优化和部署建议 ---- + +## Windows + +:::tip 提示 +Windows编译需要Visual Studio 2022或Visual Studio Build Tools 2022。 +::: + +### 环境要求 + +**系统要求**: +- Windows 10版本1909或更高版本 +- Visual Studio 2022或Visual Studio Build Tools 2022 +- Windows SDK (最新版本) +- Git for Windows + +**详细要求**: [Requirements to build dotnet/runtime on Windows](https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/windows-requirements.md) + +### 编译步骤 + +```powershell +# 克隆源码 +git clone https://github.com/dotnet/runtime.git +cd runtime + +# Debug版本编译 +.\build.cmd mono+libs + +# Release版本编译 +.\build.cmd mono+libs -c release + +# 指定架构编译 (可选) +.\build.cmd mono+libs -arch x64 +``` + +:::warning 注意 +编译过程可能需要1-2小时,确保有足够的磁盘空间(至少20GB)。 +::: + +### 产物目录 + +#### 头文件 (Include Files) +``` +artifacts/bin/mono/windows.x64.Debug/include/ +├── mono/ +│ ├── jit/ +│ ├── metadata/ +│ └── utils/ +└── ... +``` + +#### 托管库文件 (Managed Assemblies) +| 文件类型 | 位置 | 说明 | +|---------|------|------| +| NuGet包 | [Microsoft.NETCore.App.Runtime.Mono.win-x64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.win-x64/8.0.5) | 下载后解压获取运行时库 | +| 运行时库 | `artifacts/bin/runtime/net8.0-windows-Debug-x64/` | 根据`runtimes/win-x64/lib/net8.0`筛选 | +| 核心库 | `artifacts/bin/mono/windows.x64.Debug/System.Private.CoreLib.dll` | Mono核心类库 | + +#### 本机库文件 (Native Libraries) +位于 `artifacts/obj/mono/windows.x64.Debug/out/lib/` 目录下: + +| 文件名 | 用途 | +|--------|------| +| `coreclr.dll` | 核心运行时库 | +| `coreclr.import.lib` | 导入库 | +| `mono-component-debugger-static.lib` | 调试器组件 | +| `mono-component-debugger-stub-static.lib` | 调试器存根 | +| `mono-component-diagnostics_tracing-static.lib` | 诊断跟踪组件 | +| `mono-component-diagnostics_tracing-stub-static.lib` | 诊断跟踪存根 | +| `mono-component-hot_reload-static.lib` | 热重载组件 | +| `mono-component-hot_reload-stub-static.lib` | 热重载存根 | +| `mono-component-marshal-ilgen-static.lib` | 编组IL生成组件 | +| `mono-component-marshal-ilgen-stub-static.lib` | 编组IL生成存根 | +| `mono-profiler-aot.lib` | AOT分析器 | +| `monosgen-2.0.lib` | Mono SGen垃圾回收器 | + +## Linux + +:::tip 提示 +Linux编译支持多种发行版,推荐使用Ubuntu 20.04 LTS或更高版本。 +::: + +### 环境要求 + +**系统要求**: +- Ubuntu 20.04 LTS, CentOS 8, 或其他现代Linux发行版 +- GCC 9+ 或 Clang 10+ +- CMake 3.16+ +- Python 3.6+ +- Git + +**包管理器安装**: +```bash +# Ubuntu/Debian +sudo apt-get update +sudo apt-get install build-essential cmake python3 git + +# CentOS/RHEL +sudo yum groupinstall "Development Tools" +sudo yum install cmake python3 git +``` + +**详细要求**: [Requirements to build dotnet/runtime on Linux](https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/linux-requirements.md) + +### 编译选项 + +**自定义修改参考**: [v8.0.5-Linux 修改参考](https://github.com/crazytuzi/runtime/commit/0458ead883ddb88e269fc14d1937d95f77279031) + +### 编译步骤 + +```bash +# 克隆源码 +git clone https://github.com/dotnet/runtime.git +cd runtime + +# 确保脚本可执行 +chmod +x build.sh + +# Debug版本编译 +./build.sh mono+libs + +# Release版本编译 +./build.sh mono+libs -c release + +# 指定架构编译 +./build.sh mono+libs -arch x64 +``` + +### 产物目录 + +#### 头文件 (Include Files) +``` +artifacts/bin/mono/linux.x64.Debug/include/ +``` + +#### 托管库文件 (Managed Assemblies) +| 文件类型 | 位置 | 说明 | +|---------|------|------| +| NuGet包 | [Microsoft.NETCore.App.Runtime.Mono.linux-x64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.linux-x64/8.0.5) | 下载后解压获取运行时库 | +| 运行时库 | `artifacts/bin/runtime/net8.0-linux-Debug-x64/` | 根据`runtimes/linux-x64/lib/net8.0`筛选 | +| 核心库 | `artifacts/bin/mono/linux.x64.Debug/System.Private.CoreLib.dll` | Mono核心类库 | + +#### 本机库文件 (Native Libraries) + +**主要库文件**位于 `artifacts/obj/mono/linux.x64.Debug/out/lib/` 目录下: + +| 文件名 | 用途 | +|--------|------| +| `libcoreclr.so` | 核心运行时共享库 | +| `libmono-component-debugger-static.a` | 调试器组件静态库 | +| `libmono-component-debugger-stub-static.a` | 调试器存根静态库 | +| `libmono-component-diagnostics_tracing-static.a` | 诊断跟踪组件 | +| `libmono-component-diagnostics_tracing-stub-static.a` | 诊断跟踪存根 | +| `libmono-component-hot_reload-static.a` | 热重载组件 | +| `libmono-component-hot_reload-stub-static.a` | 热重载存根 | +| `libmono-component-marshal-ilgen-static.a` | 编组IL生成组件 | +| `libmono-component-marshal-ilgen-stub-static.a` | 编组IL生成存根 | +| `libmono-profiler-aot.a` | AOT分析器 | +| `libmonosgen-2.0.a` | Mono SGen垃圾回收器 | + +**系统库文件**位于 `artifacts/bin/runtime/net8.0-linux-Debug-x64/` 目录下: + +| 文件名 | 用途 | +|--------|------| +| `libSystem.Globalization.Native.a` | 全球化支持静态库 | +| `libSystem.Native.so` | 系统本机库 | + +## macOS + +### 环境要求 +[Requirements to build dotnet/runtime on macOS](https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/macos-requirements.md) + +### 编译步骤 +```bash +# Debug版本 +./build.sh mono+libs + +# Release版本 +./build.sh mono+libs -c release +``` + +### 产物目录 + +#### Include文件 +``` +artifacts/bin/mono/osx.x64.Debug/include +``` + +#### DLL文件 +- [Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64/8.0.5) + > 下载后修改后缀为.zip并解压 +- 根据`runtimes/maccatalyst-x64/lib/net8.0`筛选`artifacts/bin/runtime/net8.0-osx-Debug-x64`中的dll +- `artifacts/bin/mono/osx.x64.Debug/System.Private.CoreLib.dll` + +#### 库文件 + +**基础库文件**位于`artifacts/obj/mono/osx.x64.Debug/out/lib`目录下: +- `libmono-component-debugger-static.a` +- `libmono-component-debugger-stub-static.a` +- `libmono-component-diagnostics_tracing-static.a` +- `libmono-component-diagnostics_tracing-stub-static.a` +- `libmono-component-hot_reload-static.a` +- `libmono-component-hot_reload-stub-static.a` +- `libmono-component-marshal-ilgen-static.a` +- `libmono-component-marshal-ilgen-stub-static.a` +- `libmono-profiler-aot.a` +- `libmonosgen-2.0.a` + +**核心库文件**位于`artifacts/bin/mono/osx.x64.Debug`目录下: +- `libcoreclr.dylib` + +**系统库文件**位于`artifacts/bin/runtime/net8.0-osx-Debug-x64`目录下: +- `libSystem.Globalization.Native.a` +- `libSystem.Globalization.Native.dylib` +- `libSystem.IO.Compression.Native.dylib` +- `libSystem.IO.Ports.Native.dylib` +- `libSystem.Native.dylib` +- `libSystem.Net.Security.Native.dylib` +- `libSystem.Security.Cryptography.Native.Apple.dylib` +- `libSystem.Security.Cryptography.Native.OpenSsl.dylib` + +## Android + +### 环境要求 +[Testing Libraries on Android](https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/libraries/testing-android.md) + +### 编译步骤 +```bash +# Debug版本 +./build.sh mono+libs -os android -arch arm64 + +# Release版本 +./build.sh mono+libs -os android -arch arm64 -c release +``` + +### 产物目录 + +#### Include文件 +``` +artifacts/bin/mono/android.arm64.Debug/include +``` + +#### DLL文件 +- [Microsoft.NETCore.App.Runtime.Mono.android-arm64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.android-arm64/8.0.5) + > 下载后修改后缀为.zip并解压 +- 根据`runtimes/android-arm64/lib/net8.0`筛选`artifacts/bin/runtime/net8.0-android-Debug-arm64`中的dll +- `artifacts/bin/mono/android.arm64.Debug/System.Private.CoreLib.dll` + +#### 库文件 + +**核心库文件**位于`artifacts/obj/mono/android.arm64.Debug/out/lib`目录下: +- `libmono-component-debugger-static.a` +- `libmono-component-debugger-stub-static.a` +- `libmono-component-diagnostics_tracing-static.a` +- `libmono-component-diagnostics_tracing-stub-static.a` +- `libmono-component-hot_reload-static.a` +- `libmono-component-hot_reload-stub-static.a` +- `libmono-component-marshal-ilgen-static.a` +- `libmono-component-marshal-ilgen-stub-static.a` +- `libmonosgen-2.0.a` +- `libmonosgen-2.0.so` + +**系统库文件**位于`artifacts/bin/runtime/net8.0-android-Debug-arm64`目录下: +- `libSystem.Native.so` + +## iOS + +:::tip 提示 +iOS编译需要macOS系统和完整的Xcode开发环境,支持AOT编译。 +::: + +### 环境要求 + +**系统要求**: +- macOS 12.0 (Monterey) 或更高版本 +- Xcode 14.0 或更高版本 +- iOS SDK 16.0 或更高版本 +- 命令行工具 + +**安装命令行工具**: +```bash +sudo xcode-select --install +sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer +``` + +**详细要求**: [Testing Libraries on iOS, tvOS, and MacCatalyst](https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/libraries/testing-apple.md) + +### 编译选项 + +**自定义修改参考**: [v8.0.5-iOS 修改参考](https://github.com/crazytuzi/runtime/commit/511b15e287bbb5eb084911da3218f9466b8950e0) + +### 编译步骤 + +```bash +# 克隆源码 +git clone https://github.com/dotnet/runtime.git +cd runtime + +# Debug版本编译 +./build.sh mono+libs -os ios -arch arm64 + +# Release版本编译 +./build.sh mono+libs -os ios -arch arm64 -c release + +# 多架构编译 (Universal Binary) +./build.sh mono+libs -os ios -arch "arm64+x64" +``` + +### AOT编译步骤 + +:::info AOT编译说明 +Ahead-of-Time (AOT) 编译将.NET程序集预编译为本机代码,提升iOS应用启动性能。 +::: + +```bash +# 1. 拷贝核心库到AOT工具目录 +cp artifacts/obj/mono/System.Private.CoreLib/arm64/Debug/PreTrim/System.Private.CoreLib.dll \ + artifacts/obj/mono/ios.arm64.Debug/cross/mono/mini/mono-aot-cross/ + +# 2. 进入AOT工具目录 +cd artifacts/obj/mono/ios.arm64.Debug/cross/mono/mini/mono-aot-cross + +# 3. 执行AOT编译 +./mono-aot-cross --aot=asmonly,static,interp System.Private.CoreLib.dll + +# 4. 编译汇编代码为目标文件 +xcrun -sdk iphoneos clang -arch arm64 \ + -o System.Private.CoreLib.dll.o \ + -c System.Private.CoreLib.dll.s + +# 5. 创建静态库 +ar rcs System.Private.CoreLib.dll.a System.Private.CoreLib.dll.o +``` + +**AOT编译参数说明**: +- `asmonly`: 仅生成汇编代码 +- `static`: 生成静态链接库 +- `interp`: 支持解释器回退 + +### 产物目录 + +#### Include文件 +``` +artifacts/bin/mono/ios.arm64.Debug/include +``` + +#### DLL文件 +- [Microsoft.NETCore.App.Runtime.Mono.ios-arm64](https://www.nuget.org/packages/Microsoft.NETCore.App.Runtime.Mono.ios-arm64/8.0.5) + > 下载后修改后缀为.zip并解压 +- 根据`runtimes/ios-arm64/lib/net8.0`筛选`artifacts/bin/runtime/net8.0-ios-Debug-arm64`中的dll +- `artifacts/obj/mono/System.Private.CoreLib/arm64/Debug/PreTrim/System.Private.CoreLib.dll` + +#### 库文件 + +**核心库文件**位于`artifacts/obj/mono/ios.arm64.Debug/out/lib`目录下: +- `libmono-component-debugger-static.a` +- `libmono-component-debugger-stub-static.a` +- `libmono-component-diagnostics_tracing-static.a` +- `libmono-component-diagnostics_tracing-stub-static.a` +- `libmono-component-hot_reload-static.a` +- `libmono-component-hot_reload-stub-static.a` +- `libmono-component-marshal-ilgen-static.a` +- `libmono-component-marshal-ilgen-stub-static.a` +- `libmonosgen-2.0.a` + +**系统库文件**位于`artifacts/bin/runtime/net8.0-ios-Debug-arm64`目录下: +- `libicudata.a` +- `libicui18n.a` +- `libicuuc.a` +- `libSystem.Globalization.Native.a` +- `libSystem.Globalization.Native.dylib` +- `libSystem.IO.Compression.Native.dylib` +- `libSystem.Native.dylib` +- `libSystem.Net.Security.Native.dylib` +- `libSystem.Security.Cryptography.Native.Apple.dylib` + +**AOT编译产物**位于`artifacts/obj/mono/ios.arm64.Debug/cross/mono/mini/mono-aot-cross`目录下: +- `System.Private.CoreLib.dll.a` + +### Framework创建步骤 + +:::tip Framework用途 +创建iOS Framework便于在Xcode项目中集成Mono运行时。 +::: + +#### 1. 创建Xcode项目 + +在Xcode中创建新项目: +- **模板**: iOS → Framework +- **产品名称**: `Mono` +- **语言**: Objective-C +- **选项**: 取消勾选 `Include Tests` 和 `Include Documentation` +- **部署目标**: iOS 14.0或更高 + +#### 2. 配置构建设置 + +**Library Search Paths**: +``` +Build Settings → Library Search Paths → Debug +``` +添加包含 `*.dylib` 文件的目录路径 + +**链接库文件**: +``` +Build Phases → Link Binary With Libraries +``` +添加所需的 `*.dylib` 文件 + +**嵌入设置**: +``` +General → Frameworks and Libraries → Embed +``` +选择 `Embed & Sign` + +**构建目标**: +选择 `Any iOS Device (arm64)` + +#### 3. 项目设置优化 + +**工作空间设置**: +``` +File → Project Settings → Advanced → Custom +``` +选择 `Relative to Workspace` + +#### 4. 自动化打包脚本 + +```bash +#!/bin/bash +# build_framework.sh + +set -e + +PROJECT_NAME="Mono" +BUILD_DIR="Build/Products" +SCHEME_NAME="Debug-iphoneos" + +echo "开始构建 ${PROJECT_NAME} Framework..." + +# 清理之前的构建产物 +xcodebuild clean -project ${PROJECT_NAME}.xcodeproj -scheme ${PROJECT_NAME} + +# 构建Framework +xcodebuild archive \ + -project ${PROJECT_NAME}.xcodeproj \ + -scheme ${PROJECT_NAME} \ + -destination "generic/platform=iOS" \ + -archivePath ${BUILD_DIR}/${PROJECT_NAME}.xcarchive \ + SKIP_INSTALL=NO \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES + +# 创建嵌入式Framework目录 +EMBED_DIR="${BUILD_DIR}/${SCHEME_NAME}/${PROJECT_NAME}.embeddedframework" +mkdir -p "${EMBED_DIR}" + +# 拷贝Framework +cp -R "${BUILD_DIR}/${SCHEME_NAME}/${PROJECT_NAME}.framework" "${EMBED_DIR}/" + +# 压缩打包 +cd "${BUILD_DIR}/${SCHEME_NAME}" +zip -r "${PROJECT_NAME}.embeddedframework.zip" "${PROJECT_NAME}.embeddedframework" + +echo "Framework打包完成: ${BUILD_DIR}/${SCHEME_NAME}/${PROJECT_NAME}.embeddedframework.zip" +``` + +**使用方法**: +```bash +chmod +x build_framework.sh +./build_framework.sh +``` diff --git a/docs/document/advanced/directory.md b/docs/document/advanced/directory.md index 381c5c6..67987ba 100644 --- a/docs/document/advanced/directory.md +++ b/docs/document/advanced/directory.md @@ -7,17 +7,64 @@ sidebar_position: 2 custom_edit_url: null --- -## - -- Game - - Proxy,生成代码,不可编辑 - - 其他,项目代码 -- UE - - Proxy,生成代码,不可编辑 - - CoreUObject,反射数据类型实现及拓展,工具类 - - Dynamic,动态类 - - Library,InternalCall - - Log,重写Log,接入UE - - Reflection,用于TFieldPath +# 目录结构 + +UnrealCSharp 项目的目录结构清晰地分为两个主要部分:`Game` 和 `UE`,每个部分都有其特定的功能和职责。 + +## 📁 Game 目录 + +游戏项目相关代码目录,包含游戏逻辑和生成的代理代码。 + +### 📄 Proxy +:::warning 自动生成代码 +此目录包含自动生成的代理代码,**请勿手动编辑**,任何修改都会在下次生成时被覆盖。 +::: + +### 📄 其他目录 +包含项目的核心游戏逻辑代码,这些是开发者主要编写和维护的代码文件。 + +--- + +## 📁 UE 目录 + +Unreal Engine 相关的功能模块,提供与引擎交互的核心功能。 + +### 📄 Proxy +:::warning 自动生成代码 +与Game目录下的Proxy类似,包含自动生成的引擎代理代码,**请勿手动编辑**。 +::: + +### 📄 CoreUObject +**反射数据类型实现及拓展模块** +- 提供反射数据类型的C#实现 +- 包含各种工具类和扩展方法 +- 为UE对象系统提供C#支持 + +### 📄 Dynamic +**动态类功能模块** +- 支持运行时动态创建和修改类 +- 提供动态类型系统的核心功能 + +### 📄 Library +**内部调用接口模块** +- 实现InternalCall机制 +- 提供C#与C++之间的高效调用桥梁 + +### 📄 Log +**日志系统模块** +- 重写并扩展了标准日志功能 +- 与Unreal Engine的日志系统深度集成 +- 提供统一的日志输出接口 + +### 📄 Reflection +**反射工具模块** +- 专门用于支持`TFieldPath`相关功能 +- 提供反射操作的辅助工具和方法 --- + +:::tip 开发建议 +- 只在非Proxy目录下编写和修改代码 +- Proxy目录的内容会在项目重新生成时自动更新 +- 充分利用各个UE模块提供的功能来构建你的游戏逻辑 +::: diff --git a/docs/document/advanced/framework.md b/docs/document/advanced/framework.md index ec308d8..7347dac 100644 --- a/docs/document/advanced/framework.md +++ b/docs/document/advanced/framework.md @@ -7,19 +7,86 @@ sidebar_position: 1 custom_edit_url: null --- -## +# 框架架构 -- CrossVersion,跨版本支持 -- ThirdParty,Mono头文件以及lib -- UnrealCSharpCore,Runtime和Editor通用功能 -- ScriptCodeGenerator,C#代码生成 -- SourceCodeGenerator,C++代码生成 -- Compiler,C#编译 -- UnrealCSharpEditor,编辑器功能 -- UnrealCSharp,Runtime功能 +UnrealCSharp 是一个完整的C#集成解决方案,为Unreal Engine提供全面的C#开发支持。整个框架由多个核心模块组成,各司其职,协同工作。 + +## 🏗️ 核心模块 + +### 🔄 CrossVersion +**跨版本支持模块** +- 提供对不同Unreal Engine版本的兼容性支持 +- 处理引擎版本差异,确保代码在多个版本间的稳定性 + +### 📦 ThirdParty +**第三方依赖模块** +- 包含Mono运行时的头文件和库文件 +- 管理外部依赖项,确保编译和运行时的完整性 + +### ⚙️ UnrealCSharpCore +**核心功能模块** +- Runtime和Editor共享的通用功能 +- 提供基础设施和公共服务 +- 是整个框架的基石 + +--- + +## 🛠️ 开发工具模块 + +### 📝 ScriptCodeGenerator +**C#代码生成器** +- 自动生成C#绑定代码 +- 根据UE类型自动创建对应的C#接口 +- 保证C#代码与引擎API的同步 + +### ⚡ SourceCodeGenerator +**C++代码生成器** +- 生成必要的C++桥接代码 +- 创建C#与C++之间的互操作层 +- 优化调用性能 + +### 🔨 Compiler +**C#编译器模块** +- 集成的C#代码编译功能 +- 支持热重载和增量编译 +- 提供编译错误诊断 --- +## 🎯 运行时模块 + +### 🎨 UnrealCSharpEditor +**编辑器功能模块** +- 专门用于Unreal Engine编辑器环境 +- 提供编辑器工具和界面集成 +- 支持设计时功能和调试工具 + +### 🚀 UnrealCSharp +**运行时功能模块** +- 游戏运行时的核心功能 +- 处理游戏逻辑执行 +- 管理C#脚本的生命周期 + +--- + +## 📊 架构图 + +下图展示了各模块之间的关系和数据流: + ![framework](./img/framework.png) --- + +## 🔄 工作流程 + +1. **开发阶段**:开发者编写C#代码 +2. **生成阶段**:代码生成器创建绑定代码 +3. **编译阶段**:编译器处理所有C#代码 +4. **运行阶段**:运行时模块执行游戏逻辑 + +:::info 架构优势 +- **模块化设计**:各模块职责清晰,便于维护和扩展 +- **跨版本兼容**:支持多个UE版本,降低迁移成本 +- **高性能**:优化的调用机制,确保运行效率 +- **开发友好**:完整的工具链支持,提升开发体验 +::: diff --git a/docs/document/getting-started/binding.md b/docs/document/getting-started/binding.md index 11e17f5..9a2cc2c 100644 --- a/docs/document/getting-started/binding.md +++ b/docs/document/getting-started/binding.md @@ -1,8 +1,7 @@ --- -title: 静态导出 -description: 导出未被标记反射的类,变量和函数 -hide_title: true -slug: binding +title: 🔗 静态绑定 +description: 扩展 UE 反射系统,导出未标记反射的类、变量和函数 +hide_title: false sidebar_position: 4 custom_edit_url: null --- @@ -10,38 +9,100 @@ custom_edit_url: null import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## 介绍 +# 🔗 静态绑定 (Static Binding) -基于UE的反射机制能够访问到被标记反射的类,变量和函数,但是还是存在部分类由于不是UE支持的反射类型,或者类,变量和函数并没有被标记反射而导致访问不到。针对这种情况,提供了静态导出,拓展了支持的类,变量和函数,同时也可以用于优化变量访问和函数调用的效率。 +
+

+ 🚀 扩展 UE 反射系统,访问更多 C++ 类型和功能 +

+
--- -## 枚举 +## 🎯 什么是静态绑定? + +
+ 💡 核心概念: 静态绑定是 UnrealCSharp 提供的强大功能,用于扩展 UE 反射系统的覆盖范围。 +
+ +虽然 UE 的反射机制可以访问标记了反射的类、变量和函数,但仍有部分内容因为以下原因无法直接访问: + +
+
+
+
+

⚠️ 无法访问的情况

+
+
+
    +
  • 不是 UE 支持的反射类型
  • +
  • 类/变量/函数未标记反射
  • +
  • 第三方库的类型
  • +
  • 原生 C++ 标准库类型
  • +
+
+
+
+
+
+
+

✨ 静态绑定的优势

+
+
+
    +
  • 扩展支持的类型范围
  • +
  • 优化变量访问效率
  • +
  • 提升函数调用性能
  • +
  • 完全自定义绑定逻辑
  • +
+
+
+
+
-静态导出枚举时,会通过std::underlying_type_t拿到UnderlyingType并生成,保证C++和C#两侧内存大小一致。 +--- + +## 📋 枚举绑定 + +
+ 🔧 技术实现: 使用 std::underlying_type_t 获取 UnderlyingType 并生成,确保 C++ 和 C# 两侧内存大小完全一致。 +
+ +### 🎯 绑定流程 + +1. **声明绑定** - 使用 `BINDING_ENUM` 宏声明枚举 +2. **注册器类** - 创建注册器结构体 +3. **枚举值绑定** - 使用 `TBindingEnumBuilder` 绑定每个枚举值 +4. **静态注册** - 创建静态实例完成注册
-示例:枚举 +💻 完整代码示例:枚举绑定 - + -```cpp +```cpp title="ERawTestEnum.h" +// 原始的 C++ 枚举,未标记 UE 反射 enum ERawTestEnum { RawTestEnumZero, - RawTestEnumOne, + RawTestEnumOne, RawTestEnumTwo }; ``` +
+ ⚠️ 问题: 这个枚举没有 UENUM 标记,C# 无法直接访问 +
+
- + -```cpp +```cpp title="ERawTestEnumBinding.cpp" +// 静态绑定实现 BINDING_ENUM(ERawTestEnum) struct FRegisterRawTestEnum @@ -55,9 +116,39 @@ struct FRegisterRawTestEnum } }; +// 静态实例,程序启动时自动注册 static FRegisterRawTestEnum RegisterRawTestEnum; ``` +
+ ✅ 解决: 现在 C# 可以直接使用这个枚举了! +
+ +
+ + + +```csharp title="Usage.cs" +// 在 C# 中使用绑定的枚举 +public class ExampleUsage +{ + public void UseEnum() + { + // 直接使用原本无法访问的枚举 + var enumValue = ERawTestEnum.RawTestEnumOne; + + // 进行枚举比较 + if (enumValue == ERawTestEnum.RawTestEnumZero) + { + // 处理逻辑 + } + + // 枚举转换 + int intValue = (int)enumValue; + } +} +``` +
@@ -66,68 +157,194 @@ static FRegisterRawTestEnum RegisterRawTestEnum; --- -## 类/结构体 - -静态导出时,不区分类或者结构体,但是区分反射和非反射类型,需要通过不同的模板来导出。除了常规的导出变量和函数,还支持一些额外的操作。 - -- 构造函数 -- 函数重载 -- 继承 -- 静态变量 -- 一元操作符,`!,+,-,~,++,--` -- 二元操作符,`+,-,*,/,%,&,|,^,<<,>>,==,!=,<,<=,>,>=` -- 下标运算符,`[]` +## 🏗️ 类与结构体绑定 + +
+ 🔍 灵活设计: 静态绑定不区分类或结构体,但会区分反射和非反射类型,使用不同的模板进行导出。 +
+ +### ⚡ 支持的高级功能 + +
+
+
+
+

🔧 基础功能

+
+
+
    +
  • 构造函数
  • +
  • 函数重载
  • +
  • 继承关系
  • +
  • 静态变量
  • +
+
+
+
+
+
+
+

🎯 操作符重载

+
+
+

一元操作符:

+

! + - ~ ++ --

+

二元操作符:

+

+ - * / % & | ^

+

<< >> == != < <= > >=

+

下标运算符: []

+
+
+
+
+ +### 🎯 绑定步骤 + +1. **声明绑定类** - 使用 `BINDING_CLASS` 宏 +2. **创建注册器** - 实现注册结构体 +3. **绑定成员** - 使用 `TBindingClassBuilder` 绑定属性和函数 +4. **完成注册** - 创建静态实例
-示例:类/结构体 +💻 完整代码示例:类绑定 - + -```cpp +```cpp title="FTestBindingFunction.h" #pragma once +// 普通的 C++ 类,未使用 UE 反射 class FTestBindingFunction { public: - FTestBindingFunction(); + FTestBindingFunction(); public: - void SetInt32ValueFunction(int32 InInt32Value); + // 设置整型值 + void SetInt32ValueFunction(int32 InInt32Value); - int32 GetInt32ValueFunction() const; + // 获取整型值 + int32 GetInt32ValueFunction() const; - void OutInt32ValueFunction(int32& OutInt32Value) const; + // 输出参数示例 + void OutInt32ValueFunction(int32& OutInt32Value) const; public: - int32 Int32Value; + int32 Int32Value; }; ``` +
+ ⚠️ 限制: 普通 C++ 类无法被 UE 反射系统识别,C# 无法直接访问 +
+
- + + +```cpp title="FTestBindingFunctionBinding.cpp" +#include "FTestBindingFunction.h" -```cpp +// 声明这是一个需要绑定的类 BINDING_CLASS(FTestBindingFunction) struct FRegisterTestBindingFunction { - FRegisterTestBindingFunction() - { - TBindingClassBuilder(NAMESPACE_BINDING) - .Property("Int32Value", BINDING_PROPERTY(&FTestBindingFunction::Int32Value)) - .Function("SetInt32ValueFunction", BINDING_FUNCTION(&FTestBindingFunction::SetInt32ValueFunction)) - .Function("GetInt32ValueFunction", BINDING_FUNCTION(&FTestBindingFunction::GetInt32ValueFunction)) - .Function("OutInt32ValueFunction", BINDING_FUNCTION(&FTestBindingFunction::OutInt32ValueFunction)); - } + FRegisterTestBindingFunction() + { + // 使用 TBindingClassBuilder 进行绑定 + TBindingClassBuilder(NAMESPACE_BINDING) + // 绑定属性 + .Property("Int32Value", + BINDING_PROPERTY(&FTestBindingFunction::Int32Value)) + + // 绑定成员函数 + .Function("SetInt32ValueFunction", + BINDING_FUNCTION(&FTestBindingFunction::SetInt32ValueFunction)) + .Function("GetInt32ValueFunction", + BINDING_FUNCTION(&FTestBindingFunction::GetInt32ValueFunction)) + .Function("OutInt32ValueFunction", + BINDING_FUNCTION(&FTestBindingFunction::OutInt32ValueFunction)); + } }; +// 静态注册实例 static FRegisterTestBindingFunction RegisterTestBindingFunction; ``` +
+ 🎉 成功: 现在 C# 可以完全访问这个类的所有功能! +
+ +
+ + + +```csharp title="Usage.cs" +// 在 C# 中使用绑定的类 +public class ExampleUsage +{ + public void UseBindingClass() + { + // 创建实例 + var testObj = new FTestBindingFunction(); + + // 直接访问属性 + testObj.Int32Value = 42; + int currentValue = testObj.Int32Value; + + // 调用成员函数 + testObj.SetInt32ValueFunction(100); + int getValue = testObj.GetInt32ValueFunction(); + + // 使用输出参数 + int outValue; + testObj.OutInt32ValueFunction(out outValue); + + Console.WriteLine($"当前值: {outValue}"); + } +} +``` + + + + + +```cpp title="AdvancedBinding.cpp" +// 高级绑定功能示例 +BINDING_CLASS(FAdvancedClass) + +struct FRegisterAdvancedClass +{ + FRegisterAdvancedClass() + { + TBindingClassBuilder(NAMESPACE_BINDING) + // 绑定构造函数 + .Constructor() + + // 绑定静态变量 + .StaticProperty("StaticValue", + BINDING_STATIC_PROPERTY(&FAdvancedClass::StaticValue)) + + // 绑定操作符重载 + .Operator("+", BINDING_OPERATOR(&FAdvancedClass::operator+)) + .Operator("==", BINDING_OPERATOR(&FAdvancedClass::operator==)) + + // 绑定下标运算符 + .Operator("[]", BINDING_OPERATOR(&FAdvancedClass::operator[])) + + // 绑定重载函数 + .Function("Process", + BINDING_OVERLOAD(void, FAdvancedClass, (int32), &FAdvancedClass::Process)) + .Function("Process", + BINDING_OVERLOAD(void, FAdvancedClass, (float, bool), &FAdvancedClass::Process)); + } +}; +``` +
@@ -136,28 +353,306 @@ static FRegisterTestBindingFunction RegisterTestBindingFunction; --- -## 通过UHT生成 - -通过UHT,根据[配置](../guides/configuration/editor)的模块或者插件,自动生成静态绑定代码。 +## 🤖 通过 UHT 自动生成 + +
+ 🚀 自动化流程: UnrealCSharp 可以通过 UHT (Unreal Header Tool) 根据配置自动生成静态绑定代码,大大减少手工编写的工作量。 +
+ +### 📋 配置步骤 + +1. **配置模块/插件** - 在[编辑器配置](../guides/configuration/editor)中指定需要生成绑定的模块或插件 +2. **运行 UHT** - UHT 会扫描指定的头文件 +3. **自动生成** - 生成对应的静态绑定代码文件 +4. **引用文件** - 在项目中引用生成的绑定文件 + +### 💡 优势对比 + +
+
+
+
+

✍️ 手动绑定

+
+
+
    +
  • 🎯 精确控制绑定内容
  • +
  • 🔧 自定义绑定逻辑
  • +
  • ⚠️ 工作量大,易出错
  • +
  • 🔄 维护成本高
  • +
+
+
+
+
+
+
+

🤖 自动生成

+
+
+
    +
  • ⚡ 快速批量生成
  • +
  • ✅ 减少人为错误
  • +
  • 🔄 易于维护更新
  • +
  • 📦 覆盖范围广
  • +
+
+
+
+
-示例:引用静态绑定文件 +💻 代码示例:引用生成的绑定文件 -```cpp + + + + +```cpp title="YourModule.cpp" +// 引用自动生成的静态绑定文件 #if WITH_BINDING -#include "Binding/Class/PreHeader.h" -#include "Engine.header.inl" -#include "UMG.header.inl" + #include "Binding/Class/PreHeader.h" + + // 引用 Engine 模块的绑定 + #include "Engine.header.inl" + + // 引用 UMG 模块的绑定 + #include "UMG.header.inl" + + // 引用其他模块的绑定 + #include "YourCustomModule.header.inl" #endif ``` +
+ 💡 说明: +
    +
  • WITH_BINDING 宏确保只在需要时编译绑定代码
  • +
  • PreHeader.h 包含必要的绑定基础设施
  • +
  • *.header.inl 文件包含具体的绑定实现
  • +
+
+ +
+ + + +```cpp title="Engine.header.inl (生成的文件)" +// 这是 UHT 自动生成的文件,请勿手动修改 + +// AActor 类的绑定 +BINDING_CLASS(AActor) +struct FRegister_AActor +{ + FRegister_AActor() + { + TBindingClassBuilder(TEXT("Script.Engine")) + .Property("RootComponent", + BINDING_PROPERTY(&AActor::RootComponent)) + .Function("GetActorLocation", + BINDING_FUNCTION(&AActor::GetActorLocation)) + .Function("SetActorLocation", + BINDING_FUNCTION(&AActor::SetActorLocation)) + // ... 更多绑定 + ; + } +}; +static FRegister_AActor Register_AActor; + +// UStaticMeshComponent 类的绑定 +BINDING_CLASS(UStaticMeshComponent) +struct FRegister_UStaticMeshComponent +{ + FRegister_UStaticMeshComponent() + { + TBindingClassBuilder(TEXT("Script.Engine")) + .Property("StaticMesh", + BINDING_PROPERTY(&UStaticMeshComponent::GetStaticMesh)) + .Function("SetStaticMesh", + BINDING_FUNCTION(&UStaticMeshComponent::SetStaticMesh)) + // ... 更多绑定 + ; + } +}; +static FRegister_UStaticMeshComponent Register_UStaticMeshComponent; +``` + + + + + +```json title="UnrealCSharpSettings.json" +{ + "BindingModules": [ + { + "Name": "Engine", + "Enabled": true, + "IncludePatterns": [ + "*.h" + ], + "ExcludePatterns": [ + "*Private*", + "*Internal*" + ] + }, + { + "Name": "UMG", + "Enabled": true + }, + { + "Name": "YourCustomModule", + "Enabled": true, + "CustomBindings": [ + "FSpecialClass", + "ESpecialEnum" + ] + } + ] +} +``` + + + +
+
--- -## 示例 +## 📚 学习资源与示例 + +### 🎯 官方示例代码 + +
+ 📁 示例位置: Source/UnrealCSharp/Private/Domain/InternalCall 目录下包含了大量的绑定示例。 +
+ +
+
+
+
+

🎯 推荐学习示例

+
+
+
    +
  • + [FRegisterVector](https://github.com/crazytuzi/UnrealCSharp/blob/main/Source/UnrealCSharp/Private/Domain/InternalCall/FRegisterVector.cpp) - 向量类型绑定 +
  • +
  • FRegisterRotator - 旋转器绑定
  • +
  • FRegisterTransform - 变换矩阵绑定
  • +
  • FRegisterArray - 数组容器绑定
  • +
+
+
+
+
+
+
+

🔧 实践建议

+
+
+
    +
  • 从简单的结构体开始
  • +
  • 先绑定基础功能
  • +
  • 逐步添加高级特性
  • +
  • 参考官方示例代码
  • +
+
+
+
+
+ +### 💡 最佳实践 + +
+ 🎯 绑定技巧: +
    +
  • 命名规范: 保持 C++ 和 C# 命名一致性
  • +
  • 类型安全: 确保参数和返回类型匹配
  • +
  • 内存管理: 注意对象生命周期管理
  • +
  • 性能考虑: 避免频繁的跨语言调用
  • +
+
+ +### 🔍 调试技巧 + + + + + +```cpp title="调试绑定代码" +// 1. 启用详细日志 +UE_LOG(LogUnrealCSharp, Log, TEXT("绑定 %s 类"), *ClassName); + +// 2. 检查绑定状态 +if (!IsBindingRegistered(ClassName)) +{ + UE_LOG(LogUnrealCSharp, Error, TEXT("绑定失败: %s"), *ClassName); +} + +// 3. 验证函数签名 +static_assert(std::is_same_v, + "函数签名不匹配"); +``` + + + + + +```csharp title="测试绑定功能" +// C# 测试代码 +public class BindingTest +{ + public void TestBinding() + { + try + { + // 测试类创建 + var testObj = new FTestBindingFunction(); + + // 测试属性访问 + testObj.Int32Value = 123; + Assert.AreEqual(123, testObj.Int32Value); + + // 测试函数调用 + testObj.SetInt32ValueFunction(456); + Assert.AreEqual(456, testObj.GetInt32ValueFunction()); + + Console.WriteLine("✅ 绑定测试通过!"); + } + catch (Exception ex) + { + Console.WriteLine($"❌ 绑定测试失败: {ex.Message}"); + } + } +} +``` + + + + + +--- -```Source/UnrealCSharp/Private/Domain/InternalCall```下有不少示例,如[FRegisterVector](https://github.com/crazytuzi/UnrealCSharp/blob/main/Source/UnrealCSharp/Private/Domain/InternalCall/FRegisterVector.cpp)。 +## 🚀 下一步 + +
+

现在您已经掌握了静态绑定的基础知识!

+ + ⚡ 学习动态类 + + {' '} + + 🔄 了解函数覆盖 + +
+ +### 📖 相关文档 + +- [📋 反射机制详解](./reflection) - 了解 UE 反射系统基础 +- [⚡ 动态类创建](./dynamic) - 学习如何创建动态 UE 类型 +- [🔄 函数覆盖](./override) - 掌握 C++ 函数重写技巧 +- [⚙️ 编辑器配置](../guides/configuration/editor) - 配置自动绑定选项 --- diff --git a/docs/document/getting-started/dynamic.md b/docs/document/getting-started/dynamic.md index 80dfb64..3b1ce27 100644 --- a/docs/document/getting-started/dynamic.md +++ b/docs/document/getting-started/dynamic.md @@ -1,8 +1,7 @@ --- -title: 动态类 -description: 不需要蓝图载体的动态类 -hide_title: true -slug: dynamic +title: ⚡ 动态类系统 +description: 无需蓝图载体,直接通过 C# 创建 UE 类型 +hide_title: false sidebar_position: 5 custom_edit_url: null --- @@ -10,31 +9,137 @@ custom_edit_url: null import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## 介绍 +# ⚡ 动态类系统 -通过C#可以动态生成UClass,UInterface,UStruct和UEnum,并且不需要蓝图载体。 +
+

+ 🎯 革命性功能:纯 C# 创建完整的 UE 类型系统 +

+
--- -## 基础概念 +## 🌟 什么是动态类? + +
+ 🚀 核心特性: 动态类系统允许您通过 C# 代码直接生成 UClass、UInterface、UStruct 和 UEnum,无需任何蓝图载体! +
+ +### 🎯 支持的类型 + +
+
+
+
+

📋 基础类型

+
+
+
    +
  • 🔢 UEnum - 枚举类型
  • +
  • 📦 UStruct - 结构体类型
  • +
+
+
+
+
+
+
+

🏗️ 高级类型

+
+
+
    +
  • 🎮 UClass - 游戏对象类
  • +
  • 🔌 UInterface - 接口类型
  • +
+
+
+
+
-在[反射](reflection.md)中,有介绍C++中Package和C#中Namespace的映射关系,对于动态类来说,不论namespace是什么,都会被创建到`/Script/CoreUObject`中。这样做的目是有一些特殊的情景,如动态类被其他类所引用或者被放置在场景中时,但是由于没有蓝图载体,如果放在其他Package中,会导致序列化失败。其中UClassAttribute,UStructAttribute和UFunctionAttribute继承于OverrideAttribute,换言之,动态类的变量访问和函数调用又会回到反射绑定流程。同时,为了编辑器热重载,文件命名具有规范。 +--- + +## 🏗️ 架构设计原理 + +
+ 🔍 技术细节: 了解动态类的底层工作机制,有助于更好地使用这一强大功能。 +
+ +### 📦 Package 映射机制 + +在 [反射文档](reflection.md) 中介绍了 C++ Package 和 C# Namespace 的映射关系。对于动态类有特殊处理: + +
+
+
+
+

🎯 统一 Package

+
+
+

所有动态类都创建在:

+

/Script/CoreUObject

+

原因:

+
    +
  • 避免序列化失败
  • +
  • 支持场景放置
  • +
  • 确保引用安全
  • +
+
+
+
+
+
+
+

🔄 热重载支持

+
+
+

特殊设计:

+
    +
  • 继承于 OverrideAttribute
  • +
  • 回到反射绑定流程
  • +
  • 支持编辑器热重载
  • +
  • 规范的文件命名
  • +
+
+
+
+
+ +### 📝 命名规范 + +
+ ⚠️ 重要: 动态类必须遵循严格的命名规范,这是确保系统正常工作的关键! +
+ +| 类型 | 类名前缀 | 文件名前缀 | 示例 | +|------|----------|------------|------| +| UEnum | `E` | `E` | `ETestDynamicEnum` | +| UStruct | `F` | 无 | `FTestDynamicStruct` | +| UClass | `U` 或 `A` | 无 | `ATestDynamicActor` | +| UInterface | `I` | 无 | `ITestDynamicInterface` | --- -## UEnum +## 🔢 UEnum - 动态枚举 + +
+ 🎯 蓝图兼容性: 如果需要标记 BlueprintType(被蓝图使用),UnderlyingType 必须设置为 byte。 +
+ +### 📋 创建要求 -如果需要标记BlueprintType,即被蓝图使用,需要将UnderlyingType设置为byte。枚举名和文件名都需要`E`前缀。 +- **类名前缀:** `E` (例如: `ETestDynamicEnum`) +- **文件名前缀:** `E` (例如: `ETestDynamicEnum.cs`) +- **蓝图类型:** UnderlyingType 必须为 `byte`
-示例:UEnum +💻 完整代码示例:动态枚举 - + -```csharp +```csharp title="ETestDynamicEnum.cs" using Script.Dynamic; namespace Script.CoreUObject @@ -49,6 +154,96 @@ namespace Script.CoreUObject } ``` +
+ ✅ 特性说明: +
    +
  • [UEnum] - 标记为 UE 枚举类型
  • +
  • [BlueprintType] - 允许在蓝图中使用
  • +
  • : byte - 确保蓝图兼容性
  • +
+
+ +
+ + + +```csharp title="EnumUsage.cs" +public class EnumUsageExample +{ + public void UseEnum() + { + // 直接使用动态枚举 + ETestDynamicEnum currentValue = ETestDynamicEnum.TestDynamicOne; + + // 枚举比较 + if (currentValue == ETestDynamicEnum.TestDynamicZero) + { + Console.WriteLine("值为零"); + } + + // 枚举转换 + byte numericValue = (byte)currentValue; + ETestDynamicEnum backToEnum = (ETestDynamicEnum)numericValue; + + // 在蓝图函数中使用 + SetGameState(ETestDynamicEnum.TestDynamicTwo); + } + + [UFunction, BlueprintCallable] + public void SetGameState(ETestDynamicEnum newState) + { + // 这个函数可以在蓝图中调用 + // 参数类型会在蓝图中正确显示 + } +} +``` + + + + + +```csharp title="EGameState.cs" +using Script.Dynamic; + +namespace Script.CoreUObject +{ + [UEnum, BlueprintType] + public enum EGameState : byte + { + [DisplayName("游戏菜单")] + Menu = 0, + + [DisplayName("游戏中")] + Playing = 1, + + [DisplayName("暂停")] + Paused = 2, + + [DisplayName("游戏结束")] + GameOver = 3 + } + + [UEnum, BlueprintType] + public enum EPlayerAction : byte + { + Idle = 0, + Moving = 1, + Jumping = 2, + Attacking = 4, // 可以用作位标志 + Defending = 8 + } +} +``` + +
+ 💡 高级用法: +
    +
  • 使用 [DisplayName] 自定义蓝图中的显示名称
  • +
  • 可以设计为位标志枚举
  • +
  • 支持多个枚举在同一文件中
  • +
+
+
@@ -57,19 +252,27 @@ namespace Script.CoreUObject --- -## UStruct +## 📦 UStruct - 动态结构体 + +
+ 📝 命名规范: 类名需要 F 前缀,但文件名不需要前缀。 +
-类名需要`F`前缀,文件名不需要`F`前缀。 +### 📋 创建要求 + +- **类名前缀:** `F` (例如: `FTestDynamicStruct`) +- **文件名:** 无前缀 (例如: `TestDynamicStruct.cs`) +- **继承标记:** 必须标记 `partial` 以支持代码生成
-示例:UStruct +💻 完整代码示例:动态结构体 - + -```csharp +```csharp title="TestDynamicStruct.cs" using Script.Dynamic; namespace Script.CoreUObject @@ -83,6 +286,158 @@ namespace Script.CoreUObject } ``` +
+ ✅ 特性说明: +
    +
  • [UStruct] - 标记为 UE 结构体
  • +
  • [BlueprintType] - 蓝图可用
  • +
  • partial - 支持代码生成
  • +
  • [UProperty] - 标记属性为 UE 属性
  • +
+
+ +
+ + + +```csharp title="PlayerStats.cs" +using Script.Dynamic; +using Script.CoreUObject; +using Script.Engine; + +namespace Script.CoreUObject +{ + [UStruct, BlueprintType] + public partial class FPlayerStats + { + [UProperty, BlueprintReadWrite, Category = "基础属性"] + public int Health { get; set; } = 100; + + [UProperty, BlueprintReadWrite, Category = "基础属性"] + public int MaxHealth { get; set; } = 100; + + [UProperty, BlueprintReadWrite, Category = "基础属性"] + public float Speed { get; set; } = 600.0f; + + [UProperty, BlueprintReadWrite, Category = "游戏数据"] + public int Score { get; set; } = 0; + + [UProperty, BlueprintReadWrite, Category = "游戏数据"] + public int Level { get; set; } = 1; + + [UProperty, BlueprintReadWrite, Category = "状态"] + public bool IsAlive { get; set; } = true; + + [UProperty, BlueprintReadWrite, Category = "位置信息"] + public FVector LastPosition { get; set; } + + // 构造函数 + public FPlayerStats() + { + Health = MaxHealth; + LastPosition = FVector.ZeroVector; + } + } +} +``` + + + + + +```csharp title="StructUsage.cs" +public class StructUsageExample +{ + public void UseStruct() + { + // 创建结构体实例 + var playerStats = new FPlayerStats + { + Health = 80, + Score = 1500, + Level = 5 + }; + + // 访问属性 + int currentHealth = playerStats.Health; + + // 修改属性 + playerStats.Health = Math.Max(0, playerStats.Health - 10); + + // 检查状态 + if (playerStats.Health <= 0) + { + playerStats.IsAlive = false; + } + + // 在函数中使用 + UpdatePlayerUI(playerStats); + } + + [UFunction, BlueprintCallable] + public void UpdatePlayerUI(FPlayerStats stats) + { + // 这个函数可以在蓝图中调用 + // 结构体会作为完整的参数类型显示 + } +} +``` + + + + + +```csharp title="GameConfig.cs" +using Script.Dynamic; +using Script.CoreUObject; + +namespace Script.CoreUObject +{ + [UStruct, BlueprintType] + public partial class FGameConfig + { + [UProperty, BlueprintReadWrite, Category = "图形设置"] + [Meta(ClampMin = "0", ClampMax = "3")] + public int GraphicsQuality { get; set; } = 2; + + [UProperty, BlueprintReadWrite, Category = "音频设置"] + [Meta(ClampMin = "0.0", ClampMax = "1.0")] + public float MasterVolume { get; set; } = 1.0f; + + [UProperty, BlueprintReadWrite, Category = "游戏设置"] + public bool EnableTutorial { get; set; } = true; + + [UProperty, BlueprintReadWrite, Category = "控制设置"] + public TArray KeyMappings { get; set; } + + // 验证配置的方法 + public bool IsValid() + { + return GraphicsQuality >= 0 && GraphicsQuality <= 3 && + MasterVolume >= 0.0f && MasterVolume <= 1.0f; + } + + // 重置为默认值 + public void ResetToDefaults() + { + GraphicsQuality = 2; + MasterVolume = 1.0f; + EnableTutorial = true; + } + } +} +``` + +
+ 💡 高级特性: +
    +
  • [Meta] 特性用于添加编辑器约束
  • +
  • Category 用于在蓝图中分组显示
  • +
  • 支持复杂的 UE 类型如 TArray
  • +
  • 可以添加自定义方法(不会暴露给蓝图)
  • +
+
+
@@ -91,52 +446,285 @@ namespace Script.CoreUObject --- -## UClass +--- + +## 🎮 UClass - 动态游戏类 -约定了命令规范,对于动态蓝图类,需要以`_C`结尾。类名需要`U`或者`A`前缀,文件名不需要`U`或者`A`前缀。 +
+ 📝 命名约定: 类名需要 UA 前缀,文件名不需要前缀。动态蓝图类需要以 _C 结尾。 +
+ +### 📋 创建要求 + +- **Actor 类前缀:** `A` (例如: `ATestDynamicActor`) +- **Object 类前缀:** `U` (例如: `UTestDynamicComponent`) +- **文件名:** 无前缀 (例如: `TestDynamicActor.cs`) +- **蓝图类:** 以 `_C` 结尾 (例如: `AMyGameActor_C`)
-示例:UClass +💻 完整代码示例:动态游戏类 - + -```csharp +```csharp title="TestDynamicActor.cs" using Script.Dynamic; using Script.Engine; +using Script.CoreUObject; namespace Script.CoreUObject { - [UClass] - public partial class ATestRawDynamicFunctionActor : AActor, ITestDynamicInterface + [UClass, BlueprintType, Blueprintable] + public partial class ATestDynamicActor : AActor, ITestDynamicInterface { - public ATestRawDynamicFunctionActor() + public ATestDynamicActor() { + // 设置默认值 Int32Value = 12; + PrimaryActorTick.bCanEverTick = true; + + // 创建默认组件 + SceneComponent = CreateDefaultSubobject("SceneComponent"); + RootComponent = SceneComponent; } - [UProperty] + [UProperty, BlueprintReadWrite, Category = "测试属性"] public int Int32Value { get; set; } + + [UProperty, BlueprintReadWrite, Category = "组件"] + public USceneComponent SceneComponent { get; set; } - [UFunction] + [UFunction, BlueprintCallable, Category = "测试函数"] public void SetInt32ValueFunction(int InInt32Value) { Int32Value = InInt32Value; } - [UFunction] + [UFunction, BlueprintCallable, BlueprintPure, Category = "测试函数"] public int GetInt32ValueFunction() { return Int32Value; } - [UFunction] + [UFunction, BlueprintCallable, Category = "测试函数"] public void OutInt32ValueFunction(ref int OutInt32Value) { OutInt32Value = Int32Value; } + + // 重写 Actor 生命周期函数 + public override void BeginPlay() + { + base.BeginPlay(); + // 游戏开始时的逻辑 + } + + public override void Tick(float DeltaTime) + { + base.Tick(DeltaTime); + // 每帧更新逻辑 + } + } +} +``` + +
+ ✅ 特性说明: +
    +
  • [UClass] - 标记为 UE 类
  • +
  • [BlueprintType] - 可在蓝图中使用作为变量类型
  • +
  • [Blueprintable] - 可以创建蓝图子类
  • +
  • partial - 支持代码生成
  • +
+
+ +
+ + + +```csharp title="TestDynamicComponent.cs" +using Script.Dynamic; +using Script.Engine; +using Script.CoreUObject; + +namespace Script.CoreUObject +{ + [UClass, BlueprintType, Blueprintable] + public partial class UTestDynamicComponent : UActorComponent + { + public UTestDynamicComponent() + { + // 组件默认设置 + PrimaryComponentTick.bCanEverTick = true; + Health = MaxHealth; + } + + [UProperty, BlueprintReadWrite, Category = "健康系统"] + [Meta(ClampMin = "0")] + public float Health { get; set; } = 100.0f; + + [UProperty, BlueprintReadWrite, Category = "健康系统"] + [Meta(ClampMin = "1")] + public float MaxHealth { get; set; } = 100.0f; + + [UProperty, BlueprintReadOnly, Category = "状态")] + public bool IsAlive + { + get => Health > 0; + } + + [UFunction, BlueprintCallable, Category = "健康系统"] + public void TakeDamage(float DamageAmount) + { + Health = FMath.Max(0.0f, Health - DamageAmount); + + if (Health <= 0) + { + OnDeath(); + } + } + + [UFunction, BlueprintCallable, Category = "健康系统"] + public void Heal(float HealAmount) + { + Health = FMath.Min(MaxHealth, Health + HealAmount); + } + + [UFunction, BlueprintImplementableEvent, Category = "事件"] + public void OnDeath(); + + [UFunction, BlueprintImplementableEvent, Category = "事件"] + public void OnHealthChanged(float NewHealth, float OldHealth); + + public override void TickComponent(float DeltaTime, ELevelTick TickType, ref FActorComponentTickFunction ThisTickFunction) + { + base.TickComponent(DeltaTime, TickType, ref ThisTickFunction); + // 组件更新逻辑 + } + } +} +``` + + + + + +```csharp title="TestDynamicGameMode.cs" +using Script.Dynamic; +using Script.Engine; +using Script.CoreUObject; + +namespace Script.CoreUObject +{ + [UClass, BlueprintType, Blueprintable] + public partial class ATestDynamicGameMode : AGameModeBase + { + public ATestDynamicGameMode() + { + // 设置默认类 + DefaultPawnClass = typeof(ATestDynamicPawn); + PlayerControllerClass = typeof(ATestDynamicPlayerController); + } + + [UProperty, BlueprintReadWrite, Category = "游戏设置"] + public int MaxPlayers { get; set; } = 4; + + [UProperty, BlueprintReadWrite, Category = "游戏设置"] + public float GameDuration { get; set; } = 300.0f; // 5分钟 + + [UProperty, BlueprintReadOnly, Category = "游戏状态"] + public float RemainingTime { get; private set; } + + [UProperty, BlueprintReadOnly, Category = "游戏状态"] + public bool IsGameActive { get; private set; } + + [UFunction, BlueprintCallable, Category = "游戏控制"] + public void StartGame() + { + IsGameActive = true; + RemainingTime = GameDuration; + OnGameStarted(); + } + + [UFunction, BlueprintCallable, Category = "游戏控制"] + public void EndGame() + { + IsGameActive = false; + OnGameEnded(); + } + + [UFunction, BlueprintImplementableEvent, Category = "游戏事件"] + public void OnGameStarted(); + + [UFunction, BlueprintImplementableEvent, Category = "游戏事件"] + public void OnGameEnded(); + + [UFunction, BlueprintImplementableEvent, Category = "游戏事件"] + public void OnTimeUpdate(float NewTime); + + public override void Tick(float DeltaSeconds) + { + base.Tick(DeltaSeconds); + + if (IsGameActive && RemainingTime > 0) + { + RemainingTime -= DeltaSeconds; + OnTimeUpdate(RemainingTime); + + if (RemainingTime <= 0) + { + EndGame(); + } + } + } + } +} +``` + + + + + +```csharp title="DynamicClassUsage.cs" +public class DynamicClassUsageExample +{ + public void SpawnDynamicActor() + { + // 获取世界引用 + UWorld world = GetWorld(); + + // 生成动态 Actor + var spawnParams = new FActorSpawnParameters + { + SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod.AlwaysSpawn + }; + + var dynamicActor = world.SpawnActor( + new FVector(0, 0, 100), + FRotator.ZeroRotator, + spawnParams + ); + + // 使用动态 Actor 的功能 + dynamicActor.SetInt32ValueFunction(42); + int value = dynamicActor.GetInt32ValueFunction(); + + // 添加动态组件 + var healthComponent = dynamicActor.CreateDefaultSubobject("HealthComponent"); + healthComponent.TakeDamage(25.0f); + } + + public void CreateDynamicComponent() + { + // 为现有 Actor 添加动态组件 + var actor = GetOwner(); + var component = actor.CreateDefaultSubobject("DynamicComponent"); + + // 配置组件 + component.MaxHealth = 150.0f; + component.Heal(50.0f); } } ``` @@ -149,26 +737,170 @@ namespace Script.CoreUObject --- -## UInterface +--- + +## 🔌 UInterface - 动态接口 + +
+ ⚠️ 限制: 动态接口不支持继承蓝图接口,但可以定义纯 C# 接口供动态类实现。 +
+ +### 📋 创建要求 -不支持继承蓝图接口。接口名需要`I`前缀,文件名不需要`I`前缀。 +- **接口名前缀:** `I` (例如: `ITestDynamicInterface`) +- **文件名:** 无前缀 (例如: `TestDynamicInterface.cs`) +- **必须继承:** `IInterface` 基接口
-示例:UInterface +💻 完整代码示例:动态接口 - + -```csharp +```csharp title="TestDynamicInterface.cs" using Script.Dynamic; +using Script.CoreUObject; namespace Script.CoreUObject { [UInterface, Blueprintable] public interface ITestDynamicInterface : IInterface { + // 接口定义(仅声明,无实现) + } +} +``` + +
+ ✅ 特性说明: +
    +
  • [UInterface] - 标记为 UE 接口
  • +
  • [Blueprintable] - 允许蓝图实现
  • +
  • : IInterface - 必须继承基接口
  • +
+
+ +
+ + + +```csharp title="IHealthSystem.cs" +using Script.Dynamic; +using Script.CoreUObject; + +namespace Script.CoreUObject +{ + [UInterface, Blueprintable] + public interface IHealthSystem : IInterface + { + // 接口方法将在实现类中定义 + } + + // 接口的默认实现类(可选) + public class HealthSystemImplementation + { + [UFunction, BlueprintCallable, BlueprintImplementableEvent] + public virtual void TakeDamage(float DamageAmount) { } + + [UFunction, BlueprintCallable, BlueprintImplementableEvent] + public virtual void Heal(float HealAmount) { } + + [UFunction, BlueprintCallable, BlueprintImplementableEvent] + public virtual float GetHealthPercentage() { return 1.0f; } + } +} +``` + + + + + +```csharp title="ImplementingClass.cs" +using Script.Dynamic; +using Script.Engine; +using Script.CoreUObject; + +namespace Script.CoreUObject +{ + [UClass, BlueprintType] + public partial class AHealthyActor : AActor, IHealthSystem + { + public AHealthyActor() + { + Health = MaxHealth; + } + + [UProperty, BlueprintReadWrite, Category = "健康系统"] + public float Health { get; set; } = 100.0f; + + [UProperty, BlueprintReadWrite, Category = "健康系统"] + public float MaxHealth { get; set; } = 100.0f; + + // 实现接口方法 + [UFunction, BlueprintCallable, Category = "健康系统"] + public void TakeDamage(float DamageAmount) + { + Health = FMath.Max(0.0f, Health - DamageAmount); + if (Health <= 0) + { + OnDeath(); + } + } + + [UFunction, BlueprintCallable, Category = "健康系统"] + public void Heal(float HealAmount) + { + Health = FMath.Min(MaxHealth, Health + HealAmount); + } + + [UFunction, BlueprintCallable, BlueprintPure, Category = "健康系统"] + public float GetHealthPercentage() + { + return MaxHealth > 0 ? Health / MaxHealth : 0.0f; + } + + [UFunction, BlueprintImplementableEvent, Category = "事件"] + public void OnDeath(); + } +} +``` + + + + + +```csharp title="InterfaceUsage.cs" +public class InterfaceUsageExample +{ + public void UseInterface() + { + // 通过接口引用操作对象 + IHealthSystem healthSystem = GetSomeHealthyActor(); + + // 调用接口方法 + healthSystem.TakeDamage(25.0f); + healthSystem.Heal(10.0f); + + float healthPercent = healthSystem.GetHealthPercentage(); + + // 检查接口实现 + if (healthSystem is AHealthyActor actor) + { + // 访问具体类型的成员 + actor.Health = 50.0f; + } + } + + // 接受接口参数的函数 + [UFunction, BlueprintCallable] + public void ProcessHealthSystem(TScriptInterface healthSystem) + { + if (healthSystem.GetInterface() != null) + { + healthSystem.GetInterface().TakeDamage(10.0f); + } } } ``` diff --git a/docs/document/getting-started/installation.md b/docs/document/getting-started/installation.md index d8c08bf..de65164 100644 --- a/docs/document/getting-started/installation.md +++ b/docs/document/getting-started/installation.md @@ -1,48 +1,174 @@ --- -title: 安装流程 -description: 如何从零开始生成一个C#工程 -hide_title: true -slug: installation -sidebar_position: 1 +title: 📥 安装指南 +description: 从零开始搭建 UnrealCSharp 开发环境 +hide_title: false custom_edit_url: null +sidebar_position: 1 --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## 环境依赖 +# 📥 安装指南 + +
+

+ 🎯 快速搭建您的 UnrealCSharp 开发环境 +

+
+ +--- + +## 🔧 环境依赖 -- .NET 8及以上版本 - - Windows上可通过Visual Studio Installer直接安装 - - macOS上可参考[Install .NET on macOS](https://learn.microsoft.com/en-us/dotnet/core/install/macos) -- [Mono](https://github.com/dotnet/runtime),插件已内置 +### 必需组件 + +
+
+
+
+

⚡ .NET 8+ Runtime

+
+
+ + +

📦 通过 Visual Studio Installer 直接安装

+

或从 Microsoft 官网 下载

+
+ +

📖 参考官方指南:
Install .NET on macOS

+
+
+
+
+
+
+
+
+

🔥 Mono Runtime

+
+
+

已内置在插件中

+

基于 dotnet/runtime

+

🎉 无需额外安装配置

+
+
+
+
--- -## 推荐IDE +## 🛠️ 推荐 IDE -- [Rider](https://www.jetbrains.com/rider/) -- [Visual Studio](https://visualstudio.microsoft.com/) -- [Visual Studio Code](https://code.visualstudio.com/) +
+
+
+
+

🚀 JetBrains Rider

+
+
+

推荐指数:⭐⭐⭐⭐⭐

+
    +
  • 最佳 C# 开发体验
  • +
  • 强大的调试功能
  • +
  • 优秀的 Unreal 支持
  • +
+ 下载 +
+
+
+
+
+
+

💼 Visual Studio

+
+
+

推荐指数:⭐⭐⭐⭐

+
    +
  • Microsoft 官方 IDE
  • +
  • 完整 .NET 生态支持
  • +
  • 免费 Community 版本
  • +
+ 下载 +
+
+
+
+
+
+

⚡ VS Code

+
+
+

推荐指数:⭐⭐⭐

+
    +
  • 轻量级编辑器
  • +
  • 丰富的扩展生态
  • +
  • 完全免费开源
  • +
+ 下载 +
+
+
+
--- -## 安装插件 +## 📦 安装插件 - + + +### 步骤说明 -1. `git clone --recurse-submodule https://github.com/crazytuzi/UnrealCSharp` -2. 拷贝到`项目`的`Plugins`目录 +
+ 💡 推荐理由: 获取最新功能,完整源码控制,便于自定义修改 +
+ +1. **📥 克隆仓库** + ```bash + git clone --recurse-submodule https://github.com/crazytuzi/UnrealCSharp + ``` + +2. **📁 复制到项目** + ``` + 将整个文件夹复制到: + YourProject/ + └── Plugins/ + └── UnrealCSharp/ + ``` + +3. **✅ 验证安装** + - 重新生成项目文件 + - 编译项目 + - 启动编辑器
- + + +### 步骤说明 -1. 通过[releases](https://github.com/crazytuzi/UnrealCSharp/releases)下载需要的版本 -2. 下载[Mono](https://github.com/crazytuzi/Mono)和[SourceCodeGenerator](https://github.com/crazytuzi/SourceCodeGenerator),放到对应目录 -3. 拷贝到`项目`的`Plugins`目录 +
+ 📝 注意: 需要手动下载依赖组件 +
+ +1. **📥 下载发布包** + - 访问 [GitHub Releases](https://github.com/crazytuzi/UnrealCSharp/releases) + - 选择对应版本下载 + +2. **📥 下载依赖组件** + - [Mono Runtime](https://github.com/crazytuzi/Mono) + - [SourceCodeGenerator](https://github.com/crazytuzi/SourceCodeGenerator) + - 按照目录结构放置 + +3. **📁 复制到项目** + ``` + 将整个文件夹复制到: + YourProject/ + └── Plugins/ + └── UnrealCSharp/ + ```
@@ -50,24 +176,112 @@ import TabItem from '@theme/TabItem'; --- -## 生成C#工程 +## 🎯 生成 C# 工程 + +安装完成后,需要生成 C# 项目文件: - + -- 点击`Generator Code` -- `项目/Script`即为C#工程目录 +### 使用编辑器按钮 + +
+ 🎯 最简单的方式 +
+ +1. **🔍 找到按钮** + - 在 Unreal Editor 工具栏中 + - 查找 `Generator Code` 按钮 + +2. **🖱️ 点击生成** + - 点击按钮开始生成 + - 等待生成完成 + +3. **📁 检查结果** + ``` + YourProject/ + └── Script/ ← C# 工程目录 + ├── Game/ + ├── Engine/ + └── YourProject.sln + ```
- + + +### 使用控制台命令 + +
+ 🔧 适合高级用户 +
+ +1. **📝 打开控制台** + - 在编辑器中按 `` ` `` 键 + - 或者在 Window → Developer Tools → Output Log + +2. **⌨️ 执行命令** + ``` + UnrealCSharp.Editor.Generator + ``` -- `UnrealCSharp.Editor.Generator` -- `项目/Script`即为C#工程目录 +3. **📁 检查结果** + - 生成的 C# 工程位于 `项目/Script` 目录
--- + +## ✅ 验证安装 + +### 🔍 检查清单 + +
+
+
+
+

📁 文件结构

+
+
+
    +
  • ✅ Plugins/UnrealCSharp/ 存在
  • +
  • ✅ Script/ 目录已生成
  • +
  • ✅ 解决方案文件 (.sln) 已创建
  • +
+
+
+
+
+
+
+

🛠️ 编辑器功能

+
+
+
    +
  • ✅ Generator Code 按钮可见
  • +
  • ✅ UnrealCSharp 插件已启用
  • +
  • ✅ 控制台命令可用
  • +
+
+
+
+
+ +### 🎉 下一步 + +安装完成!现在您可以: + + + +--- diff --git a/docs/document/getting-started/override.md b/docs/document/getting-started/override.md index 7c4eba7..9d6c0df 100644 --- a/docs/document/getting-started/override.md +++ b/docs/document/getting-started/override.md @@ -1,7 +1,7 @@ --- -title: 覆盖函数 -description: 通过覆盖函数,重写C++和蓝图函数逻辑 -hide_title: true +title: 函数覆盖 (Function Override) +description: 学习如何通过 C# 覆盖 C++ 和蓝图函数,实现自定义逻辑 +hide_title: false slug: override sidebar_position: 3 custom_edit_url: null @@ -10,41 +10,59 @@ custom_edit_url: null import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## 介绍 +# 🔄 函数覆盖 -对于标记有BlueprintImplementableEvent或者BlueprintNativeEvent的C++和蓝图函数,能够被C#重写函数逻辑。 +## 📝 概述 -:::warning +通过函数覆盖机制,您可以使用 **C#** 重写标记有 `BlueprintImplementableEvent` 或 `BlueprintNativeEvent` 的 C++ 和蓝图函数逻辑,实现灵活的自定义行为。 -UE5.5开始对C++类BlueprintNativeEvent函数做了改动,插件从UE5.5开始不再支持覆盖C++类BlueprintNativeEvent函数,参看[Change the code generation of UHT for BP implementable events to check for any script implementations of the event.](https://github.com/EpicGames/UnrealEngine/commit/9a428198ab8616a896de16f110caf09491a8ece9)。 +:::warning ⚠️ 重要提醒:UE5.5 兼容性变更 + +从 **UE5.5** 开始,Epic Games 对 C++ 类的 `BlueprintNativeEvent` 函数进行了架构调整。因此,插件从 UE5.5 版本开始不再支持覆盖 C++ 类的 `BlueprintNativeEvent` 函数。 + +📖 详细信息请参考:[UHT 代码生成变更](https://github.com/EpicGames/UnrealEngine/commit/9a428198ab8616a896de16f110caf09491a8ece9) ::: --- -## 流程 +## 🛠️ 实现步骤 + +### 第一步:创建 Partial 类 + +使用 C# 的 [Partial 类](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods) 机制,为目标函数所属的类创建一个 Partial 类,并添加 `[Override]` 特性标记。 + +### 第二步:声明覆盖函数 + +创建与原函数相同签名的函数,同样需要标记 `[Override]` 特性: + +| 函数类型 | C++/蓝图函数名 | C# 函数名 | 说明 | +|---------|---------------|----------|------| +| **普通函数** | `Test` | `Test` | 函数名保持一致 | +| **RPC 函数** | `Server_Test` | `Server_Test_Implementation` | 添加 `_Implementation` 后缀 | + +:::tip 💡 提示 +确保函数签名(参数类型、返回值类型)与原函数完全匹配,这样才能正确覆盖原有逻辑。 +::: -1. 通过[Partial](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods),新建一个函数所属类的Partial类,并且标记`Override` -2. 声明一个拥有相同函数签名的函数,并且同样需要标记`Override` - - 普通函数:C++或蓝图函数名`Test`,C#函数名`Test` - - RPC函数:C++或蓝图函数名`Server_Test`,C#函数名`Server_Test_Implementation` +--- -
+## 📚 完整示例 -示例:覆盖函数 +下面展示了一个完整的函数覆盖示例,包括 C++ 定义和 C# 实现: - + -```cpp +```cpp title="TestCSharpFunctionActor.h" #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "TestCSharpFunctionActor.generated.h" -UCLASS() +UCLASS(BlueprintType, Blueprintable) class UNREALCSHARPTEST_API ATestCSharpFunctionActor : public AActor { GENERATED_BODY() @@ -53,45 +71,75 @@ public: // Sets default values for this actor's properties ATestCSharpFunctionActor(); +protected: + // 私有成员变量,用于存储整数值 + UPROPERTY(BlueprintReadWrite, Category = "Test Values") + int32 Int32Value = 0; + public: - UFUNCTION(BlueprintCallable, BlueprintImplementableEvent) + // 🔹 设置整数值的可实现事件 + UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = "Test Functions") void SetInt32ValueFunction(int32 InInt32Value); - UFUNCTION(BlueprintCallable, BlueprintImplementableEvent) + // 🔹 获取整数值的可实现事件 + UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = "Test Functions") int32 GetInt32ValueFunction() const; - UFUNCTION(BlueprintCallable, BlueprintImplementableEvent) + // 🔹 通过引用输出整数值的可实现事件 + UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = "Test Functions") void OutInt32ValueFunction(int32& OutInt32Value) const; }; ``` - + -```csharp +```csharp title="ATestCSharpFunctionActor.Override.cs" using Script.CoreUObject; namespace Script.UnrealCSharpTest { + /// + /// TestCSharpFunctionActor 的 C# 函数覆盖实现 + /// 通过 Partial 类机制扩展原有功能 + /// [Override] public partial class ATestCSharpFunctionActor { + /// + /// 设置整数值 + /// + /// 要设置的整数值 [Override] public void SetInt32ValueFunction(int InInt32Value) { + // 🎯 将传入的值赋给内部存储 Int32Value = InInt32Value; + + // 可以在这里添加额外的逻辑 + // 例如:日志记录、数据验证等 } + /// + /// 获取当前存储的整数值 + /// + /// 当前的整数值 [Override] public int GetInt32ValueFunction() { + // 🎯 返回内部存储的值 return Int32Value; } + /// + /// 通过引用参数输出整数值 + /// + /// 输出参数,用于接收当前值 [Override] public void OutInt32ValueFunction(ref int OutInt32Value) { + // 🎯 将内部值赋给输出参数 OutInt32Value = Int32Value; } } @@ -102,11 +150,60 @@ namespace Script.UnrealCSharpTest -
+:::info 🎯 代码说明 + +- **`[Override]` 特性**:标记在类和方法上,告知系统这是一个覆盖实现 +- **Partial 类**:允许将类的定义分散到多个文件中,便于组织代码 +- **函数签名匹配**:C# 函数的参数和返回值类型必须与 C++ 声明保持一致 +- **引用参数**:`ref` 关键字对应 C++ 中的引用参数 `&` + +::: --- -## 代码扫描 -在生成C#工程的时候,会先通过[Microsoft.CodeAnalysis.CSharp](https://www.nuget.org/packages/Microsoft.CodeAnalysis.CSharp/)对项目代码进行一次代码扫描,分析出标记有`Override`的类和函数,并且生成到`项目/Intermediate/CodeAnalysis`中,避免覆盖函数后续再生成,导致重定义。 +## 🔍 代码扫描机制 + +### 工作原理 + +在生成 C# 工程时,系统会执行以下自动化流程: + +```mermaid +graph LR + A[🔄 项目生成开始] --> B[📊 代码扫描] + B --> C[🔍 分析 Override 标记] + C --> D[📁 生成分析文件] + D --> E[🚫 避免重定义] + E --> F[✅ 生成完成] +``` + +### 技术细节 + +1. **扫描工具**:使用 [Microsoft.CodeAnalysis.CSharp](https://www.nuget.org/packages/Microsoft.CodeAnalysis.CSharp/) 进行静态代码分析 +2. **扫描目标**:检测所有标记了 `[Override]` 特性的类和函数 +3. **输出位置**:分析结果保存在 `项目/Intermediate/CodeAnalysis` 目录 +4. **防冲突**:确保覆盖函数不会在后续生成中重复定义,避免编译错误 + +:::note 📝 技术说明 + +这一机制确保了覆盖函数的稳定性和一致性,让开发者可以安心使用函数覆盖功能而无需担心代码生成冲突。 + +::: + +--- + +## 🚀 最佳实践 + +### ✅ 推荐做法 + +- **明确命名**:使用描述性的文件名,如 `ClassName.Override.cs` +- **添加注释**:为覆盖函数添加详细的 XML 文档注释 +- **逻辑清晰**:保持覆盖函数的逻辑简洁明了 +- **错误处理**:适当添加参数验证和异常处理 + +### ❌ 避免做法 + +- **重复覆盖**:避免在多个 Partial 类中覆盖同一个函数 +- **签名不匹配**:确保函数签名与原始声明完全一致 +- **过度复杂**:避免在覆盖函数中实现过于复杂的逻辑 --- diff --git a/docs/document/getting-started/reflection.md b/docs/document/getting-started/reflection.md index 0a2ae5e..48298cd 100644 --- a/docs/document/getting-started/reflection.md +++ b/docs/document/getting-started/reflection.md @@ -1,7 +1,7 @@ --- -title: 反射 -description: 介绍对于UE反射的支持,变量访问和函数调用 -hide_title: true +title: 反射系统 (Reflection System) +description: 深入了解 UnrealCSharp 对 UE 反射系统的完整支持,包括类型映射、变量访问和函数调用 +hide_title: false slug: reflection sidebar_position: 2 custom_edit_url: null @@ -10,27 +10,97 @@ custom_edit_url: null import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## 介绍 +# 🪞 反射系统 -通过UE提供的反射,插件会根据[配置](../guides/configuration/editor)生成指定模块和插件下的类,结构体,枚举,以及资源类型。 +## 🌟 概述 + +UnrealCSharp 插件基于 **Unreal Engine 反射系统** 构建,能够根据[编辑器配置](../guides/configuration/editor)自动生成指定模块和插件下的各种类型绑定。 + +### � 支持的类型 + +| 类型 | 图标 | 描述 | +|------|------|------| +| **类 (Classes)** | 🏗️ | UObject、Actor 等 C++ 类 | +| **结构体 (Structs)** | 📦 | USTRUCT 标记的结构体 | +| **枚举 (Enums)** | 🔢 | UENUM 标记的枚举类型 | +| **资源类型 (Assets)** | 🎯 | 各种 UE 资源类型 | + +:::tip 💡 核心优势 +🔄 **无缝互操作**:C++ 和 C# 之间的完美桥接 +⚡ **实时同步**:反射类型变更自动同步 +🛡️ **类型安全**:编译时类型检查保障 +🚀 **高性能**:原生 UE 反射系统性能 +::: --- -## 基础概念 +## 🧭 类型映射规则 + +UE 和 C# 两侧的反射类型存在 **一一对应关系**。对于复杂类型(如 UObject、蓝图等),需要理解 UE 中 **Package** 的概念。 -UE和C#两侧的反射类型存在一一对应关系,对于简单类型比较容易理解,针对如UObject,蓝图等此类复杂类型,需要先了解一下UE中Package的概念,推荐[UE4的资源管理](https://zhuanlan.zhihu.com/p/357904199)和[[中文直播]第33期 | UE4资产管理基础1 | Epic 大钊](https://www.bilibili.com/video/BV1Mr4y1A7nZ)。 +:::note 📚 学习资源 +📖 [UE4的资源管理 - 知乎专栏](https://zhuanlan.zhihu.com/p/357904199) +🎥 [UE4资产管理基础 - Epic 官方直播](https://www.bilibili.com/video/BV1Mr4y1A7nZ) +::: + +### 🔄 映射规则详解 - + + +**🔧 转换规则**:去掉首位 `/`,将 `/` 替换为 `.` -如AActor,会将`/Script/Engine.Actor`映射为`Script.Engine.Actor`,规则为去掉首位`/`,并将`/`替换为`.` +```cpp title="💡 映射示例" +// 📍 C++ 类型路径 +/Script/Engine.Actor + +// ➡️ 映射后的 C# 命名空间 +Script.Engine.Actor +``` + +**📋 常见映射示例**: + +| 🎯 C++ 类型 | ➡️ | 🎯 C# 类型 | +|-------------|-----|------------| +| `AActor` | → | `Script.Engine.Actor` | +| `UObject` | → | `Script.CoreUObject.Object` | +| `FVector` | → | `Script.CoreUObject.Vector` | - + + +**🎨 转换规则**:添加 `Script/` 前缀,去掉重复的类名部分,将 `/` 替换为 `.` + +```cpp title="💡 映射示例" +// 📍 蓝图类型路径 +/Game/UnitTest/Reflection/BP_TestReflectionPropertyActor.BP_TestReflectionPropertyActor_C + +// ➡️ 映射后的 C# 命名空间 +Script.Game.UnitTest.Reflection.BP_TestReflectionPropertyActor_C +``` + +**🔄 转换步骤流程**: + +```mermaid +graph LR + A["📝 原路径"] --> B["➕ 添加前缀"] + B --> C["🗑️ 去掉重复"] + C --> D["🔄 替换分隔符"] + + style A fill:#e1f5fe + style B fill:#f3e5f5 + style C fill:#fff3e0 + style D fill:#e8f5e8 +``` -如BP_TestReflectionPropertyActor_C,会将`/Game/UnitTest/Reflection/BP_TestReflectionPropertyActor.BP_TestReflectionPropertyActor_C`映射为`Script.Game.UnitTest.Reflection.BP_TestReflectionPropertyActor_C`,规则为加上`Script/`,去掉`BP_TestReflectionPropertyActor.`,并将`/`替换为`.` +| 步骤 | 内容 | +|------|------| +| 1️⃣ **原路径** | `/Game/UnitTest/Reflection/BP_TestReflectionPropertyActor.BP_TestReflectionPropertyActor_C` | +| 2️⃣ **添加前缀** | `Script/Game/UnitTest/Reflection/BP_TestReflectionPropertyActor.BP_TestReflectionPropertyActor_C` | +| 3️⃣ **去掉重复** | `Script/Game/UnitTest/Reflection/BP_TestReflectionPropertyActor_C` | +| 4️⃣ **替换分隔符** | `Script.Game.UnitTest.Reflection.BP_TestReflectionPropertyActor_C` | @@ -38,53 +108,65 @@ UE和C#两侧的反射类型存在一一对应关系,对于简单类型比较 --- -## 数据类型 +## 📊 数据类型 -针对不同的数据类型,有不同的处理方式,分为以下几个大类。 +针对不同的数据类型,插件提供了对应的映射机制,确保类型安全和性能优化。 + +:::info 🎯 设计理念 +每种数据类型都经过精心设计,在保证功能完整性的同时,最大化性能表现。 +::: - - -| C++ | C# | -| -------- | -------- | -| bool | bool | -| int8 | sbyte | -| int16 | short | -| int32 | int | -| int64 | long | -| uint8 | byte | -| uint16 | ushort | -| uint32 | uint | -| uint64 | ulong | -| float | float | -| double | double | + + +基本类型提供了 C++ 和 C# 之间的直接映射,确保最佳性能。 + +| 🎯 C++ 类型 | ➡️ | 🎯 C# 类型 | 📝 说明 | +|-------------|-----|------------|---------| +| `bool` | → | `bool` | 布尔值 | +| `int8` | → | `sbyte` | 8位有符号整数 | +| `int16` | → | `short` | 16位有符号整数 | +| `int32` | → | `int` | 32位有符号整数 | +| `int64` | → | `long` | 64位有符号整数 | +| `uint8` | → | `byte` | 8位无符号整数 | +| `uint16` | → | `ushort` | 16位无符号整数 | +| `uint32` | → | `uint` | 32位无符号整数 | +| `uint64` | → | `ulong` | 64位无符号整数 | +| `float` | → | `float` | 单精度浮点数 | +| `double` | → | `double` | 双精度浮点数 | - + + +UE 提供了多种字符串类型,每种都有其特定的用途和性能特征。 -| C++ | C# | -| -------- | -------- | -| FName | Script.CoreUObject.FName | -| FText | Script.CoreUObject.FText | -| FString | Script.CoreUObject.FString | +| 🎯 C++ 类型 | ➡️ | 🎯 C# 类型 | 📝 用途 | +|-------------|-----|------------|---------| +| `FName` | → | `Script.CoreUObject.FName` | 🏷️ 标识符,内存优化 | +| `FText` | → | `Script.CoreUObject.FText` | 🌍 本地化文本显示 | +| `FString` | → | `Script.CoreUObject.FString` | 📄 通用字符串处理 | + +:::tip 💡 选择建议 +- **FName**:用于标识符、资源名称等不变字符串 +- **FText**:用于用户界面显示文本,支持本地化 +- **FString**:用于一般字符串操作和处理 +::: - + -对于枚举和TEnumAsByte都会被对应到映射关系下的枚举。 +枚举类型(包括 `TEnumAsByte`)会自动映射到对应的 C# 枚举,保持类型安全。
- -示例:枚举 +💡 查看枚举映射示例 + - - -```cpp +```cpp title="ETestEnum.h" UENUM(BlueprintType) enum ETestEnum { @@ -96,9 +178,9 @@ enum ETestEnum - + -```csharp +```csharp title="ETestEnum.cs" using Script.CoreUObject; namespace Script.UnrealCSharpTest @@ -114,26 +196,30 @@ namespace Script.UnrealCSharpTest ``` - +:::note 📋 特点说明 +✅ **自动生成**:基于 C++ 枚举自动生成 +✅ **类型安全**:编译时类型检查 +✅ **值对应**:枚举值完全一致 +✅ **属性标记**:包含路径名等元数据 +::: +
- + -会生成反射变量,StaticStruct,构造函数和析构函数等。 +结构体会生成完整的 C# 类,包含反射变量、静态结构体信息、构造函数和析构函数等。
- -示例:结构体 +💡 查看结构体映射示例 + - - -```cpp +```cpp title="FTestStruct.h" USTRUCT(BlueprintType) struct FTestStruct { @@ -146,9 +232,9 @@ struct FTestStruct - + -```csharp +```csharp title="FTestStruct.cs" using Script.Library; using Script.CoreUObject; @@ -177,7 +263,6 @@ namespace Script.UnrealCSharpTest public int Value { get => FPropertyImplementation.FProperty_GetStructInt32PropertyImplementation(GarbageCollectionHandle, __Value); - set => FPropertyImplementation.FProperty_SetStructInt32PropertyImplementation(GarbageCollectionHandle, __Value, value); } @@ -189,26 +274,30 @@ namespace Script.UnrealCSharpTest ``` - +:::note 🔧 功能特性 +✅ **完整映射**:包含所有 UPROPERTY 变量 +✅ **内存管理**:自动处理生命周期 +✅ **运算符重载**:支持比较操作 +✅ **反射支持**:提供 StaticStruct 信息 +::: +
- + -会生成反射变量,反射函数,接口函数和StaticClass等。 +UObject 类型会生成包含反射变量、反射函数、接口函数和 StaticClass 等完整功能的 C# 类。
- -示例:UObject +💡 查看 UObject 映射示例 + - - -```cpp +```cpp title="ATestReflectionPropertyActor.h" #pragma once #include "CoreMinimal.h" @@ -233,9 +322,9 @@ public: - + -```csharp +```csharp title="ATestReflectionPropertyActor.cs" using Script.Engine; using Script.CoreUObject; using Script.Library; @@ -248,7 +337,6 @@ namespace Script.UnrealCSharpTest public int Int32Value { get => FPropertyImplementation.FProperty_GetObjectInt32PropertyImplementation(GarbageCollectionHandle, __Int32Value); - set => FPropertyImplementation.FProperty_SetObjectInt32PropertyImplementation(GarbageCollectionHandle, __Int32Value, value); } @@ -263,62 +351,83 @@ namespace Script.UnrealCSharpTest ``` - +:::note 🎯 核心特性 +✅ **继承关系**:完整保持 C++ 的继承链 +✅ **接口支持**:自动实现所有接口 +✅ **属性访问**:Properties 方式访问变量 +✅ **静态信息**:提供 StaticClass 反射信息 +::: +
- + + +UE 的模板类型提供了类型安全的泛型支持,在 C# 中映射为对应的泛型类。 + +| 🎯 C++ 模板类型 | ➡️ | 🎯 C# 泛型类型 | 📝 用途 | +|-----------------|-----|----------------|---------| +| `TScriptInterface` | → | `Script.CoreUObject.TScriptInterface` | 🔌 接口引用 | +| `TSubclassOf` | → | `Script.CoreUObject.TSubclassOf` | 🏷️ 类类型引用 | +| `TWeakObjectPtr` | → | `Script.CoreUObject.TWeakObjectPtr` | 🔗 弱引用指针 | +| `TLazyObjectPtr` | → | `Script.CoreUObject.TLazyObjectPtr` | ⏳ 延迟加载指针 | +| `TSoftObjectPtr` | → | `Script.CoreUObject.TSoftObjectPtr` | 💾 软引用指针 | +| `TSoftClassPtr` | → | `Script.CoreUObject.TSoftClassPtr` | 🏗️ 软类引用 | +| `TOptional` | → | `Script.CoreUObject.TOptional` | ❓ 可选值类型 | -| C++ | C# | -| -------- | -------- | -| TScriptInterface | Script.CoreUObject.TScriptInterface`1 | -| TSubclassOf | Script.CoreUObject.TSubclassOf`1 | -| TWeakObjectPtr | Script.CoreUObject.TWeakObjectPtr`1 | -| TLazyObjectPtr | Script.CoreUObject.TLazyObjectPtr`1 | -| TSoftObjectPtr | Script.CoreUObject.TSoftObjectPtr`1 | -| TSoftClassPtr | Script.CoreUObject.TSoftClassPtr`1 | -| TOptional | Script.CoreUObject.TOptional`1 | +:::tip 💡 使用建议 +- **TWeakObjectPtr**:避免循环引用的安全选择 +- **TSoftObjectPtr**:异步加载资源的最佳实践 +- **TOptional**:表示可能为空的值,增强代码健壮性 +::: - + -| C++ | C# | -| -------- | -------- | -| TArray | Script.CoreUObject.TArray`1 | -| TSet | Script.CoreUObject.TSet`1 | -| TMap | Script.CoreUObject.TMap`2 | +UE 的容器类型在 C# 中提供了对应的泛型集合实现。 + +| 🎯 C++ 容器 | ➡️ | 🎯 C# 泛型容器 | 📝 特性 | +|-------------|-----|----------------|---------| +| `TArray` | → | `Script.CoreUObject.TArray` | 📚 动态数组,高效随机访问 | +| `TSet` | → | `Script.CoreUObject.TSet` | 🎯 唯一元素集合,快速查找 | +| `TMap` | → | `Script.CoreUObject.TMap` | 🗂️ 键值对映射,高效关联 | + +:::note 🚀 性能特点 +- **TArray**:内存连续,缓存友好,适合频繁遍历 +- **TSet**:哈希实现,O(1) 查找,适合去重和成员检测 +- **TMap**:哈希表,快速键值查找,适合数据关联 +::: - + -单播和多播都会映射为C#中的类,并且提供相关操作函数。 +UE 的单播和多播委托在 C# 中映射为对应的委托类,提供完整的事件处理机制。 + - +单播委托适用于一对一的事件回调场景。
- -示例:单播 +💡 查看单播委托示例 + - - -```cpp +```cpp title="FOnPointerEvent.h" DECLARE_DYNAMIC_DELEGATE_RetVal_TwoParams(FEventReply, FOnPointerEvent, FGeometry, MyGeometry, const FPointerEvent&, MouseEvent); ``` - + -```csharp +```csharp title="FOnPointerEvent.cs" using System; using Script.CoreUObject; using Script.Library; @@ -342,32 +451,38 @@ namespace Script.UMG.Widget ``` - +:::note 🎯 单播委托特点 +✅ **类型安全**:强类型参数和返回值 +✅ **单一绑定**:一个委托只能绑定一个方法 +✅ **高性能**:直接调用,无需遍历 +✅ **返回值支持**:可以获取执行结果 +::: +
- + -
+多播委托适用于一对多的事件广播场景。 -示例:多播 +
+💡 查看多播委托示例 + - - -```cpp +```cpp title="FOnButtonClickedEvent.h" DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnButtonClickedEvent); ``` - + -```csharp +```csharp title="FOnButtonClickedEvent.cs" using System; using Script.CoreUObject; using Script.Library; @@ -389,13 +504,18 @@ namespace Script.UMG ``` - +:::note 🎯 多播委托特点 +✅ **多重绑定**:可以绑定多个方法 +✅ **广播机制**:一次调用触发所有绑定 +✅ **事件系统**:适合实现观察者模式 +✅ **动态管理**:运行时添加/移除绑定 +::: +
- @@ -404,19 +524,23 @@ namespace Script.UMG --- -## 变量访问 +## 🔧 变量访问 -对于C++或者蓝图中的反射变量,会生成对应的[Properties](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties),而非[Fields](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/fields),实际内存还是放在C++侧。 +反射变量在 C# 中以 **Properties**(属性)的形式呈现,而非 Fields(字段),这样可以确保数据的实际存储仍在 C++ 端,同时提供类型安全的访问接口。 -
+:::info 🎯 设计理念 +**Properties 设计**:确保数据完整性和性能最优 +**C++ 内存**:实际数据存储在 C++ 侧,避免数据同步问题 +**类型安全**:编译时检查,运行时保障 +::: -示例:变量访问 +
+💡 查看变量访问示例 + - - -```cpp +```cpp title="ATestReflectionPropertyActor.h" #pragma once #include "CoreMinimal.h" @@ -440,9 +564,9 @@ public: - + -```csharp +```csharp title="PropertyAccessExample.cs" using Script.CoreUObject; namespace Script.UnrealCSharpTest @@ -451,37 +575,53 @@ namespace Script.UnrealCSharpTest { private void TestReflectionProperty() { + // 🎯 创建Actor实例 var PropertyActor = GetWorld().SpawnActor(new FTransform()); + // 📖 读取属性值 var Int32Value = PropertyActor.Int32Value; + // ✏️ 设置属性值 PropertyActor.Int32Value = 21; + + // 🎉 属性访问完全类型安全! } } } ``` - +:::note 💡 访问特点 +✅ **智能提示**:VS Code/Visual Studio 完整支持 +✅ **类型检查**:编译时验证类型匹配 +✅ **性能优化**:直接访问 C++ 内存 +✅ **调试友好**:可在调试器中查看值 +::: +
--- -## 函数调用 +## ⚡ 函数调用 -对于C++或者蓝图中的反射函数,会生成对应的C#函数,并且处理好函数默认参数。 +C++ 和蓝图中的反射函数会自动生成对应的 C# 方法,包括完整的参数处理、默认值支持和返回值处理。 -
+:::tip 🚀 功能亮点 +**自动映射**:无需手动绑定,自动生成调用代码 +**参数支持**:完整支持输入、输出、引用参数 +**默认值**:保持 C++ 函数的默认参数行为 +**异常安全**:提供完整的错误处理机制 +::: -示例:函数调用 +
+💡 查看函数调用示例 + - - -```cpp +```cpp title="ATestReflectionFunctionActor.h" #pragma once #include "CoreMinimal.h" @@ -511,9 +651,9 @@ public: - + -```csharp +```csharp title="FunctionCallExample.cs" using Script.CoreUObject; using Script.Engine; @@ -523,24 +663,52 @@ namespace Script.UnrealCSharpTest { private void TestReflectionFunction() { + // 🎯 创建函数测试Actor var FunctionActor = GetWorld().SpawnActor(new FTransform()); + // 📖 调用获取函数(返回值) var Int32Value = FunctionActor.GetInt32ValueFunction(); + // ✏️ 调用设置函数(输入参数) FunctionActor.SetInt32ValueFunction(21); + // 🔄 调用输出函数(引用参数) var OutInt32Value = 12; - FunctionActor.OutInt32ValueFunction(ref OutInt32Value); + // OutInt32Value 现在包含函数输出的值 } } } ``` - +:::note 🎯 调用特点 +✅ **完整映射**:支持所有 UFUNCTION 函数 +✅ **参数类型**:输入、输出、引用参数完整支持 +✅ **返回值**:正确处理各种返回类型 +✅ **异步支持**:对于异步函数提供 async/await 支持 +::: +
--- + +## 🎉 总结 + +UnrealCSharp 的反射系统为 C++ 和 C# 之间搭建了一座无缝的桥梁: + +| 🎯 核心特性 | 📝 说明 | 🚀 优势 | +|-------------|---------|---------| +| **自动生成** | 基于 UE 反射自动生成绑定 | 无需手动维护绑定代码 | +| **类型安全** | 编译时类型检查 | 减少运行时错误 | +| **高性能** | 直接访问 C++ 内存 | 接近原生性能 | +| **完整支持** | 涵盖所有 UE 反射类型 | 功能无缺失 | + +:::tip 🎯 最佳实践 +1. **充分利用**:使用 IntelliSense 提高开发效率 +2. **类型检查**:依赖编译器捕获类型错误 +3. **性能考虑**:大量数据处理时注意内存布局 +4. **调试技巧**:使用混合模式调试追踪 C++/C# 调用栈 +::: diff --git a/docs/document/guides/command.md b/docs/document/guides/command.md index e5c1a99..47c656f 100644 --- a/docs/document/guides/command.md +++ b/docs/document/guides/command.md @@ -1,17 +1,220 @@ --- -title: 命令 -description: 控制台命令 -hide_title: true -slug: command +title: ⌨️ 控制台命令 +description: UnrealCSharp 控制台命令完整指南 +hide_title: false sidebar_position: 2 custom_edit_url: null --- -## Editor +# ⌨️ 控制台命令 -- `UnrealCSharp.Editor.CodeAnalysis`,代码分析 -- `UnrealCSharp.Editor.SolutionGenerator`,生成解决方案 -- `UnrealCSharp.Editor.Compile`,编译代码 -- `UnrealCSharp.Editor.Generator`,完整生成 +
+

+ 🚀 使用控制台命令高效管理您的 C# 项目 +

+
+ +--- + +## 🛠️ 编辑器命令 + +### 核心开发命令 + +
+
+
+
+

🔍 代码分析

+
+
+

命令:UnrealCSharp.Editor.CodeAnalysis

+

功能:分析 C# 代码质量和潜在问题

+

用途:

+
    +
  • 检查代码规范
  • +
  • 发现潜在错误
  • +
  • 优化建议
  • +
+
+
+
+
+
+
+

📝 生成解决方案

+
+
+

命令:UnrealCSharp.Editor.SolutionGenerator

+

功能:生成 Visual Studio 解决方案文件

+

用途:

+
    +
  • 创建 .sln 文件
  • +
  • 配置项目引用
  • +
  • IDE 集成支持
  • +
+
+
+
+
+ +
+
+
+
+

🔨 编译代码

+
+
+

命令:UnrealCSharp.Editor.Compile

+

功能:编译 C# 代码并热重载

+

用途:

+
    +
  • 增量编译
  • +
  • 热重载更新
  • +
  • 快速验证修改
  • +
+
+
+
+
+
+
+

⚡ 完整生成

+
+
+

命令:UnrealCSharp.Editor.Generator

+

功能:完整重新生成 C# 项目

+

用途:

+
    +
  • 全量代码生成
  • +
  • 解决方案重建
  • +
  • 清理并重新开始
  • +
+
+
+
+
+ +--- + +## 🎯 命令使用指南 + +### 📝 如何执行命令 + +
+ 💡 三种执行方式: +
+ +1. **编辑器控制台** + - 按下 `` ` `` 键打开控制台 + - 输入命令并按回车 + +2. **输出日志窗口** + - Window → Developer Tools → Output Log + - 在命令输入框中执行 + +3. **蓝图节点** + - 在蓝图中使用 "Execute Console Command" 节点 + - 适合自动化流程 + +### ⚡ 常用命令组合 + +
+
+
+
+

🔄 开发工作流

+
+
+
    +
  1. UnrealCSharp.Editor.CodeAnalysis
  2. +
  3. UnrealCSharp.Editor.Compile
  4. +
  5. 测试功能
  6. +
  7. 重复步骤 1-3
  8. +
+
+
+
+
+
+
+

🚀 项目初始化

+
+
+
    +
  1. UnrealCSharp.Editor.Generator
  2. +
  3. UnrealCSharp.Editor.SolutionGenerator
  4. +
  5. 在 IDE 中打开解决方案
  6. +
  7. 开始开发
  8. +
+
+
+
+
+ +--- + +## 🔧 高级用法 + +### 🎯 自动化脚本 + +您可以将这些命令集成到自动化脚本中: + +```bash +# 示例:自动化构建脚本 +echo "开始 C# 代码分析..." +UnrealCSharp.Editor.CodeAnalysis + +echo "编译 C# 代码..." +UnrealCSharp.Editor.Compile + +echo "构建完成!" +``` + +### 🔄 CI/CD 集成 + +
+ 💡 持续集成建议: +
+ +- 在 CI 流程中使用 `UnrealCSharp.Editor.CodeAnalysis` 进行质量检查 +- 使用 `UnrealCSharp.Editor.Compile` 验证代码可编译性 +- 定期使用 `UnrealCSharp.Editor.Generator` 确保代码生成一致性 + +--- + +## ⚠️ 注意事项 + +### 🚨 执行顺序 + +
+ ⚠️ 重要提醒: +
+ +- 首次使用时必须先执行 `UnrealCSharp.Editor.Generator` +- 代码分析应在编译前进行 +- 修改绑定后需要重新生成解决方案 + +### 🐛 故障排除 + +| 问题 | 解决方案 | +|------|----------| +| 命令无法识别 | 确认插件已正确加载 | +| 编译失败 | 检查 C# 代码语法错误 | +| 生成失败 | 验证项目结构完整性 | + +--- + +## 🤝 更多帮助 + +
+

需要更多命令行工具的帮助?

+ + 🐛 学习调试 + + {' '} + + ❓ 查看 FAQ + +
--- diff --git a/docs/document/guides/configuration/editor.md b/docs/document/guides/configuration/editor.md index b2d4fca..19e865e 100644 --- a/docs/document/guides/configuration/editor.md +++ b/docs/document/guides/configuration/editor.md @@ -1,57 +1,113 @@ --- title: Editor -description: Editor配置参数 +description: Editor配置参数详解 hide_title: true slug: editor sidebar_position: 1 custom_edit_url: null --- -### DotNet +# Editor 配置参数 -- DotNetPath,DotNet路径 - - Windows上默认为`C:/Program Files/dotnet/dotnet.exe` - - macOS上默认为`/usr/local/share/dotnet/dotnet` +本文档详细介绍UnrealCSharp在编辑器模式下的各项配置参数,帮助开发者根据项目需求进行个性化配置。 + +## DotNet 配置 + +配置.NET运行时环境相关参数。 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `DotNetPath` | string | 见下方说明 | .NET可执行文件的完整路径 | + +**默认路径:** +- **Windows**: `C:/Program Files/dotnet/dotnet.exe` +- **macOS**: `/usr/local/share/dotnet/dotnet` + +:::tip 提示 +确保指定的.NET路径存在且可执行,建议使用.NET 6.0及以上版本。 +::: --- -### Generator - -- ScriptDirectory,脚本目录,默认为Script -- bEnableDeleteProxyDirectory,是否删除Proxy目录,默认关闭 -- bEnableCompiled,是否开启编译,默认开启 -- bEnableAssetChanged,是否开启监听资源变更,默认开启 -- bEnableDirectoryChanged,是否开启监听C#文件变更,默认开启 -- bIsSkipGenerateEngineModules,是否跳过引擎侧生成,默认关闭,当确认引擎侧不需要重复生成时,可开启,用于加快生成速度 -- bIsGenerateAllModules,是否全量生成,默认开启,当想要通过SupportedModule自定义生成规则时,可关闭 -- SupportedModule,需要对C++代码生成C#代码的模块或者插件 - - 对于类,需要类继承的基类以及接口被导出 - - 对于变量,需要变量类型被导出 - - 对于函数,需要函数所有参数类型以及返回值类型被导出 - - 默认添加如下模块或者插件: - - Core - - CoreUObject - - Engine - - SlateCore - - FieldNotification - - UMG - - UnrealCSharpCore - - `项目` -- bIsGenerateAsset,是否生成资源类型,默认开启,当确认不需要生成资源类型时,可关闭,用于加快生成速度 -- SupportedAssetPath,需要对资源生成C#代码的模块或者插件 - - 默认添加`项目` -- SupportedAssetClass,需要对资源生成C#代码的资源类型 - - 对于蓝图类,会生成变量和函数 - - 对于蓝图结构体,会生成变量 - - 对于蓝图枚举,会生成枚举值 - - 对于其他类型,会生成继承资源类型的空类,主要用于防止资源路径硬编码,可借助代码分析工具实现收集C#侧资源引用情况 - - 默认添加如下资源类型: - - Blueprint - - UserDefinedStruct - - UserDefinedEnum - - WidgetBlueprint -- bIsGenerateFunctionComment,是否生成函数注释,默认开启 -- bEnableExport,是否开启通过UHT生成静态绑定代码,默认关闭 -- ExportModule,需要通过UHT生成静态绑定代码的模块或者插件 +## Generator 生成器配置 + +控制C#代码生成和编译相关的配置参数。 + +### 基础配置 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `ScriptDirectory` | string | `Script` | C#脚本存放的根目录名称 | +| `bEnableDeleteProxyDirectory` | bool | `false` | 是否在生成前删除Proxy目录 | +| `bEnableCompiled` | bool | `true` | 是否启用自动编译功能 | + +### 监听配置 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `bEnableAssetChanged` | bool | `true` | 是否监听UE资源文件变更并自动重新生成 | +| `bEnableDirectoryChanged` | bool | `true` | 是否监听C#文件变更并自动重新编译 | + +### 模块生成配置 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `bIsSkipGenerateEngineModules` | bool | `false` | 跳过引擎模块的重复生成以提升速度 | +| `bIsGenerateAllModules` | bool | `true` | 是否生成所有模块,关闭时使用SupportedModule自定义 | + +#### SupportedModule(支持的模块) + +指定需要从C++代码生成C#绑定的模块或插件列表。 + +**生成要求:** +- **类**: 基类和接口必须被导出 +- **变量**: 变量类型必须被导出 +- **函数**: 所有参数类型和返回值类型必须被导出 + +**默认包含的模块:** +- `Core` - UE核心模块 +- `CoreUObject` - UE对象系统 +- `Engine` - UE引擎模块 +- `SlateCore` - UI核心模块 +- `FieldNotification` - 字段通知系统 +- `UMG` - UE用户界面系统 +- `UnrealCSharpCore` - UnrealCSharp核心模块 +- 当前项目模块 + +### 资源生成配置 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `bIsGenerateAsset` | bool | `true` | 是否生成资源类型的C#绑定 | + +#### SupportedAssetPath(支持的资源路径) + +指定需要生成C#代码的资源所在的模块或插件路径。 + +**默认值:** 当前项目 + +#### SupportedAssetClass(支持的资源类型) + +指定需要生成C#绑定的资源类型及其生成规则: + +| 资源类型 | 生成内容 | 说明 | +|----------|----------|------| +| `Blueprint` | 变量和函数 | 蓝图类的完整绑定 | +| `UserDefinedStruct` | 变量 | 用户定义结构体 | +| `UserDefinedEnum` | 枚举值 | 用户定义枚举 | +| `WidgetBlueprint` | 变量和函数 | UI蓝图的完整绑定 | +| 其他类型 | 空类继承 | 防止资源路径硬编码,便于引用分析 | + +### 其他配置 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `bIsGenerateFunctionComment` | bool | `true` | 是否在生成的C#代码中包含函数注释 | +| `bEnableExport` | bool | `false` | 是否通过UHT生成静态绑定代码 | +| `ExportModule` | array | `[]` | 需要通过UHT生成静态绑定的模块列表 | + +:::warning 注意 +`bEnableExport` 功能仍在实验阶段,建议在生产环境中谨慎使用。 +::: --- \ No newline at end of file diff --git a/docs/document/guides/configuration/runtime.md b/docs/document/guides/configuration/runtime.md index 9d6e1c2..b05564f 100644 --- a/docs/document/guides/configuration/runtime.md +++ b/docs/document/guides/configuration/runtime.md @@ -1,49 +1,135 @@ --- title: Runtime -description: Runtime配置参数 +description: Runtime运行时配置参数详解 hide_title: true slug: runtime sidebar_position: 2 custom_edit_url: null --- -### Publish +# Runtime 运行时配置 -- PublishDirectory,发布目录,默认为Script -- UEName,UE程序集名 -- GameName,Game程序集名 -- CustomProjects,自定义程序集 +本文档详细介绍UnrealCSharp在运行时的各项配置参数,涵盖程序集发布、函数覆盖、域管理、绑定和调试等关键功能。 + +## Publish 发布配置 + +配置程序集的发布和加载相关参数。 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `PublishDirectory` | string | `Script` | 已编译程序集的发布目录 | +| `UEName` | string | - | UE引擎程序集的名称 | +| `GameName` | string | - | 游戏项目程序集的名称 | +| `CustomProjects` | array | `[]` | 自定义程序集列表,用于加载额外的程序集 | + +:::info 说明 +`PublishDirectory` 指定运行时加载程序集的目录,通常与编译输出目录保持一致。 +::: --- -### Override +## Override 函数覆盖配置 + +控制C#中覆盖UE函数的行为和命名规则。 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `bEnableCallOverrideFunction` | bool | `true` | 是否启用调用被覆盖的原始函数功能 | +| `OverrideFunctionNamePrefix` | string | `""` | 被覆盖函数的名称前缀 | +| `OverrideFunctionNameSuffix` | string | `_Override` | 被覆盖函数的名称后缀 | + +### 使用示例 + +当覆盖UE中的`BeginPlay`函数时: +- 原始函数调用:`BeginPlay_Override()` (使用默认后缀) +- 如果设置前缀为`Super_`:`Super_BeginPlay()` + +:::tip 最佳实践 +建议保持默认的`_Override`后缀,这样可以清晰地区分原始函数调用。 +::: + +--- + +## Domain 程序域配置 + +管理.NET程序集的加载和隔离。 -- bEnableCallOverrideFunction,是否开启调用被覆盖函数,默认开启 -- OverrideFunctionNamePrefix,被覆盖函数前缀,默认为空 -- OverrideFunctionNameSuffix,被覆盖函数后缀,默认为_Override +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `AssemblyLoader` | string | - | 自定义程序集加载器的完整类名 | + +### 自定义加载器 + +可以通过实现自定义加载器来控制程序集的加载行为,例如: +- 热重载支持 +- 版本管理 +- 依赖解析 --- -### Domain +## Bind 预绑定配置 + +配置需要预先绑定的类型,优化运行时性能。 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `BindClass` | array | `[]` | 需要预先绑定的C#类型列表 | + +### 使用场景 + +主要用于绑定以下类型: +- **CDO (Class Default Object)**: 类默认对象 +- **蓝图函数库**: 如`UBlueprintFunctionLibrary`的子类 +- **静态类**: 频繁使用的工具类 + +### 配置示例 -- AssemblyLoader,自定义程序集加载规则 +```json +"BindClass": [ + "MyProject.MyBlueprintFunctionLibrary", + "MyProject.Utilities.MathHelper" +] +``` --- -### Bind +## Debug 调试配置 -- BindClass,需要预先绑定的类型,可用于绑定CDO,比如UBlueprintFunctionLibrary +配置C#代码的调试功能,支持远程调试。 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `bEnableDebug` | bool | `false` | 是否启用调试模式 | +| `Host` | string | `localhost` | 调试服务器地址 | +| `Port` | int | `4711` | 调试服务器端口 | + +### 调试设置 + +1. **启用调试**: 将`bEnableDebug`设置为`true` +2. **配置IDE**: 在Visual Studio或VS Code中配置远程调试 +3. **连接调试器**: 使用指定的Host和Port连接 + +:::warning 性能提醒 +调试模式会影响运行时性能,请在发布版本中关闭此功能。 +::: --- -### Debug +## Module 模块配置 + +控制模块的激活和生命周期管理。 + +| 参数名 | 类型 | 默认值 | 描述 | +|--------|------|--------|------| +| `bEnableImmediatelyActive` | bool | `true` | 是否在加载后立即激活模块 | -- bEnableDebug,是否开启调试模式 -- Host,调试地址 -- Port,调试端口 +### 模块激活策略 -### Module +- **立即激活** (`true`): 模块加载后立即执行初始化代码 +- **延迟激活** (`false`): 模块加载后等待手动激活或特定事件触发 -- bEnableImmediatelyActive,是否开启直接启动Module,默认开启 +:::note 注意事项 +对于依赖其他系统的模块,可能需要关闭立即激活以确保正确的初始化顺序。 +::: --- \ No newline at end of file diff --git a/docs/document/guides/debug.md b/docs/document/guides/debug.md index f10f10f..7d04cf1 100644 --- a/docs/document/guides/debug.md +++ b/docs/document/guides/debug.md @@ -1,6 +1,6 @@ --- title: 调试 -description: 如何配置和使用调试工具进行调试 +description: UnrealCSharp调试完整指南:从基础配置到真机调试 hide_title: true slug: debug sidebar_position: 3 @@ -10,37 +10,163 @@ custom_edit_url: null import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## 基础概念 +# C# 调试指南 -[Mono](https://github.com/dotnet/runtime)已经摒弃[Guide:Debugger](https://www.mono-project.com/archived/guidedebugger/)这套调试流程,目前需要参考[C# Compiler Options that control code generation](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/code-generation)将`DebugType`设置为`embedded`(插件已处理好)。 +本文档提供UnrealCSharp的完整调试解决方案,包括项目配置、IDE设置和真机调试等内容。 + +## 📖 基础概念 + +### 调试机制说明 + +由于[Mono](https://github.com/dotnet/runtime)已经废弃了传统的[Guide:Debugger](https://www.mono-project.com/archived/guidedebugger/)调试流程,UnrealCSharp采用了新的调试机制: + +- **调试符号格式**: 使用`embedded` DebugType(插件已自动配置) +- **协议支持**: 基于.NET标准调试协议 +- **跨平台兼容**: 支持Windows、macOS、Linux等平台 + +:::info 技术背景 +根据[C# Compiler Options](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/code-generation)文档,`embedded` DebugType将调试信息直接嵌入到程序集中,提供更好的调试体验。 +::: --- -## 项目配置 +## ⚙️ 项目配置 + +### Runtime 调试配置 + +在项目的Runtime配置中启用调试功能: -参考[配置](../guides/configuration/runtime) +```json +{ + "Debug": { + "bEnableDebug": true, + "Host": "localhost", + "Port": 4711 + } +} +``` + +| 参数 | 说明 | 默认值 | +|------|------|--------| +| `bEnableDebug` | 启用调试模式 | `false` | +| `Host` | 调试服务器地址 | `localhost` | +| `Port` | 调试端口 | `4711` | + +:::tip 配置建议 +- 开发阶段建议启用调试模式 +- 发布版本务必关闭调试以提升性能 +- 团队开发时可使用不同端口避免冲突 +::: + +详细配置参数请参考:[Runtime配置文档](../guides/configuration/runtime#debug-调试配置) --- -## IDE配置 +## 🛠️ IDE 配置 + +根据您使用的开发环境选择相应的配置方法: - + + +### 配置步骤 + +1. **创建调试配置** + - `Run` → `Edit Configurations...` + - 点击 `+` → `.NET` → `Mono Remote` -`Run-Edit Configurations...-Add New Configuration-.NET-Mono Remote` +2. **配置参数** + ``` + Name: UnrealCSharp Debug + Host: localhost + Port: 4711 + ``` + +3. **高级设置** + - ✅ `Suspend on connection` + - ✅ `Wait for connections` + +### 使用方法 + +1. 启动UE编辑器或游戏 +2. 在Rider中点击调试按钮 +3. 设置断点并开始调试 + +:::tip Rider优势 +- 原生支持Mono调试 +- 强大的代码分析功能 +- 优秀的UE集成支持 +::: -[VSMonoDebugger](https://github.com/GordianDotNet/VSMonoDebugger) +### 插件安装 + +安装 [VSMonoDebugger](https://github.com/GordianDotNet/VSMonoDebugger) 扩展: + +1. 打开 `Extensions` → `Manage Extensions` +2. 搜索 "Mono Debugger" +3. 安装并重启VS + +### 配置调试 + +1. **创建调试配置** + - `Debug` → `Attach to Process...` + - 选择 `Mono Remote (MonoDebugger)` + +2. **连接设置** + ``` + Host: localhost + Port: 4711 + ``` + +### 注意事项 + +- 确保VS版本支持该插件 +- 可能需要手动配置符号路径 +- 建议使用VS 2019或更高版本 -[vscode-mono-debug](https://github.com/microsoft/vscode-mono-debug) +### 插件安装 + +安装 [vscode-mono-debug](https://github.com/microsoft/vscode-mono-debug) 扩展: + +```bash +code --install-extension ms-vscode.mono-debug +``` + +### launch.json 配置 + +在项目根目录创建 `.vscode/launch.json`: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "UnrealCSharp Debug", + "type": "mono", + "request": "attach", + "address": "localhost", + "port": 4711, + "localRoot": "${workspaceFolder}", + "remoteRoot": "/path/to/remote/source" + } + ] +} +``` + +### 调试步骤 + +1. 按 `F5` 或点击调试按钮 +2. 选择 "UnrealCSharp Debug" 配置 +3. 连接到运行中的UE实例 @@ -48,8 +174,80 @@ import TabItem from '@theme/TabItem'; --- -## 真机调试 +## 📱 真机调试 + +### 移动端调试配置 + +对于Android和iOS等移动平台的调试,需要使用反向代理技术: + +#### 网络配置 + +1. **端口转发设置** + ```bash + # Android (ADB) + adb forward tcp:4711 tcp:4711 + + # iOS (可使用 libimobiledevice) + iproxy 4711 4711 + ``` + +2. **防火墙配置** + - 确保调试端口在防火墙中开放 + - 移动设备能够访问开发机器 + +#### 配置示例 + +```json +{ + "Debug": { + "bEnableDebug": true, + "Host": "0.0.0.0", // 监听所有网卡 + "Port": 4711 + } +} +``` + +### 网络调试 + +参考 [LuaPanda 真机调试指南](https://github.com/Tencent/LuaPanda/blob/master/Docs/Manual/debug-on-phone.md) 中的反向代理配置方法。 + +#### 关键步骤 + +1. **建立代理连接** + - 使用USB连接或WiFi网络 + - 配置端口转发规则 + +2. **调试器连接** + - IDE连接到本地转发端口 + - 自动转发到设备上的调试端口 + +3. **断点调试** + - 设置断点并启动应用 + - 在移动设备上触发相应代码 + +:::warning 注意事项 +- 真机调试可能影响游戏性能 +- 确保网络连接稳定 +- 建议在开发版本中使用 +::: + +--- + +## 🔧 故障排除 + +### 常见问题 + +| 问题 | 原因 | 解决方案 | +|------|------|----------| +| 连接超时 | 端口被占用或防火墙阻止 | 检查端口状态,配置防火墙规则 | +| 断点无效 | 调试符号缺失 | 确认DebugType为embedded | +| 性能下降 | 调试模式开销 | 发布时关闭调试功能 | + +### 调试技巧 -参考[debug-on-phone](https://github.com/Tencent/LuaPanda/blob/master/Docs/Manual/debug-on-phone.md)中提及的`反向代理` +1. **日志输出**: 使用`UE_LOG`输出调试信息 +2. **条件断点**: 在特定条件下触发断点 +3. **监视变量**: 实时查看变量值变化 +4. **调用堆栈**: 分析函数调用路径 --- diff --git a/docs/document/guides/hotreload.md b/docs/document/guides/hotreload.md index b908263..846c731 100644 --- a/docs/document/guides/hotreload.md +++ b/docs/document/guides/hotreload.md @@ -1,20 +1,189 @@ --- title: 编辑器热重载 -description: 编辑器下监听C#文件和资源变更并热重载 +description: UnrealCSharp编辑器热重载机制详解 hide_title: true slug: hotreload sidebar_position: 4 custom_edit_url: null --- -## C#文件变更 +# 编辑器热重载 -使用`IDirectoryWatcher::FDirectoryChanged`监听`Script`项目中`Game`工程的C#文件变更情况,当编辑器切换到前台时,如果检测到有文件变更,则会触发C#编译,当变更列表中存在动态类时,也会对动态类进行热重载。 +UnrealCSharp提供强大的热重载功能,支持C#代码和UE资源的实时更新,大幅提升开发效率。 + +## 🔄 C#文件热重载 + +### 工作机制 + +UnrealCSharp使用`IDirectoryWatcher::FDirectoryChanged`监听Script项目中Game工程的C#文件变更,实现以下流程: + +```mermaid +graph LR + A[C#文件修改] --> B[文件监听器检测] + B --> C[编辑器切换到前台] + C --> D[触发编译] + D --> E{存在动态类?} + E -->|是| F[执行热重载] + E -->|否| G[仅编译] + F --> H[更新完成] + G --> H +``` + +### 触发条件 + +| 条件 | 说明 | +|------|------| +| **文件变更** | C#源文件被修改、添加或删除 | +| **编辑器激活** | UE编辑器窗口获得焦点时检查变更 | +| **动态类检测** | 变更列表中包含可热重载的动态类 | + +### 监听范围 + +- **监听目录**: `Script/Game/` 项目目录 +- **文件类型**: `.cs` C#源代码文件 +- **排除项**: 临时文件、备份文件等 + +### 配置参数 + +在Editor配置中控制热重载行为: + +```json +{ + "Generator": { + "bEnableDirectoryChanged": true, // 启用C#文件监听 + "bEnableCompiled": true // 启用自动编译 + } +} +``` + +:::tip 性能优化 +- 大型项目建议使用增量编译 +- 可通过配置排除不需要监听的目录 +- 建议在SSD上存放项目文件以提升编译速度 +::: --- -## 资源变更 +## 🎨 资源热重载 + +### 支持的资源操作 + +UnrealCSharp监听以下UE资源变更操作: + +| 操作类型 | 描述 | 触发行为 | +|----------|------|----------| +| **新增** | 创建新的蓝图、结构体等资源 | 生成对应C#绑定文件 | +| **删除** | 删除现有资源 | 移除对应C#文件 | +| **修改** | 更新资源内容(如添加变量) | 重新生成C#绑定 | +| **重命名** | 资源重命名或移动 | 更新C#文件名和命名空间 | + +### 资源类型支持 + +根据[Editor配置](../guides/configuration/editor#supportedassetclass支持的资源类型),默认支持: + +#### 完整绑定(变量+函数) +- **Blueprint** - 蓝图类 +- **WidgetBlueprint** - UI蓝图 + +#### 变量绑定 +- **UserDefinedStruct** - 用户定义结构体 + +#### 枚举绑定 +- **UserDefinedEnum** - 用户定义枚举 + +#### 类型引用 +- **其他资源类型** - 生成空类以防止硬编码 + +### 配置示例 + +```json +{ + "Generator": { + "bEnableAssetChanged": true, + "bIsGenerateAsset": true, + "SupportedAssetPath": ["MyProject"], + "SupportedAssetClass": [ + "Blueprint", + "UserDefinedStruct", + "UserDefinedEnum", + "WidgetBlueprint" + ] + } +} +``` + +### 生成规则 + +当资源变更时,系统会: + +1. **检查资源类型**: 是否在`SupportedAssetClass`列表中 +2. **验证路径**: 资源是否属于`SupportedAssetPath`指定的模块 +3. **生成C#代码**: 创建或覆盖对应的C#绑定文件 +4. **触发编译**: 自动编译更新后的代码 + +:::info 命名规则 +- C#类名与UE资源名保持一致 +- 命名空间根据资源路径自动生成 +- 特殊字符会被自动转换为有效的C#标识符 +::: + +--- + +## ⚡ 性能优化 + +### 编译优化 + +| 策略 | 说明 | 效果 | +|------|------|------| +| **增量编译** | 仅编译变更的文件 | 显著减少编译时间 | +| **并行编译** | 多线程编译支持 | 充分利用多核CPU | +| **缓存机制** | 缓存编译结果 | 避免重复编译 | + +### 监听优化 + +```json +{ + "Generator": { + "bIsSkipGenerateEngineModules": true, // 跳过引擎模块重复生成 + "bIsGenerateAllModules": false, // 使用自定义模块列表 + "SupportedModule": ["MyProject"] // 仅监听项目模块 + } +} +``` + +### 文件系统优化 + +- **SSD存储**: 将项目存放在SSD上 +- **排除监听**: 排除临时文件和缓存目录 +- **合理分组**: 按功能模块组织代码结构 + +--- + +## 🚨 注意事项 + +### 限制条件 + +- **静态类限制**: 某些静态绑定类型无法热重载 +- **内存引用**: 已创建的对象实例不会自动更新 +- **依赖关系**: 类型依赖变更可能需要重启编辑器 + +### 最佳实践 + +1. **及时保存**: 修改后及时保存文件以触发热重载 +2. **避免循环依赖**: 设计时避免复杂的类型依赖关系 +3. **测试验证**: 热重载后及时测试功能是否正常 +4. **备份重要代码**: 重要修改前建议备份代码 + +### 故障排除 + +| 问题 | 可能原因 | 解决方案 | +|------|----------|----------| +| 热重载失败 | 编译错误 | 检查编译输出,修复语法错误 | +| 变更未生效 | 缓存问题 | 重启编辑器或清理缓存 | +| 性能下降 | 频繁重载 | 优化代码结构,减少不必要的变更 | -当发生资源变更(增加,删除,修改和重命名)时,如果该资源类型以及该资源所属模块或插件在[配置](../guides/configuration/editor)中匹配成功,则会新建或者覆盖对应C#文件,并且触发C#编译。 +:::warning 重要提醒 +热重载功能主要用于开发阶段,打包发布时会使用完整编译流程以确保稳定性。 +::: --- diff --git a/docs/document/introduction/introduction.md b/docs/document/introduction/introduction.md index 2bd7b4d..3291c3f 100644 --- a/docs/document/introduction/introduction.md +++ b/docs/document/introduction/introduction.md @@ -1,11 +1,150 @@ --- -description: "" -hide_title: true +title: UnrealCSharp 介绍 +description: 一个强大的 Unreal Engine C# 编程插件,基于 .NET 8,支持全平台开发 +hide_title: false custom_edit_url: null --- -## +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -    UnrealCSharp是UE下C#编程插件,基于.NET 8(Mono),支持全部的反射类型,自动生成C#代码,能够静态导出各种数据类型和函数,同时拥有强大的动态类特性,可以通过C#直接生成UClass,UInterface,UStruct和UEnum,并且不需要蓝图载体。目前已适配Windows,macOS,Linux,Android和IOS多个平台;支持Dedicated Server;支持Editor,Runtime和Android真机调试;能够通过Pak进行热更新;编辑器下,能够热重载C#改动,包括替换动态类。拥有完善的生态,完备的单元测试和回归测试,详细的性能测试,已经使用插件复刻了Epic提供的StackOBot和Cropout游戏示例,目前社区中已经有项目实际接入使用。 +# 🎮 UnrealCSharp + +
+

+ 🚀 现代化的 Unreal Engine C# 编程解决方案 +

+
+ +--- + +## ✨ 什么是 UnrealCSharp? + +**UnrealCSharp** 是一个功能强大的 Unreal Engine C# 编程插件,基于 **.NET 8 (Mono)** 构建,为开发者提供了完整的 C# 开发体验。 + +### 🎯 核心特性 + +
+
+
+
+

🔄 完整反射支持

+
+
+

支持全部反射类型,自动生成 C# 代码,静态导出各种数据类型和函数

+
+
+
+
+
+
+

⚡ 动态类特性

+
+
+

通过 C# 直接生成 UClass、UInterface、UStruct 和 UEnum,无需蓝图载体

+
+
+
+
+ +### 🌍 平台支持 + + + + +- ✅ **Windows** +- ✅ **macOS** +- ✅ **Linux** + + + + +- ✅ **Android** +- ✅ **iOS** + + + + +- ✅ **Dedicated Server** + + + + +### 🛠️ 开发工具支持 + +
+
+
+
+
🐛 调试支持
+
    +
  • Editor 调试
  • +
  • Runtime 调试
  • +
  • Android 真机调试
  • +
+
+
+
+
+
+
+
🔥 热重载
+
    +
  • C# 代码热重载
  • +
  • 动态类替换
  • +
  • 编辑器内实时更新
  • +
+
+
+
+
+
+
+
📦 热更新
+
    +
  • 通过 Pak 文件热更新
  • +
  • 运行时代码更新
  • +
  • 无需重启应用
  • +
+
+
+
+
+ +--- + +## 🏆 生态与质量保证 + +### 📊 测试覆盖 + +- ✅ **完备的单元测试** +- ✅ **全面的回归测试** +- ✅ **详细的性能测试** + +### 🎮 实战验证 + +插件已成功复刻 Epic 官方提供的游戏示例: +- 🤖 **StackOBot** +- 🌾 **Cropout** + +### 👥 社区应用 + +目前已有多个社区项目成功接入使用,经过实际生产环境验证。 + +--- + +## 🚀 快速开始 + +准备好开始您的 UnrealCSharp 之旅了吗? + + --- diff --git a/docs/update/2025/01.md b/docs/update/2025/01.md index bbac885..b979527 100644 --- a/docs/update/2025/01.md +++ b/docs/update/2025/01.md @@ -1,32 +1,184 @@ --- -title: 01月 -description: "" -hide_title: true -slug: 1 +title: 📅 2025年1月更新 +description: 2025年1月 UnrealCSharp 功能更新与改进 +hide_title: false sidebar_position: -1 custom_edit_url: null --- -## 01月01日 +# 📅 2025年1月更新日志 -- [新增Module开关。](https://github.com/crazytuzi/UnrealCSharp/commit/127c2833247ab9526e64e8c02ac002646d5f4ba0) +
+

+ 🚀 新年新气象,带来更多强大功能! +

+
--- -## 01月08日 +## 🎉 01月01日 -- [优化引用关系。](https://github.com/crazytuzi/UnrealCSharp/commit/f128e2f4f42b7ea2d0ebc2f8343837f9ef9b3ab2) +
+
+

✨ 新增功能

+
+
+
🔧 Module 开关功能
+

新增了灵活的 Module 开关控制,允许开发者按需启用/禁用特定模块。

+

🔗 相关提交: 127c283

+ +
+ 💡 优势: +
    +
  • 更细粒度的模块控制
  • +
  • 减少不必要的资源占用
  • +
  • 提升项目启动速度
  • +
+
+
+
--- -## 01月14日 +## 🔧 01月08日 -- [新增动态类支持自定义Namespace。](https://github.com/crazytuzi/UnrealCSharp/commit/37106f337bfa277f9ad9ba378241c81b94e1d585) +
+
+

⚡ 性能优化

+
+
+
🔗 引用关系优化
+

重构并优化了模块间的引用关系,提升了系统整体性能。

+

🔗 相关提交: f128e2f

+ +
+ 🚀 改进效果: +
    +
  • 减少循环依赖
  • +
  • 优化内存使用
  • +
  • 提升编译速度
  • +
+
+
+
--- -## 01月23日 +## 🏗️ 01月14日 -- [修复IsNativeFunction。](https://github.com/crazytuzi/UnrealCSharp/commit/933c9d2e4f9d3067a593645c057976290ee54065) +
+
+

🆕 功能增强

+
+
+
📦 动态类自定义命名空间
+

动态类现在支持自定义 Namespace,提供更好的代码组织和管理能力。

+

🔗 相关提交: 37106f3

+ +
+ 📋 使用场景: +
    +
  • 更清晰的代码结构
  • +
  • 避免命名冲突
  • +
  • 便于模块化开发
  • +
+
+ +
💻 示例代码:
+ ```csharp + [UClass(Namespace = "MyGame.Gameplay")] + public class MyGameplayActor : AActor + { + // 现在位于 MyGame.Gameplay 命名空间下 + } + ``` +
+
+ +--- + +## 🐛 01月23日 + +
+
+

🔧 问题修复

+
+
+
⚙️ IsNativeFunction 修复
+

修复了 IsNativeFunction 判断逻辑的错误,确保原生函数识别的准确性。

+

🔗 相关提交: 933c9d2

+ +
+ 🎯 修复内容: +
    +
  • 正确识别原生 C++ 函数
  • +
  • 修复反射调用问题
  • +
  • 提升函数绑定稳定性
  • +
+
+
+
+ +--- + +## 📊 本月总结 + +
+
+
+
+

📈 功能统计

+
+
+
    +
  • 2 项新功能
  • +
  • 1 项性能优化
  • +
  • 🐛 1 个问题修复
  • +
+
+
+
+
+
+
+

🎯 影响范围

+
+
+
    +
  • 🏗️ 架构改进
  • +
  • 🔧 开发体验提升
  • +
  • ⚡ 性能优化
  • +
+
+
+
+
+
+
+

🔮 展望二月

+
+
+
    +
  • 更多平台支持
  • +
  • 性能进一步优化
  • +
  • 开发工具增强
  • +
+
+
+
+
+ +--- + +
+

🎉 感谢社区的持续支持与反馈!

+ + 👀 查看二月更新 + + {' '} + + 💬 参与讨论 + +
---