当前位置:网站首页>Unity AssetBundle subcontracting
Unity AssetBundle subcontracting
2022-07-02 01:18:00 【Si Junli】
One 、Unity AssetBundle Subcontracting flow chart

Two 、 Source code
AssetBundleGroupGetter object , Responsible for group management
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class AssetBundleGroupGetter
{
/// <summary>
/// Of all the resources AssetInfo
/// </summary>
private static Dictionary<string, AssetInfo> assetInfoDict = new Dictionary<string, AssetInfo>();
/// <summary>
/// Grouped AssetInfo key=> Header file value=> All sub dependency lists referenced only by the header file
/// </summary>
private static Dictionary<AssetInfo, List<AssetInfo>> assetGroupInfoDict =
new Dictionary<AssetInfo, List<AssetInfo>>();
private static string progressTitle;
private static float progress;
public static List<List<string>> GetAllUncompressedGroup()
{
List<List<string>> list = new List<List<string>>();
int index = 0;
foreach(var ais in assetGroupInfoDict)
{
if(ais.Key.assetType != AssetType.Video) continue;
index = list.Count;
list.Add(new List<string>());
list[index].Add(ais.Key.path);
foreach(var ai in ais.Value)
{
list[index].Add(ai.path);
}
}
return list;
}
public static List<List<string>> GetAllGroup()
{
List<List<string>> list = new List<List<string>>();
int index = 0;
foreach(var ais in assetGroupInfoDict)
{
if(ais.Key.assetType == AssetType.Video) continue;
index = list.Count;
list.Add(new List<string>());
if(ais.Key.assetType != AssetType.SpriteAtlas)
list[index].Add(ais.Key.path);
foreach(var ai in ais.Value)
{
list[index].Add(ai.path);
}
}
return list;
}
/// <summary>
/// hit Bundle initialization
/// </summary>
public static void InitBuild(string assetPath)
{
assetInfoDict.Clear();
assetGroupInfoDict.Clear();
progressTitle = " Analysis dependence ";
InitAllAssetInfo(assetPath);
progressTitle = " Resource grouping ";
AllAssetInfoToGroup();
EditorUtility.ClearProgressBar();
}
private static void ShowProgress(string title, string info, float progress)
{
EditorUtility.DisplayProgressBar(title, info, progress);
}
/// <summary>
/// Instantiate all AssetInfo
/// </summary>
private static void InitAllAssetInfo(string assetPath)
{
string[] allFileArr = Directory.GetFiles(assetPath, "*", SearchOption.AllDirectories);
int allFileCount = allFileArr == null ? 0 : allFileArr.Length;
for (int i = 0; i < allFileCount; i++)
{
string filePath = allFileArr[i];
progress = (float) i / allFileCount;
ShowProgress(progressTitle, filePath, progress);
if (filePath.EndsWith(".meta"))
{
continue;
}
filePath = filePath.Replace("\\", "/");
CreateAssetInfo(filePath, null);
}
}
/// <summary>
/// Generate AssetInfo
/// </summary>
/// <param name="path">AssetInfo The path of </param>
/// <param name="parent"> Parent dependency </param>
private static void CreateAssetInfo(string path, AssetInfo parent = null)
{
AssetInfo info = null;
if (assetInfoDict.ContainsKey(path))
{
info = assetInfoDict[path];
}
else
{
info = new AssetInfo(path);
assetInfoDict.Add(path, info);
}
if (parent != null)
{
parent.AddChild(info);
// The parent of the file Scene The file does not record dependencies
if (parent.assetType != AssetType.Scene)
{
info.AddParent(parent);
}
}
List<string> depends = info.GetDepends();
if (depends != null && depends.Count > 0)
{
foreach (var item in depends)
{
CreateAssetInfo(item, info);
}
}
}
/// <summary>
/// For all AssetInfo Grouping
/// </summary>
private static void AllAssetInfoToGroup()
{
int assetCount = assetInfoDict == null ? 0 : assetInfoDict.Count;
int id = 0;
if (assetCount > 0)
{
foreach (var item in assetInfoDict)
{
AssetInfo info = item.Value;
AssetInfoToGroup(info);
progress = (float) id / assetCount;
ShowProgress(progressTitle, info.path, progress);
id++;
}
}
}
/// <summary>
/// AssetInfo Grouping
/// </summary>
/// <param name="info"></param>
private static void AssetInfoToGroup(AssetInfo info)
{
if (info.isGrouped)
{
return;
}
bool isTop = info.IsTop();
if (isTop) // It's a top-level file
{
AddAssetGroupInfoDict(info, null);
return;
}
AssetInfo atlasInfo = info.GetBelongSpriteAtlas();
if (atlasInfo != null) // This document has been typed into the atlas
{
AddAssetGroupInfoDict(atlasInfo, info);
return;
}
List<AssetInfo> topParentList = info.FindTopParent();
if (topParentList.Count == 1) // There is only one top-level parent file , Then this file and the top-level parent file are divided into a group
{
AddAssetGroupInfoDict(topParentList[0], info);
}
else
{
// The child dependency shared by all the top-level parent objects of the current file
List<AssetInfo> crossChildInfo = FindMultipleParentCrossChilds(topParentList);
for (int i = crossChildInfo.Count - 1; i >= 0; i--)
{
AssetInfo crossInfo = crossChildInfo[i];
if (crossInfo.isGrouped)
{
crossChildInfo.Remove(crossInfo);
continue;
}
List<AssetInfo> crossChildInfoTopParentList = crossInfo.FindTopParent();
int count = crossChildInfoTopParentList == null ? 0 : crossChildInfoTopParentList.Count;
if (count != topParentList.Count) // This common sub file is also referenced by other top-level files
{
crossChildInfo.Remove(crossInfo);
}
}
// Divide these files that are jointly dependent by multiple top-level parent files into a group
if (crossChildInfo.Count > 0)
{
// Find a file with the table to occupy the pit of the grouping dictionary
AssetInfo headInfo = crossChildInfo[0];
crossChildInfo.RemoveAt(0);
AddAssetListGroupInfoDict(headInfo, crossChildInfo);
}
}
}
/// <summary>
/// Add the file to the grouping dictionary
/// </summary>
/// <param name="headInfo"> Header file , That is to say Key</param>
/// <param name="childInfo"> Dependency file </param>
private static void AddAssetGroupInfoDict(AssetInfo headInfo, AssetInfo childInfo)
{
if (headInfo == null)
{
return;
}
if (!assetGroupInfoDict.ContainsKey(headInfo))
{
assetGroupInfoDict.Add(headInfo, new List<AssetInfo>());
headInfo.isGrouped = true;
}
if (childInfo != null && !childInfo.isGrouped)
{
assetGroupInfoDict[headInfo].Add(childInfo);
childInfo.isGrouped = true;
}
}
private static void AddAssetListGroupInfoDict(AssetInfo headInfo, List<AssetInfo> childInfoList)
{
if (childInfoList == null || childInfoList.Count == 0)
{
AddAssetGroupInfoDict(headInfo, null);
return;
}
for (int i = 0; i < childInfoList.Count; i++)
{
AssetInfo childInfo = childInfoList[i];
AddAssetGroupInfoDict(headInfo, childInfo);
}
}
/// <summary>
/// Get the child files that multiple parent files depend on
/// </summary>
/// <param name="parentList"></param>
/// <returns></returns>
private static List<AssetInfo> FindMultipleParentCrossChilds(List<AssetInfo> parents)
{
if (parents == null || parents.Count < 2)
{
return null;
}
List<AssetInfo> list = parents[0].childList;
if (list == null || list.Count == 0)
{
return null;
}
for (int i = 1; i < parents.Count; i++)
{
List<AssetInfo> childs = parents[i].childList;
if (childs == null || childs.Count == 0)
{
return null;
}
list = list.Intersect(childs).ToList();
if (list == null || list.Count == 0)
{
return null;
}
}
return list;
}
/// <summary>
/// Get the parent file shared by multiple child files
/// </summary>
/// <param name="childs"></param>
/// <returns></returns>
private static List<AssetInfo> FindMultipleChildCrossParents(List<AssetInfo> childs)
{
if (childs == null || childs.Count < 2)
{
return null;
}
List<AssetInfo> list = childs[0].parentList;
if (list == null || list.Count == 0)
{
return null;
}
for (int i = 1; i < childs.Count; i++)
{
List<AssetInfo> parents = childs[i].parentList;
if (parents == null || parents.Count == 0)
{
return null;
}
list = list.Intersect(parents).ToList();
if (list == null || list.Count == 0)
{
return null;
}
}
return list;
}
}
AssetInfo object This is a file object , Each resource file corresponds to one AssetInfo
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using Object = UnityEngine.Object;
public enum AssetType{
// atlas
SpriteAtlas,
// picture ( spirit 、 Mapping )
Image,
// The precast body
Prefab,
// Audio
Audio,
// video
Video,
// scene
Scene,
// other
Other,
}
public class AssetInfo
{
/// <summary>
/// Whether it has been grouped
/// </summary>
public bool isGrouped = false;
// The resource type
public AssetType assetType;
/// <summary>
/// File path
/// </summary>
public string path;
/// <summary>
/// All parent dependent files
/// </summary>
public List<AssetInfo> parentList;
/// <summary>
/// All sub dependent files
/// </summary>
public List<AssetInfo> childList;
public AssetInfo(string _path)
{
path = _path;
SetAssetType();
}
/// <summary>
/// Set file type
/// </summary>
private void SetAssetType()
{
string suffix = Path.GetExtension(path);
switch (suffix)
{
case ".prefab":
assetType = AssetType.Prefab;
break;
case ".spriteatlas":
assetType = AssetType.SpriteAtlas;
break;
case ".png":
case ".jpg":
case ".psd":
case ".tiff":
case ".tga":
case ".gif":
assetType = AssetType.Image;
break;
case ".mp3":
case ".aif":
case ".wav":
case ".ogg":
assetType = AssetType.Audio;
break;
case ".mp4":
case ".mov":
case ".mpg":
case ".mpeg":
case ".avi":
case ".asf":
assetType = AssetType.Video;
break;
case ".unity":
assetType = AssetType.Scene;
break;
default:
assetType = AssetType.Other;
break;
}
}
/// <summary>
/// Add parent file
/// </summary>
/// <param name="info"></param>
public void AddParent(AssetInfo info)
{
if (parentList==null)
{
parentList= new List<AssetInfo>();
}
if (!parentList.Contains(info))
{
parentList.Add(info);
}
}
/// <summary>
/// Add child files
/// </summary>
/// <param name="info"></param>
public void AddChild(AssetInfo info)
{
if (childList==null)
{
childList= new List<AssetInfo>();
}
if (!childList.Contains(info))
{
childList.Add(info);
}
}
/// <summary>
/// Get the topmost parent
/// </summary>
/// <returns></returns>
public List<AssetInfo> FindTopParent()
{
List<AssetInfo> list = new List<AssetInfo>();
if (IsTop())
{
return list;
}
for (int i = 0; i < parentList.Count; i++)
{
AssetInfo info = parentList[i];
if (info.parentList==null||info.parentList.Count==0)
{
list.Add(info);
}
}
return list;
}
/// <summary>
/// Is it a top-level file
/// </summary>
/// <returns></returns>
public bool IsTop()
{
return parentList==null||parentList.Count==0;
}
/// <summary>
/// Get the atlas file to which the file belongs
/// </summary>
/// <returns></returns>
public AssetInfo GetBelongSpriteAtlas()
{
AssetInfo atlasInfo = null;
if (assetType!=AssetType.Image||IsTop())
{
return atlasInfo;
}
for (int i = 0; i < parentList.Count; i++)
{
AssetInfo parentInfo = parentList[i];
if (parentInfo.assetType==AssetType.SpriteAtlas)
{
atlasInfo = parentInfo;
break;
}
}
return atlasInfo;
}
/// <summary>
/// Get the lowest sub dependency
/// </summary>
/// <returns></returns>
public List<AssetInfo> FindBottomChild()
{
List<AssetInfo> list = new List<AssetInfo>();
if (childList==null||childList.Count==0)
{
return list;
}
for (int i = 0; i < parentList.Count; i++)
{
AssetInfo info = childList[i];
if (info.childList==null||info.childList.Count==0)
{
list.Add(info);
}
}
return list;
}
/// <summary>
/// Get all the dependencies of the target object
/// </summary>
/// <param name="objPath"> Target object path (Assets/xx/xx.abc)</param>
/// <returns></returns>
public List<string> GetDepends()
{
List<string> list = null;
string[] dependArr =AssetDatabase.GetDependencies(path,true);
if (dependArr!=null&&dependArr.Length>0)
{
list=new List<string>();
foreach (var dependPath in dependArr)
{
if (string.IsNullOrEmpty(Path.GetExtension(dependPath)))
continue;
Object obj = AssetDatabase.LoadMainAssetAtPath(dependPath);
if (obj is MonoScript || obj is LightingDataAsset)
continue;
if (dependPath == path)
continue;
if (dependPath.EndsWith(".cs"))
continue;
if (!dependPath.StartsWith("Assets"))
continue;
if (!list.Contains(dependPath))
{
list.Add(dependPath);
}
}
}
return list;
}
}
边栏推荐
- 教你白嫖Amazon rds一年并搭建MySQL云数据库(只需10分钟,真香)
- With the acquisition of Xilinx, AMD is more than "walking on two legs" | Jiazi found
- Global and Chinese market of wireless chipsets 2022-2028: Research Report on technology, participants, trends, market size and share
- The author is more willing to regard industrial Internet as a concept much richer than consumer Internet
- ECS project deployment
- 【八大排序④】归并排序、不基于比较的排序(计数排序、基数排序、桶排序)
- Exclusive delivery of secret script move disassembly (the first time)
- [eight sorts ②] select sort (select sort, heap sort)
- How can programmers better plan their career development?
- Excel search and reference function
猜你喜欢

