当前位置:网站首页>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;
}
}
边栏推荐
- LeetCode、3无重复最长子序列
- No converter found for return value of type: class
- 6-3漏洞利用-SSH环境搭建
- 【八大排序②】选择排序(选择排序,堆排序)
- GL Studio 5 安装与体验
- Luogu p1775 stone merger (weakened version)
- Global and Chinese markets of beverage seasoning systems 2022-2028: Research Report on technology, participants, trends, market size and share
- Load and domcontentloaded in JS
- 笔者更加愿意将产业互联网看成是一个比消费互联网要丰富得多的概念
- 969 interlaced string
猜你喜欢

I'll teach you to visit Amazon RDS for a year and build a MySQL cloud database (only 10 minutes, really fragrant)

6-3 vulnerability exploitation SSH environment construction

We should make clear the branch prediction

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

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

About asp Net core uses a small detail of datetime date type parameter

【八大排序③】快速排序(动图演绎Hoare法、挖坑法、前后指针法)

Principle of finding combinatorial number and template code

学习笔记2--高精度地图定义及价值

浅浅了解Servlet
随机推荐
Global and Chinese markets of beverage seasoning systems 2022-2028: Research Report on technology, participants, trends, market size and share
XMind思维导图
How does schedulerx help users solve the problem of distributed task scheduling?
[image enhancement] vascular image enhancement based on frangi filter with matlab code
MySQL winter vacation self-study 2022 12 (4)
Viewing and modifying volume group attributes of Aix storage management (II)
Error creating bean with name ‘stringRedisTemplate‘ defined in class path re
GL Studio 5 installation and experience
Excel search and reference function
Global and Chinese markets for distributed generation and energy storage in telecommunications networks 2022-2028: Research Report on technology, participants, trends, market size and share
Learn C language from scratch day 025 (maze)
学习笔记24--多传感器后融合技术
Liteos learning - first knowledge of development environment
What skills does an excellent software tester need to master?
ECS project deployment
Leetcode, 3 repeatless longest subsequence
[eight sorts ④] merge sort, sort not based on comparison (count sort, cardinal sort, bucket sort)
Single chip microcomputer -- hlk-w801 transplant NES simulator (III)
error: . repo/manifests/: contains uncommitted changes
站在新的角度来看待产业互联网,并且去寻求产业互联网的正确方式和方法