mcpField
U
unity-platforms

unity-platforms

github.com/nice-wolf-studio开发4067 次安装6 周前更新
代码仓库

关于 unity-platforms

面向 Unity 开发者的跨平台开发参考技能,汇总平台构建配置、条件编译、移动端与 WebGL 注意事项,以及 IL2CPP、Mono 和 Addressables 的用法。适合规划平台配置并排查构建与性能问题。

主要功能

  1. 01Build Profiles 与场景配置
  2. 02平台条件编译宏
  3. 03iOS 与 Android 设置和优化
  4. 04WebGL 内存与 JavaScript 互操作
  5. 05IL2CPP 与 Mono 对比
  6. 06Addressables 资源加载

适用场景

  1. 01为不同平台维护独立构建配置
  2. 02添加平台专属代码或功能
  3. 03优化移动端与 WebGL 的资源和内存
  4. 04选择脚本后端并配置资源加载

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nice-wolf-studio/unity-claude-skills --skill unity-platforms

安装后在 Claude Code 中输入/unity-platforms确认已加载。

附带文件references/mobile-optimization.mdreferences/platform-defines.md

详细介绍

Unity 平台技能

支持的平台

Unity 6 支持以下平台类别:

  • 桌面:Windows、macOS、Linux
  • 移动:Android、iOS
  • 新兴平台:visionOS、tvOS
  • Web:WebGL(包括 Facebook Instant Games)
  • 服务器:专用服务器
  • 嵌入式:Embedded Linux、QNX
  • UWP:Universal Windows Platform
  • 封闭平台:PlayStation、Xbox(Game Core)、Nintendo(需要保密/法律协议,并通过 Platform Module Installation 注册)

构建配置文件和设置

构建配置文件取代了旧版 Build Settings 窗口。构建配置文件是一组配置设置,用于为特定平台构建应用程序。

两种配置文件类型
  1. 平台:显示当前已安装的平台,各配置共享相同设置。启用 Development Build 等选项后,该设置将应用于所有配置。各平台配置文件共享相同的场景数据。
  2. 构建配置文件:独立配置,不与其他平台共享。每个配置文件都可以指定独有的场景和设置。配置文件以资产文件形式存储,兼容版本控制。
主要功能
  • 自定义名称,以便整理多个构建配置
  • 集成版本控制(配置文件以资产文件形式存储)
  • 为每个配置文件分配场景
  • 开发版构建(调试符号、Profiler 访问权限)和发布版构建
  • 通过 File > Build Profiles 访问
  • 右键单击平台,然后选择“Copy to new profile”即可复制平台
场景管理

场景按配置文件进行管理。你可以在构建中添加、排除、移除和重新排序场景。每个唯一的 Scene 文件都代表一个独立的关卡或屏幕。

平台脚本定义

使用 #if 指令按平台有条件地编译代码。

