您的位置:首页 > 移动开发 > Unity3D

2.Unity中AB资源标签一键标记(最详细)

2020-02-02 11:54 1516 查看

本篇主要是给AB资源的标签一键标记,省得在资源的的时候一个个添加标记,标记名称按文件夹路径和资源名称为依据。

下面是操作步骤:

1.在Editor目录下创建标记脚本文件,如图:

2.资源放入art文件下 按场景区分。

3.编辑代码(代码还可再精简一半,后来者去做吧,哈哈):

sing System.Collections;
using System.Collections.Generic;
using System.IO;
using System;
using UnityEditor;
using UnityEngine;

public class AssetBundlesEditor
{
    [MenuItem("AB/Set AssetBundle Lables")]//这是执行这个类的一个按钮,在菜单栏里会多出这一个按钮,不懂看图1-1

    //写一个静态的启动内容的方法
    public static void Assetbundleseditor()
    {
        //第一步我们可以清空所有没有使用过的AB包的名字(如果你没不懂可以忽略这条,)
        AssetDatabase.RemoveUnusedAssetBundleNames();

        //第二步,获取的们存取资源的路径的一级文件夹,类似Resource的这种资源根文件夹,当然打AB包的资源不能放在Resource里面
        string ResPath = Application.dataPath + "/Art";

        //获取路径之后,把路径的文件夹实例化(Dir就相当于Res,这样能明白了嘛)
        DirectoryInfo Dir = new DirectoryInfo(ResPath);

        //获取该文件夹下的所有文件系统(文件系统指 文件还有文件夹)(DirSons就相当于Res里所有的文件系统,这样能明白了嘛)
        DirectoryInfo[] DirSons = Dir.GetDirectories();                          //这里是二级文件夹

        //第三步,遍历Res文件夹里面的子文件夹的所有文件系统,例如Res/Sence1     Res/Sence2
        foreach (FileSystemInfo filesysinfo in DirSons) //为什么这里要用FileSystemInfo,最下面有文字注释
        {
            //获取Res的子文件系统的路径(由于DirctoryInfo要通过路径才能获取文件系统)
            string SonsPath = ResPath + "/" + filesysinfo.Name;
            //获取文件系统
            DirectoryInfo Dinfo = new DirectoryInfo(SonsPath);
            //判断DInfo是否为空
            if (Dinfo == null)
            {
                return;
            }
            else
            {
                ////F:/WorkScript/New Unity Project/Assets/Res/sence这是我们搜到的Dinfo路径    获取“/”最后一个的文件系统的名字
                //获取该名字是为了等下给文件打AB包时,设置AB包名用的
               // int index = Dinfo.FullName.LastIndexOf("/");
                int index = SonsPath.LastIndexOf("/");
               // string lastName = Dinfo.FullName.Substring(index + 1);//通过这个可以获取当前我们搜到的文件系统的名称Sence
                string lastName = SonsPath.Substring(index + 1);//通过这个可以获取当前我们搜到的文件系统的名称Sence

                //写一个方法。用于修改文件的AB包名称,如果是文件夹还得继续遍历
                AssetBundleFilesystemInfo(Dinfo, SonsPath);


            }

        }
        AssetDatabase.Refresh();

    }
    //第一个参数是文件系统,第二个参数是ab包的路径名称
    public static void AssetBundleFilesystemInfo(FileSystemInfo filesysteminfo, string AbPathName)
    {
        //判断文件系统是否为空
        if (!filesysteminfo.Exists)
        {
            Debug.LogError("该文件夹为空" + filesysteminfo.FullName + "is null");
            return;
        }
        //如果继续则是找到了文件系统
        //获取该文件系统(实例化,这是二级文件夹下的文件系统)
        DirectoryInfo Dire_02 = new DirectoryInfo(AbPathName);
        //if(Dire_02)
        DirectoryInfo[] dires = Dire_02.GetDirectories();
        FileSystemInfo [] fileinfo = Dire_02.GetFileSystemInfos();                          //这里是二级文件夹
        FileInfo file ;
        string patheNAME = AbPathName;
        //遍历二级文件夹 下所有的文件系统
        foreach (FileSystemInfo sysinfo_03 in fileinfo)
        {
            DirectoryInfo dirinfo = sysinfo_03 as DirectoryInfo;
            file = sysinfo_03 as FileInfo;
            if (file == null)
            {
                patheNAME = AbPathName + "/" + dirinfo.Name;
                AssetBundleFilesystemInfo(dirinfo, patheNAME);
                continue;
            }
            SetAssetBundleName(file, AbPathName);
           
        }
       
    }

