unity多渠道打包

这里写自定义目录标题

unity多渠道打包工具

最近公司叫我写一个unity多渠道打包的工具,方便他们使用,因为要每个渠道配置不太一样,只能用代码来写方便使用。
1.
#这是我的渠道配置文件build.json
在这里插入图片描述

2.然后还要去相应的渠道下载那些SDK回来,像googleplay sdk,直接百度搜就有一大把的,再导入项目。
3.在unity创建Editor文件,再新建一个脚本MyEditor
在这里插入图片描述
4.MyEditor脚本

using UnityEditor;
using System.Collections;
using UnityEngine;
using System.IO;
using Newtonsoft.Json;
using System.Collections.Generic;

public class MyEditor
{
    //得到项目所有场景名称
    static string[] scenesNameArr = FindEnabledEditorScenes();

    static string[] secnesName;

    //googleplay打包
    [MenuItem("多渠道打包/Build Android googleplay")]
    static void BuildAndroidKGp()
    {
        BulidTarget("googleplay", "Android");
    }

    //huwei打包
    [MenuItem("多渠道打包/Build Android huwei")]
    static void BuildAndroidHuwei()
    {
        BulidTarget("huwei", "Android");
    }

    //批量打包apk包
    [MenuItem("多渠道打包/Build ALL Android")]
    static void BuildAllAndroid()
    {
        BulidTarget("googleplay", "Android");
        BulidTarget("huwei", "Android");
    }

    //苹果Xcode工程打包
    [MenuItem("多渠道打包/Build iPhone XcodeProj")]
    static void PerformiPhoneQQBuild()
    {
        BulidTarget("XcodeProj", "IOS");
    }


    //这里封装了一个简单的通用方法。
    static void BulidTarget(string channel, string target)
    {
        for (int i = 0; i < scenesNameArr.Length; i++)
        {
            if (scenesNameArr[i] == "Main")
            {
                secnesName[0] = scenesNameArr[i];
            }
        }
        string app_name = channel + "_" + Application.companyName;
        string outTarget_dir = Application.dataPath + "/OutAndroid";
        string target_name = app_name + ".apk";
        BuildTargetGroup targetGroup = BuildTargetGroup.Android;
        BuildTarget buildTarget = BuildTarget.Android;


        string applicationPath = Application.dataPath.Replace("/Assets", "");


        if (target == "Android")
        {
            outTarget_dir = applicationPath + "/OutAndroid";
            target_name = app_name + ".apk";
            targetGroup = BuildTargetGroup.Android;
        }
        if (target == "IOS")
        {
            outTarget_dir = applicationPath + "/OutIOS";
            target_name = app_name;
            targetGroup = BuildTargetGroup.iOS;
            buildTarget = BuildTarget.iOS;
        }

        //每次build之前删除的文件
        if (Directory.Exists(outTarget_dir))
        {
            if (File.Exists(target_name))
            {
                File.Delete(target_name);
            }
            Debug.Log("=exists="+outTarget_dir);
        }
        else
        {
            Directory.CreateDirectory(outTarget_dir);
            Debug.Log("=noexists="+outTarget_dir);
        }
        //build.json是存放不同渠道的数据配置
        FileStream StreamFile = new FileStream(Application.dataPath + "/Resources/build.json", FileMode.Open);
        StreamReader StreamReader = new StreamReader(StreamFile);
        string data = StreamReader.ReadToEnd();
        BuildData bd= JsonConvert.DeserializeObject<BuildData>(data);
        //记得关闭,要不然有可能打包第2次会出现资源占用问题
        StreamFile.Close();
        StreamReader.Close();
        Debug.Log(bd.path+"===="+channel);
        //==================这里我是要读到相应的数据,然后再设置打包apk的bundleID以及对应相应代码=======================
        foreach (var item in bd.channels)
        {
            if (channel==item.channel)
            {
                Debug.Log("=="+channel);
                PlayerSettings.applicationIdentifier = item.packagename;
                PlayerSettings.bundleVersion = item.version;
                PlayerSettings.Android.bundleVersionCode = item.code;
                string[] art = item.architectures.Split(',');
                if (art.Length>0)
                {
                    for (int i = 0; i < art.Length; i++)
                    {
                        PlayerSettings.Android.targetArchitectures =(AndroidArchitecture)int.Parse(art[i]);
                    }
                }
                PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup, item.script_define);
                PlayerSettings.Android.keystoreName = item.keystore;
                PlayerSettings.Android.keyaliasPass = item.pw;
                PlayerSettings.Android.keystorePass = item.pw;
                PlayerSettings.keystorePass = item.pw;
                break;
            }
        }
        CommonBuild(scenesNameArr, outTarget_dir + "/" + target_name, targetGroup, buildTarget, BuildOptions.None);
    }

    static string[] FindEnabledEditorScenes()
    {
        List<string> EditorScenes = new List<string>();
        foreach (EditorBuildSettingsScene scene in EditorBuildSettings.scenes)
        {
            if (!scene.enabled) continue;
            EditorScenes.Add(scene.path);
        }
        return EditorScenes.ToArray();
    }

    static void CommonBuild(string[] scenes, string dir,BuildTargetGroup buildTargetGroup, BuildTarget build_target, BuildOptions build_options)
    {
        EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup,build_target);
        BuildPipeline.BuildPlayer(scenes, dir, build_target, build_options);
    }

}