平台定义
定义平台
UNITY_EDITOR任意 Editor 代码
UNITY_EDITOR_WINWindows Editor
UNITY_EDITOR_OSXmacOS Editor
UNITY_EDITOR_LINUXLinux Editor
UNITY_STANDALONE_OSXmacOS Standalone
UNITY_STANDALONE_WINWindows Standalone
UNITY_STANDALONE_LINUXLinux Standalone
UNITY_STANDALONE任意 Standalone(Win/Mac/Linux)
UNITY_SERVER专用服务器
UNITY_IOSiOS
UNITY_ANDROIDAndroid
UNITY_TVOStvOS
UNITY_VISIONOSvisionOS
UNITY_WEBGLWebGL
UNITY_WSAUniversal Windows Platform
UNITY_WSA_10_0UWP 10.0
UNITY_EMBEDDED_LINUXEmbedded Linux
UNITY_QNXQNX
UNITY_FACEBOOK_INSTANT_GAMESFacebook Instant Games
功能和后端定义
定义含义
UNITY_ANALYTICS已启用 Analytics
UNITY_ASSERTIONS已启用断言
UNITY_6464 位平台
ENABLE_MONOMono 脚本后端
ENABLE_IL2CPPIL2CPP 脚本后端
ENABLE_VR已启用 VR 支持
ENABLE_INPUT_SYSTEM已启用新 Input System
ENABLE_LEGACY_INPUT_MANAGER已启用旧版 Input Manager
ENABLE_WINMD_SUPPORTWinMD 支持
DEVELOPMENT_BUILD开发版构建
UNITY_CLOUD_BUILDCloud Build
.NET API 级别定义
定义API 级别
NET_STANDARD_2_0.NET Standard 2.0
NET_STANDARD_2_1.NET Standard 2.1
NET_STANDARD / NETSTANDARD任意 .NET Standard
NETSTANDARD2_1.NET Standard 2.1(C# 定义)
NET_4_6.NET Framework
NET_2_0 / NET_LEGACY.NET 2.0(旧版)
CSHARP_7_3_OR_NEWER可用 C# 7.3 或更高版本
版本定义

格式:UNITY_X、UNITY_X_Y、UNITY_X_Y_Z、UNITY_X_Y_OR_NEWER

Unity 6000.0.33 示例:

  • UNITY_6000、UNITY_6000_0、UNITY_6000_0_33、UNITY_6000_0_OR_NEWER

移动平台优化

iOS

架构:仅支持 ARM64(不支持 ARMv7)。

脚本后端:iOS 必须使用 IL2CPP(不支持 Mono 选项)。

Player 设置(Edit > Project Settings > Player > iOS):

  • Bundle Identifier:com.CompanyName.ProductName
  • 签名 Team ID + 为 Xcode 启用自动签名
  • 可选择目标最低 iOS 版本
  • 用于调试着色器问题的 Metal API Validation
  • 在非默认方向下提升性能的 Metal Write-Only Backbuffer
  • 在 Metal 上强制使用硬阴影(通过点采样提升性能)
  • 方向:纵向、横向或自动旋转,并可设置允许的方向
  • 启动画面:默认、图像或自定义 Storyboard
  • 要求支持 ARKit 时,设备必须为 iPhone 6s 或更高版本,且系统为 iOS 11 或更高版本
Android

架构:ARMv7 和 ARM64(ARM64 必须使用 IL2CPP)。

Player 设置(Edit > Project Settings > Player > Android):

  • Package Name:com.YourCompanyName.YourProductName
  • 最低 API 级别和目标 API 级别
  • Graphics API:自动(优先 Vulkan,回退到 GLES)、Vulkan 或 OpenGL ES 3.x
  • 按目标架构拆分 APK,以减小 Google Play 上的下载体积
  • 用于签名的 Keystore 配置(生产环境使用自定义 keystore)
  • 脚本后端:Mono 或 IL2CPP
  • API 兼容性:.NET Framework 或 .NET Standard 2.1
  • 托管代码剥离级别:最低到高

主要差异:不同型号的 Android 设备在硬件能力上差异很大。请在多台设备上进行测试。

移动端优化技巧
  • 使用 ASTC 纹理压缩(现代 iOS 和 Android 设备均支持)
  • 通过批处理(静态和动态)尽量减少绘制调用
  • 使用 AssetBundles 或 Addressables 按需加载内容
  • 使用 Unity Profiler 和平台专用工具进行分析
  • 降低移动 GPU 上的着色器复杂度

WebGL 注意事项

内存管理
  • Unity 堆通过 WebAssembly Memory 实现(可调整大小的 ArrayBuffer)
  • 堆最多可扩展至 4 GB(Player 设置中的 Maximum Memory Size)
  • 资源数据从 .data 文件解包到虚拟内存文件系统(Emscripten)中
  • 垃圾回收器仅在每帧结束时运行(帧中不会进行回收)
  • 可用内存取决于设备、操作系统、浏览器(32/64 位)和标签页隔离模型
内存优化

在循环中使用 StringBuilder,而不是字符串拼接:

// BAD: Creates ~15 GB temporary allocations for 100k iterations
string hugeString = "";
for (int i = 0; i < 100000; i++)
    hugeString += "foo";

// GOOD: Pre-allocated StringBuilder
var sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
    sb.Append("foo");

使用 NativeArray<T> 进行临时分配,以绕过 GC:

using (var data = new NativeArray<byte>(size, Allocator.Temp))
{
    // Memory freed immediately upon scope exit
}

使用 AssetBundles 加载资源(直接下载到 Unity 堆中,不会额外占用浏览器分配的内存)。

启用 Data Caching(IndexedDB/Caching APIs)以减少重复下载。

JavaScript 互操作

Unity 支持两种 JavaScript 插件文件类型:

  • .jslib:定义可从 C# 代码调用的函数
  • .jspre:包含现有 JavaScript 库

限制:.jslib 和 .jspre 文件仅支持 ECMAScript 5(ES5)语法,暂不支持 ES6。

.jslib 插件示例
// Assets/Plugins/WebGL/MyPlugin.jslib
mergeInto(LibraryManager.library, {
    ShowAlert: function (message) {
        window.alert(UTF8ToString(message));
    },
});
C# 调用 JavaScript
using System.Runtime.InteropServices;
using UnityEngine;

public class WebGLBridge : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void ShowAlert(string message);

    void Start()
    {
        #if UNITY_WEBGL && !UNITY_EDITOR
        ShowAlert("Hello from Unity!");
        #endif
    }
}