Single chip microcomputer -- hlk-w801 transplant NES simulator (III)

关于ASP.NET CORE使用DateTime日期类型参数的一个小细节

6-3漏洞利用-SSH环境搭建
![[WesternCTF2018]shrine writeup](/img/26/1700095c9b38b9b74a1b1136e5d5de.jpg)
[WesternCTF2018]shrine writeup

Learning note 24 - multi sensor post fusion technology

gradle

Docker安装Oracle_11g

Exclusive delivery of secret script move disassembly (the first time)

"C zero foundation introduction hundred knowledge hundred examples" (73) anonymous function -- lambda expression

Iclr2022 | spherenet and g-spherenet: autoregressive flow model for 3D molecular graph representation and molecular geometry generation
随机推荐
You probably haven't noticed the very important testing strategy in your work
Infiltration records of CFS shooting range in the fourth phase of the western regions' Dadu Mansion
Day 13 of hcip (relevant contents of BGP agreement)
UDS bootloader of s32kxxx bootloader
[eight sorts ①] insert sort (direct insert sort, Hill sort)
Geek DIY open source solution sharing - digital amplitude frequency equalization power amplifier design (practical embedded electronic design works, comprehensive practice of software and hardware)
【八大排序④】归并排序、不基于比较的排序(计数排序、基数排序、桶排序)
How can I batch produce the same title for the video?
Recommend an online interface mock tool usemock
Error creating bean with name ‘stringRedisTemplate‘ defined in class path re
学习笔记25--多传感器前融合技术
The concept and application of Cartland number
Basic usage of shell script
首场“移动云杯”空宣会,期待与开发者一起共创算网新世界!
ACM教程 - 快速排序(常规 + 尾递归 + 随机基准数)
Global and Chinese market of wireless charging magnetic discs 2022-2028: Research Report on technology, participants, trends, market size and share
Study note 2 -- definition and value of high-precision map
What skills does an excellent software tester need to master?
The author is more willing to regard industrial Internet as a concept much richer than consumer Internet
Global and Chinese market of ancillary software 2022-2028: Research Report on technology, participants, trends, market size and share