当前位置:网站首页>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;
}
}
边栏推荐
- How does schedulerx help users solve the problem of distributed task scheduling?
- JMeter做接口测试,如何提取登录Cookie
- What is commercial endowment insurance? Is commercial endowment insurance safe?
- Minimize the error
- [eight sorts ②] select sort (select sort, heap sort)
- cookie、session、tooken
- 学习笔记24--多传感器后融合技术
- Global and Chinese market of safety detection systems 2022-2028: Research Report on technology, participants, trends, market size and share
- Iclr2022 | spherenet and g-spherenet: autoregressive flow model for 3D molecular graph representation and molecular geometry generation
- Learning note 3 -- Key Technologies of high-precision map (Part 1)
猜你喜欢

How can I batch produce the same title for the video?

首场“移动云杯”空宣会,期待与开发者一起共创算网新世界!

Leetcode, 3 repeatless longest subsequence

Evolution of Himalayan self-developed gateway architecture

Study note 2 -- definition and value of high-precision map

Sql--- related transactions

With the acquisition of Xilinx, AMD is more than "walking on two legs" | Jiazi found

How to compress video size while adding watermark with one click?

Day 13 of hcip (relevant contents of BGP agreement)

How does schedulerx help users solve the problem of distributed task scheduling?
随机推荐
[image enhancement] vascular image enhancement based on frangi filter with matlab code
[IVX junior engineer training course 10 papers to get certificates] 09 chat room production
[eight sorts ②] select sort (select sort, heap sort)
The pain of Xiao Sha
NeRV: Neural Reflectance and Visibility Fields for Relighting and View Synthesis
Since I understand the idea of dynamic planning, I have opened the door to a new world
学习笔记2--高精度地图定义及价值
We should make clear the branch prediction
Recommend an online interface mock tool usemock
S32Kxxx bootloader之UDS bootloader
Global and Chinese market of wireless charging magnetic discs 2022-2028: Research Report on technology, participants, trends, market size and share
6-2漏洞利用-ftp不可避免的问题
About asp Net core uses a small detail of datetime date type parameter
Liteos learning - first knowledge of development environment
[JS download files through url]
A problem about function template specialization
浅浅了解Servlet
969 interlaced string
Tencent cloud techo youth dream campus trip into Wuhan University
ACM教程 - 快速排序(常规 + 尾递归 + 随机基准数)