IL2CPP 与 Mono

IL2CPP(中间语言转 C++)

IL2CPP 是 Unity 自定义的 AOT 脚本后端,可通过 C++ 将 C# 转换为原生代码。

转换流程:

  1. Roslyn 编译器将 C# 转换为 .NET 托管程序集(DLL)
  2. 托管代码裁剪可减小应用体积
  3. 将所有托管程序集转换为标准 C++ 代码
  4. C++ 编译器生成特定于平台的机器码
  5. 创建可执行文件、DLL、APK/AAB 或应用包

优点:

  • 与 Mono 相比,运行时性能更好
  • 应用启动时间更短
  • 支持所有平台
  • 支持与 Mono 完全相同的托管代码调试

缺点:

  • 构建时间比 Mono 长得多
  • 最终应用体积更大
  • 通常不支持交叉编译(必须在目标操作系统上构建)
  • 例外:支持从任意桌面平台交叉编译到 Linux

配置:

  • Player Settings:Edit > Project Settings > Player > Configuration > Scripting Backend
  • 脚本 API:PlayerSettings.SetScriptingBackend

构建速度优化:

  • 将项目文件夹从反恶意软件扫描中排除
  • 使用速度最快的可用存储设备
  • 选择“Optimize for code size and build time”(以运行时性能为代价)
  • 对兼容代码同时使用 Burst 编译器和 IL2CPP
Mono
  • 构建速度更快(JIT 编译)
  • 构建输出更小
  • 并非所有平台都支持(iOS 要求使用 IL2CPP)
  • 运行时性能不如 IL2CPP
如何选择
标准IL2CPPMono
iOS 构建必需不支持
Android 构建ARM64 推荐使用支持 ARMv7
构建迭代速度较慢较快
运行时性能更好良好
主机平台必需不支持
WebGL必需不支持

Addressables 概述

Addressable Asset System(com.unity.addressables v2.9.1)支持通过地址而非直接路径引用资源。

核心概念
  • 将任意资源标记为“addressable”,即可生成可从任何位置调用的唯一地址
  • 支持从本地或远程位置加载
  • 使用异步加载,并自动解析依赖项
  • 可替代直接引用、传统资源包和 Resources 文件夹
  • 访问路径:Window > Asset Management > Addressables
