Unity 多场景打包

文章讲述了在Unity中使用自定义脚本进行多场景打包的过程,包括修改包名、LOGO和版本号等设置,以及遇到的打包完成后GUI代码不执行的问题。作者提供了相关代码片段,并寻求解决打包错误的建议。
摘要由CSDN通过智能技术生成

Unity多场景打包,多场景组合打包,单独打包,序列化打包

废话不多说,直接粘代码,代码一

这段代码是展示你想要修改包名了,LOGO了,版本号了等等乱七八糟的。新手别搞了,对新手不友好,代码点击单独打包按钮打包完成后会报错,我没解决,但是不影响使用,有大佬可以帮忙解决一下错误,我感觉是程序打包完成之后后边的GUI代码就不运行了。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
/// <summary>
/// 打包任务
/// </summary>
[Serializable]
public sealed class BuildTask
{

    /// <summary>
    /// 默认图标
    /// </summary>
    public Texture2D DefaultIcon;
    /// <summary>
    /// 版本号
    /// </summary>
    public string Version;
    /// <summary>
    /// 包名,安卓平台用得到,Windows平台就可以直接注销了,相关连接的代码也都注销了即可
    /// </summary>
    public string PackageName;
    /// <summary>
    /// 名称
    /// </summary>
    public string ProductName;
    /// <summary>
    /// 目标平台
    /// </summary>
    public BuildTarget BuildTarget;
    /// <summary>
    /// 打包路径
    /// </summary>
    public string BuildPath;
    /// <summary>
    /// 打包场景
    /// </summary>
    public List<SceneAsset> SceneAssets = new List<SceneAsset>(0);
}
/// <summary>
/// 打包配置表
/// </summary>
[CreateAssetMenu(fileName = "New Build Profile", menuName = "Build Profile")]
public sealed class BuildProfile : ScriptableObject
{
    /// <summary>
    /// 打包任务列表
    /// </summary>
    public List<BuildTask> BuildTasks = new List<BuildTask>(0);
}

代码2

using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(BuildProfile))]
public sealed class BuildProfileInspector : Editor
{
    private readonly Dictionary<BuildTask, bool> foldoutMap = new Dictionary<BuildTask, bool>();
    private Vector2 scroll = Vector2.zero;
    private BuildProfile profile;
    private SerializedObject serializedProfile;
    private SerializedProperty buildTasksProperty;

    private void OnEnable()
    {
        profile = target as BuildProfile;
        serializedProfile = new SerializedObject(profile);
        buildTasksProperty = serializedProfile.FindProperty("BuildTasks");
        serializedProfile.Update();
    }
    public override void OnInspectorGUI()
    {
        GUILayout.BeginHorizontal();
        {
            if (GUILayout.Button("新建", "ButtonLeft"))
            {
                Undo.RecordObject(profile, "Create");
                var task = new BuildTask()
                {
                    //preferb = null,
                    ProductName = "Product Name",
                    Version = "1.0.0.0",
                    BuildTarget = BuildTarget.Android,
                    BuildPath = Directory.GetParent(Application.dataPath).FullName
                };
                profile.BuildTasks.Add(task);
            }
            if (GUILayout.Button("展开", "ButtonMid"))
            {
                for (int i = 0; i < profile.BuildTasks.Count; i++)
                {
                    foldoutMap[profile.BuildTasks[i]] = true;
                }
            }
            if (GUILayout.Button("收缩", "ButtonMid"))
            {
                for (int i = 0; i < profile.BuildTasks.Count; i++)
                {
                    foldoutMap[profile.BuildTasks[i]] = false;
                }
            }
            GUI.color = Color.yellow;
            if (GUILayout.Button("清空", "ButtonMid"))
            {
                Undo.RecordObject(profile, "Clear");
                if (EditorUtility.DisplayDialog("提醒", "是否确定清空列表?", "确定", "取消"))
                {
                    profile.BuildTasks.Clear();
                }
            }
            GUI.color = Color.cyan;
            if (GUILayout.Button("打包", "ButtonRight"))
            {
                if (EditorUtility.DisplayDialog("提醒", "打包需要耗费一定时间,是否确定开始?", "确定", "取消"))
                {
                    StringBuilder sb = new StringBuilder();
                    sb.Append("打包报告:\r\n");
                    for (int i = 0; i < profile.BuildTasks.Count; i++)
                    {
                        EditorUtility.DisplayProgressBar("Build", "Building...", i + 1 / profile.BuildTasks.Count);
                        var task = profile.BuildTasks[i];
                        List<EditorBuildSettingsScene> buildScenes = new List<EditorBuildSettingsScene>();
                        for (int j = 0; j < task.SceneAssets.Count; j++)
                        {
                            var scenePath = AssetDatabase.GetAssetPath(task.SceneAssets[j]);
                            if (!string.IsNullOrEmpty(scenePath))
                            {
                                buildScenes.Add(new EditorBuildSettingsScene(scenePath, true));
                            }
                        }
                        //profile.BuildTasks[i].preferb.GetComponent<LoadSceneByAssetBundle>().m_ABScenesSeriesFileName = profile.BuildTasks[i].ABScenesFileName;
                        //profile.BuildTasks[i].preferb.GetComponent<LoadSceneByAssetBundle>().m_ABFileName = profile.BuildTasks[i].ABSceneName;
                        //EditorUtility.SetDirty(profile.BuildTasks[i].preferb);
                        AssetDatabase.SaveAssets();
                        AssetDatabase.Refresh();

                        //PlayerSettings.productName = task.ProductName;
                        PlayerSettings.bundleVersion = task.Version;
                        AssetDatabase.SaveAssets();
                        string locationPathName = string.Empty;
                        // 动态设置应用标识和图标
                        BuildTargetGroup targetGroup = BuildPipeline.GetBuildTargetGroup(task.BuildTarget);
                        if (targetGroup != BuildTargetGroup.Unknown)
                        {
                            PlayerSettings.SetIconsForTargetGroup(targetGroup, new Texture2D[] { task.DefaultIcon });
                            //PlayerSettings.SetApplicationIdentifier(targetGroup, task.PackageName);
                        }
                        if (targetGroup == BuildTargetGroup.Android)
                        {
                            locationPathName = $"{task.BuildPath}/{task.ProductName}.apk"; // 指定输出文件为APK格式
                        }
                        else
                        {
                            locationPathName = $"{task.BuildPath}/{task.ProductName}.exe";
                        }
                        var report = BuildPipeline.BuildPlayer(buildScenes.ToArray(), locationPathName, task.BuildTarget, BuildOptions.None);
                        sb.Append($"[{task.ProductName}] 打包结果: {report.summary.result}\r\n");
                    }
                    EditorUtility.ClearProgressBar();
                    Debug.Log(sb.ToString());
                }
                return;
            }
            GUI.color = Color.white;
        }
        GUILayout.EndHorizontal();
        scroll = GUILayout.BeginScrollView(scroll);
        {
            for (int i = 0; i < profile.BuildTasks.Count; i++)
            {
                var task = profile.BuildTasks[i];
                if (!foldoutMap.ContainsKey(task)) foldoutMap.Add(task, true);
                GUILayout.BeginHorizontal("Badge");
                GUI.color = Color.green;
                GUILayout.Label($"#{i + 1}", GUILayout.Width(30));
                GUI.color = Color.white;
                GUILayout.Space(12);

                foldoutMap[task] = EditorGUILayout.Foldout(foldoutMap[task], $"{task.ProductName}", true);
                GUILayout.Label(string.Empty);
                if (GUILayout.Button(EditorGUIUtility.IconContent("TreeEditor.Trash"), "IconButton", GUILayout.Width(20)))
                {
                    Undo.RecordObject(profile, "Delete Task");
                    foldoutMap.Remove(task);
                    profile.BuildTasks.Remove(task);
                    break;
                }
                if (GUILayout.Button("↑", "MiniButtonLeft", GUILayout.Width(20)))
                {
                    MoveTaskUp(task);
                }
                if (GUILayout.Button("↓", "MiniButtonMid", GUILayout.Width(20)))
                {
                    MoveTaskDown(task);
                }
                if (GUILayout.Button("复制", "MiniButtonMid", GUILayout.Width(30)))
                {
                    CopyTask(task);
                }
                GUILayout.EndHorizontal();
                if (foldoutMap[task])
                {
                    GUILayout.BeginVertical("Box");
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("打包场景:", GUILayout.Width(70));
                    if (GUILayout.Button(EditorGUIUtility.IconContent("Toolbar Plus More"), GUILayout.Width(28)))
                    {
                        task.SceneAssets.Add(null);
                    }
                    GUILayout.EndHorizontal();
                    if (task.SceneAssets.Count > 0)
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Space(75);
                        GUILayout.BeginVertical("Badge");
                        for (int j = 0; j < task.SceneAssets.Count; j++)
                        {
                            var sceneAsset = task.SceneAssets[j];
                            GUILayout.BeginHorizontal();
                            GUILayout.Label($"{j + 1}.", GUILayout.Width(20));
                            task.SceneAssets[j] = EditorGUILayout.ObjectField(sceneAsset, typeof(SceneAsset), false) as SceneAsset;
                            if (GUILayout.Button("↑", "MiniButtonLeft", GUILayout.Width(20)))
                            {
                                if (j > 0)
                                {
                                    Undo.RecordObject(profile, "Move Up Scene Assets");
                                    var temp = task.SceneAssets[j - 1];
                                    task.SceneAssets[j - 1] = sceneAsset;
                                    task.SceneAssets[j] = temp;
                                }
                            }
                            if (GUILayout.Button("↓", "MiniButtonMid", GUILayout.Width(20)))
                            {
                                if (j < task.SceneAssets.Count - 1)
                                {
                                    Undo.RecordObject(profile, "Move Down Scene Assets");
                                    var temp = task.SceneAssets[j + 1];
                                    task.SceneAssets[j + 1] = sceneAsset;
                                    task.SceneAssets[j] = temp;
                                }
                            }
                            if (GUILayout.Button(EditorGUIUtility.IconContent("Toolbar Plus"), "MiniButtonMid", GUILayout.Width(20)))
                            {
                                Undo.RecordObject(profile, "Add Scene Assets");
                                task.SceneAssets.Insert(j + 1, null);
                                break;
                            }
                            if (GUILayout.Button(EditorGUIUtility.IconContent("Toolbar Minus"), "MiniButtonMid", GUILayout.Width(20)))
                            {
                                Undo.RecordObject(profile, "Delete Scene Assets");
                                task.SceneAssets.RemoveAt(j);
                                break;
                            }
                            GUILayout.EndHorizontal();
                        }
                        GUILayout.EndVertical();
                        GUILayout.EndHorizontal();
                    }
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("产品名称:", GUILayout.Width(70));
                    var newPN = GUILayout.TextField(task.ProductName);
                    if (task.ProductName != newPN)
                    {
                        Undo.RecordObject(profile, "Product Name");
                        task.ProductName = newPN;
                        serializedProfile.ApplyModifiedProperties(); // 应用修改
                    }
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("打包平台:", GUILayout.Width(70));
                    var newBT = (BuildTarget)EditorGUILayout.EnumPopup(task.BuildTarget);
                    if (task.BuildTarget != newBT)
                    {
                        Undo.RecordObject(profile, "Build Target");
                        task.BuildTarget = newBT;
                    }
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("打包路径:", GUILayout.Width(70));
                    GUILayout.TextField(task.BuildPath);
                    if (GUILayout.Button("Browse", GUILayout.Width(60)))
                    {
                        task.BuildPath = EditorUtility.SaveFolderPanel("Build Path", task.BuildPath, "");
                    }
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("默认图标:", GUILayout.Width(70));
                    var newIcon = (Texture2D)EditorGUILayout.ObjectField(task.DefaultIcon, typeof(Texture2D), false);
                    if (task.DefaultIcon != newIcon)
                    {
                        Undo.RecordObject(profile, "Default Icon");
                        task.DefaultIcon = newIcon;
                        serializedProfile.ApplyModifiedProperties(); // 应用修改
                    }
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("版本号:", GUILayout.Width(70));
                    var newVersion = GUILayout.TextField(task.Version);
                    if (task.Version != newVersion)
                    {
                        Undo.RecordObject(profile, "Version");
                        task.Version = newVersion;
                        serializedProfile.ApplyModifiedProperties(); // 应用修改
                    }
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("包名:", GUILayout.Width(70));
                    var newPackageName = GUILayout.TextField(task.PackageName);
                    if (task.PackageName != newPackageName)
                    {
                        Undo.RecordObject(profile, "Package Name");
                        task.PackageName = newPackageName;
                        serializedProfile.ApplyModifiedProperties(); // 应用修改
                    }
                    GUILayout.EndHorizontal();
                    /* GUILayout.BeginHorizontal();
                     GUILayout.Label("需要修改的预制体:", GUILayout.Width(70));
                     var newpreferb = (GameObject)EditorGUILayout.ObjectField(task.preferb, typeof(GameObject), false);
                     if (task.preferb != newpreferb)
                     {
                         Undo.RecordObject(profile, "Default preferb");
                         task.preferb = newpreferb;
                         serializedProfile.ApplyModifiedProperties(); // 应用修改
                     }
                     GUILayout.EndHorizontal();
                     GUILayout.BeginHorizontal();
                     GUILayout.Label("文件名:", GUILayout.Width(70));
                     var ABScenesFileName = GUILayout.TextField(task.ABScenesFileName);
                     if (task.ABScenesFileName != ABScenesFileName)
                     {
                         Undo.RecordObject(profile, "ABScenesFileName");
                         task.ABScenesFileName = ABScenesFileName;
                         serializedProfile.ApplyModifiedProperties(); // 应用修改
                     }
                     GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                     GUILayout.Label("AB场景名:", GUILayout.Width(70));
                     var newABSceneName = GUILayout.TextField(task.ABSceneName);
                     if (task.ABSceneName != newABSceneName)
                     {
                         Undo.RecordObject(profile, "ABSceneName");
                         task.ABSceneName = newABSceneName;
                         serializedProfile.ApplyModifiedProperties(); // 应用修改
                     }
                     GUILayout.EndHorizontal();*/
                    GUILayout.BeginHorizontal();
                    GUILayout.FlexibleSpace(); // 灵活空间使按钮居中
                    GUI.color = Color.green;
                    if (GUILayout.Button("打包", GUILayout.Width(100)))
                    {
                        Pack(task);
                    }
                    GUI.color = Color.white;
                    GUILayout.FlexibleSpace();
                    GUILayout.EndHorizontal();
                    GUILayout.EndVertical();
                }
            }
        }
        GUILayout.EndScrollView();
        serializedObject.ApplyModifiedProperties();
        if (GUI.changed) EditorUtility.SetDirty(profile);
    }
    private void Pack(BuildTask task)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("打包报告:\r\n");

        List<EditorBuildSettingsScene> buildScenes = new List<EditorBuildSettingsScene>();
        foreach (var sceneAsset in task.SceneAssets)
        {
            var scenePath = AssetDatabase.GetAssetPath(sceneAsset);
            if (!string.IsNullOrEmpty(scenePath))
            {
                buildScenes.Add(new EditorBuildSettingsScene(scenePath, true));
            }
        }

        PlayerSettings.productName = task.ProductName;
        PlayerSettings.bundleVersion = task.Version;
        AssetDatabase.SaveAssets();
        string locationPathName = string.Empty;
        // 动态设置应用标识和图标
        BuildTargetGroup targetGroup = BuildPipeline.GetBuildTargetGroup(task.BuildTarget);
        if (targetGroup != BuildTargetGroup.Unknown)
        {
            if (task.DefaultIcon != null)
            {
                PlayerSettings.SetIconsForTargetGroup(targetGroup, new Texture2D[] { task.DefaultIcon });
            }

            PlayerSettings.SetApplicationIdentifier(targetGroup, task.PackageName);
        }
        if (targetGroup == BuildTargetGroup.Android)
        {
            locationPathName = $"{task.BuildPath}/{task.ProductName}.apk"; // 指定输出文件为APK格式
        }
        else
        {
            locationPathName = $"{task.BuildPath}/{task.ProductName}.exe";
        }
        var report = BuildPipeline.BuildPlayer(buildScenes.ToArray(), locationPathName, task.BuildTarget, BuildOptions.None);
        sb.Append($"[{task.ProductName}] 打包结果: {report.summary.result}\r\n");

        Debug.Log(sb.ToString());
    }
    private void MoveTaskUp(BuildTask task)
    {
        int index = profile.BuildTasks.IndexOf(task);
        if (index > 0)
        {
            Undo.RecordObject(profile, "Move Task Up");
            profile.BuildTasks.RemoveAt(index);
            profile.BuildTasks.Insert(index - 1, task);
        }
    }

    private void MoveTaskDown(BuildTask task)
    {
        int index = profile.BuildTasks.IndexOf(task);
        if (index < profile.BuildTasks.Count - 1)
        {
            Undo.RecordObject(profile, "Move Task Down");
            profile.BuildTasks.RemoveAt(index);
            profile.BuildTasks.Insert(index + 1, task);
        }
    }

    private void CopyTask(BuildTask task)
    {
        Undo.RecordObject(profile, "Copy Task");
        var copy = new BuildTask
        {
            ProductName = task.ProductName,
            Version = task.Version,
            BuildTarget = task.BuildTarget,
            BuildPath = task.BuildPath,
            SceneAssets = new List<SceneAsset>(task.SceneAssets),
            DefaultIcon = task.DefaultIcon,
            PackageName = task.PackageName
        };
        profile.BuildTasks.Add(copy);
    }
}

创建ScriptableObject

在这里插入图片描述
就点击它,就创建出来了
创建出来的这个长这样
在这里插入图片描述

有问题私聊,看到了就回复,看不到就抱歉了

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高达打架用铁锹

谢谢老板赏饭

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值