5.然后返回unity点击多渠道打包,Build Android googleplay就完成了
在这里插入图片描述
简单吧,收工罗!第一次写有什么不懂可以留言我改进,谢谢!

### Unity多渠道打包版本控制方案 在Unity项目中实现多渠道打包并进行有效的版本管理是一个复杂的过程,涉及多个方面的技术细节。以下是基于提供的参考资料以及专业知识整理的一个完整的解决方案。 #### 1. 配置管理 为了支持不同渠道的需求,可以采用JSON或其他轻量级数据格式作为配置文件存储各渠道的信息。例如: ```json { "channels": [ { "name": "ChannelA", "applicationName": "App_A", "iconPath": "Assets/Icons/channel_a.png", "packageName": "com.example.channela", "keystorePath": "Assets/Keystores/channel_a.keystore" }, { "name": "ChannelB", "applicationName": "App_B", "iconPath": "Assets/Icons/channel_b.png", "packageName": "com.example.channelb", "keystorePath": "Assets/Keystores/channel_b.keystore" } ] } ``` 此配置文件定义了每个渠道的应用名称、图标路径、包名和签名密钥位置[^4]。 #### 2. 插件动态加载机制 为了避免重复接入不同的SDK,可以通过插件化的方式实现解耦。具体做法如下: - 将所有第三方SDK放置于`Assets/Plugins/Android`目录下的子文件夹中。 - 使用脚本根据当前构建的渠道自动复制所需的插件到目标目录。这一步骤可以在自定义的Editor脚本中完成。 示例代码展示如何根据不同渠道加载对应的插件: ```csharp using UnityEditor; using System.IO; public class MultiChannelBuildTool : MonoBehaviour { public static void BuildForChannel(string channelName) { string configFilePath = Path.Combine(Application.dataPath, "build.json"); var buildConfig = JsonUtility.FromJson<BuildConfiguration>(File.ReadAllText(configFilePath)); foreach (var channel in buildConfig.channels) { if (channel.name.Equals(channelName)) { CopyPluginFiles(channel); PlayerSettings.applicationIdentifier = channel.packageName; PlayerSettings.productName = channel.applicationName; // 更改ICON逻辑省略 break; } } EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTarget.Android); BuildPipeline.BuildPlayer(GetAllScenes(), GetOutputPath(channelName), BuildTarget.Android, BuildOptions.None); } private static void CopyPluginFiles(ChannelInfo channel) { string sourceDir = Path.Combine(Application.dataPath, $"Plugins/{channel.name}"); string targetDir = Path.Combine(Application.dataPath, "Plugins/Android"); if (Directory.Exists(targetDir)) Directory.Delete(targetDir, true); Directory.CreateDirectory(targetDir); FileUtil.CopyFolder(sourceDir, targetDir); } } [System.Serializable] public class ChannelInfo { public string name; public string applicationName; public string iconPath; public string packageName; public string keystorePath; } [System.Serializable] public class BuildConfiguration { public ChannelInfo[] channels; } ``` 上述代码片段展示了如何读取配置文件,并依据特定渠道调整项目的设置[^5]。 #### 3. 自动化流程集成 利用CI/CD工具(如Jenkins或GitLab CI),配合上述脚本实现自动化构建过程。这样不仅可以减少人为错误,还能显著提升开发效率。 #### 4. 解决常见问题 针对提到的不同功能模块之间的差异性(比如广告与支付系统的区别),建议引入接口层设计模式,在运行时决定调用哪个具体的实现类[^3]。 --- ### 总结 综上所述,通过合理规划资源配置方式、运用灵活高效的插件管理系统以及完善的持续交付体系,能够在Unity环境中成功实施一套稳健可靠的多渠道打包策略。
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值