基本用法模式
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class AddressableLoader : MonoBehaviour
{
    [SerializeField] private AssetReference prefabRef;

    async void Start()
    {
        AsyncOperationHandle<GameObject> handle =
            Addressables.InstantiateAsync(prefabRef);
        await handle.Task;

        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            Debug.Log("Asset loaded successfully");
        }
    }

    void OnDestroy()
    {
        // Always release when done
        prefabRef.ReleaseAsset();
    }
}

常见模式

特定于平台的代码
public class PlatformManager : MonoBehaviour
{
    void Start()
    {
        #if UNITY_IOS
        Application.targetFrameRate = 60;
        #elif UNITY_ANDROID
        Application.targetFrameRate = 60;
        Screen.sleepTimeout = SleepTimeout.NeverSleep;
        #elif UNITY_WEBGL
        // WebGL runs at browser refresh rate
        #elif UNITY_STANDALONE
        Application.targetFrameRate = -1; // Uncapped
        #endif
    }
}
运行时平台检查
void ConfigureForPlatform()
{
    switch (Application.platform)
    {
        case RuntimePlatform.IPhonePlayer:
            SetupMobileControls();
            break;
        case RuntimePlatform.Android:
            SetupMobileControls();
            break;
        case RuntimePlatform.WebGLPlayer:
            SetupWebControls();
            break;
        default:
            SetupDesktopControls();
            break;
    }
}
构建配置脚本
#if DEVELOPMENT_BUILD
    Debug.Log("Development build active");
#endif

#if ENABLE_IL2CPP
    // IL2CPP-specific code
#elif ENABLE_MONO
    // Mono-specific code
#endif

反模式

  1. 什么都用 Resources 文件夹,而不使用 Addressables。Resources 文件夹会在启动时加载所有资源,增加内存占用和加载时间。

  2. 不使用平台定义,只依赖运行时检查。编译时定义可以将未使用的代码完全排除在构建之外。

  3. 在 WebGL 循环中进行字符串拼接。WebGL 中的 GC 只会在帧结束时运行,从而产生大量临时分配。请使用 StringBuilder 或 NativeArray<T>。

  4. 忽略 IL2CPP 的 AOT 限制。依赖反射的代码、System.Reflection.Emit 和运行时代码生成在 IL2CPP 下会失败。设计时应考虑 AOT。

  5. 启用 Development Build 后直接发布。开发构建包含 Profiler 开销和调试符号,会增大体积并降低性能。

  6. 未在 Android 上按架构拆分 APK。发布同时包含 ARMv7 和 ARM64 的单个大型 APK 会浪费用户流量。请使用 Split APKs 或 App Bundles。

  7. 硬编码平台路径。跨平台访问文件时,请使用 Application.persistentDataPath、Application.streamingAssetsPath 和 Application.temporaryCachePath。

  8. 未在实际设备上测试。Android 硬件差异很大。模拟器和仿真器无法体现真实的性能特征。

API 快速参考

API用途
Application.platform检测运行时平台
RuntimePlatform enum用于运行时检查的平台常量
SystemInfo.graphicsDeviceType当前图形 API(Vulkan、Metal 等)
SystemInfo.supportsComputeShaders检查是否支持计算着色器
PlayerSettings.SetScriptingBackend()通过脚本设置 IL2CPP 或 Mono
Addressables.InstantiateAsync()加载并实例化可寻址资源
Addressables.LoadAssetAsync<T>()加载可寻址资源,但不实例化
AssetReference对可寻址资源的可序列化引用
Application.targetFrameRate设置目标帧率
Screen.sleepTimeout防止移动设备屏幕变暗
Application.persistentDataPath平台安全的可写数据路径

相关技能

  • unity-graphics — 渲染管线、着色器和视觉效果
  • unity-packages-services — Package Manager 工作流和 Unity Gaming Services

其他资源

评论

支持 Markdown