/* * Tracy Unity Plugin - 简化版实现 * * 这是一个简化的 Tracy Unity Plugin 实现 * 用于演示如何将 Tracy 集成到 Unity Native Plugin 中 * * 编译说明: * Windows: cl /LD /MD SimplifiedPlugin.cpp /I"path/to/tracy/public" ws2_32.lib dbghelp.lib * macOS: clang++ -shared -fPIC SimplifiedPlugin.cpp -I"path/to/tracy/public" -o libUnityTracyPlugin.dylib * Linux: g++ -shared -fPIC SimplifiedPlugin.cpp -I"path/to/tracy/public" -o libUnityTracyPlugin.so -lpthread -ldl */ // 定义 Tracy 启用标志 #define TRACY_ENABLE #define TRACY_ON_DEMAND #include "tracy/Tracy.hpp" #include #include // 平台特定的导出定义 #if defined(_WIN32) || defined(_WIN64) #define UNITY_PLUGIN_EXPORT __declspec(dllexport) #elif defined(__APPLE__) || defined(__linux__) #define UNITY_PLUGIN_EXPORT __attribute__((visibility("default"))) #else #define UNITY_PLUGIN_EXPORT #endif // C 导出函数(Unity 需要 C 链接) extern "C" { /** * 初始化 Tracy * Unity C# 调用: [DllImport] private static extern void TracyInit(); */ UNITY_PLUGIN_EXPORT void TracyInit() { // Tracy 会自动初始化,这里可以添加额外的初始化逻辑 // 例如:设置采样率、配置选项等 } /** * 关闭 Tracy * Unity C# 调用: [DllImport] private static extern void TracyShutdown(); */ UNITY_PLUGIN_EXPORT void TracyShutdown() { // Tracy 会在程序退出时自动清理 // 这里可以添加自定义的清理逻辑 } /** * 标记帧边界 * Unity C# 调用: [DllImport] private static extern void TracyFrameMark(); */ UNITY_PLUGIN_EXPORT void TracyFrameMark() { FrameMark; } /** * 绘制数值 * Unity C# 调用: [DllImport] private static extern void TracyPlotValue(string name, double value); */ UNITY_PLUGIN_EXPORT void TracyPlotValue(const char* name, double value) { if (name != nullptr) { TracyPlot(name, value); } } /** * 发送消息 * Unity C# 调用: [DllImport] private static extern void TracyMessage(string message); */ UNITY_PLUGIN_EXPORT void TracyMessage(const char* message) { if (message != nullptr) { TracyMessage(message, std::strlen(message)); } } /** * 设置线程名称 * Unity C# 调用: [DllImport] private static extern void TracySetThreadName(string name); */ UNITY_PLUGIN_EXPORT void TracySetThreadName(const char* name) { if (name != nullptr) { tracy::SetThreadName(name); } } /** * 开始一个命名的 Zone * Unity C# 调用: [DllImport] private static extern void TracyZoneBegin(string name); * * 注意: 这是简化版实现,实际使用中需要更复杂的 Zone 管理 */ UNITY_PLUGIN_EXPORT void TracyZoneBegin(const char* name) { if (name != nullptr) { // 简化版: 使用动态分配的 Zone // 实际应用中需要管理 Zone 的生命周期 // 方案1: 使用全局 Zone 栈(简单但不支持多线程) // 方案2: 使用线程局部存储(复杂但支持多线程) // 方案3: 返回 Zone ID 给 C#,让 C# 管理(推荐) // 这里使用宏创建一个 Zone // 注意:这只是示例,实际使用需要更好的管理方式 ZoneName(name, std::strlen(name)); } } /** * 结束当前 Zone * Unity C# 调用: [DllImport] private static extern void TracyZoneEnd(); */ UNITY_PLUGIN_EXPORT void TracyZoneEnd() { // 简化版: 与 ZoneBegin 配对使用 // 实际应用中需要管理 Zone 的结束 } /** * Unity 插件生命周期函数 - 加载时调用 */ UNITY_PLUGIN_EXPORT void UnityPluginLoad() { // 可选:在插件加载时执行初始化 } /** * Unity 插件生命周期函数 - 卸载时调用 */ UNITY_PLUGIN_EXPORT void UnityPluginUnload() { // 可选:在插件卸载时执行清理 } } // extern "C" /* * 高级实现示例 - Zone 管理 * * 下面是一个更完善的 Zone 管理实现示例 * 可以根据需要扩展 */ #ifdef ADVANCED_ZONE_MANAGEMENT #include #include #include // Zone 管理器(线程安全) class ZoneManager { private: struct ThreadZones { std::stack zones; }; std::unordered_map threadZones; std::mutex mutex; public: void BeginZone(const char* name, const char* function, const char* file, uint32_t line) { std::lock_guard lock(mutex); auto threadId = std::this_thread::get_id(); auto& zones = threadZones[threadId].zones; // 创建源位置信息 static const tracy::SourceLocationData loc{name, function, file, line, 0}; // 创建 Zone(注意:需要在堆上分配) auto* zone = new tracy::ScopedZone(&loc, true); zones.push(zone); } void EndZone() { std::lock_guard lock(mutex); auto threadId = std::this_thread::get_id(); auto it = threadZones.find(threadId); if (it != threadZones.end() && !it->second.zones.empty()) { auto* zone = it->second.zones.top(); it->second.zones.pop(); delete zone; } } void ClearThread() { std::lock_guard lock(mutex); auto threadId = std::this_thread::get_id(); auto it = threadZones.find(threadId); if (it != threadZones.end()) { // 清理所有未结束的 Zone while (!it->second.zones.empty()) { delete it->second.zones.top(); it->second.zones.pop(); } threadZones.erase(it); } } }; // 全局 Zone 管理器实例 static ZoneManager g_zoneManager; extern "C" { UNITY_PLUGIN_EXPORT void TracyZoneBeginAdvanced(const char* name, const char* function, const char* file, int line) { g_zoneManager.BeginZone(name, function, file, static_cast(line)); } UNITY_PLUGIN_EXPORT void TracyZoneEndAdvanced() { g_zoneManager.EndZone(); } UNITY_PLUGIN_EXPORT void TracyClearThreadZones() { g_zoneManager.ClearThread(); } } // extern "C" #endif // ADVANCED_ZONE_MANAGEMENT /* * 编译和部署说明: * * 1. Windows (Visual Studio): * - 创建 DLL 项目 * - 添加 Tracy 源文件: tracy/public/TracyClient.cpp * - 包含目录: tracy/public * - 链接库: ws2_32.lib dbghelp.lib * - 输出: UnityTracyPlugin.dll * * 2. macOS: * clang++ -std=c++17 -shared -fPIC \ * SimplifiedPlugin.cpp \ * tracy/public/TracyClient.cpp \ * -I tracy/public \ * -DTRACY_ENABLE -DTRACY_ON_DEMAND \ * -o libUnityTracyPlugin.dylib * * 3. Linux: * g++ -std=c++17 -shared -fPIC \ * SimplifiedPlugin.cpp \ * tracy/public/TracyClient.cpp \ * -I tracy/public \ * -DTRACY_ENABLE -DTRACY_ON_DEMAND \ * -lpthread -ldl \ * -o libUnityTracyPlugin.so * * 4. Android (NDK): * 在 Android.mk 或 CMakeLists.txt 中配置 * * 5. iOS: * 使用 Xcode 编译为静态库 (.a) * * 部署到 Unity: * - 将编译好的库文件复制到 Unity 项目的 Assets/Plugins/ 目录 * - 根据平台放置在相应的子目录中 * - 配置 Plugin Import Settings 以匹配目标平台 */