    public static void SetAssetBundleName(FileInfo fileinfo, string AbPathName)
    {
        if (fileinfo.Extension == ".meta")//这个.meta文件是属于系统自动生成的备份文件,我们不需要,所以写个方法排除掉
        {
            return;
        }
        //接下来就是我们找到的需要的文件了
        //找到文件要给文件设置包名,那么我们需要获取包名,例如图片上的Sence/Mode这种路径就是包名
        //写个方法,获取包名
        string ABname = GetBundlePath(fileinfo, AbPathName);
        int indexs = ABname.IndexOf("Art");
        ABname = ABname.Substring(indexs)+"/"+ fileinfo.Name;

        //获取到了包名之后,我们就需要开始将文件资源进行设置包名
        //获取文件资源,此时我们只需要Asset后面的路径
        int index = fileinfo.FullName.IndexOf("Assets");    //从头开始计数看到第几位会遇到这个字符串,返回数值
        string path_last = fileinfo.FullName.Substring(index);  //获得Assets\Res\Sence\Mode\Cube.prefab

        AssetImporter assetImporter = AssetImporter.GetAtPath(path_last);//通过该API获取路径资源(该路径是unity项目内部的路径)
        assetImporter.assetBundleName = ABname;//设置包名成功

        //还有一步,设置后缀,检测该文件资源是不是场景
        if (fileinfo.Extension == ".unity")//文件名后缀是不是unity
        {
            //是场景文件
            assetImporter.assetBundleVariant = "u3d";
        }
        else
            assetImporter.assetBundleVariant = "assetbundle";

        //自动标记工具完成!

    }
    public static string GetBundlePath(FileInfo fileinfo, string AbPathName)
    {
        string WindowsPath = fileinfo.FullName; //我们可以获取到全路径例如F:\WorkScript\New Unity Project\Assets\Res\Sence\Mode\Cube.prefab

        //你可以发现这路径是反斜杠,因为Windows的路径就是用反斜杠的
        //把他转成Unity可以识别的路径
        string UnityPath = WindowsPath.Replace(@"\", "/");//替换斜杠

        //然后这个全路径我们却不用全要,我们只要例如Sence\Mode这个,即第二文件夹/第三文件夹(或者第二文件夹/  )
        //而Sence这个二级文件夹的名字就是AbPathName
        //那么就需要获取三级文件夹的名称的,当然如果是三级文件,那就只要获取二级文件夹的名称
        int Index = UnityPath.IndexOf("AbPathName") + AbPathName.Length;


        string SenceAfter = UnityPath.Substring(Index + 1); //可以获得Mode\Cube.prefab,这是个example,也可能获取的是其他

        //如果Sence后面还有/表示有三级文件夹,如果没有那么就是三级文件
        if (SenceAfter.Contains("/"))
        {
            //有三级文件夹,对路径按/为标记进行切割
            string[] temp = SenceAfter.Split('/');
            return AbPathName + "/" + temp[0];          //我这个只写到0,例如这条返回的可能是Sence/Mode,即可能不是Mode而是None,你可以扩展
        }
        else
        {
            return AbPathName;//这条返回的是Sence
        }

    }
}

4.点击一键标记运行结果:

  • 点赞
  • 收藏
  • 分享
  • 文章举报
东皇十三妖 发布了12 篇原创文章 · 获赞 0 · 访问量 934 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: