You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity如何通过脚本将运行时GameObject发送至其他编辑器生成AssetBundle?

实现方法

要实现点击应用内按钮将GameObject传递到另一个Unity编辑器并生成AssetBundle,核心思路是序列化GameObject数据→通过命令行参数传递给BatchMode启动的Unity→在编辑器中重建对象并打包,具体步骤如下:

1. 运行时:序列化GameObject并启动BatchMode进程

在你的运行时项目中,给按钮绑定点击事件,将目标GameObject的关键数据序列化为临时文件,然后通过命令行启动另一个Unity编辑器的BatchMode实例,传递临时文件路径和AssetBundle输出路径。

示例代码:

using UnityEngine;
using System.IO;
using System.Diagnostics;

public class ExportToAssetBundle : MonoBehaviour
{
    public GameObject targetGameObject; // 要导出的目标对象
    public string unityEditorPath = @"C:\Program Files\Unity\Hub\Editor\2022.3.1f1\Editor\Unity.exe";
    public string assetBundleOutputPath = @"D:\MyAssetBundles\my_bundle";

    public void OnExportButtonClick()
    {
        // 1. 序列化GameObject数据到临时JSON文件
        string tempJsonPath = Path.Combine(Application.temporaryCachePath, "exported_obj_data.json");
        ObjectExportData exportData = new ObjectExportData(targetGameObject);
        string jsonData = JsonUtility.ToJson(exportData);
        File.WriteAllText(tempJsonPath, jsonData);

        // 2. 构造BatchMode命令行参数
        // -batchmode: 后台运行Unity
        // -quit: 任务完成后自动退出
        // -executeMethod: 指定要执行的静态方法
        string commandArgs = $"-batchmode -quit -executeMethod AssetBundleBuilder.BuildFromExportData \"{tempJsonPath}\" \"{assetBundleOutputPath}\"";

        // 3. 启动Unity编辑器进程
        Process.Start(new ProcessStartInfo(unityEditorPath, commandArgs)
        {
            UseShellExecute = false,
            RedirectStandardOutput = true,
            CreateNoWindow = true
        });
    }
}

// 自定义序列化类,存储GameObject的必要信息(按需扩展)
[System.Serializable]
public class ObjectExportData
{
    public Vector3 position;
    public Quaternion rotation;
    public Vector3 localScale;
    public string prefabResourcePath; // 如果对象基于预制体,存储预制体在编辑器项目中的路径

    public ObjectExportData(GameObject obj)
    {
        position = obj.transform.position;
        rotation = obj.transform.rotation;
        localScale = obj.transform.localScale;
        // 这里可以扩展存储组件、材质引用等信息,比如Mesh数据、材质路径等
    }
}

2. 编辑器端:实现BatchMode执行的打包逻辑

在用于生成AssetBundle的Unity编辑器项目中,创建一个静态工具类,实现从临时文件读取数据、重建GameObject、生成AssetBundle的逻辑。

示例代码:

using UnityEditor;
using UnityEngine;
using System.IO;

public static class AssetBundleBuilder
{
    // 这个方法会被BatchMode调用,参数来自命令行
    public static void BuildFromExportData(string inputJsonPath, string outputPath)
    {
        // 1. 读取并反序列化数据
        string jsonContent = File.ReadAllText(inputJsonPath);
        ObjectExportData exportData = JsonUtility.FromJson<ObjectExportData>(jsonContent);

        // 2. 重建GameObject
        GameObject targetObj;
        if (!string.IsNullOrEmpty(exportData.prefabResourcePath))
        {
            // 如果是基于预制体,直接加载并实例化
            targetObj = AssetDatabase.LoadAssetAtPath<GameObject>(exportData.prefabResourcePath);
            targetObj = Object.Instantiate(targetObj);
        }
        else
        {
            // 动态创建对象并设置属性
            targetObj = new GameObject("Exported_Object");
            targetObj.transform.position = exportData.position;
            targetObj.transform.rotation = exportData.rotation;
            targetObj.transform.localScale = exportData.localScale;
            // 按需添加组件、设置材质等,比如读取序列化的Mesh数据添加MeshFilter
        }

        // 3. 将对象保存为预制体(AssetBundle需要基于AssetDatabase中的资源)
        string tempAssetDir = "Assets/TempExportAssets";
        if (!Directory.Exists(tempAssetDir))
        {
            Directory.CreateDirectory(tempAssetDir);
        }
        string tempPrefabPath = Path.Combine(tempAssetDir, "ExportedPrefab.prefab");
        PrefabUtility.SaveAsPrefabAsset(targetObj, tempPrefabPath);

        // 4. 刷新AssetDatabase并设置AssetBundle标签
        AssetDatabase.Refresh();
        AssetImporter importer = AssetImporter.GetAtPath(tempPrefabPath);
        importer.SetAssetBundleNameAndVariant("custom_bundle", "");

        // 5. 构建AssetBundle
        BuildPipeline.BuildAssetBundles(Path.GetDirectoryName(outputPath),
            BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);

        // 6. 清理临时文件
        AssetDatabase.DeleteAsset(tempAssetDir);
        File.Delete(inputJsonPath);

        // 退出编辑器
        EditorApplication.Exit(0);
    }
}

// 注意:这个类要和运行时的ObjectExportData完全一致
[System.Serializable]
public class ObjectExportData
{
    public Vector3 position;
    public Quaternion rotation;
    public Vector3 localScale;
    public string prefabResourcePath;
}

3. 关键注意事项

  • 序列化一致性:运行时和编辑器项目中的ObjectExportData类定义必须完全相同,否则会出现反序列化失败。
  • 资源依赖:如果GameObject包含自定义脚本、材质、纹理等资源,编辑器项目中必须存在这些资源,或者在序列化时存储资源的GUID/相对路径,确保编辑器能正确加载。
  • 路径配置:Unity编辑器的路径要根据你的安装版本和系统调整(Mac系统路径类似/Applications/Unity/Hub/Editor/2022.3.1f1/Unity.app/Contents/MacOS/Unity)。
  • 权限问题:确保运行时应用有写入临时目录的权限,编辑器进程有写入AssetBundle输出路径的权限。
  • 扩展序列化逻辑:如果需要导出复杂对象,比如带动画、粒子系统的GameObject,需要扩展ObjectExportData,序列化更多组件数据,在编辑器端重建对应组件。

内容的提问来源于stack exchange,提问作者zakilman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 16:52:09