专栏首页游戏开发之旅Unity使用AssetImporter整理资源对其进行打包

Unity使用AssetImporter整理资源对其进行打包

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/CJB_King/article/details/102669979

AssetImporter概述

AssetImporter.GetAtPath获取路径资源 static function GetAtPath (path : string) : AssetImporter

Description描述

Retrieves the asset importer for the asset at path.

通过资源路径 ,导入器重新获取资源。 简单的说,通过指定路径来导入资源。

该方法返回的是AssetImporter对象,我们通常给该对象的assetBundleName赋值为要打包的资源路径名称,这个操作实际上相当于在Unity编辑器Inspector页面中手动添加是一样的。

打包思路

这里我把要打包的所有资源统一放在同一个Res文件夹下面,Res中不同的资源类型,不同的加载时间的资源新建文件夹,按照文件夹分类(如:把通用的资源放在同一个文件夹下,UI统一放入一个文件夹,material建一个文件夹),打包时在打包配置里指定要打包的资源路径,打包类型(这里类型指的是:1.整个文件夹打一个包,2.将文件夹下单个资源都对应一个ab包)

具体实现

资源配置

[System.Serializable]
public class PackageItem
{
    public enum PackType {File,DirFiles,Dir}
    public PackType type;
    public string path;
    public string searchPattern = "*.*";
    public SearchOption searchOption;
}

效果如下:

资源配置的信息

[System.Serializable]
public class PackageConfig : ScriptableObject {

    private static PackageConfig _instance;
    public  static PackageConfig instance
    {
        get
        {
            _instance = AssetDatabase.LoadAssetAtPath<PackageConfig>("Assets/Tools/Editor/PackConf.asset");
            if(_instance==null)
            {
                _instance = ScriptableObject.CreateInstance<PackageConfig>();
                AssetDatabase.CreateAsset(_instance, "Assets/Tools/Editor/PackConf.asset");
            }

            return _instance;
        }
    }

    //版本号
    [SerializeField]
    private string _version = "1.0";
    public static string version { get { return instance._version; } }

    //游戏名称
    [SerializeField]
    private string _appName = "Test";
    public static string appName { get { return instance._appName; } }


    //游戏发布的目录
    [SerializeField]
    private string _publishDir = "publish/";
    public static string publishDir { get { return instance._publishDir; } }

    //游戏web发布目录
    [SerializeField]
    private string _webPublishUrl = "http://192.168.1.27/publish/";
    public static string webPulishUrl { get { return instance._webPublishUrl; } }

    // 是否使用jit
    [SerializeField]
    private bool _luaJit = true;
    public  bool luaJit { get { return instance._luaJit; } }

    // debugBuild
    [SerializeField]
    private bool _debugBuild = true;
    public static bool debugBuild { get { return instance._debugBuild; } }

    // 自动开启
    [SerializeField]
    private bool _autoRunPlayer = false;
    public static bool autoRunPlayer { get { return instance._autoRunPlayer; } }

    [SerializeField]
    private List<PackageItem> _packItems = new List<PackageItem>();
    public  List<PackageItem> packItems { get { return instance._packItems; } }

    public static BuildOptions buildOptions
    {
        get
        {
            if(debugBuild)
            {
                BuildOptions op = BuildOptions.AllowDebugging | BuildOptions.ConnectWithProfiler | BuildOptions.Development;
                if(autoRunPlayer)
                {
                    return op | BuildOptions.AutoRunPlayer;
                }
                return op;
            }
            else
            {
                return BuildOptions.None;
            }
        }
    }
   
}

调用生成

        // 各种配置文件
        [MenuItem("BuildTool/依赖打包方式/发布设定")]
        public static void open()
        {
            Selection.activeObject = PackageConfig.instance;
        }

打包

打包分类

按照单个文件打包

直接指定文件所在路径

    //文件打包
    public bool PackFile(string res)
    {
        AssetImporter importer = AssetImporter.GetAtPath(res);
        if (importer == null)
        {
            Debug.LogError("Path not Exist!" + res);
            return false;
        }
        importer.assetBundleName = res + abExtens;
        return true;
    }

指定资源所在的文件夹路径,查找文件夹下的所有文件,每个文件单独一个AB包

    //打包目录中所有资源
    public bool PackDirFiles(string res,string pattern,SearchOption searchOption)
    {
        string[] files = GetDirFiles(res,pattern,searchOption);
        if (files.Length == 0) return false;
        foreach(var file in files)
        {
            PackFile(file);
        }
        return true;
    }

按照文件夹打包

    //目录打包
    public bool PackDir(string res,string pattern,SearchOption searchOption)
    {
        string[] files = GetDirFiles(res, pattern, searchOption);
        if (files.Length == 0) return false;
        string fn = res.Trim('/') + abDirExtens;

        foreach(var file in files)
        {
            AssetImporter impoter = AssetImporter.GetAtPath(file);
            impoter.assetBundleName = fn;
        }
        return true;
    }
    //打包目录中所有资源
    public bool PackDirDir(string res,string pattern)
    {
        string[] Dirs = Directory.GetDirectories(res);
        if (Dirs.Length == 0) return false;
        foreach(var d in Dirs)
        {
            PackDir(d.Replace('\\', '/'), pattern, SearchOption.AllDirectories);
        }
        return true;
    }

打包Lua文件(特别的)

如果Lua需要使用Jit进行编译

    //编译Lua到固定目录
    public void CompileLuaJit(string []src,string[]dst)
    {
        Debug.Log("Start CompileLuaJit");

#if !UNITY_EDITOR_OSX
        string workDir = Application.dataPath + "/../jit/";
        Dictionary<BUILDLUATYPE, string> build = new Dictionary<BUILDLUATYPE, string>()
        {
            { BUILDLUATYPE.WIN32,Application.dataPath+"/../jit/win/x86/luajit.exe"},
            { BUILDLUATYPE.WIN64,Application.dataPath+"/../jit/win/x64/luajit.exe"},
            { BUILDLUATYPE.GC64,Application.dataPath+"/../jit/win/gc64/luajit.exe"},
        };
        string exePath = build[buildLuaDict[_target]];
        System.Diagnostics.Process[] psList = new System.Diagnostics.Process[src.Length];
#endif
        for(int i=0;i<src.Length;i++)
        {
            string srcLua = Application.dataPath + "/../" + src[i];
            string dstLua = Application.dataPath + "/../" + dst[i];
            string cmd = " -b " + srcLua + " " + dstLua;

            psList[i] = ProcessHelper.StartProcess(exePath,cmd,workDir);

        }

#if !UNITY_EDITOR_OSX
        foreach(var ps in psList)
        {
            if(ps!=null&&!ps.HasExited)
            {
                ps.WaitForExit();
            }
        }
#endif
    }

编译的过程需要使用Process调起进程exe执行编译指令

public class ProcessHelper {

    public static Process StartProcess(string command,string parm,string workDir="")
    {
        return StartProcess(command, parm, workDir, DataReceived, ErrorReceived);
    }
    public static Process StartProcess(string command, string parm, string workDir, DataReceivedEventHandler dataReceived, DataReceivedEventHandler errorReceive)
    {
        Process ps = new Process()
        {
            StartInfo =
            {
                FileName=command,
                Arguments=parm,
                CreateNoWindow=true,
                UseShellExecute=false,
                RedirectStandardOutput=true,
                RedirectStandardError=true,
                WorkingDirectory=workDir
            }
        };
        ps.OutputDataReceived += DataReceived;
        ps.ErrorDataReceived += ErrorReceived;
        ps.Start();
        ps.BeginOutputReadLine();
        ps.BeginErrorReadLine();
        return ps;
    }
    
    private static void DataReceived(object sender,DataReceivedEventArgs eventArgs)
    {
        if (null != eventArgs.Data) UnityEngine.Debug.Log(eventArgs.Data);
    }
    private static void ErrorReceived(object sender,DataReceivedEventArgs eventArgs)
    {
        if(null !=eventArgs.Data) UnityEngine.Debug.Log(eventArgs.Data);
    }
}

打包lua到 "Assets/Res/Lua/"路径下

    //打包Lua目录
    public bool PackLuaDir(string res,bool useJit=true)
    {
        string fixLuaDIr = "Assets/Res/Lua/";
        AssetDatabase.DeleteAsset(fixLuaDIr);
        var files = Directory.GetFiles(res, "*.lua", SearchOption.AllDirectories);
        var dests = new string[files.Length];

        for(int i=0;i<files.Length;i++)
        {
            string file = files[i].Replace('\\', '/');
            string dst = "Assets/Res/" + file;
            string dstName = dst.Substring(0, dst.Length - 3) + "bytes"; //lua后缀改为bytes后缀

            string destDir = Path.GetDirectoryName(dstName);

            if(!Directory.Exists(destDir))
            {
                Directory.CreateDirectory(destDir);
            }
            files[i] = file;
            dests[i] = dstName;
        }
        if(useJit)
        {
            CompileLuaJit(files,dests);
        }
        else
        {
            CompileLua(files,dests);
        }
        AssetDatabase.Refresh();

        PackDir(fixLuaDIr,"*.bytes",SearchOption.AllDirectories);
        return true;
    }

使用打包方法进行打包

    public AssetBundleManifest BuildAllAssetRes()
    {
        if (!Directory.Exists(_targetDir)) Directory.CreateDirectory(_targetDir);
        return BuildPipeline.BuildAssetBundles(_targetDir, BuildAssetBundleOptions.None, _target);
    }

打包调用

   static void BuildAllResources(BuildTarget buildTarget)
        {
            Package pack = new Package(buildTarget);
            try { Directory.Delete(pack.targetDir, true); } catch(Exception c) { UnityEngine.Debug.LogError(c.Message); }

            foreach(var item in PackageConfig.instance.packItems)
            {
                if(item.type== PackageItem.PackType.File)
                {
                    pack.PackFile(item.path);
                }else if(item.type==PackageItem.PackType.DirFiles)
                {
                    pack.PackDirFiles(item.path,item.searchPattern,item.searchOption);
                }else if(item.type==PackageItem.PackType.Dir)
                {
                    pack.PackDir(item.path,item.searchPattern,item.searchOption);
                }
            }
            pack.PackLuaDir("lua/", PackageConfig.instance.luaJit);
            AssetBundleManifest manifest = pack.BuildAllAssetRes();


        }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 我使用的Unity开发多语言处理方案

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    bering
  • Unity打iOS包之xcodeapi的使用

    https://bitbucket.org/Unity-Technologies/xcodeapi

    bering
  • 封装Unity的网络请求中常用功能

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    bering
  • 让web api 4.5支持Jquery.getJson(url,handle)跨域访问

    代码片段,google了半天,找到的都是4.5 rc,或之前版本的代码,发现都不能用,正式版后有些方法做了修改。我重新修改一下分享给大家 public stat...

    阿新
  • +从零实现一款12306刷票软件1.3

    12306的图片验证码一般由八个图片组成,像上面的“龙舟”文字,也是图片,这两处的图片(文字图片和验证码)都是在服务器上拼装后,发给客户端的,12306服务器上...

    范蠡
  • 原 利用Appdomain动态加载程序集,

    魂祭心
  • dotNET Core 3.X 使用 Web API

    现在的 Web 开发大多都是前后端分离的方式,后端接口的正确使用显得尤为重要,本文讲下在 dotNET Core 3.X 下使用 Web API 。

    oec2003
  • [ASP.NET Core 3框架揭秘] 配置[6]:多样化的配置源[上篇]

    .NET Core采用的这个全新的配置模型的一个主要的特点就是对多种不同配置源的支持。我们可以将内存变量、命令行参数、环境变量和物理文件作为原始配置数据的来源。...

    蒋金楠
  • WebAPi的可视化输出模式(RabbitMQ、消息补偿相关)——所有webapi似乎都缺失的一个功能

    最近的工作我在做一个有关于消息发送和接受封装工作。大概流程是这样的,消息中间件是采用rabbitmq,为了保证消息的绝对无丢失,我们需要在发送和接受前对消息进行...

    王清培
  • WebAPi的可视化输出模式(RabbitMQ、消息补偿相关)——所有webapi似乎都缺失的一个功能

    最近的工作我在做一个有关于消息发送和接受封装工作。大概流程是这样的,消息中间件是采用rabbitmq,为了保证消息的绝对无丢失,我们需要在发送和接受前对消息进行...

    王清培

扫码关注云+社区

领取腾讯云代金券