Initial Package with errors
This commit is contained in:
commit
a7623cd55a
106
.gitignore
vendored
Normal file
106
.gitignore
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
# This .gitignore file should be placed at the root of your Unity project directory
|
||||
#
|
||||
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
|
||||
#
|
||||
.utmp/
|
||||
/[Ll]ibrary/
|
||||
/[Tt]emp/
|
||||
/[Oo]bj/
|
||||
/[Bb]uild/
|
||||
/[Bb]uilds/
|
||||
/[Ll]ogs/
|
||||
/[Uu]ser[Ss]ettings/
|
||||
*.log
|
||||
|
||||
# By default unity supports Blender asset imports, *.blend1 blender files do not need to be commited to version control.
|
||||
*.blend1
|
||||
*.blend1.meta
|
||||
|
||||
# MemoryCaptures can get excessive in size.
|
||||
# They also could contain extremely sensitive data
|
||||
/[Mm]emoryCaptures/
|
||||
|
||||
# Recordings can get excessive in size
|
||||
/[Rr]ecordings/
|
||||
|
||||
# Uncomment this line if you wish to ignore the asset store tools plugin
|
||||
# /[Aa]ssets/AssetStoreTools*
|
||||
|
||||
# Autogenerated Jetbrains Rider plugin
|
||||
/[Aa]ssets/Plugins/Editor/JetBrains*
|
||||
# Jetbrains Rider personal-layer settings
|
||||
*.DotSettings.user
|
||||
|
||||
# Visual Studio cache directory
|
||||
.vs/
|
||||
|
||||
# Gradle cache directory
|
||||
.gradle/
|
||||
|
||||
# Autogenerated VS/MD/Consulo solution and project files
|
||||
ExportedObj/
|
||||
.consulo/
|
||||
*.csproj
|
||||
*.unityproj
|
||||
*.sln
|
||||
*.suo
|
||||
*.tmp
|
||||
*.user
|
||||
*.userprefs
|
||||
*.pidb
|
||||
*.booproj
|
||||
*.svd
|
||||
*.pdb
|
||||
*.mdb
|
||||
*.opendb
|
||||
*.VC.db
|
||||
|
||||
# Unity3D generated meta files
|
||||
*.pidb.meta
|
||||
*.pdb.meta
|
||||
*.mdb.meta
|
||||
|
||||
# Unity3D generated file on crash reports
|
||||
sysinfo.txt
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Builds
|
||||
*.apk
|
||||
*.aab
|
||||
*.unitypackage
|
||||
*.unitypackage.meta
|
||||
|
||||
# Crashlytics generated file
|
||||
crashlytics-build.properties
|
||||
|
||||
# TestRunner generated files
|
||||
InitTestScene*.unity*
|
||||
|
||||
# Addressables default ignores, before user customizations
|
||||
/ServerData
|
||||
/[Aa]ssets/StreamingAssets/aa*
|
||||
/[Aa]ssets/AddressableAssetsData/link.xml*
|
||||
/[Aa]ssets/Addressables_Temp*
|
||||
# By default, Addressables content builds will generate addressables_content_state.bin
|
||||
# files in platform-specific subfolders, for example:
|
||||
# /Assets/AddressableAssetsData/OSX/addressables_content_state.bin
|
||||
/[Aa]ssets/AddressableAssetsData/*/*.bin*
|
||||
|
||||
# Visual Scripting auto-generated files
|
||||
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db
|
||||
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db.meta
|
||||
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers
|
||||
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers.meta
|
||||
|
||||
# Auto-generated scenes by play mode tests
|
||||
/[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity*
|
||||
|
||||
.vsconfig
|
||||
|
||||
Logs/
|
||||
[Aa]ssets/
|
||||
[Pp]ublish/
|
||||
.vscode/settings.json
|
||||
*.dat
|
||||
8
Packages/com.bywaystudios.resourceloader/Editor.meta
Normal file
8
Packages/com.bywaystudios.resourceloader/Editor.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da7bdb8bfa22af447854131661c3f140
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Byway.ResourceLoader.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"Byway.ResourceLoader"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ceb5850fa4b1da54f8485d145ce1f7fb
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd9595fe20f16b6418ee574335afadca
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,21 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public enum AssetsOrder : byte
|
||||
{
|
||||
AssetNameAsc,
|
||||
AssetNameDesc,
|
||||
DependencyResourceCountAsc,
|
||||
DependencyResourceCountDesc,
|
||||
DependencyAssetCountAsc,
|
||||
DependencyAssetCountDesc,
|
||||
ScatteredDependencyAssetCountAsc,
|
||||
ScatteredDependencyAssetCountDesc,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53e74863b20de0742bad85898d617db6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,96 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed class DependencyData
|
||||
{
|
||||
private List<Resource> m_DependencyResources;
|
||||
private List<Asset> m_DependencyAssets;
|
||||
private List<string> m_ScatteredDependencyAssetNames;
|
||||
|
||||
public DependencyData()
|
||||
{
|
||||
m_DependencyResources = new List<Resource>();
|
||||
m_DependencyAssets = new List<Asset>();
|
||||
m_ScatteredDependencyAssetNames = new List<string>();
|
||||
}
|
||||
|
||||
public int DependencyResourceCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_DependencyResources.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public int DependencyAssetCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_DependencyAssets.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public int ScatteredDependencyAssetCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ScatteredDependencyAssetNames.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddDependencyAsset(Asset asset)
|
||||
{
|
||||
if (!m_DependencyResources.Contains(asset.Resource))
|
||||
{
|
||||
m_DependencyResources.Add(asset.Resource);
|
||||
}
|
||||
|
||||
m_DependencyAssets.Add(asset);
|
||||
}
|
||||
|
||||
public void AddScatteredDependencyAsset(string dependencyAssetName)
|
||||
{
|
||||
m_ScatteredDependencyAssetNames.Add(dependencyAssetName);
|
||||
}
|
||||
|
||||
public Resource[] GetDependencyResources()
|
||||
{
|
||||
return m_DependencyResources.ToArray();
|
||||
}
|
||||
|
||||
public Asset[] GetDependencyAssets()
|
||||
{
|
||||
return m_DependencyAssets.ToArray();
|
||||
}
|
||||
|
||||
public string[] GetScatteredDependencyAssetNames()
|
||||
{
|
||||
return m_ScatteredDependencyAssetNames.ToArray();
|
||||
}
|
||||
|
||||
public void RefreshData()
|
||||
{
|
||||
m_DependencyResources.Sort(DependencyResourcesComparer);
|
||||
m_DependencyAssets.Sort(DependencyAssetsComparer);
|
||||
m_ScatteredDependencyAssetNames.Sort();
|
||||
}
|
||||
|
||||
private int DependencyResourcesComparer(Resource a, Resource b)
|
||||
{
|
||||
return a.FullName.CompareTo(b.FullName);
|
||||
}
|
||||
|
||||
private int DependencyAssetsComparer(Asset a, Asset b)
|
||||
{
|
||||
return a.Name.CompareTo(b.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 325edc30663628f4a917226eeee0b733
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,533 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源分析器。
|
||||
/// </summary>
|
||||
internal sealed class ResourceAnalyzer : EditorWindow
|
||||
{
|
||||
private ResourceAnalyzerController m_Controller = null;
|
||||
private bool m_Analyzed = false;
|
||||
private int m_ToolbarIndex = 0;
|
||||
|
||||
private int m_AssetCount = 0;
|
||||
private string[] m_CachedAssetNames = null;
|
||||
private int m_SelectedAssetIndex = -1;
|
||||
private string m_SelectedAssetName = null;
|
||||
private DependencyData m_SelectedDependencyData = null;
|
||||
private AssetsOrder m_AssetsOrder = AssetsOrder.AssetNameAsc;
|
||||
private string m_AssetsFilter = null;
|
||||
private Vector2 m_AssetsScroll = Vector2.zero;
|
||||
private Vector2 m_DependencyResourcesScroll = Vector2.zero;
|
||||
private Vector2 m_DependencyAssetsScroll = Vector2.zero;
|
||||
private Vector2 m_ScatteredDependencyAssetsScroll = Vector2.zero;
|
||||
|
||||
private int m_ScatteredAssetCount = 0;
|
||||
private string[] m_CachedScatteredAssetNames = null;
|
||||
private int m_SelectedScatteredAssetIndex = -1;
|
||||
private string m_SelectedScatteredAssetName = null;
|
||||
private Asset[] m_SelectedHostAssets = null;
|
||||
private ScatteredAssetsOrder m_ScatteredAssetsOrder = ScatteredAssetsOrder.AssetNameAsc;
|
||||
private string m_ScatteredAssetsFilter = null;
|
||||
private Vector2 m_ScatteredAssetsScroll = Vector2.zero;
|
||||
private Vector2 m_HostAssetsScroll = Vector2.zero;
|
||||
|
||||
private int m_CircularDependencyCount = 0;
|
||||
private string[][] m_CachedCircularDependencyDatas = null;
|
||||
private Vector2 m_CircularDependencyScroll = Vector2.zero;
|
||||
|
||||
[MenuItem("Game Framework/Resource Tools/Resource Analyzer", false, 42)]
|
||||
private static void Open()
|
||||
{
|
||||
ResourceAnalyzer window = GetWindow<ResourceAnalyzer>("Resource Analyzer", true);
|
||||
window.minSize = new Vector2(800f, 600f);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_Controller = new ResourceAnalyzerController();
|
||||
m_Controller.OnLoadingResource += OnLoadingResource;
|
||||
m_Controller.OnLoadingAsset += OnLoadingAsset;
|
||||
m_Controller.OnLoadCompleted += OnLoadCompleted;
|
||||
m_Controller.OnAnalyzingAsset += OnAnalyzingAsset;
|
||||
m_Controller.OnAnalyzeCompleted += OnAnalyzeCompleted;
|
||||
|
||||
m_Analyzed = false;
|
||||
m_ToolbarIndex = 0;
|
||||
|
||||
m_AssetCount = 0;
|
||||
m_CachedAssetNames = null;
|
||||
m_SelectedAssetIndex = -1;
|
||||
m_SelectedAssetName = null;
|
||||
m_SelectedDependencyData = new DependencyData();
|
||||
m_AssetsOrder = AssetsOrder.ScatteredDependencyAssetCountDesc;
|
||||
m_AssetsFilter = null;
|
||||
m_AssetsScroll = Vector2.zero;
|
||||
m_DependencyResourcesScroll = Vector2.zero;
|
||||
m_DependencyAssetsScroll = Vector2.zero;
|
||||
m_ScatteredDependencyAssetsScroll = Vector2.zero;
|
||||
|
||||
m_ScatteredAssetCount = 0;
|
||||
m_CachedScatteredAssetNames = null;
|
||||
m_SelectedScatteredAssetIndex = -1;
|
||||
m_SelectedScatteredAssetName = null;
|
||||
m_SelectedHostAssets = new Asset[] { };
|
||||
m_ScatteredAssetsOrder = ScatteredAssetsOrder.HostAssetCountDesc;
|
||||
m_ScatteredAssetsFilter = null;
|
||||
m_ScatteredAssetsScroll = Vector2.zero;
|
||||
m_HostAssetsScroll = Vector2.zero;
|
||||
|
||||
m_CircularDependencyCount = 0;
|
||||
m_CachedCircularDependencyDatas = null;
|
||||
m_CircularDependencyScroll = Vector2.zero;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height));
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
int toolbarIndex = GUILayout.Toolbar(m_ToolbarIndex, new string[] { "Summary", "Asset Dependency Viewer", "Scattered Asset Viewer", "Circular Dependency Viewer" }, GUILayout.Height(30f));
|
||||
if (toolbarIndex != m_ToolbarIndex)
|
||||
{
|
||||
m_ToolbarIndex = toolbarIndex;
|
||||
GUI.FocusControl(null);
|
||||
}
|
||||
|
||||
switch (m_ToolbarIndex)
|
||||
{
|
||||
case 0:
|
||||
DrawSummary();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DrawAssetDependencyViewer();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
DrawScatteredAssetViewer();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
DrawCircularDependencyViewer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawAnalyzeButton()
|
||||
{
|
||||
if (!m_Analyzed)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Please analyze first.", MessageType.Info);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Analyze", GUILayout.Height(30f)))
|
||||
{
|
||||
m_Controller.Clear();
|
||||
|
||||
m_SelectedAssetIndex = -1;
|
||||
m_SelectedAssetName = null;
|
||||
m_SelectedDependencyData = new DependencyData();
|
||||
|
||||
m_SelectedScatteredAssetIndex = -1;
|
||||
m_SelectedScatteredAssetName = null;
|
||||
m_SelectedHostAssets = new Asset[] { };
|
||||
|
||||
if (m_Controller.Prepare())
|
||||
{
|
||||
m_Controller.Analyze();
|
||||
m_Analyzed = true;
|
||||
m_AssetCount = m_Controller.GetAssetNames().Length;
|
||||
m_ScatteredAssetCount = m_Controller.GetScatteredAssetNames().Length;
|
||||
m_CachedCircularDependencyDatas = m_Controller.GetCircularDependencyDatas();
|
||||
m_CircularDependencyCount = m_CachedCircularDependencyDatas.Length;
|
||||
OnAssetsOrderOrFilterChanged();
|
||||
OnScatteredAssetsOrderOrFilterChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Resource Analyze", "Can not parse 'ResourceCollection.xml', please use 'Resource Editor' tool first.", "OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSummary()
|
||||
{
|
||||
DrawAnalyzeButton();
|
||||
}
|
||||
|
||||
private void DrawAssetDependencyViewer()
|
||||
{
|
||||
if (!m_Analyzed)
|
||||
{
|
||||
DrawAnalyzeButton();
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.4f));
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
string title = null;
|
||||
if (string.IsNullOrEmpty(m_AssetsFilter))
|
||||
{
|
||||
title = Utility.Text.Format("Assets In Resources ({0})", m_AssetCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
title = Utility.Text.Format("Assets In Resources ({0}/{1})", m_CachedAssetNames.Length, m_AssetCount);
|
||||
}
|
||||
EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height - 150f));
|
||||
{
|
||||
m_AssetsScroll = EditorGUILayout.BeginScrollView(m_AssetsScroll);
|
||||
{
|
||||
int selectedIndex = GUILayout.SelectionGrid(m_SelectedAssetIndex, m_CachedAssetNames, 1, "toggle");
|
||||
if (selectedIndex != m_SelectedAssetIndex)
|
||||
{
|
||||
m_SelectedAssetIndex = selectedIndex;
|
||||
m_SelectedAssetName = m_CachedAssetNames[selectedIndex];
|
||||
m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.LabelField("Asset Name", m_SelectedAssetName ?? "<None>");
|
||||
EditorGUILayout.LabelField("Resource Name", m_SelectedAssetName == null ? "<None>" : m_Controller.GetAsset(m_SelectedAssetName).Resource.FullName);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
AssetsOrder assetsOrder = (AssetsOrder)EditorGUILayout.EnumPopup("Order by", m_AssetsOrder);
|
||||
if (assetsOrder != m_AssetsOrder)
|
||||
{
|
||||
m_AssetsOrder = assetsOrder;
|
||||
OnAssetsOrderOrFilterChanged();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
string assetsFilter = EditorGUILayout.TextField("Assets Filter", m_AssetsFilter);
|
||||
if (assetsFilter != m_AssetsFilter)
|
||||
{
|
||||
m_AssetsFilter = assetsFilter;
|
||||
OnAssetsOrderOrFilterChanged();
|
||||
}
|
||||
EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_AssetsFilter));
|
||||
{
|
||||
if (GUILayout.Button("x", GUILayout.Width(20f)))
|
||||
{
|
||||
m_AssetsFilter = null;
|
||||
GUI.FocusControl(null);
|
||||
OnAssetsOrderOrFilterChanged();
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.6f - 14f));
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.LabelField(Utility.Text.Format("Dependency Resources ({0})", m_SelectedDependencyData.DependencyResourceCount), EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height * 0.2f));
|
||||
{
|
||||
m_DependencyResourcesScroll = EditorGUILayout.BeginScrollView(m_DependencyResourcesScroll);
|
||||
{
|
||||
Resource[] dependencyResources = m_SelectedDependencyData.GetDependencyResources();
|
||||
foreach (Resource dependencyResource in dependencyResources)
|
||||
{
|
||||
GUILayout.Label(dependencyResource.FullName);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.LabelField(Utility.Text.Format("Dependency Assets ({0})", m_SelectedDependencyData.DependencyAssetCount), EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height * 0.3f));
|
||||
{
|
||||
m_DependencyAssetsScroll = EditorGUILayout.BeginScrollView(m_DependencyAssetsScroll);
|
||||
{
|
||||
Asset[] dependencyAssets = m_SelectedDependencyData.GetDependencyAssets();
|
||||
foreach (Asset dependencyAsset in dependencyAssets)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
if (GUILayout.Button("GO", GUILayout.Width(30f)))
|
||||
{
|
||||
m_SelectedAssetName = dependencyAsset.Name;
|
||||
m_SelectedAssetIndex = new List<string>(m_CachedAssetNames).IndexOf(m_SelectedAssetName);
|
||||
m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName);
|
||||
}
|
||||
|
||||
GUILayout.Label(dependencyAsset.Name);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.LabelField(Utility.Text.Format("Scattered Dependency Assets ({0})", m_SelectedDependencyData.ScatteredDependencyAssetCount), EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height * 0.5f - 116f));
|
||||
{
|
||||
m_ScatteredDependencyAssetsScroll = EditorGUILayout.BeginScrollView(m_ScatteredDependencyAssetsScroll);
|
||||
{
|
||||
string[] scatteredDependencyAssetNames = m_SelectedDependencyData.GetScatteredDependencyAssetNames();
|
||||
foreach (string scatteredDependencyAssetName in scatteredDependencyAssetNames)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
int count = m_Controller.GetHostAssets(scatteredDependencyAssetName).Length;
|
||||
EditorGUI.BeginDisabledGroup(count < 2);
|
||||
{
|
||||
if (GUILayout.Button("GO", GUILayout.Width(30f)))
|
||||
{
|
||||
m_SelectedScatteredAssetName = scatteredDependencyAssetName;
|
||||
m_SelectedScatteredAssetIndex = new List<string>(m_CachedScatteredAssetNames).IndexOf(m_SelectedScatteredAssetName);
|
||||
m_SelectedHostAssets = m_Controller.GetHostAssets(m_SelectedScatteredAssetName);
|
||||
m_ToolbarIndex = 2;
|
||||
GUI.FocusControl(null);
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
GUILayout.Label(count > 1 ? Utility.Text.Format("{0} ({1})", scatteredDependencyAssetName, count) : scatteredDependencyAssetName);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawScatteredAssetViewer()
|
||||
{
|
||||
if (!m_Analyzed)
|
||||
{
|
||||
DrawAnalyzeButton();
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.4f));
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
string title = null;
|
||||
if (string.IsNullOrEmpty(m_ScatteredAssetsFilter))
|
||||
{
|
||||
title = Utility.Text.Format("Scattered Assets ({0})", m_ScatteredAssetCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
title = Utility.Text.Format("Scattered Assets ({0}/{1})", m_CachedScatteredAssetNames.Length, m_ScatteredAssetCount);
|
||||
}
|
||||
EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height - 132f));
|
||||
{
|
||||
m_ScatteredAssetsScroll = EditorGUILayout.BeginScrollView(m_ScatteredAssetsScroll);
|
||||
{
|
||||
int selectedIndex = GUILayout.SelectionGrid(m_SelectedScatteredAssetIndex, m_CachedScatteredAssetNames, 1, "toggle");
|
||||
if (selectedIndex != m_SelectedScatteredAssetIndex)
|
||||
{
|
||||
m_SelectedScatteredAssetIndex = selectedIndex;
|
||||
m_SelectedScatteredAssetName = m_CachedScatteredAssetNames[selectedIndex];
|
||||
m_SelectedHostAssets = m_Controller.GetHostAssets(m_SelectedScatteredAssetName);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.LabelField("Scattered Asset Name", m_SelectedScatteredAssetName ?? "<None>");
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
ScatteredAssetsOrder scatteredAssetsOrder = (ScatteredAssetsOrder)EditorGUILayout.EnumPopup("Order by", m_ScatteredAssetsOrder);
|
||||
if (scatteredAssetsOrder != m_ScatteredAssetsOrder)
|
||||
{
|
||||
m_ScatteredAssetsOrder = scatteredAssetsOrder;
|
||||
OnScatteredAssetsOrderOrFilterChanged();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
string scatteredAssetsFilter = EditorGUILayout.TextField("Assets Filter", m_ScatteredAssetsFilter);
|
||||
if (scatteredAssetsFilter != m_ScatteredAssetsFilter)
|
||||
{
|
||||
m_ScatteredAssetsFilter = scatteredAssetsFilter;
|
||||
OnScatteredAssetsOrderOrFilterChanged();
|
||||
}
|
||||
EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_ScatteredAssetsFilter));
|
||||
{
|
||||
if (GUILayout.Button("x", GUILayout.Width(20f)))
|
||||
{
|
||||
m_ScatteredAssetsFilter = null;
|
||||
GUI.FocusControl(null);
|
||||
OnScatteredAssetsOrderOrFilterChanged();
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.BeginVertical(GUILayout.Width(position.width * 0.6f - 14f));
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.LabelField(Utility.Text.Format("Host Assets ({0})", m_SelectedHostAssets.Length), EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.Height(position.height - 68f));
|
||||
{
|
||||
m_HostAssetsScroll = EditorGUILayout.BeginScrollView(m_HostAssetsScroll);
|
||||
{
|
||||
foreach (Asset hostAsset in m_SelectedHostAssets)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
if (GUILayout.Button("GO", GUILayout.Width(30f)))
|
||||
{
|
||||
m_SelectedAssetName = hostAsset.Name;
|
||||
m_SelectedAssetIndex = new List<string>(m_CachedAssetNames).IndexOf(m_SelectedAssetName);
|
||||
m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName);
|
||||
m_ToolbarIndex = 1;
|
||||
GUI.FocusControl(null);
|
||||
}
|
||||
|
||||
GUILayout.Label(Utility.Text.Format("{0} [{1}]", hostAsset.Name, hostAsset.Resource.FullName));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawCircularDependencyViewer()
|
||||
{
|
||||
if (!m_Analyzed)
|
||||
{
|
||||
DrawAnalyzeButton();
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.LabelField(Utility.Text.Format("Circular Dependency ({0})", m_CircularDependencyCount), EditorStyles.boldLabel);
|
||||
m_CircularDependencyScroll = EditorGUILayout.BeginScrollView(m_CircularDependencyScroll);
|
||||
{
|
||||
int count = 0;
|
||||
foreach (string[] circularDependencyData in m_CachedCircularDependencyDatas)
|
||||
{
|
||||
GUILayout.Label(Utility.Text.Format("{0}) {1}", ++count, circularDependencyData[circularDependencyData.Length - 1]), EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
foreach (string circularDependency in circularDependencyData)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
GUILayout.Label(circularDependency);
|
||||
if (GUILayout.Button("GO", GUILayout.Width(30f)))
|
||||
{
|
||||
m_SelectedAssetName = circularDependency;
|
||||
m_SelectedAssetIndex = new List<string>(m_CachedAssetNames).IndexOf(m_SelectedAssetName);
|
||||
m_SelectedDependencyData = m_Controller.GetDependencyData(m_SelectedAssetName);
|
||||
m_ToolbarIndex = 1;
|
||||
GUI.FocusControl(null);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
GUILayout.Space(5f);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void OnAssetsOrderOrFilterChanged()
|
||||
{
|
||||
m_CachedAssetNames = m_Controller.GetAssetNames(m_AssetsOrder, m_AssetsFilter);
|
||||
if (!string.IsNullOrEmpty(m_SelectedAssetName))
|
||||
{
|
||||
m_SelectedAssetIndex = new List<string>(m_CachedAssetNames).IndexOf(m_SelectedAssetName);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScatteredAssetsOrderOrFilterChanged()
|
||||
{
|
||||
m_CachedScatteredAssetNames = m_Controller.GetScatteredAssetNames(m_ScatteredAssetsOrder, m_ScatteredAssetsFilter);
|
||||
if (!string.IsNullOrEmpty(m_SelectedScatteredAssetName))
|
||||
{
|
||||
m_SelectedScatteredAssetIndex = new List<string>(m_CachedScatteredAssetNames).IndexOf(m_SelectedScatteredAssetName);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLoadingResource(int index, int count)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index, count), (float)index / count);
|
||||
}
|
||||
|
||||
private void OnLoadingAsset(int index, int count)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index, count), (float)index / count);
|
||||
}
|
||||
|
||||
private void OnLoadCompleted()
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
private void OnAnalyzingAsset(int index, int count)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Analyzing Assets", Utility.Text.Format("Analyzing assets, {0}/{1} analyzed.", index, count), (float)index / count);
|
||||
}
|
||||
|
||||
private void OnAnalyzeCompleted()
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e7971f49bcdc654fb34a9fdaa2a6d29
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,76 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed partial class ResourceAnalyzerController
|
||||
{
|
||||
private sealed class CircularDependencyChecker
|
||||
{
|
||||
private readonly Stamp[] m_Stamps;
|
||||
|
||||
public CircularDependencyChecker(Stamp[] stamps)
|
||||
{
|
||||
m_Stamps = stamps;
|
||||
}
|
||||
|
||||
public string[][] Check()
|
||||
{
|
||||
HashSet<string> hosts = new HashSet<string>();
|
||||
foreach (Stamp stamp in m_Stamps)
|
||||
{
|
||||
hosts.Add(stamp.HostAssetName);
|
||||
}
|
||||
|
||||
List<string[]> results = new List<string[]>();
|
||||
foreach (string host in hosts)
|
||||
{
|
||||
LinkedList<string> route = new LinkedList<string>();
|
||||
HashSet<string> visited = new HashSet<string>();
|
||||
if (Check(host, route, visited))
|
||||
{
|
||||
results.Add(route.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
private bool Check(string host, LinkedList<string> route, HashSet<string> visited)
|
||||
{
|
||||
visited.Add(host);
|
||||
route.AddLast(host);
|
||||
|
||||
foreach (Stamp stamp in m_Stamps)
|
||||
{
|
||||
if (host != stamp.HostAssetName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (visited.Contains(stamp.DependencyAssetName))
|
||||
{
|
||||
route.AddLast(stamp.DependencyAssetName);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Check(stamp.DependencyAssetName, route, visited))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
route.RemoveLast();
|
||||
visited.Remove(host);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97329d75bce6b634282bf05ff3453fba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,43 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed partial class ResourceAnalyzerController
|
||||
{
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
private struct Stamp
|
||||
{
|
||||
private readonly string m_HostAssetName;
|
||||
private readonly string m_DependencyAssetName;
|
||||
|
||||
public Stamp(string hostAssetName, string dependencyAssetName)
|
||||
{
|
||||
m_HostAssetName = hostAssetName;
|
||||
m_DependencyAssetName = dependencyAssetName;
|
||||
}
|
||||
|
||||
public string HostAssetName
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HostAssetName;
|
||||
}
|
||||
}
|
||||
|
||||
public string DependencyAssetName
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_DependencyAssetName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15cf99f0cd968de4e876c49401fa5294
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,324 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed partial class ResourceAnalyzerController
|
||||
{
|
||||
private readonly ResourceCollection m_ResourceCollection;
|
||||
|
||||
private readonly Dictionary<string, DependencyData> m_DependencyDatas;
|
||||
private readonly Dictionary<string, List<Asset>> m_ScatteredAssets;
|
||||
private readonly List<string[]> m_CircularDependencyDatas;
|
||||
private readonly HashSet<Stamp> m_AnalyzedStamps;
|
||||
|
||||
public ResourceAnalyzerController()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public ResourceAnalyzerController(ResourceCollection resourceCollection)
|
||||
{
|
||||
m_ResourceCollection = resourceCollection != null ? resourceCollection : new ResourceCollection();
|
||||
|
||||
m_ResourceCollection.OnLoadingResource += delegate (int index, int count)
|
||||
{
|
||||
if (OnLoadingResource != null)
|
||||
{
|
||||
OnLoadingResource(index, count);
|
||||
}
|
||||
};
|
||||
|
||||
m_ResourceCollection.OnLoadingAsset += delegate (int index, int count)
|
||||
{
|
||||
if (OnLoadingAsset != null)
|
||||
{
|
||||
OnLoadingAsset(index, count);
|
||||
}
|
||||
};
|
||||
|
||||
m_ResourceCollection.OnLoadCompleted += delegate ()
|
||||
{
|
||||
if (OnLoadCompleted != null)
|
||||
{
|
||||
OnLoadCompleted();
|
||||
}
|
||||
};
|
||||
|
||||
m_DependencyDatas = new Dictionary<string, DependencyData>(StringComparer.Ordinal);
|
||||
m_ScatteredAssets = new Dictionary<string, List<Asset>>(StringComparer.Ordinal);
|
||||
m_AnalyzedStamps = new HashSet<Stamp>();
|
||||
m_CircularDependencyDatas = new List<string[]>();
|
||||
}
|
||||
|
||||
public event GameFrameworkAction<int, int> OnLoadingResource = null;
|
||||
|
||||
public event GameFrameworkAction<int, int> OnLoadingAsset = null;
|
||||
|
||||
public event GameFrameworkAction OnLoadCompleted = null;
|
||||
|
||||
public event GameFrameworkAction<int, int> OnAnalyzingAsset = null;
|
||||
|
||||
public event GameFrameworkAction OnAnalyzeCompleted = null;
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_ResourceCollection.Clear();
|
||||
m_DependencyDatas.Clear();
|
||||
m_ScatteredAssets.Clear();
|
||||
m_CircularDependencyDatas.Clear();
|
||||
m_AnalyzedStamps.Clear();
|
||||
}
|
||||
|
||||
public bool Prepare()
|
||||
{
|
||||
m_ResourceCollection.Clear();
|
||||
return m_ResourceCollection.Load();
|
||||
}
|
||||
|
||||
public void Analyze()
|
||||
{
|
||||
m_DependencyDatas.Clear();
|
||||
m_ScatteredAssets.Clear();
|
||||
m_CircularDependencyDatas.Clear();
|
||||
m_AnalyzedStamps.Clear();
|
||||
|
||||
HashSet<string> scriptAssetNames = GetFilteredAssetNames("t:Script");
|
||||
Asset[] assets = m_ResourceCollection.GetAssets();
|
||||
int count = assets.Length;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (OnAnalyzingAsset != null)
|
||||
{
|
||||
OnAnalyzingAsset(i, count);
|
||||
}
|
||||
|
||||
string assetName = assets[i].Name;
|
||||
if (string.IsNullOrEmpty(assetName))
|
||||
{
|
||||
Debug.LogWarning(Utility.Text.Format("Can not find asset by guid '{0}'.", assets[i].Guid));
|
||||
continue;
|
||||
}
|
||||
|
||||
DependencyData dependencyData = new DependencyData();
|
||||
AnalyzeAsset(assetName, assets[i], dependencyData, scriptAssetNames);
|
||||
dependencyData.RefreshData();
|
||||
m_DependencyDatas.Add(assetName, dependencyData);
|
||||
}
|
||||
|
||||
foreach (List<Asset> scatteredAsset in m_ScatteredAssets.Values)
|
||||
{
|
||||
scatteredAsset.Sort((a, b) => a.Name.CompareTo(b.Name));
|
||||
}
|
||||
|
||||
m_CircularDependencyDatas.AddRange(new CircularDependencyChecker(m_AnalyzedStamps.ToArray()).Check());
|
||||
|
||||
if (OnAnalyzeCompleted != null)
|
||||
{
|
||||
OnAnalyzeCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
private void AnalyzeAsset(string assetName, Asset hostAsset, DependencyData dependencyData, HashSet<string> scriptAssetNames)
|
||||
{
|
||||
string[] dependencyAssetNames = AssetDatabase.GetDependencies(assetName, false);
|
||||
foreach (string dependencyAssetName in dependencyAssetNames)
|
||||
{
|
||||
if (scriptAssetNames.Contains(dependencyAssetName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dependencyAssetName == assetName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dependencyAssetName.EndsWith(".unity", StringComparison.Ordinal))
|
||||
{
|
||||
// 忽略对场景的依赖
|
||||
continue;
|
||||
}
|
||||
|
||||
Stamp stamp = new Stamp(hostAsset.Name, dependencyAssetName);
|
||||
if (m_AnalyzedStamps.Contains(stamp))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m_AnalyzedStamps.Add(stamp);
|
||||
|
||||
string guid = AssetDatabase.AssetPathToGUID(dependencyAssetName);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
Debug.LogWarning(Utility.Text.Format("Can not find guid by asset '{0}'.", dependencyAssetName));
|
||||
continue;
|
||||
}
|
||||
|
||||
Asset asset = m_ResourceCollection.GetAsset(guid);
|
||||
if (asset != null)
|
||||
{
|
||||
dependencyData.AddDependencyAsset(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
dependencyData.AddScatteredDependencyAsset(dependencyAssetName);
|
||||
|
||||
List<Asset> scatteredAssets = null;
|
||||
if (!m_ScatteredAssets.TryGetValue(dependencyAssetName, out scatteredAssets))
|
||||
{
|
||||
scatteredAssets = new List<Asset>();
|
||||
m_ScatteredAssets.Add(dependencyAssetName, scatteredAssets);
|
||||
}
|
||||
|
||||
scatteredAssets.Add(hostAsset);
|
||||
|
||||
AnalyzeAsset(dependencyAssetName, hostAsset, dependencyData, scriptAssetNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Asset GetAsset(string assetName)
|
||||
{
|
||||
return m_ResourceCollection.GetAsset(AssetDatabase.AssetPathToGUID(assetName));
|
||||
}
|
||||
|
||||
public string[] GetAssetNames()
|
||||
{
|
||||
return GetAssetNames(AssetsOrder.AssetNameAsc, null);
|
||||
}
|
||||
|
||||
public string[] GetAssetNames(AssetsOrder order, string filter)
|
||||
{
|
||||
HashSet<string> filteredAssetNames = GetFilteredAssetNames(filter);
|
||||
IEnumerable<KeyValuePair<string, DependencyData>> filteredResult = m_DependencyDatas.Where(pair => filteredAssetNames.Contains(pair.Key));
|
||||
IEnumerable<KeyValuePair<string, DependencyData>> orderedResult = null;
|
||||
switch (order)
|
||||
{
|
||||
case AssetsOrder.AssetNameAsc:
|
||||
orderedResult = filteredResult.OrderBy(pair => pair.Key);
|
||||
break;
|
||||
|
||||
case AssetsOrder.AssetNameDesc:
|
||||
orderedResult = filteredResult.OrderByDescending(pair => pair.Key);
|
||||
break;
|
||||
|
||||
case AssetsOrder.DependencyResourceCountAsc:
|
||||
orderedResult = filteredResult.OrderBy(pair => pair.Value.DependencyResourceCount);
|
||||
break;
|
||||
|
||||
case AssetsOrder.DependencyResourceCountDesc:
|
||||
orderedResult = filteredResult.OrderByDescending(pair => pair.Value.DependencyResourceCount);
|
||||
break;
|
||||
|
||||
case AssetsOrder.DependencyAssetCountAsc:
|
||||
orderedResult = filteredResult.OrderBy(pair => pair.Value.DependencyAssetCount);
|
||||
break;
|
||||
|
||||
case AssetsOrder.DependencyAssetCountDesc:
|
||||
orderedResult = filteredResult.OrderByDescending(pair => pair.Value.DependencyAssetCount);
|
||||
break;
|
||||
|
||||
case AssetsOrder.ScatteredDependencyAssetCountAsc:
|
||||
orderedResult = filteredResult.OrderBy(pair => pair.Value.ScatteredDependencyAssetCount);
|
||||
break;
|
||||
|
||||
case AssetsOrder.ScatteredDependencyAssetCountDesc:
|
||||
orderedResult = filteredResult.OrderByDescending(pair => pair.Value.ScatteredDependencyAssetCount);
|
||||
break;
|
||||
|
||||
default:
|
||||
orderedResult = filteredResult;
|
||||
break;
|
||||
}
|
||||
|
||||
return orderedResult.Select(pair => pair.Key).ToArray();
|
||||
}
|
||||
|
||||
public DependencyData GetDependencyData(string assetName)
|
||||
{
|
||||
DependencyData dependencyData = null;
|
||||
if (m_DependencyDatas.TryGetValue(assetName, out dependencyData))
|
||||
{
|
||||
return dependencyData;
|
||||
}
|
||||
|
||||
return dependencyData;
|
||||
}
|
||||
|
||||
public string[] GetScatteredAssetNames()
|
||||
{
|
||||
return GetScatteredAssetNames(ScatteredAssetsOrder.HostAssetCountDesc, null);
|
||||
}
|
||||
|
||||
public string[] GetScatteredAssetNames(ScatteredAssetsOrder order, string filter)
|
||||
{
|
||||
HashSet<string> filterAssetNames = GetFilteredAssetNames(filter);
|
||||
IEnumerable<KeyValuePair<string, List<Asset>>> filteredResult = m_ScatteredAssets.Where(pair => filterAssetNames.Contains(pair.Key) && pair.Value.Count > 1);
|
||||
IEnumerable<KeyValuePair<string, List<Asset>>> orderedResult = null;
|
||||
switch (order)
|
||||
{
|
||||
case ScatteredAssetsOrder.AssetNameAsc:
|
||||
orderedResult = filteredResult.OrderBy(pair => pair.Key);
|
||||
break;
|
||||
|
||||
case ScatteredAssetsOrder.AssetNameDesc:
|
||||
orderedResult = filteredResult.OrderByDescending(pair => pair.Key);
|
||||
break;
|
||||
|
||||
case ScatteredAssetsOrder.HostAssetCountAsc:
|
||||
orderedResult = filteredResult.OrderBy(pair => pair.Value.Count);
|
||||
break;
|
||||
|
||||
case ScatteredAssetsOrder.HostAssetCountDesc:
|
||||
orderedResult = filteredResult.OrderByDescending(pair => pair.Value.Count);
|
||||
break;
|
||||
|
||||
default:
|
||||
orderedResult = filteredResult;
|
||||
break;
|
||||
}
|
||||
|
||||
return orderedResult.Select(pair => pair.Key).ToArray();
|
||||
}
|
||||
|
||||
public Asset[] GetHostAssets(string scatteredAssetName)
|
||||
{
|
||||
List<Asset> assets = null;
|
||||
if (m_ScatteredAssets.TryGetValue(scatteredAssetName, out assets))
|
||||
{
|
||||
return assets.ToArray();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string[][] GetCircularDependencyDatas()
|
||||
{
|
||||
return m_CircularDependencyDatas.ToArray();
|
||||
}
|
||||
|
||||
private HashSet<string> GetFilteredAssetNames(string filter)
|
||||
{
|
||||
string[] filterAssetGuids = AssetDatabase.FindAssets(filter);
|
||||
HashSet<string> filterAssetNames = new HashSet<string>();
|
||||
foreach (string filterAssetGuid in filterAssetGuids)
|
||||
{
|
||||
filterAssetNames.Add(AssetDatabase.GUIDToAssetPath(filterAssetGuid));
|
||||
}
|
||||
|
||||
return filterAssetNames;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f05a10a252bec6c44b19b0cf7c105ff3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,17 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public enum ScatteredAssetsOrder : byte
|
||||
{
|
||||
AssetNameAsc,
|
||||
AssetNameDesc,
|
||||
HostAssetCountAsc,
|
||||
HostAssetCountDesc,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d9068195c1bd334d8dfb4211ad27f7b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2dd745915ad459e4c9d5aef04e1dfeea
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 对 AssetBundle 应用的压缩算法类型。
|
||||
/// </summary>
|
||||
public enum AssetBundleCompressionType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 不使用压缩算法。
|
||||
/// </summary>
|
||||
Uncompressed = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 使用 LZ4 压缩算法。
|
||||
/// </summary>
|
||||
LZ4,
|
||||
|
||||
/// <summary>
|
||||
/// 使用 LZMA 压缩算法。
|
||||
/// </summary>
|
||||
LZMA
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 690743de30449bf46aa333e5117930d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,138 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成资源事件处理函数。
|
||||
/// </summary>
|
||||
public interface IBuildEventHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当某个平台生成失败时,是否继续生成下一个平台。
|
||||
/// </summary>
|
||||
bool ContinueOnFailure
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 所有平台生成开始前的预处理事件。
|
||||
/// </summary>
|
||||
/// <param name="productName">产品名称。</param>
|
||||
/// <param name="companyName">公司名称。</param>
|
||||
/// <param name="gameIdentifier">游戏识别号。</param>
|
||||
/// <param name="gameFrameworkVersion">游戏框架版本。</param>
|
||||
/// <param name="unityVersion">Unity 版本。</param>
|
||||
/// <param name="applicableGameVersion">适用游戏版本。</param>
|
||||
/// <param name="internalResourceVersion">内部资源版本。</param>
|
||||
/// <param name="platforms">生成的目标平台。</param>
|
||||
/// <param name="assetBundleCompression">AssetBundle 压缩类型。</param>
|
||||
/// <param name="compressionHelperTypeName">压缩解压缩辅助器类型名称。</param>
|
||||
/// <param name="additionalCompressionSelected">是否进行再压缩以降低传输开销。</param>
|
||||
/// <param name="forceRebuildAssetBundleSelected">是否强制重新构建 AssetBundle。</param>
|
||||
/// <param name="buildEventHandlerTypeName">生成资源事件处理函数名称。</param>
|
||||
/// <param name="outputDirectory">生成目录。</param>
|
||||
/// <param name="buildAssetBundleOptions">AssetBundle 生成选项。</param>
|
||||
/// <param name="workingPath">生成时的工作路径。</param>
|
||||
/// <param name="outputPackageSelected">是否生成单机模式所需的文件。</param>
|
||||
/// <param name="outputPackagePath">为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
/// <param name="outputFullSelected">是否生成可更新模式所需的远程文件。</param>
|
||||
/// <param name="outputFullPath">为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。</param>
|
||||
/// <param name="outputPackedSelected">是否生成可更新模式所需的本地文件。</param>
|
||||
/// <param name="outputPackedPath">为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
/// <param name="buildReportPath">生成报告路径。</param>
|
||||
void OnPreprocessAllPlatforms(string productName, string companyName, string gameIdentifier, string gameFrameworkVersion, string unityVersion, string applicableGameVersion, int internalResourceVersion,
|
||||
Platform platforms, AssetBundleCompressionType assetBundleCompression, string compressionHelperTypeName, bool additionalCompressionSelected, bool forceRebuildAssetBundleSelected, string buildEventHandlerTypeName, string outputDirectory, BuildAssetBundleOptions buildAssetBundleOptions,
|
||||
string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath, string buildReportPath);
|
||||
|
||||
/// <summary>
|
||||
/// 某个平台生成开始前的预处理事件。
|
||||
/// </summary>
|
||||
/// <param name="platform">生成平台。</param>
|
||||
/// <param name="workingPath">生成时的工作路径。</param>
|
||||
/// <param name="outputPackageSelected">是否生成单机模式所需的文件。</param>
|
||||
/// <param name="outputPackagePath">为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
/// <param name="outputFullSelected">是否生成可更新模式所需的远程文件。</param>
|
||||
/// <param name="outputFullPath">为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。</param>
|
||||
/// <param name="outputPackedSelected">是否生成可更新模式所需的本地文件。</param>
|
||||
/// <param name="outputPackedPath">为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
void OnPreprocessPlatform(Platform platform, string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath);
|
||||
|
||||
/// <summary>
|
||||
/// 某个平台生成 AssetBundle 完成事件。
|
||||
/// </summary>
|
||||
/// <param name="platform">生成平台。</param>
|
||||
/// <param name="workingPath">生成时的工作路径。</param>
|
||||
/// <param name="outputPackageSelected">是否生成单机模式所需的文件。</param>
|
||||
/// <param name="outputPackagePath">为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
/// <param name="outputFullSelected">是否生成可更新模式所需的远程文件。</param>
|
||||
/// <param name="outputFullPath">为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。</param>
|
||||
/// <param name="outputPackedSelected">是否生成可更新模式所需的本地文件。</param>
|
||||
/// <param name="outputPackedPath">为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
/// <param name="assetBundleManifest">AssetBundle 的描述文件。</param>
|
||||
void OnBuildAssetBundlesComplete(Platform platform, string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath, AssetBundleManifest assetBundleManifest);
|
||||
|
||||
/// <summary>
|
||||
/// 某个平台可更新模式版本列表文件的输出事件。
|
||||
/// </summary>
|
||||
/// <param name="platform">生成平台。</param>
|
||||
/// <param name="versionListPath">可更新模式版本列表文件的路径。</param>
|
||||
/// <param name="versionListLength">可更新模式版本列表文件的长度。</param>
|
||||
/// <param name="versionListHashCode">可更新模式版本列表文件的校验值。</param>
|
||||
/// <param name="versionListCompressedLength">可更新模式版本列表文件压缩后的长度。</param>
|
||||
/// <param name="versionListCompressedHashCode">可更新模式版本列表文件压缩后的校验值。</param>
|
||||
void OnOutputUpdatableVersionListData(Platform platform, string versionListPath, int versionListLength, int versionListHashCode, int versionListCompressedLength, int versionListCompressedHashCode);
|
||||
|
||||
/// <summary>
|
||||
/// 某个平台生成结束后的后处理事件。
|
||||
/// </summary>
|
||||
/// <param name="platform">生成平台。</param>
|
||||
/// <param name="workingPath">生成时的工作路径。</param>
|
||||
/// <param name="outputPackageSelected">是否生成单机模式所需的文件。</param>
|
||||
/// <param name="outputPackagePath">为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
/// <param name="outputFullSelected">是否生成可更新模式所需的远程文件。</param>
|
||||
/// <param name="outputFullPath">为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。</param>
|
||||
/// <param name="outputPackedSelected">是否生成可更新模式所需的本地文件。</param>
|
||||
/// <param name="outputPackedPath">为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
/// <param name="isSuccess">是否生成成功。</param>
|
||||
void OnPostprocessPlatform(Platform platform, string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath, bool isSuccess);
|
||||
|
||||
/// <summary>
|
||||
/// 所有平台生成结束后的后处理事件。
|
||||
/// </summary>
|
||||
/// <param name="productName">产品名称。</param>
|
||||
/// <param name="companyName">公司名称。</param>
|
||||
/// <param name="gameIdentifier">游戏识别号。</param>
|
||||
/// <param name="gameFrameworkVersion">游戏框架版本。</param>
|
||||
/// <param name="unityVersion">Unity 版本。</param>
|
||||
/// <param name="applicableGameVersion">适用游戏版本。</param>
|
||||
/// <param name="internalResourceVersion">内部资源版本。</param>
|
||||
/// <param name="platforms">生成的目标平台。</param>
|
||||
/// <param name="assetBundleCompression">AssetBundle 压缩类型。</param>
|
||||
/// <param name="compressionHelperTypeName">压缩解压缩辅助器类型名称。</param>
|
||||
/// <param name="additionalCompressionSelected">是否进行再压缩以降低传输开销。</param>
|
||||
/// <param name="forceRebuildAssetBundleSelected">是否强制重新构建 AssetBundle。</param>
|
||||
/// <param name="buildEventHandlerTypeName">生成资源事件处理函数名称。</param>
|
||||
/// <param name="outputDirectory">生成目录。</param>
|
||||
/// <param name="buildAssetBundleOptions">AssetBundle 生成选项。</param>
|
||||
/// <param name="workingPath">生成时的工作路径。</param>
|
||||
/// <param name="outputPackageSelected">是否生成单机模式所需的文件。</param>
|
||||
/// <param name="outputPackagePath">为单机模式生成的文件存放于此路径。若游戏是单机游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
/// <param name="outputFullSelected">是否生成可更新模式所需的远程文件。</param>
|
||||
/// <param name="outputFullPath">为可更新模式生成的远程文件存放于此路径。若游戏是网络游戏,生成结束后应将此目录上传至 Web 服务器,供玩家下载用。</param>
|
||||
/// <param name="outputPackedSelected">是否生成可更新模式所需的本地文件。</param>
|
||||
/// <param name="outputPackedPath">为可更新模式生成的本地文件存放于此路径。若游戏是网络游戏,生成结束后将此目录中对应平台的文件拷贝至 StreamingAssets 后打包 App 即可。</param>
|
||||
/// <param name="buildReportPath">生成报告路径。</param>
|
||||
void OnPostprocessAllPlatforms(string productName, string companyName, string gameIdentifier, string gameFrameworkVersion, string unityVersion, string applicableGameVersion, int internalResourceVersion,
|
||||
Platform platforms, AssetBundleCompressionType assetBundleCompression, string compressionHelperTypeName, bool additionalCompressionSelected, bool forceRebuildAssetBundleSelected, string buildEventHandlerTypeName, string outputDirectory, BuildAssetBundleOptions buildAssetBundleOptions,
|
||||
string workingPath, bool outputPackageSelected, string outputPackagePath, bool outputFullSelected, string outputFullPath, bool outputPackedSelected, string outputPackedPath, string buildReportPath);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a24c2d69ef707e94c8ec819667089bce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,57 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
[Flags]
|
||||
public enum Platform : int
|
||||
{
|
||||
Undefined = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Windows 32 位。
|
||||
/// </summary>
|
||||
Windows = 1 << 0,
|
||||
|
||||
/// <summary>
|
||||
/// Windows 64 位。
|
||||
/// </summary>
|
||||
Windows64 = 1 << 1,
|
||||
|
||||
/// <summary>
|
||||
/// macOS。
|
||||
/// </summary>
|
||||
MacOS = 1 << 2,
|
||||
|
||||
/// <summary>
|
||||
/// Linux。
|
||||
/// </summary>
|
||||
Linux = 1 << 3,
|
||||
|
||||
/// <summary>
|
||||
/// iOS。
|
||||
/// </summary>
|
||||
IOS = 1 << 4,
|
||||
|
||||
/// <summary>
|
||||
/// Android。
|
||||
/// </summary>
|
||||
Android = 1 << 5,
|
||||
|
||||
/// <summary>
|
||||
/// Windows Store。
|
||||
/// </summary>
|
||||
WindowsStore = 1 << 6,
|
||||
|
||||
/// <summary>
|
||||
/// WebGL。
|
||||
/// </summary>
|
||||
WebGL = 1 << 7,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 443d82794c390e043b1565cea8da60cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,513 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源生成器。
|
||||
/// </summary>
|
||||
internal sealed class ResourceBuilder : EditorWindow
|
||||
{
|
||||
private ResourceBuilderController m_Controller = null;
|
||||
private bool m_OrderBuildResources = false;
|
||||
private int m_CompressionHelperTypeNameIndex = 0;
|
||||
private int m_BuildEventHandlerTypeNameIndex = 0;
|
||||
|
||||
[MenuItem("Game Framework/Resource Tools/Resource Builder", false, 40)]
|
||||
private static void Open()
|
||||
{
|
||||
ResourceBuilder window = GetWindow<ResourceBuilder>("Resource Builder", true);
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
window.minSize = new Vector2(800f, 640f);
|
||||
#else
|
||||
window.minSize = new Vector2(800f, 600f);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_Controller = new ResourceBuilderController();
|
||||
m_Controller.OnLoadingResource += OnLoadingResource;
|
||||
m_Controller.OnLoadingAsset += OnLoadingAsset;
|
||||
m_Controller.OnLoadCompleted += OnLoadCompleted;
|
||||
m_Controller.OnAnalyzingAsset += OnAnalyzingAsset;
|
||||
m_Controller.OnAnalyzeCompleted += OnAnalyzeCompleted;
|
||||
m_Controller.ProcessingAssetBundle += OnProcessingAssetBundle;
|
||||
m_Controller.ProcessingBinary += OnProcessingBinary;
|
||||
m_Controller.ProcessResourceComplete += OnProcessResourceComplete;
|
||||
m_Controller.BuildResourceError += OnBuildResourceError;
|
||||
|
||||
m_OrderBuildResources = false;
|
||||
|
||||
if (m_Controller.Load())
|
||||
{
|
||||
Debug.Log("Load configuration success.");
|
||||
|
||||
m_CompressionHelperTypeNameIndex = 0;
|
||||
string[] compressionHelperTypeNames = m_Controller.GetCompressionHelperTypeNames();
|
||||
for (int i = 0; i < compressionHelperTypeNames.Length; i++)
|
||||
{
|
||||
if (m_Controller.CompressionHelperTypeName == compressionHelperTypeNames[i])
|
||||
{
|
||||
m_CompressionHelperTypeNameIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_Controller.RefreshCompressionHelper();
|
||||
|
||||
m_BuildEventHandlerTypeNameIndex = 0;
|
||||
string[] buildEventHandlerTypeNames = m_Controller.GetBuildEventHandlerTypeNames();
|
||||
for (int i = 0; i < buildEventHandlerTypeNames.Length; i++)
|
||||
{
|
||||
if (m_Controller.BuildEventHandlerTypeName == buildEventHandlerTypeNames[i])
|
||||
{
|
||||
m_BuildEventHandlerTypeNameIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_Controller.RefreshBuildEventHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Load configuration failure.");
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (m_OrderBuildResources)
|
||||
{
|
||||
m_OrderBuildResources = false;
|
||||
BuildResources();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height));
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.LabelField("Environment Information", EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Product Name", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.ProductName);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Company Name", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.CompanyName);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Game Identifier", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.GameIdentifier);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Game Framework Version", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.GameFrameworkVersion);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Unity Version", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.UnityVersion);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Applicable Game Version", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.ApplicableGameVersion);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
EditorGUILayout.LabelField("Platforms", EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginHorizontal("box");
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
DrawPlatform(Platform.Windows, "Windows");
|
||||
DrawPlatform(Platform.Windows64, "Windows x64");
|
||||
DrawPlatform(Platform.MacOS, "macOS");
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
DrawPlatform(Platform.Linux, "Linux");
|
||||
DrawPlatform(Platform.IOS, "iOS");
|
||||
DrawPlatform(Platform.Android, "Android");
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
DrawPlatform(Platform.WindowsStore, "Windows Store");
|
||||
DrawPlatform(Platform.WebGL, "WebGL");
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.LabelField("Compression", EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("AssetBundle Compression", GUILayout.Width(160f));
|
||||
m_Controller.AssetBundleCompression = (AssetBundleCompressionType)EditorGUILayout.EnumPopup(m_Controller.AssetBundleCompression);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Compression Helper", GUILayout.Width(160f));
|
||||
string[] names = m_Controller.GetCompressionHelperTypeNames();
|
||||
int selectedIndex = EditorGUILayout.Popup(m_CompressionHelperTypeNameIndex, names);
|
||||
if (selectedIndex != m_CompressionHelperTypeNameIndex)
|
||||
{
|
||||
m_CompressionHelperTypeNameIndex = selectedIndex;
|
||||
m_Controller.CompressionHelperTypeName = selectedIndex <= 0 ? string.Empty : names[selectedIndex];
|
||||
if (m_Controller.RefreshCompressionHelper())
|
||||
{
|
||||
Debug.Log("Set compression helper success.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Set compression helper failure.");
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Additional Compression", GUILayout.Width(160f));
|
||||
m_Controller.AdditionalCompressionSelected = EditorGUILayout.ToggleLeft("Additional Compression for Output Full Resources with Compression Helper", m_Controller.AdditionalCompressionSelected);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.LabelField("Build", EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Force Rebuild AssetBundle", GUILayout.Width(160f));
|
||||
m_Controller.ForceRebuildAssetBundleSelected = EditorGUILayout.Toggle(m_Controller.ForceRebuildAssetBundleSelected);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Build Event Handler", GUILayout.Width(160f));
|
||||
string[] names = m_Controller.GetBuildEventHandlerTypeNames();
|
||||
int selectedIndex = EditorGUILayout.Popup(m_BuildEventHandlerTypeNameIndex, names);
|
||||
if (selectedIndex != m_BuildEventHandlerTypeNameIndex)
|
||||
{
|
||||
m_BuildEventHandlerTypeNameIndex = selectedIndex;
|
||||
m_Controller.BuildEventHandlerTypeName = selectedIndex <= 0 ? string.Empty : names[selectedIndex];
|
||||
if (m_Controller.RefreshBuildEventHandler())
|
||||
{
|
||||
Debug.Log("Set build event handler success.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Set build event handler failure.");
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Internal Resource Version", GUILayout.Width(160f));
|
||||
m_Controller.InternalResourceVersion = EditorGUILayout.IntField(m_Controller.InternalResourceVersion);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Resource Version", GUILayout.Width(160f));
|
||||
GUILayout.Label(Utility.Text.Format("{0} ({1})", m_Controller.ApplicableGameVersion, m_Controller.InternalResourceVersion));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Output Directory", GUILayout.Width(160f));
|
||||
m_Controller.OutputDirectory = EditorGUILayout.TextField(m_Controller.OutputDirectory);
|
||||
if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
|
||||
{
|
||||
BrowseOutputDirectory();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Working Path", GUILayout.Width(160f));
|
||||
GUILayout.Label(m_Controller.WorkingPath);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(!m_Controller.OutputPackageSelected);
|
||||
EditorGUILayout.LabelField("Output Package Path", GUILayout.Width(160f));
|
||||
GUILayout.Label(m_Controller.OutputPackagePath);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
m_Controller.OutputPackageSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputPackageSelected, GUILayout.Width(70f));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(!m_Controller.OutputFullSelected);
|
||||
EditorGUILayout.LabelField("Output Full Path", GUILayout.Width(160f));
|
||||
GUILayout.Label(m_Controller.OutputFullPath);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
m_Controller.OutputFullSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputFullSelected, GUILayout.Width(70f));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(!m_Controller.OutputPackedSelected);
|
||||
EditorGUILayout.LabelField("Output Packed Path", GUILayout.Width(160f));
|
||||
GUILayout.Label(m_Controller.OutputPackedPath);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
m_Controller.OutputPackedSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputPackedSelected, GUILayout.Width(70f));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Build Report Path", GUILayout.Width(160f));
|
||||
GUILayout.Label(m_Controller.BuildReportPath);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
string buildMessage = string.Empty;
|
||||
MessageType buildMessageType = MessageType.None;
|
||||
GetBuildMessage(out buildMessage, out buildMessageType);
|
||||
EditorGUILayout.HelpBox(buildMessage, buildMessageType);
|
||||
GUILayout.Space(2f);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(m_Controller.Platforms == Platform.Undefined || string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName) || !m_Controller.IsValidOutputDirectory);
|
||||
{
|
||||
if (GUILayout.Button("Start Build Resources"))
|
||||
{
|
||||
m_OrderBuildResources = true;
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
if (GUILayout.Button("Save", GUILayout.Width(80f)))
|
||||
{
|
||||
SaveConfiguration();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void BrowseOutputDirectory()
|
||||
{
|
||||
string directory = EditorUtility.OpenFolderPanel("Select Output Directory", m_Controller.OutputDirectory, string.Empty);
|
||||
if (!string.IsNullOrEmpty(directory))
|
||||
{
|
||||
m_Controller.OutputDirectory = directory;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetBuildMessage(out string message, out MessageType messageType)
|
||||
{
|
||||
message = string.Empty;
|
||||
messageType = MessageType.Error;
|
||||
if (m_Controller.Platforms == Platform.Undefined)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
message += Environment.NewLine;
|
||||
}
|
||||
|
||||
message += "Platform is invalid.";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
message += Environment.NewLine;
|
||||
}
|
||||
|
||||
message += "Compression helper is invalid.";
|
||||
}
|
||||
|
||||
if (!m_Controller.IsValidOutputDirectory)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
message += Environment.NewLine;
|
||||
}
|
||||
|
||||
message += "Output directory is invalid.";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
messageType = MessageType.Info;
|
||||
if (Directory.Exists(m_Controller.OutputPackagePath))
|
||||
{
|
||||
message += Utility.Text.Format("{0} will be overwritten.", m_Controller.OutputPackagePath);
|
||||
messageType = MessageType.Warning;
|
||||
}
|
||||
|
||||
if (Directory.Exists(m_Controller.OutputFullPath))
|
||||
{
|
||||
if (message.Length > 0)
|
||||
{
|
||||
message += " ";
|
||||
}
|
||||
|
||||
message += Utility.Text.Format("{0} will be overwritten.", m_Controller.OutputFullPath);
|
||||
messageType = MessageType.Warning;
|
||||
}
|
||||
|
||||
if (Directory.Exists(m_Controller.OutputPackedPath))
|
||||
{
|
||||
if (message.Length > 0)
|
||||
{
|
||||
message += " ";
|
||||
}
|
||||
|
||||
message += Utility.Text.Format("{0} will be overwritten.", m_Controller.OutputPackedPath);
|
||||
messageType = MessageType.Warning;
|
||||
}
|
||||
|
||||
if (messageType == MessageType.Warning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
message = "Ready to build.";
|
||||
}
|
||||
|
||||
private void BuildResources()
|
||||
{
|
||||
if (m_Controller.BuildResources())
|
||||
{
|
||||
Debug.Log("Build resources success.");
|
||||
SaveConfiguration();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Build resources failure.");
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveConfiguration()
|
||||
{
|
||||
if (m_Controller.Save())
|
||||
{
|
||||
Debug.Log("Save configuration success.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Save configuration failure.");
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPlatform(Platform platform, string platformName)
|
||||
{
|
||||
m_Controller.SelectPlatform(platform, EditorGUILayout.ToggleLeft(platformName, m_Controller.IsPlatformSelected(platform)));
|
||||
}
|
||||
|
||||
private void OnLoadingResource(int index, int count)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index, count), (float)index / count);
|
||||
}
|
||||
|
||||
private void OnLoadingAsset(int index, int count)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index, count), (float)index / count);
|
||||
}
|
||||
|
||||
private void OnLoadCompleted()
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
private void OnAnalyzingAsset(int index, int count)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Analyzing Assets", Utility.Text.Format("Analyzing assets, {0}/{1} analyzed.", index, count), (float)index / count);
|
||||
}
|
||||
|
||||
private void OnAnalyzeCompleted()
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
private bool OnProcessingAssetBundle(string assetBundleName, float progress)
|
||||
{
|
||||
if (EditorUtility.DisplayCancelableProgressBar("Processing AssetBundle", Utility.Text.Format("Processing '{0}'...", assetBundleName), progress))
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Repaint();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool OnProcessingBinary(string binaryName, float progress)
|
||||
{
|
||||
if (EditorUtility.DisplayCancelableProgressBar("Processing Binary", Utility.Text.Format("Processing '{0}'...", binaryName), progress))
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Repaint();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnProcessResourceComplete(Platform platform)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
Debug.Log(Utility.Text.Format("Build resources for '{0}' complete.", platform));
|
||||
}
|
||||
|
||||
private void OnBuildResourceError(string errorMessage)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
Debug.LogWarning(Utility.Text.Format("Build resources error with error message '{0}'.", errorMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e863c5f9e4c0a9d47a926fbb0416a149
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,16 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// ResourceBuilder 配置路径属性。
|
||||
/// </summary>
|
||||
public sealed class ResourceBuilderConfigPathAttribute : ConfigPathAttribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 099a19e921c6da944ba2cdf51139d818
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,67 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed partial class ResourceBuilderController
|
||||
{
|
||||
private sealed class AssetData
|
||||
{
|
||||
private readonly string m_Guid;
|
||||
private readonly string m_Name;
|
||||
private readonly int m_Length;
|
||||
private readonly int m_HashCode;
|
||||
private readonly string[] m_DependencyAssetNames;
|
||||
|
||||
public AssetData(string guid, string name, int length, int hashCode, string[] dependencyAssetNames)
|
||||
{
|
||||
m_Guid = guid;
|
||||
m_Name = name;
|
||||
m_Length = length;
|
||||
m_HashCode = hashCode;
|
||||
m_DependencyAssetNames = dependencyAssetNames;
|
||||
}
|
||||
|
||||
public string Guid
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Guid;
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Length;
|
||||
}
|
||||
}
|
||||
|
||||
public int HashCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HashCode;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetDependencyAssetNames()
|
||||
{
|
||||
return m_DependencyAssetNames;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b52ab112713ba504a84693edd59a6b03
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,276 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed partial class ResourceBuilderController
|
||||
{
|
||||
private sealed class BuildReport
|
||||
{
|
||||
private const string BuildReportName = "BuildReport.xml";
|
||||
private const string BuildLogName = "BuildLog.txt";
|
||||
|
||||
private string m_BuildReportName = null;
|
||||
private string m_BuildLogName = null;
|
||||
private string m_ProductName = null;
|
||||
private string m_CompanyName = null;
|
||||
private string m_GameIdentifier = null;
|
||||
private string m_GameFrameworkVersion = null;
|
||||
private string m_UnityVersion = null;
|
||||
private string m_ApplicableGameVersion = null;
|
||||
private int m_InternalResourceVersion = 0;
|
||||
private Platform m_Platforms = Platform.Undefined;
|
||||
private AssetBundleCompressionType m_AssetBundleCompression;
|
||||
private string m_CompressionHelperTypeName;
|
||||
private bool m_AdditionalCompressionSelected = false;
|
||||
private bool m_ForceRebuildAssetBundleSelected = false;
|
||||
private string m_BuildEventHandlerTypeName;
|
||||
private string m_OutputDirectory;
|
||||
private BuildAssetBundleOptions m_BuildAssetBundleOptions = BuildAssetBundleOptions.None;
|
||||
private StringBuilder m_LogBuilder = null;
|
||||
private SortedDictionary<string, ResourceData> m_ResourceDatas = null;
|
||||
|
||||
public void Initialize(string buildReportPath, string productName, string companyName, string gameIdentifier, string gameFrameworkVersion, string unityVersion, string applicableGameVersion, int internalResourceVersion,
|
||||
Platform platforms, AssetBundleCompressionType assetBundleCompression, string compressionHelperTypeName, bool additionalCompressionSelected, bool forceRebuildAssetBundleSelected, string buildEventHandlerTypeName, string outputDirectory, BuildAssetBundleOptions buildAssetBundleOptions, SortedDictionary<string, ResourceData> resourceDatas)
|
||||
{
|
||||
if (string.IsNullOrEmpty(buildReportPath))
|
||||
{
|
||||
throw new GameFrameworkException("Build report path is invalid.");
|
||||
}
|
||||
|
||||
m_BuildReportName = Utility.Path.GetRegularPath(Path.Combine(buildReportPath, BuildReportName));
|
||||
m_BuildLogName = Utility.Path.GetRegularPath(Path.Combine(buildReportPath, BuildLogName));
|
||||
m_ProductName = productName;
|
||||
m_CompanyName = companyName;
|
||||
m_GameIdentifier = gameIdentifier;
|
||||
m_GameFrameworkVersion = gameFrameworkVersion;
|
||||
m_UnityVersion = unityVersion;
|
||||
m_ApplicableGameVersion = applicableGameVersion;
|
||||
m_InternalResourceVersion = internalResourceVersion;
|
||||
m_Platforms = platforms;
|
||||
m_AssetBundleCompression = assetBundleCompression;
|
||||
m_CompressionHelperTypeName = compressionHelperTypeName;
|
||||
m_AdditionalCompressionSelected = additionalCompressionSelected;
|
||||
m_ForceRebuildAssetBundleSelected = forceRebuildAssetBundleSelected;
|
||||
m_BuildEventHandlerTypeName = buildEventHandlerTypeName;
|
||||
m_OutputDirectory = outputDirectory;
|
||||
m_BuildAssetBundleOptions = buildAssetBundleOptions;
|
||||
m_LogBuilder = new StringBuilder();
|
||||
m_ResourceDatas = resourceDatas;
|
||||
}
|
||||
|
||||
public void LogInfo(string format, params object[] args)
|
||||
{
|
||||
LogInternal("INFO", format, args);
|
||||
}
|
||||
|
||||
public void LogWarning(string format, params object[] args)
|
||||
{
|
||||
LogInternal("WARNING", format, args);
|
||||
}
|
||||
|
||||
public void LogError(string format, params object[] args)
|
||||
{
|
||||
LogInternal("ERROR", format, args);
|
||||
}
|
||||
|
||||
public void LogFatal(string format, params object[] args)
|
||||
{
|
||||
LogInternal("FATAL", format, args);
|
||||
}
|
||||
|
||||
public void SaveReport()
|
||||
{
|
||||
XmlElement xmlElement = null;
|
||||
XmlAttribute xmlAttribute = null;
|
||||
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.AppendChild(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null));
|
||||
|
||||
XmlElement xmlRoot = xmlDocument.CreateElement("UnityGameFramework");
|
||||
xmlDocument.AppendChild(xmlRoot);
|
||||
|
||||
XmlElement xmlBuildReport = xmlDocument.CreateElement("BuildReport");
|
||||
xmlRoot.AppendChild(xmlBuildReport);
|
||||
|
||||
XmlElement xmlSummary = xmlDocument.CreateElement("Summary");
|
||||
xmlBuildReport.AppendChild(xmlSummary);
|
||||
|
||||
xmlElement = xmlDocument.CreateElement("ProductName");
|
||||
xmlElement.InnerText = m_ProductName;
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("CompanyName");
|
||||
xmlElement.InnerText = m_CompanyName;
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("GameIdentifier");
|
||||
xmlElement.InnerText = m_GameIdentifier;
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("GameFrameworkVersion");
|
||||
xmlElement.InnerText = m_GameFrameworkVersion;
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("UnityVersion");
|
||||
xmlElement.InnerText = m_UnityVersion;
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("ApplicableGameVersion");
|
||||
xmlElement.InnerText = m_ApplicableGameVersion;
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("InternalResourceVersion");
|
||||
xmlElement.InnerText = m_InternalResourceVersion.ToString();
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("Platforms");
|
||||
xmlElement.InnerText = m_Platforms.ToString();
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("AssetBundleCompression");
|
||||
xmlElement.InnerText = m_AssetBundleCompression.ToString();
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("CompressionHelperTypeName");
|
||||
xmlElement.InnerText = m_CompressionHelperTypeName;
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("AdditionalCompressionSelected");
|
||||
xmlElement.InnerText = m_AdditionalCompressionSelected.ToString();
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("ForceRebuildAssetBundleSelected");
|
||||
xmlElement.InnerText = m_ForceRebuildAssetBundleSelected.ToString();
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("BuildEventHandlerTypeName");
|
||||
xmlElement.InnerText = m_BuildEventHandlerTypeName;
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("OutputDirectory");
|
||||
xmlElement.InnerText = m_OutputDirectory;
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("BuildAssetBundleOptions");
|
||||
xmlElement.InnerText = m_BuildAssetBundleOptions.ToString();
|
||||
xmlSummary.AppendChild(xmlElement);
|
||||
|
||||
XmlElement xmlResources = xmlDocument.CreateElement("Resources");
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Count");
|
||||
xmlAttribute.Value = m_ResourceDatas.Count.ToString();
|
||||
xmlResources.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlBuildReport.AppendChild(xmlResources);
|
||||
foreach (ResourceData resourceData in m_ResourceDatas.Values)
|
||||
{
|
||||
XmlElement xmlResource = xmlDocument.CreateElement("Resource");
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Name");
|
||||
xmlAttribute.Value = resourceData.Name;
|
||||
xmlResource.Attributes.SetNamedItem(xmlAttribute);
|
||||
if (resourceData.Variant != null)
|
||||
{
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Variant");
|
||||
xmlAttribute.Value = resourceData.Variant;
|
||||
xmlResource.Attributes.SetNamedItem(xmlAttribute);
|
||||
}
|
||||
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Extension");
|
||||
xmlAttribute.Value = GetExtension(resourceData);
|
||||
xmlResource.Attributes.SetNamedItem(xmlAttribute);
|
||||
|
||||
if (resourceData.FileSystem != null)
|
||||
{
|
||||
xmlAttribute = xmlDocument.CreateAttribute("FileSystem");
|
||||
xmlAttribute.Value = resourceData.FileSystem;
|
||||
xmlResource.Attributes.SetNamedItem(xmlAttribute);
|
||||
}
|
||||
|
||||
xmlAttribute = xmlDocument.CreateAttribute("LoadType");
|
||||
xmlAttribute.Value = ((byte)resourceData.LoadType).ToString();
|
||||
xmlResource.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Packed");
|
||||
xmlAttribute.Value = resourceData.Packed.ToString();
|
||||
xmlResource.Attributes.SetNamedItem(xmlAttribute);
|
||||
string[] resourceGroups = resourceData.GetResourceGroups();
|
||||
if (resourceGroups.Length > 0)
|
||||
{
|
||||
xmlAttribute = xmlDocument.CreateAttribute("ResourceGroups");
|
||||
xmlAttribute.Value = string.Join(",", resourceGroups);
|
||||
xmlResource.Attributes.SetNamedItem(xmlAttribute);
|
||||
}
|
||||
|
||||
xmlResources.AppendChild(xmlResource);
|
||||
|
||||
AssetData[] assetDatas = resourceData.GetAssetDatas();
|
||||
XmlElement xmlAssets = xmlDocument.CreateElement("Assets");
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Count");
|
||||
xmlAttribute.Value = assetDatas.Length.ToString();
|
||||
xmlAssets.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlResource.AppendChild(xmlAssets);
|
||||
foreach (AssetData assetData in assetDatas)
|
||||
{
|
||||
XmlElement xmlAsset = xmlDocument.CreateElement("Asset");
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Guid");
|
||||
xmlAttribute.Value = assetData.Guid;
|
||||
xmlAsset.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Name");
|
||||
xmlAttribute.Value = assetData.Name;
|
||||
xmlAsset.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Length");
|
||||
xmlAttribute.Value = assetData.Length.ToString();
|
||||
xmlAsset.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAttribute = xmlDocument.CreateAttribute("HashCode");
|
||||
xmlAttribute.Value = assetData.HashCode.ToString();
|
||||
xmlAsset.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAssets.AppendChild(xmlAsset);
|
||||
string[] dependencyAssetNames = assetData.GetDependencyAssetNames();
|
||||
if (dependencyAssetNames.Length > 0)
|
||||
{
|
||||
XmlElement xmlDependencyAssets = xmlDocument.CreateElement("DependencyAssets");
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Count");
|
||||
xmlAttribute.Value = dependencyAssetNames.Length.ToString();
|
||||
xmlDependencyAssets.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAsset.AppendChild(xmlDependencyAssets);
|
||||
foreach (string dependencyAssetName in dependencyAssetNames)
|
||||
{
|
||||
XmlElement xmlDependencyAsset = xmlDocument.CreateElement("DependencyAsset");
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Name");
|
||||
xmlAttribute.Value = dependencyAssetName;
|
||||
xmlDependencyAsset.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlDependencyAssets.AppendChild(xmlDependencyAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XmlElement xmlCodes = xmlDocument.CreateElement("Codes");
|
||||
xmlResource.AppendChild(xmlCodes);
|
||||
foreach (ResourceCode resourceCode in resourceData.GetCodes())
|
||||
{
|
||||
XmlElement xmlCode = xmlDocument.CreateElement(resourceCode.Platform.ToString());
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Length");
|
||||
xmlAttribute.Value = resourceCode.Length.ToString();
|
||||
xmlCode.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAttribute = xmlDocument.CreateAttribute("HashCode");
|
||||
xmlAttribute.Value = resourceCode.HashCode.ToString();
|
||||
xmlCode.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAttribute = xmlDocument.CreateAttribute("CompressedLength");
|
||||
xmlAttribute.Value = resourceCode.CompressedLength.ToString();
|
||||
xmlCode.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAttribute = xmlDocument.CreateAttribute("CompressedHashCode");
|
||||
xmlAttribute.Value = resourceCode.CompressedHashCode.ToString();
|
||||
xmlCode.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlCodes.AppendChild(xmlCode);
|
||||
}
|
||||
}
|
||||
|
||||
xmlDocument.Save(m_BuildReportName);
|
||||
File.WriteAllText(m_BuildLogName, m_LogBuilder.ToString());
|
||||
}
|
||||
|
||||
private void LogInternal(string type, string format, object[] args)
|
||||
{
|
||||
m_LogBuilder.AppendFormat("[{0:HH:mm:ss.fff}][{1}] ", DateTime.UtcNow.ToLocalTime(), type);
|
||||
m_LogBuilder.AppendFormat(format, args);
|
||||
m_LogBuilder.AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae0020ba4726cbd46b34a2341c16cd6a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework.FileSystem;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed partial class ResourceBuilderController
|
||||
{
|
||||
private sealed class FileSystemHelper : IFileSystemHelper
|
||||
{
|
||||
public FileSystemStream CreateFileSystemStream(string fullPath, FileSystemAccess access, bool createNew)
|
||||
{
|
||||
return new CommonFileSystemStream(fullPath, access, createNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23c25a2b879a092409b04f2e7851ac6b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,70 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed partial class ResourceBuilderController
|
||||
{
|
||||
private sealed class ResourceCode
|
||||
{
|
||||
private readonly Platform m_Platform;
|
||||
private readonly int m_Length;
|
||||
private readonly int m_HashCode;
|
||||
private readonly int m_CompressedLength;
|
||||
private readonly int m_CompressedHashCode;
|
||||
|
||||
public ResourceCode(Platform platform, int length, int hashCode, int compressedLength, int compressedHashCode)
|
||||
{
|
||||
m_Platform = platform;
|
||||
m_Length = length;
|
||||
m_HashCode = hashCode;
|
||||
m_CompressedLength = compressedLength;
|
||||
m_CompressedHashCode = compressedHashCode;
|
||||
}
|
||||
|
||||
public Platform Platform
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Platform;
|
||||
}
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Length;
|
||||
}
|
||||
}
|
||||
|
||||
public int HashCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HashCode;
|
||||
}
|
||||
}
|
||||
|
||||
public int CompressedLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_CompressedLength;
|
||||
}
|
||||
}
|
||||
|
||||
public int CompressedHashCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_CompressedHashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86943b1b61e58a340b707c7c11f47700
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,167 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed partial class ResourceBuilderController
|
||||
{
|
||||
private sealed class ResourceData
|
||||
{
|
||||
private readonly string m_Name;
|
||||
private readonly string m_Variant;
|
||||
private readonly string m_FileSystem;
|
||||
private readonly LoadType m_LoadType;
|
||||
private readonly bool m_Packed;
|
||||
private readonly string[] m_ResourceGroups;
|
||||
private readonly List<AssetData> m_AssetDatas;
|
||||
private readonly List<ResourceCode> m_Codes;
|
||||
|
||||
public ResourceData(string name, string variant, string fileSystem, LoadType loadType, bool packed, string[] resourceGroups)
|
||||
{
|
||||
m_Name = name;
|
||||
m_Variant = variant;
|
||||
m_FileSystem = fileSystem;
|
||||
m_LoadType = loadType;
|
||||
m_Packed = packed;
|
||||
m_ResourceGroups = resourceGroups;
|
||||
m_AssetDatas = new List<AssetData>();
|
||||
m_Codes = new List<ResourceCode>();
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
|
||||
public string Variant
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Variant;
|
||||
}
|
||||
}
|
||||
|
||||
public string FileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_FileSystem;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsLoadFromBinary
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_LoadType == LoadType.LoadFromBinary || m_LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || m_LoadType == LoadType.LoadFromBinaryAndDecrypt;
|
||||
}
|
||||
}
|
||||
|
||||
public LoadType LoadType
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_LoadType;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Packed
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Packed;
|
||||
}
|
||||
}
|
||||
|
||||
public int AssetCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_AssetDatas.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetResourceGroups()
|
||||
{
|
||||
return m_ResourceGroups;
|
||||
}
|
||||
|
||||
public string[] GetAssetGuids()
|
||||
{
|
||||
string[] assetGuids = new string[m_AssetDatas.Count];
|
||||
for (int i = 0; i < m_AssetDatas.Count; i++)
|
||||
{
|
||||
assetGuids[i] = m_AssetDatas[i].Guid;
|
||||
}
|
||||
|
||||
return assetGuids;
|
||||
}
|
||||
|
||||
public string[] GetAssetNames()
|
||||
{
|
||||
string[] assetNames = new string[m_AssetDatas.Count];
|
||||
for (int i = 0; i < m_AssetDatas.Count; i++)
|
||||
{
|
||||
assetNames[i] = m_AssetDatas[i].Name;
|
||||
}
|
||||
|
||||
return assetNames;
|
||||
}
|
||||
|
||||
public AssetData[] GetAssetDatas()
|
||||
{
|
||||
return m_AssetDatas.ToArray();
|
||||
}
|
||||
|
||||
public AssetData GetAssetData(string assetName)
|
||||
{
|
||||
foreach (AssetData assetData in m_AssetDatas)
|
||||
{
|
||||
if (assetData.Name == assetName)
|
||||
{
|
||||
return assetData;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void AddAssetData(string guid, string name, int length, int hashCode, string[] dependencyAssetNames)
|
||||
{
|
||||
m_AssetDatas.Add(new AssetData(guid, name, length, hashCode, dependencyAssetNames));
|
||||
}
|
||||
|
||||
public ResourceCode GetCode(Platform platform)
|
||||
{
|
||||
foreach (ResourceCode code in m_Codes)
|
||||
{
|
||||
if (code.Platform == platform)
|
||||
{
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResourceCode[] GetCodes()
|
||||
{
|
||||
return m_Codes.ToArray();
|
||||
}
|
||||
|
||||
public void AddCode(Platform platform, int length, int hashCode, int compressedLength, int compressedHashCode)
|
||||
{
|
||||
m_Codes.Add(new ResourceCode(platform, length, hashCode, compressedLength, compressedHashCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61757cf57a877ce46a12429a7e8996dd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,54 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed partial class ResourceBuilderController
|
||||
{
|
||||
private sealed class VersionListData
|
||||
{
|
||||
public VersionListData(string path, int length, int hashCode, int compressedLength, int compressedHashCode)
|
||||
{
|
||||
Path = path;
|
||||
Length = length;
|
||||
HashCode = hashCode;
|
||||
CompressedLength = compressedLength;
|
||||
CompressedHashCode = compressedHashCode;
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public int HashCode
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public int CompressedLength
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public int CompressedHashCode
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c69cd2ac760709b4ab36ba15bc5d8759
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2678da0502f5874429b8bce3d35f573f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc804e13da19ff043aac07751e249b43
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,59 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源。
|
||||
/// </summary>
|
||||
public sealed class Asset : IComparable<Asset>
|
||||
{
|
||||
private Asset(string guid, Resource resource)
|
||||
{
|
||||
Guid = guid;
|
||||
Resource = resource;
|
||||
}
|
||||
|
||||
public string Guid
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return AssetDatabase.GUIDToAssetPath(Guid);
|
||||
}
|
||||
}
|
||||
|
||||
public Resource Resource
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public int CompareTo(Asset asset)
|
||||
{
|
||||
return string.Compare(Guid, asset.Guid, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static Asset Create(string guid)
|
||||
{
|
||||
return new Asset(guid, null);
|
||||
}
|
||||
|
||||
public static Asset Create(string guid, Resource resource)
|
||||
{
|
||||
return new Asset(guid, resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0147356ab2aa7548b5448288d785afe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源类型。
|
||||
/// </summary>
|
||||
public enum AssetType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 未知。
|
||||
/// </summary>
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 存放资源。
|
||||
/// </summary>
|
||||
Asset,
|
||||
|
||||
/// <summary>
|
||||
/// 存放场景。
|
||||
/// </summary>
|
||||
Scene,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca96b555ae5b2c34e8cc830446f11525
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,50 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源加载方式类型。
|
||||
/// </summary>
|
||||
public enum LoadType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用文件方式加载。
|
||||
/// </summary>
|
||||
LoadFromFile = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 使用内存方式加载。
|
||||
/// </summary>
|
||||
LoadFromMemory,
|
||||
|
||||
/// <summary>
|
||||
/// 使用内存快速解密方式加载。
|
||||
/// </summary>
|
||||
LoadFromMemoryAndQuickDecrypt,
|
||||
|
||||
/// <summary>
|
||||
/// 使用内存解密方式加载。
|
||||
/// </summary>
|
||||
LoadFromMemoryAndDecrypt,
|
||||
|
||||
/// <summary>
|
||||
/// 使用二进制方式加载。
|
||||
/// </summary>
|
||||
LoadFromBinary,
|
||||
|
||||
/// <summary>
|
||||
/// 使用二进制快速解密方式加载。
|
||||
/// </summary>
|
||||
LoadFromBinaryAndQuickDecrypt,
|
||||
|
||||
/// <summary>
|
||||
/// 使用二进制解密方式加载。
|
||||
/// </summary>
|
||||
LoadFromBinaryAndDecrypt
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5660cbfaa767b84fbc1ef8799919b26
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,192 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源。
|
||||
/// </summary>
|
||||
public sealed class Resource
|
||||
{
|
||||
private readonly List<Asset> m_Assets;
|
||||
private readonly List<string> m_ResourceGroups;
|
||||
|
||||
private Resource(string name, string variant, string fileSystem, LoadType loadType, bool packed, string[] resourceGroups)
|
||||
{
|
||||
m_Assets = new List<Asset>();
|
||||
m_ResourceGroups = new List<string>();
|
||||
|
||||
Name = name;
|
||||
Variant = variant;
|
||||
AssetType = AssetType.Unknown;
|
||||
FileSystem = fileSystem;
|
||||
LoadType = loadType;
|
||||
Packed = packed;
|
||||
|
||||
foreach (string resourceGroup in resourceGroups)
|
||||
{
|
||||
AddResourceGroup(resourceGroup);
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Variant
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string FullName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Variant != null ? Utility.Text.Format("{0}.{1}", Name, Variant) : Name;
|
||||
}
|
||||
}
|
||||
|
||||
public AssetType AssetType
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool IsLoadFromBinary
|
||||
{
|
||||
get
|
||||
{
|
||||
return LoadType == LoadType.LoadFromBinary || LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || LoadType == LoadType.LoadFromBinaryAndDecrypt;
|
||||
}
|
||||
}
|
||||
|
||||
public string FileSystem
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public LoadType LoadType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool Packed
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public static Resource Create(string name, string variant, string fileSystem, LoadType loadType, bool packed, string[] resourceGroups)
|
||||
{
|
||||
return new Resource(name, variant, fileSystem, loadType, packed, resourceGroups ?? new string[0]);
|
||||
}
|
||||
|
||||
public Asset[] GetAssets()
|
||||
{
|
||||
return m_Assets.ToArray();
|
||||
}
|
||||
|
||||
public Asset GetFirstAsset()
|
||||
{
|
||||
return m_Assets.Count > 0 ? m_Assets[0] : null;
|
||||
}
|
||||
|
||||
public void Rename(string name, string variant)
|
||||
{
|
||||
Name = name;
|
||||
Variant = variant;
|
||||
}
|
||||
|
||||
public void AssignAsset(Asset asset, bool isScene)
|
||||
{
|
||||
if (asset.Resource != null)
|
||||
{
|
||||
asset.Resource.UnassignAsset(asset);
|
||||
}
|
||||
|
||||
AssetType = isScene ? AssetType.Scene : AssetType.Asset;
|
||||
asset.Resource = this;
|
||||
m_Assets.Add(asset);
|
||||
m_Assets.Sort(AssetComparer);
|
||||
}
|
||||
|
||||
public void UnassignAsset(Asset asset)
|
||||
{
|
||||
asset.Resource = null;
|
||||
m_Assets.Remove(asset);
|
||||
if (m_Assets.Count <= 0)
|
||||
{
|
||||
AssetType = AssetType.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetResourceGroups()
|
||||
{
|
||||
return m_ResourceGroups.ToArray();
|
||||
}
|
||||
|
||||
public bool HasResourceGroup(string resourceGroup)
|
||||
{
|
||||
if (string.IsNullOrEmpty(resourceGroup))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_ResourceGroups.Contains(resourceGroup);
|
||||
}
|
||||
|
||||
public void AddResourceGroup(string resourceGroup)
|
||||
{
|
||||
if (string.IsNullOrEmpty(resourceGroup))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ResourceGroups.Contains(resourceGroup))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_ResourceGroups.Add(resourceGroup);
|
||||
m_ResourceGroups.Sort();
|
||||
}
|
||||
|
||||
public bool RemoveResourceGroup(string resourceGroup)
|
||||
{
|
||||
if (string.IsNullOrEmpty(resourceGroup))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_ResourceGroups.Remove(resourceGroup);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach (Asset asset in m_Assets)
|
||||
{
|
||||
asset.Resource = null;
|
||||
}
|
||||
|
||||
m_Assets.Clear();
|
||||
m_ResourceGroups.Clear();
|
||||
}
|
||||
|
||||
private int AssetComparer(Asset a, Asset b)
|
||||
{
|
||||
return a.Guid.CompareTo(b.Guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d3d5c5d16bedc54c976247a6a5b429e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,635 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源集合。
|
||||
/// </summary>
|
||||
public sealed class ResourceCollection
|
||||
{
|
||||
private const string SceneExtension = ".unity";
|
||||
private static readonly Regex ResourceNameRegex = new Regex(@"^([A-Za-z0-9\._-]+/)*[A-Za-z0-9\._-]+$");
|
||||
private static readonly Regex ResourceVariantRegex = new Regex(@"^[a-z0-9_-]+$");
|
||||
|
||||
private readonly string m_ConfigurationPath;
|
||||
private readonly SortedDictionary<string, Resource> m_Resources;
|
||||
private readonly SortedDictionary<string, Asset> m_Assets;
|
||||
|
||||
public ResourceCollection()
|
||||
{
|
||||
m_ConfigurationPath = Type.GetConfigurationPath<ResourceCollectionConfigPathAttribute>() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/ResourceCollection.xml"));
|
||||
m_Resources = new SortedDictionary<string, Resource>(StringComparer.Ordinal);
|
||||
m_Assets = new SortedDictionary<string, Asset>(StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
public int ResourceCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Resources.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public int AssetCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Assets.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public event GameFrameworkAction<int, int> OnLoadingResource = null;
|
||||
|
||||
public event GameFrameworkAction<int, int> OnLoadingAsset = null;
|
||||
|
||||
public event GameFrameworkAction OnLoadCompleted = null;
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_Resources.Clear();
|
||||
m_Assets.Clear();
|
||||
}
|
||||
|
||||
public bool Load()
|
||||
{
|
||||
Clear();
|
||||
|
||||
if (!File.Exists(m_ConfigurationPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.Load(m_ConfigurationPath);
|
||||
XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework");
|
||||
XmlNode xmlCollection = xmlRoot.SelectSingleNode("ResourceCollection");
|
||||
XmlNode xmlResources = xmlCollection.SelectSingleNode("Resources");
|
||||
XmlNode xmlAssets = xmlCollection.SelectSingleNode("Assets");
|
||||
|
||||
XmlNodeList xmlNodeList = null;
|
||||
XmlNode xmlNode = null;
|
||||
int count = 0;
|
||||
|
||||
xmlNodeList = xmlResources.ChildNodes;
|
||||
count = xmlNodeList.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (OnLoadingResource != null)
|
||||
{
|
||||
OnLoadingResource(i, count);
|
||||
}
|
||||
|
||||
xmlNode = xmlNodeList.Item(i);
|
||||
if (xmlNode.Name != "Resource")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string name = xmlNode.Attributes.GetNamedItem("Name").Value;
|
||||
string variant = xmlNode.Attributes.GetNamedItem("Variant") != null ? xmlNode.Attributes.GetNamedItem("Variant").Value : null;
|
||||
string fileSystem = xmlNode.Attributes.GetNamedItem("FileSystem") != null ? xmlNode.Attributes.GetNamedItem("FileSystem").Value : null;
|
||||
byte loadType = 0;
|
||||
if (xmlNode.Attributes.GetNamedItem("LoadType") != null)
|
||||
{
|
||||
byte.TryParse(xmlNode.Attributes.GetNamedItem("LoadType").Value, out loadType);
|
||||
}
|
||||
|
||||
bool packed = false;
|
||||
if (xmlNode.Attributes.GetNamedItem("Packed") != null)
|
||||
{
|
||||
bool.TryParse(xmlNode.Attributes.GetNamedItem("Packed").Value, out packed);
|
||||
}
|
||||
|
||||
string[] resourceGroups = xmlNode.Attributes.GetNamedItem("ResourceGroups") != null ? xmlNode.Attributes.GetNamedItem("ResourceGroups").Value.Split(',') : null;
|
||||
if (!AddResource(name, variant, fileSystem, (LoadType)loadType, packed, resourceGroups))
|
||||
{
|
||||
Debug.LogWarning(Utility.Text.Format("Can not add resource '{0}'.", GetResourceFullName(name, variant)));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
xmlNodeList = xmlAssets.ChildNodes;
|
||||
count = xmlNodeList.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (OnLoadingAsset != null)
|
||||
{
|
||||
OnLoadingAsset(i, count);
|
||||
}
|
||||
|
||||
xmlNode = xmlNodeList.Item(i);
|
||||
if (xmlNode.Name != "Asset")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string guid = xmlNode.Attributes.GetNamedItem("Guid").Value;
|
||||
string name = xmlNode.Attributes.GetNamedItem("ResourceName").Value;
|
||||
string variant = xmlNode.Attributes.GetNamedItem("ResourceVariant") != null ? xmlNode.Attributes.GetNamedItem("ResourceVariant").Value : null;
|
||||
if (!AssignAsset(guid, name, variant))
|
||||
{
|
||||
Debug.LogWarning(Utility.Text.Format("Can not assign asset '{0}' to resource '{1}'.", guid, GetResourceFullName(name, variant)));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (OnLoadCompleted != null)
|
||||
{
|
||||
OnLoadCompleted();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
File.Delete(m_ConfigurationPath);
|
||||
if (OnLoadCompleted != null)
|
||||
{
|
||||
OnLoadCompleted();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.AppendChild(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null));
|
||||
|
||||
XmlElement xmlRoot = xmlDocument.CreateElement("UnityGameFramework");
|
||||
xmlDocument.AppendChild(xmlRoot);
|
||||
|
||||
XmlElement xmlCollection = xmlDocument.CreateElement("ResourceCollection");
|
||||
xmlRoot.AppendChild(xmlCollection);
|
||||
|
||||
XmlElement xmlResources = xmlDocument.CreateElement("Resources");
|
||||
xmlCollection.AppendChild(xmlResources);
|
||||
|
||||
XmlElement xmlAssets = xmlDocument.CreateElement("Assets");
|
||||
xmlCollection.AppendChild(xmlAssets);
|
||||
|
||||
XmlElement xmlElement = null;
|
||||
XmlAttribute xmlAttribute = null;
|
||||
|
||||
foreach (Resource resource in m_Resources.Values)
|
||||
{
|
||||
xmlElement = xmlDocument.CreateElement("Resource");
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Name");
|
||||
xmlAttribute.Value = resource.Name;
|
||||
xmlElement.Attributes.SetNamedItem(xmlAttribute);
|
||||
|
||||
if (resource.Variant != null)
|
||||
{
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Variant");
|
||||
xmlAttribute.Value = resource.Variant;
|
||||
xmlElement.Attributes.SetNamedItem(xmlAttribute);
|
||||
}
|
||||
|
||||
if (resource.FileSystem != null)
|
||||
{
|
||||
xmlAttribute = xmlDocument.CreateAttribute("FileSystem");
|
||||
xmlAttribute.Value = resource.FileSystem;
|
||||
xmlElement.Attributes.SetNamedItem(xmlAttribute);
|
||||
}
|
||||
|
||||
xmlAttribute = xmlDocument.CreateAttribute("LoadType");
|
||||
xmlAttribute.Value = ((byte)resource.LoadType).ToString();
|
||||
xmlElement.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Packed");
|
||||
xmlAttribute.Value = resource.Packed.ToString();
|
||||
xmlElement.Attributes.SetNamedItem(xmlAttribute);
|
||||
string[] resourceGroups = resource.GetResourceGroups();
|
||||
if (resourceGroups.Length > 0)
|
||||
{
|
||||
xmlAttribute = xmlDocument.CreateAttribute("ResourceGroups");
|
||||
xmlAttribute.Value = string.Join(",", resourceGroups);
|
||||
xmlElement.Attributes.SetNamedItem(xmlAttribute);
|
||||
}
|
||||
|
||||
xmlResources.AppendChild(xmlElement);
|
||||
}
|
||||
|
||||
foreach (Asset asset in m_Assets.Values)
|
||||
{
|
||||
xmlElement = xmlDocument.CreateElement("Asset");
|
||||
xmlAttribute = xmlDocument.CreateAttribute("Guid");
|
||||
xmlAttribute.Value = asset.Guid;
|
||||
xmlElement.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlAttribute = xmlDocument.CreateAttribute("ResourceName");
|
||||
xmlAttribute.Value = asset.Resource.Name;
|
||||
xmlElement.Attributes.SetNamedItem(xmlAttribute);
|
||||
if (asset.Resource.Variant != null)
|
||||
{
|
||||
xmlAttribute = xmlDocument.CreateAttribute("ResourceVariant");
|
||||
xmlAttribute.Value = asset.Resource.Variant;
|
||||
xmlElement.Attributes.SetNamedItem(xmlAttribute);
|
||||
}
|
||||
|
||||
xmlAssets.AppendChild(xmlElement);
|
||||
}
|
||||
|
||||
string configurationDirectoryName = Path.GetDirectoryName(m_ConfigurationPath);
|
||||
if (!Directory.Exists(configurationDirectoryName))
|
||||
{
|
||||
Directory.CreateDirectory(configurationDirectoryName);
|
||||
}
|
||||
|
||||
xmlDocument.Save(m_ConfigurationPath);
|
||||
AssetDatabase.Refresh();
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (File.Exists(m_ConfigurationPath))
|
||||
{
|
||||
File.Delete(m_ConfigurationPath);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Resource[] GetResources()
|
||||
{
|
||||
return m_Resources.Values.ToArray();
|
||||
}
|
||||
|
||||
public Resource GetResource(string name, string variant)
|
||||
{
|
||||
if (!IsValidResourceName(name, variant))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Resource resource = null;
|
||||
if (m_Resources.TryGetValue(GetResourceFullName(name, variant).ToLowerInvariant(), out resource))
|
||||
{
|
||||
return resource;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool HasResource(string name, string variant)
|
||||
{
|
||||
if (!IsValidResourceName(name, variant))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_Resources.ContainsKey(GetResourceFullName(name, variant).ToLowerInvariant());
|
||||
}
|
||||
|
||||
public bool AddResource(string name, string variant, string fileSystem, LoadType loadType, bool packed)
|
||||
{
|
||||
return AddResource(name, variant, fileSystem, loadType, packed, null);
|
||||
}
|
||||
|
||||
public bool AddResource(string name, string variant, string fileSystem, LoadType loadType, bool packed, string[] resourceGroups)
|
||||
{
|
||||
if (!IsValidResourceName(name, variant))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsAvailableResourceName(name, variant, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileSystem != null && !ResourceNameRegex.IsMatch(fileSystem))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Resource resource = Resource.Create(name, variant, fileSystem, loadType, packed, resourceGroups);
|
||||
m_Resources.Add(resource.FullName.ToLowerInvariant(), resource);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RenameResource(string oldName, string oldVariant, string newName, string newVariant)
|
||||
{
|
||||
if (!IsValidResourceName(oldName, oldVariant) || !IsValidResourceName(newName, newVariant))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Resource resource = GetResource(oldName, oldVariant);
|
||||
if (resource == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (oldName == newName && oldVariant == newVariant)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!IsAvailableResourceName(newName, newVariant, resource))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Resources.Remove(resource.FullName.ToLowerInvariant());
|
||||
resource.Rename(newName, newVariant);
|
||||
m_Resources.Add(resource.FullName.ToLowerInvariant(), resource);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveResource(string name, string variant)
|
||||
{
|
||||
if (!IsValidResourceName(name, variant))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Resource resource = GetResource(name, variant);
|
||||
if (resource == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Asset[] assets = resource.GetAssets();
|
||||
resource.Clear();
|
||||
m_Resources.Remove(resource.FullName.ToLowerInvariant());
|
||||
foreach (Asset asset in assets)
|
||||
{
|
||||
m_Assets.Remove(asset.Guid);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetResourceLoadType(string name, string variant, LoadType loadType)
|
||||
{
|
||||
if (!IsValidResourceName(name, variant))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Resource resource = GetResource(name, variant);
|
||||
if (resource == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((loadType == LoadType.LoadFromBinary || loadType == LoadType.LoadFromBinaryAndQuickDecrypt || loadType == LoadType.LoadFromBinaryAndDecrypt) && resource.GetAssets().Length > 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
resource.LoadType = loadType;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetResourcePacked(string name, string variant, bool packed)
|
||||
{
|
||||
if (!IsValidResourceName(name, variant))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Resource resource = GetResource(name, variant);
|
||||
if (resource == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
resource.Packed = packed;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Asset[] GetAssets()
|
||||
{
|
||||
return m_Assets.Values.ToArray();
|
||||
}
|
||||
|
||||
public Asset[] GetAssets(string name, string variant)
|
||||
{
|
||||
if (!IsValidResourceName(name, variant))
|
||||
{
|
||||
return new Asset[0];
|
||||
}
|
||||
|
||||
Resource resource = GetResource(name, variant);
|
||||
if (resource == null)
|
||||
{
|
||||
return new Asset[0];
|
||||
}
|
||||
|
||||
return resource.GetAssets();
|
||||
}
|
||||
|
||||
public Asset GetAsset(string guid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Asset asset = null;
|
||||
if (m_Assets.TryGetValue(guid, out asset))
|
||||
{
|
||||
return asset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool HasAsset(string guid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_Assets.ContainsKey(guid);
|
||||
}
|
||||
|
||||
public bool AssignAsset(string guid, string name, string variant)
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsValidResourceName(name, variant))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Resource resource = GetResource(name, variant);
|
||||
if (resource == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string assetName = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (string.IsNullOrEmpty(assetName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Asset[] assetsInResource = resource.GetAssets();
|
||||
foreach (Asset assetInResource in assetsInResource)
|
||||
{
|
||||
if (assetInResource.Name == assetName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assetInResource.Name.ToLowerInvariant() == assetName.ToLowerInvariant())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isScene = assetName.EndsWith(SceneExtension, StringComparison.Ordinal);
|
||||
if (isScene && resource.AssetType == AssetType.Asset || !isScene && resource.AssetType == AssetType.Scene)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Asset asset = GetAsset(guid);
|
||||
if (resource.IsLoadFromBinary && assetsInResource.Length > 0 && asset != assetsInResource[0])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
asset = Asset.Create(guid);
|
||||
m_Assets.Add(asset.Guid, asset);
|
||||
}
|
||||
|
||||
resource.AssignAsset(asset, isScene);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool UnassignAsset(string guid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Asset asset = GetAsset(guid);
|
||||
if (asset != null)
|
||||
{
|
||||
asset.Resource.UnassignAsset(asset);
|
||||
m_Assets.Remove(asset.Guid);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private string GetResourceFullName(string name, string variant)
|
||||
{
|
||||
return !string.IsNullOrEmpty(variant) ? Utility.Text.Format("{0}.{1}", name, variant) : name;
|
||||
}
|
||||
|
||||
private bool IsValidResourceName(string name, string variant)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ResourceNameRegex.IsMatch(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (variant != null && !ResourceVariantRegex.IsMatch(variant))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsAvailableResourceName(string name, string variant, Resource current)
|
||||
{
|
||||
Resource found = GetResource(name, variant);
|
||||
if (found != null && found != current)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] foundPathNames = name.Split('/');
|
||||
foreach (Resource resource in m_Resources.Values)
|
||||
{
|
||||
if (current != null && resource == current)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (resource.Name == name)
|
||||
{
|
||||
if (resource.Variant == null && variant != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resource.Variant != null && variant == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (resource.Name.Length > name.Length
|
||||
&& resource.Name.IndexOf(name, StringComparison.CurrentCultureIgnoreCase) == 0
|
||||
&& resource.Name[name.Length] == '/')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name.Length > resource.Name.Length
|
||||
&& name.IndexOf(resource.Name, StringComparison.CurrentCultureIgnoreCase) == 0
|
||||
&& name[resource.Name.Length] == '/')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] pathNames = resource.Name.Split('/');
|
||||
for (int i = 0; i < foundPathNames.Length - 1 && i < pathNames.Length - 1; i++)
|
||||
{
|
||||
if (foundPathNames[i].ToLowerInvariant() != pathNames[i].ToLowerInvariant())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (foundPathNames[i] != pathNames[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1736b422b0ea4c46bbaf798d320e6f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,16 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// ResourceCollection 配置路径属性。
|
||||
/// </summary>
|
||||
public sealed class ResourceCollectionConfigPathAttribute : ConfigPathAttribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1eb3245545d87064b814268034cc7af6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e537bb30b04ebc41bd7575567444988
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,16 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public enum AssetSorterType : byte
|
||||
{
|
||||
Path,
|
||||
Name,
|
||||
Guid,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5463b22a6a4019146a38f7b80dbe6fa7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
internal sealed partial class ResourceEditor : EditorWindow
|
||||
{
|
||||
private enum MenuState : byte
|
||||
{
|
||||
Normal,
|
||||
Add,
|
||||
Rename,
|
||||
Remove,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32b00a6c44b75494f8576b42717b1f1f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,164 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
internal sealed partial class ResourceEditor : EditorWindow
|
||||
{
|
||||
private sealed class ResourceFolder
|
||||
{
|
||||
private static Texture s_CachedIcon = null;
|
||||
|
||||
private readonly List<ResourceFolder> m_Folders;
|
||||
private readonly List<ResourceItem> m_Items;
|
||||
|
||||
public ResourceFolder(string name, ResourceFolder folder)
|
||||
{
|
||||
m_Folders = new List<ResourceFolder>();
|
||||
m_Items = new List<ResourceItem>();
|
||||
|
||||
Name = name;
|
||||
Folder = folder;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public ResourceFolder Folder
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string FromRootPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Folder == null ? string.Empty : (Folder.Folder == null ? Name : Utility.Text.Format("{0}/{1}", Folder.FromRootPath, Name));
|
||||
}
|
||||
}
|
||||
|
||||
public int Depth
|
||||
{
|
||||
get
|
||||
{
|
||||
return Folder != null ? Folder.Depth + 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static Texture Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_CachedIcon == null)
|
||||
{
|
||||
s_CachedIcon = AssetDatabase.GetCachedIcon("Assets");
|
||||
}
|
||||
|
||||
return s_CachedIcon;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_Folders.Clear();
|
||||
m_Items.Clear();
|
||||
}
|
||||
|
||||
public ResourceFolder[] GetFolders()
|
||||
{
|
||||
return m_Folders.ToArray();
|
||||
}
|
||||
|
||||
public ResourceFolder GetFolder(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Resource folder name is invalid.");
|
||||
}
|
||||
|
||||
foreach (ResourceFolder folder in m_Folders)
|
||||
{
|
||||
if (folder.Name == name)
|
||||
{
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResourceFolder AddFolder(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Resource folder name is invalid.");
|
||||
}
|
||||
|
||||
ResourceFolder folder = GetFolder(name);
|
||||
if (folder != null)
|
||||
{
|
||||
throw new GameFrameworkException("Resource folder is already exist.");
|
||||
}
|
||||
|
||||
folder = new ResourceFolder(name, this);
|
||||
m_Folders.Add(folder);
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
public ResourceItem[] GetItems()
|
||||
{
|
||||
return m_Items.ToArray();
|
||||
}
|
||||
|
||||
public ResourceItem GetItem(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Resource item name is invalid.");
|
||||
}
|
||||
|
||||
foreach (ResourceItem item in m_Items)
|
||||
{
|
||||
if (item.Name == name)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void AddItem(string name, Resource resource)
|
||||
{
|
||||
ResourceItem item = GetItem(name);
|
||||
if (item != null)
|
||||
{
|
||||
throw new GameFrameworkException("Resource item is already exist.");
|
||||
}
|
||||
|
||||
item = new ResourceItem(name, resource, this);
|
||||
m_Items.Add(item);
|
||||
m_Items.Sort(ResourceItemComparer);
|
||||
}
|
||||
|
||||
private int ResourceItemComparer(ResourceItem a, ResourceItem b)
|
||||
{
|
||||
return a.Name.CompareTo(b.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cb7e55dc8f5c0b4c8bdad2802a24162
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,159 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
internal sealed partial class ResourceEditor : EditorWindow
|
||||
{
|
||||
private sealed class ResourceItem
|
||||
{
|
||||
private static Texture s_CachedUnknownIcon = null;
|
||||
private static Texture s_CachedAssetIcon = null;
|
||||
private static Texture s_CachedSceneIcon = null;
|
||||
|
||||
public ResourceItem(string name, Resource resource, ResourceFolder folder)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
throw new GameFrameworkException("Resource is invalid.");
|
||||
}
|
||||
|
||||
if (folder == null)
|
||||
{
|
||||
throw new GameFrameworkException("Resource folder is invalid.");
|
||||
}
|
||||
|
||||
Name = name;
|
||||
Resource = resource;
|
||||
Folder = folder;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Resource Resource
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public ResourceFolder Folder
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string FromRootPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Folder.Folder == null ? Name : Utility.Text.Format("{0}/{1}", Folder.FromRootPath, Name);
|
||||
}
|
||||
}
|
||||
|
||||
public int Depth
|
||||
{
|
||||
get
|
||||
{
|
||||
return Folder != null ? Folder.Depth + 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Resource.IsLoadFromBinary)
|
||||
{
|
||||
Asset asset = Resource.GetFirstAsset();
|
||||
if (asset != null)
|
||||
{
|
||||
Texture texture = AssetDatabase.GetCachedIcon(AssetDatabase.GUIDToAssetPath(asset.Guid));
|
||||
return texture != null ? texture : CachedUnknownIcon;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Resource.AssetType)
|
||||
{
|
||||
case AssetType.Asset:
|
||||
return CachedAssetIcon;
|
||||
|
||||
case AssetType.Scene:
|
||||
return CachedSceneIcon;
|
||||
}
|
||||
}
|
||||
|
||||
return CachedUnknownIcon;
|
||||
}
|
||||
}
|
||||
|
||||
private static Texture CachedUnknownIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_CachedUnknownIcon == null)
|
||||
{
|
||||
string iconName = null;
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
iconName = "GameObject Icon";
|
||||
#else
|
||||
iconName = "Prefab Icon";
|
||||
#endif
|
||||
s_CachedUnknownIcon = GetIcon(iconName);
|
||||
}
|
||||
|
||||
return s_CachedUnknownIcon;
|
||||
}
|
||||
}
|
||||
|
||||
private static Texture CachedAssetIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_CachedAssetIcon == null)
|
||||
{
|
||||
string iconName = null;
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
iconName = "Prefab Icon";
|
||||
#else
|
||||
iconName = "PrefabNormal Icon";
|
||||
#endif
|
||||
s_CachedAssetIcon = GetIcon(iconName);
|
||||
}
|
||||
|
||||
return s_CachedAssetIcon;
|
||||
}
|
||||
}
|
||||
|
||||
private static Texture CachedSceneIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_CachedSceneIcon == null)
|
||||
{
|
||||
s_CachedSceneIcon = GetIcon("SceneAsset Icon");
|
||||
}
|
||||
|
||||
return s_CachedSceneIcon;
|
||||
}
|
||||
}
|
||||
|
||||
private static Texture GetIcon(string iconName)
|
||||
{
|
||||
return EditorGUIUtility.IconContent(iconName).image;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f2127e06af00f84294606afa2dfc494
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 956e53f5acdcb4c40a8ecc68d943dde0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,16 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// ResourceEditor 配置路径属性。
|
||||
/// </summary>
|
||||
public sealed class ResourceEditorConfigPathAttribute : ConfigPathAttribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af287b4a1d99d3946b1aab8f70c78964
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,679 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed class ResourceEditorController
|
||||
{
|
||||
private const string DefaultSourceAssetRootPath = "Assets";
|
||||
|
||||
private readonly string m_ConfigurationPath;
|
||||
private readonly ResourceCollection m_ResourceCollection;
|
||||
private readonly List<string> m_SourceAssetSearchPaths;
|
||||
private readonly List<string> m_SourceAssetSearchRelativePaths;
|
||||
private readonly Dictionary<string, SourceAsset> m_SourceAssets;
|
||||
private SourceFolder m_SourceAssetRoot;
|
||||
private string m_SourceAssetRootPath;
|
||||
private string m_SourceAssetUnionTypeFilter;
|
||||
private string m_SourceAssetUnionLabelFilter;
|
||||
private string m_SourceAssetExceptTypeFilter;
|
||||
private string m_SourceAssetExceptLabelFilter;
|
||||
private AssetSorterType m_AssetSorter;
|
||||
|
||||
public ResourceEditorController()
|
||||
{
|
||||
m_ConfigurationPath = Type.GetConfigurationPath<ResourceEditorConfigPathAttribute>() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/ResourceEditor.xml"));
|
||||
m_ResourceCollection = new ResourceCollection();
|
||||
m_ResourceCollection.OnLoadingResource += delegate (int index, int count)
|
||||
{
|
||||
if (OnLoadingResource != null)
|
||||
{
|
||||
OnLoadingResource(index, count);
|
||||
}
|
||||
};
|
||||
|
||||
m_ResourceCollection.OnLoadingAsset += delegate (int index, int count)
|
||||
{
|
||||
if (OnLoadingAsset != null)
|
||||
{
|
||||
OnLoadingAsset(index, count);
|
||||
}
|
||||
};
|
||||
|
||||
m_ResourceCollection.OnLoadCompleted += delegate ()
|
||||
{
|
||||
if (OnLoadCompleted != null)
|
||||
{
|
||||
OnLoadCompleted();
|
||||
}
|
||||
};
|
||||
|
||||
m_SourceAssetSearchPaths = new List<string>();
|
||||
m_SourceAssetSearchRelativePaths = new List<string>();
|
||||
m_SourceAssets = new Dictionary<string, SourceAsset>(StringComparer.Ordinal);
|
||||
m_SourceAssetRoot = null;
|
||||
m_SourceAssetRootPath = null;
|
||||
m_SourceAssetUnionTypeFilter = null;
|
||||
m_SourceAssetUnionLabelFilter = null;
|
||||
m_SourceAssetExceptTypeFilter = null;
|
||||
m_SourceAssetExceptLabelFilter = null;
|
||||
m_AssetSorter = AssetSorterType.Path;
|
||||
|
||||
SourceAssetRootPath = DefaultSourceAssetRootPath;
|
||||
}
|
||||
|
||||
public int ResourceCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ResourceCollection.ResourceCount;
|
||||
}
|
||||
}
|
||||
|
||||
public int AssetCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ResourceCollection.AssetCount;
|
||||
}
|
||||
}
|
||||
|
||||
public SourceFolder SourceAssetRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SourceAssetRoot;
|
||||
}
|
||||
}
|
||||
|
||||
public string SourceAssetRootPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SourceAssetRootPath;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_SourceAssetRootPath == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_SourceAssetRootPath = value.Replace('\\', '/');
|
||||
m_SourceAssetRoot = new SourceFolder(m_SourceAssetRootPath, null);
|
||||
RefreshSourceAssetSearchPaths();
|
||||
}
|
||||
}
|
||||
|
||||
public string SourceAssetUnionTypeFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SourceAssetUnionTypeFilter;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_SourceAssetUnionTypeFilter == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_SourceAssetUnionTypeFilter = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string SourceAssetUnionLabelFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SourceAssetUnionLabelFilter;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_SourceAssetUnionLabelFilter == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_SourceAssetUnionLabelFilter = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string SourceAssetExceptTypeFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SourceAssetExceptTypeFilter;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_SourceAssetExceptTypeFilter == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_SourceAssetExceptTypeFilter = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string SourceAssetExceptLabelFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SourceAssetExceptLabelFilter;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_SourceAssetExceptLabelFilter == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_SourceAssetExceptLabelFilter = value;
|
||||
}
|
||||
}
|
||||
|
||||
public AssetSorterType AssetSorter
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_AssetSorter;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_AssetSorter == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_AssetSorter = value;
|
||||
}
|
||||
}
|
||||
|
||||
public event GameFrameworkAction<int, int> OnLoadingResource = null;
|
||||
|
||||
public event GameFrameworkAction<int, int> OnLoadingAsset = null;
|
||||
|
||||
public event GameFrameworkAction OnLoadCompleted = null;
|
||||
|
||||
public event GameFrameworkAction<SourceAsset[]> OnAssetAssigned = null;
|
||||
|
||||
public event GameFrameworkAction<SourceAsset[]> OnAssetUnassigned = null;
|
||||
|
||||
public bool Load()
|
||||
{
|
||||
if (!File.Exists(m_ConfigurationPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.Load(m_ConfigurationPath);
|
||||
XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework");
|
||||
XmlNode xmlEditor = xmlRoot.SelectSingleNode("ResourceEditor");
|
||||
XmlNode xmlSettings = xmlEditor.SelectSingleNode("Settings");
|
||||
|
||||
XmlNodeList xmlNodeList = null;
|
||||
XmlNode xmlNode = null;
|
||||
|
||||
xmlNodeList = xmlSettings.ChildNodes;
|
||||
for (int i = 0; i < xmlNodeList.Count; i++)
|
||||
{
|
||||
xmlNode = xmlNodeList.Item(i);
|
||||
switch (xmlNode.Name)
|
||||
{
|
||||
case "SourceAssetRootPath":
|
||||
SourceAssetRootPath = xmlNode.InnerText;
|
||||
break;
|
||||
|
||||
case "SourceAssetSearchPaths":
|
||||
m_SourceAssetSearchRelativePaths.Clear();
|
||||
XmlNodeList xmlNodeListInner = xmlNode.ChildNodes;
|
||||
XmlNode xmlNodeInner = null;
|
||||
for (int j = 0; j < xmlNodeListInner.Count; j++)
|
||||
{
|
||||
xmlNodeInner = xmlNodeListInner.Item(j);
|
||||
if (xmlNodeInner.Name != "SourceAssetSearchPath")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m_SourceAssetSearchRelativePaths.Add(xmlNodeInner.Attributes.GetNamedItem("RelativePath").Value);
|
||||
}
|
||||
break;
|
||||
|
||||
case "SourceAssetUnionTypeFilter":
|
||||
SourceAssetUnionTypeFilter = xmlNode.InnerText;
|
||||
break;
|
||||
|
||||
case "SourceAssetUnionLabelFilter":
|
||||
SourceAssetUnionLabelFilter = xmlNode.InnerText;
|
||||
break;
|
||||
|
||||
case "SourceAssetExceptTypeFilter":
|
||||
SourceAssetExceptTypeFilter = xmlNode.InnerText;
|
||||
break;
|
||||
|
||||
case "SourceAssetExceptLabelFilter":
|
||||
SourceAssetExceptLabelFilter = xmlNode.InnerText;
|
||||
break;
|
||||
|
||||
case "AssetSorter":
|
||||
AssetSorter = (AssetSorterType)Enum.Parse(typeof(AssetSorterType), xmlNode.InnerText);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RefreshSourceAssetSearchPaths();
|
||||
}
|
||||
catch
|
||||
{
|
||||
File.Delete(m_ConfigurationPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
ScanSourceAssets();
|
||||
|
||||
m_ResourceCollection.Load();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.AppendChild(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null));
|
||||
|
||||
XmlElement xmlRoot = xmlDocument.CreateElement("UnityGameFramework");
|
||||
xmlDocument.AppendChild(xmlRoot);
|
||||
|
||||
XmlElement xmlEditor = xmlDocument.CreateElement("ResourceEditor");
|
||||
xmlRoot.AppendChild(xmlEditor);
|
||||
|
||||
XmlElement xmlSettings = xmlDocument.CreateElement("Settings");
|
||||
xmlEditor.AppendChild(xmlSettings);
|
||||
|
||||
XmlElement xmlElement = null;
|
||||
XmlAttribute xmlAttribute = null;
|
||||
|
||||
xmlElement = xmlDocument.CreateElement("SourceAssetRootPath");
|
||||
xmlElement.InnerText = SourceAssetRootPath.ToString();
|
||||
xmlSettings.AppendChild(xmlElement);
|
||||
|
||||
xmlElement = xmlDocument.CreateElement("SourceAssetSearchPaths");
|
||||
xmlSettings.AppendChild(xmlElement);
|
||||
|
||||
foreach (string sourceAssetSearchRelativePath in m_SourceAssetSearchRelativePaths)
|
||||
{
|
||||
XmlElement xmlElementInner = xmlDocument.CreateElement("SourceAssetSearchPath");
|
||||
xmlAttribute = xmlDocument.CreateAttribute("RelativePath");
|
||||
xmlAttribute.Value = sourceAssetSearchRelativePath;
|
||||
xmlElementInner.Attributes.SetNamedItem(xmlAttribute);
|
||||
xmlElement.AppendChild(xmlElementInner);
|
||||
}
|
||||
|
||||
xmlElement = xmlDocument.CreateElement("SourceAssetUnionTypeFilter");
|
||||
xmlElement.InnerText = SourceAssetUnionTypeFilter ?? string.Empty;
|
||||
xmlSettings.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("SourceAssetUnionLabelFilter");
|
||||
xmlElement.InnerText = SourceAssetUnionLabelFilter ?? string.Empty;
|
||||
xmlSettings.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("SourceAssetExceptTypeFilter");
|
||||
xmlElement.InnerText = SourceAssetExceptTypeFilter ?? string.Empty;
|
||||
xmlSettings.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("SourceAssetExceptLabelFilter");
|
||||
xmlElement.InnerText = SourceAssetExceptLabelFilter ?? string.Empty;
|
||||
xmlSettings.AppendChild(xmlElement);
|
||||
xmlElement = xmlDocument.CreateElement("AssetSorter");
|
||||
xmlElement.InnerText = AssetSorter.ToString();
|
||||
xmlSettings.AppendChild(xmlElement);
|
||||
|
||||
string configurationDirectoryName = Path.GetDirectoryName(m_ConfigurationPath);
|
||||
if (!Directory.Exists(configurationDirectoryName))
|
||||
{
|
||||
Directory.CreateDirectory(configurationDirectoryName);
|
||||
}
|
||||
|
||||
xmlDocument.Save(m_ConfigurationPath);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (File.Exists(m_ConfigurationPath))
|
||||
{
|
||||
File.Delete(m_ConfigurationPath);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_ResourceCollection.Save();
|
||||
}
|
||||
|
||||
public Resource[] GetResources()
|
||||
{
|
||||
return m_ResourceCollection.GetResources();
|
||||
}
|
||||
|
||||
public Resource GetResource(string name, string variant)
|
||||
{
|
||||
return m_ResourceCollection.GetResource(name, variant);
|
||||
}
|
||||
|
||||
public bool HasResource(string name, string variant)
|
||||
{
|
||||
return m_ResourceCollection.HasResource(name, variant);
|
||||
}
|
||||
|
||||
public bool AddResource(string name, string variant, string fileSystem, LoadType loadType, bool packed)
|
||||
{
|
||||
return m_ResourceCollection.AddResource(name, variant, fileSystem, loadType, packed);
|
||||
}
|
||||
|
||||
public bool RenameResource(string oldName, string oldVariant, string newName, string newVariant)
|
||||
{
|
||||
return m_ResourceCollection.RenameResource(oldName, oldVariant, newName, newVariant);
|
||||
}
|
||||
|
||||
public bool RemoveResource(string name, string variant)
|
||||
{
|
||||
Asset[] assetsToRemove = m_ResourceCollection.GetAssets(name, variant);
|
||||
if (m_ResourceCollection.RemoveResource(name, variant))
|
||||
{
|
||||
List<SourceAsset> unassignedSourceAssets = new List<SourceAsset>();
|
||||
foreach (Asset asset in assetsToRemove)
|
||||
{
|
||||
SourceAsset sourceAsset = GetSourceAsset(asset.Guid);
|
||||
if (sourceAsset != null)
|
||||
{
|
||||
unassignedSourceAssets.Add(sourceAsset);
|
||||
}
|
||||
}
|
||||
|
||||
if (OnAssetUnassigned != null)
|
||||
{
|
||||
OnAssetUnassigned(unassignedSourceAssets.ToArray());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetResourceLoadType(string name, string variant, LoadType loadType)
|
||||
{
|
||||
return m_ResourceCollection.SetResourceLoadType(name, variant, loadType);
|
||||
}
|
||||
|
||||
public bool SetResourcePacked(string name, string variant, bool packed)
|
||||
{
|
||||
return m_ResourceCollection.SetResourcePacked(name, variant, packed);
|
||||
}
|
||||
|
||||
public int RemoveUnusedResources()
|
||||
{
|
||||
List<Resource> resources = new List<Resource>(m_ResourceCollection.GetResources());
|
||||
List<Resource> removeResources = resources.FindAll(resource => GetAssets(resource.Name, resource.Variant).Length <= 0);
|
||||
foreach (Resource removeResource in removeResources)
|
||||
{
|
||||
m_ResourceCollection.RemoveResource(removeResource.Name, removeResource.Variant);
|
||||
}
|
||||
|
||||
return removeResources.Count;
|
||||
}
|
||||
|
||||
public Asset[] GetAssets(string name, string variant)
|
||||
{
|
||||
List<Asset> assets = new List<Asset>(m_ResourceCollection.GetAssets(name, variant));
|
||||
switch (AssetSorter)
|
||||
{
|
||||
case AssetSorterType.Path:
|
||||
assets.Sort(AssetPathComparer);
|
||||
break;
|
||||
|
||||
case AssetSorterType.Name:
|
||||
assets.Sort(AssetNameComparer);
|
||||
break;
|
||||
|
||||
case AssetSorterType.Guid:
|
||||
assets.Sort(AssetGuidComparer);
|
||||
break;
|
||||
}
|
||||
|
||||
return assets.ToArray();
|
||||
}
|
||||
|
||||
public Asset GetAsset(string guid)
|
||||
{
|
||||
return m_ResourceCollection.GetAsset(guid);
|
||||
}
|
||||
|
||||
public bool AssignAsset(string guid, string name, string variant)
|
||||
{
|
||||
if (m_ResourceCollection.AssignAsset(guid, name, variant))
|
||||
{
|
||||
if (OnAssetAssigned != null)
|
||||
{
|
||||
OnAssetAssigned(new SourceAsset[] { GetSourceAsset(guid) });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool UnassignAsset(string guid)
|
||||
{
|
||||
if (m_ResourceCollection.UnassignAsset(guid))
|
||||
{
|
||||
SourceAsset sourceAsset = GetSourceAsset(guid);
|
||||
if (sourceAsset != null)
|
||||
{
|
||||
if (OnAssetUnassigned != null)
|
||||
{
|
||||
OnAssetUnassigned(new SourceAsset[] { sourceAsset });
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int RemoveUnknownAssets()
|
||||
{
|
||||
List<Asset> assets = new List<Asset>(m_ResourceCollection.GetAssets());
|
||||
List<Asset> removeAssets = assets.FindAll(asset => GetSourceAsset(asset.Guid) == null);
|
||||
foreach (Asset asset in removeAssets)
|
||||
{
|
||||
m_ResourceCollection.UnassignAsset(asset.Guid);
|
||||
}
|
||||
|
||||
return removeAssets.Count;
|
||||
}
|
||||
|
||||
public SourceAsset[] GetSourceAssets()
|
||||
{
|
||||
int count = 0;
|
||||
SourceAsset[] sourceAssets = new SourceAsset[m_SourceAssets.Count];
|
||||
foreach (KeyValuePair<string, SourceAsset> sourceAsset in m_SourceAssets)
|
||||
{
|
||||
sourceAssets[count++] = sourceAsset.Value;
|
||||
}
|
||||
|
||||
return sourceAssets;
|
||||
}
|
||||
|
||||
public SourceAsset GetSourceAsset(string guid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
SourceAsset sourceAsset = null;
|
||||
if (m_SourceAssets.TryGetValue(guid, out sourceAsset))
|
||||
{
|
||||
return sourceAsset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ScanSourceAssets()
|
||||
{
|
||||
m_SourceAssets.Clear();
|
||||
m_SourceAssetRoot.Clear();
|
||||
|
||||
string[] sourceAssetSearchPaths = m_SourceAssetSearchPaths.ToArray();
|
||||
HashSet<string> tempGuids = new HashSet<string>();
|
||||
tempGuids.UnionWith(AssetDatabase.FindAssets(SourceAssetUnionTypeFilter, sourceAssetSearchPaths));
|
||||
tempGuids.UnionWith(AssetDatabase.FindAssets(SourceAssetUnionLabelFilter, sourceAssetSearchPaths));
|
||||
tempGuids.ExceptWith(AssetDatabase.FindAssets(SourceAssetExceptTypeFilter, sourceAssetSearchPaths));
|
||||
tempGuids.ExceptWith(AssetDatabase.FindAssets(SourceAssetExceptLabelFilter, sourceAssetSearchPaths));
|
||||
|
||||
string[] guids = new List<string>(tempGuids).ToArray();
|
||||
foreach (string guid in guids)
|
||||
{
|
||||
string fullPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (AssetDatabase.IsValidFolder(fullPath))
|
||||
{
|
||||
// Skip folder.
|
||||
continue;
|
||||
}
|
||||
|
||||
string assetPath = fullPath.Substring(SourceAssetRootPath.Length + 1);
|
||||
string[] splitedPath = assetPath.Split('/');
|
||||
SourceFolder folder = m_SourceAssetRoot;
|
||||
for (int i = 0; i < splitedPath.Length - 1; i++)
|
||||
{
|
||||
SourceFolder subFolder = folder.GetFolder(splitedPath[i]);
|
||||
folder = subFolder == null ? folder.AddFolder(splitedPath[i]) : subFolder;
|
||||
}
|
||||
|
||||
SourceAsset asset = folder.AddAsset(guid, fullPath, splitedPath[splitedPath.Length - 1]);
|
||||
m_SourceAssets.Add(asset.Guid, asset);
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshSourceAssetSearchPaths()
|
||||
{
|
||||
m_SourceAssetSearchPaths.Clear();
|
||||
|
||||
if (string.IsNullOrEmpty(m_SourceAssetRootPath))
|
||||
{
|
||||
SourceAssetRootPath = DefaultSourceAssetRootPath;
|
||||
}
|
||||
|
||||
if (m_SourceAssetSearchRelativePaths.Count > 0)
|
||||
{
|
||||
foreach (string sourceAssetSearchRelativePath in m_SourceAssetSearchRelativePaths)
|
||||
{
|
||||
m_SourceAssetSearchPaths.Add(Utility.Path.GetRegularPath(Path.Combine(m_SourceAssetRootPath, sourceAssetSearchRelativePath)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SourceAssetSearchPaths.Add(m_SourceAssetRootPath);
|
||||
}
|
||||
}
|
||||
|
||||
private int AssetPathComparer(Asset a, Asset b)
|
||||
{
|
||||
SourceAsset sourceAssetA = GetSourceAsset(a.Guid);
|
||||
SourceAsset sourceAssetB = GetSourceAsset(b.Guid);
|
||||
|
||||
if (sourceAssetA != null && sourceAssetB != null)
|
||||
{
|
||||
return sourceAssetA.Path.CompareTo(sourceAssetB.Path);
|
||||
}
|
||||
|
||||
if (sourceAssetA == null && sourceAssetB == null)
|
||||
{
|
||||
return a.Guid.CompareTo(b.Guid);
|
||||
}
|
||||
|
||||
if (sourceAssetA == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sourceAssetB == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int AssetNameComparer(Asset a, Asset b)
|
||||
{
|
||||
SourceAsset sourceAssetA = GetSourceAsset(a.Guid);
|
||||
SourceAsset sourceAssetB = GetSourceAsset(b.Guid);
|
||||
|
||||
if (sourceAssetA != null && sourceAssetB != null)
|
||||
{
|
||||
return sourceAssetA.Name.CompareTo(sourceAssetB.Name);
|
||||
}
|
||||
|
||||
if (sourceAssetA == null && sourceAssetB == null)
|
||||
{
|
||||
return a.Guid.CompareTo(b.Guid);
|
||||
}
|
||||
|
||||
if (sourceAssetA == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sourceAssetB == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int AssetGuidComparer(Asset a, Asset b)
|
||||
{
|
||||
SourceAsset sourceAssetA = GetSourceAsset(a.Guid);
|
||||
SourceAsset sourceAssetB = GetSourceAsset(b.Guid);
|
||||
|
||||
if (sourceAssetA != null && sourceAssetB != null || sourceAssetA == null && sourceAssetB == null)
|
||||
{
|
||||
return a.Guid.CompareTo(b.Guid);
|
||||
}
|
||||
|
||||
if (sourceAssetA == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sourceAssetB == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c8c042eb5e752f49920cfc09aff81c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,85 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed class SourceAsset
|
||||
{
|
||||
private Texture m_CachedIcon;
|
||||
|
||||
public SourceAsset(string guid, string path, string name, SourceFolder folder)
|
||||
{
|
||||
if (folder == null)
|
||||
{
|
||||
throw new GameFrameworkException("Source asset folder is invalid.");
|
||||
}
|
||||
|
||||
Guid = guid;
|
||||
Path = path;
|
||||
Name = name;
|
||||
Folder = folder;
|
||||
m_CachedIcon = null;
|
||||
}
|
||||
|
||||
public string Guid
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public SourceFolder Folder
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string FromRootPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Folder.Folder == null ? Name : Utility.Text.Format("{0}/{1}", Folder.FromRootPath, Name);
|
||||
}
|
||||
}
|
||||
|
||||
public int Depth
|
||||
{
|
||||
get
|
||||
{
|
||||
return Folder != null ? Folder.Depth + 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public Texture Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_CachedIcon == null)
|
||||
{
|
||||
m_CachedIcon = AssetDatabase.GetCachedIcon(Path);
|
||||
}
|
||||
|
||||
return m_CachedIcon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ded5a7d9ccd4b2a409ec840ba3df0b18
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,172 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed class SourceFolder
|
||||
{
|
||||
private static Texture s_CachedIcon = null;
|
||||
|
||||
private readonly List<SourceFolder> m_Folders;
|
||||
private readonly List<SourceAsset> m_Assets;
|
||||
|
||||
public SourceFolder(string name, SourceFolder folder)
|
||||
{
|
||||
m_Folders = new List<SourceFolder>();
|
||||
m_Assets = new List<SourceAsset>();
|
||||
|
||||
Name = name;
|
||||
Folder = folder;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public SourceFolder Folder
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string FromRootPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Folder == null ? string.Empty : (Folder.Folder == null ? Name : Utility.Text.Format("{0}/{1}", Folder.FromRootPath, Name));
|
||||
}
|
||||
}
|
||||
|
||||
public int Depth
|
||||
{
|
||||
get
|
||||
{
|
||||
return Folder != null ? Folder.Depth + 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static Texture Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_CachedIcon == null)
|
||||
{
|
||||
s_CachedIcon = AssetDatabase.GetCachedIcon("Assets");
|
||||
}
|
||||
|
||||
return s_CachedIcon;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_Folders.Clear();
|
||||
m_Assets.Clear();
|
||||
}
|
||||
|
||||
public SourceFolder[] GetFolders()
|
||||
{
|
||||
return m_Folders.ToArray();
|
||||
}
|
||||
|
||||
public SourceFolder GetFolder(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Source folder name is invalid.");
|
||||
}
|
||||
|
||||
foreach (SourceFolder folder in m_Folders)
|
||||
{
|
||||
if (folder.Name == name)
|
||||
{
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SourceFolder AddFolder(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Source folder name is invalid.");
|
||||
}
|
||||
|
||||
SourceFolder folder = GetFolder(name);
|
||||
if (folder != null)
|
||||
{
|
||||
throw new GameFrameworkException("Source folder is already exist.");
|
||||
}
|
||||
|
||||
folder = new SourceFolder(name, this);
|
||||
m_Folders.Add(folder);
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
public SourceAsset[] GetAssets()
|
||||
{
|
||||
return m_Assets.ToArray();
|
||||
}
|
||||
|
||||
public SourceAsset GetAsset(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Source asset name is invalid.");
|
||||
}
|
||||
|
||||
foreach (SourceAsset asset in m_Assets)
|
||||
{
|
||||
if (asset.Name == name)
|
||||
{
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SourceAsset AddAsset(string guid, string path, string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
throw new GameFrameworkException("Source asset guid is invalid.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new GameFrameworkException("Source asset path is invalid.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new GameFrameworkException("Source asset name is invalid.");
|
||||
}
|
||||
|
||||
SourceAsset asset = GetAsset(name);
|
||||
if (asset != null)
|
||||
{
|
||||
throw new GameFrameworkException(Utility.Text.Format("Source asset '{0}' is already exist.", name));
|
||||
}
|
||||
|
||||
asset = new SourceAsset(guid, path, name, this);
|
||||
m_Assets.Add(asset);
|
||||
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcb967b558b5d254fb96db1fc5ed808b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3564da2c360cfdb46acffa4b7f42d275
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,487 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源包生成器。
|
||||
/// </summary>
|
||||
internal sealed class ResourcePackBuilder : EditorWindow
|
||||
{
|
||||
private static readonly string[] PlatformForDisplay = new string[] { "Windows", "Windows x64", "macOS", "Linux", "iOS", "Android", "Windows Store", "WebGL" };
|
||||
private static readonly int[] LengthLimit = new int[] { 0, 128, 256, 512, 1024, 2048, 4096 };
|
||||
private static readonly string[] LengthLimitForDisplay = new string[] { "<Unlimited>", "128 MB", "256 MB", "512 MB", "1 GB", "2 GB", "4 GB", "<Custom>" };
|
||||
|
||||
private ResourcePackBuilderController m_Controller = null;
|
||||
private string[] m_VersionNames = null;
|
||||
private string[] m_VersionNamesForTargetDisplay = null;
|
||||
private string[] m_VersionNamesForSourceDisplay = null;
|
||||
private int m_PlatformIndex = 0;
|
||||
private int m_CompressionHelperTypeNameIndex = 0;
|
||||
private int m_LengthLimitIndex = 0;
|
||||
private int m_TargetVersionIndex = 0;
|
||||
private bool[] m_SourceVersionIndexes = null;
|
||||
private int m_SourceVersionCount = 0;
|
||||
|
||||
[MenuItem("Game Framework/Resource Tools/Resource Pack Builder", false, 43)]
|
||||
private static void Open()
|
||||
{
|
||||
ResourcePackBuilder window = GetWindow<ResourcePackBuilder>("Resource Pack Builder", true);
|
||||
window.minSize = new Vector2(800f, 400f);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_Controller = new ResourcePackBuilderController();
|
||||
m_Controller.OnBuildResourcePacksStarted += OnBuildResourcePacksStarted;
|
||||
m_Controller.OnBuildResourcePacksCompleted += OnBuildResourcePacksCompleted;
|
||||
m_Controller.OnBuildResourcePackSuccess += OnBuildResourcePackSuccess;
|
||||
m_Controller.OnBuildResourcePackFailure += OnBuildResourcePackFailure;
|
||||
|
||||
m_Controller.Load();
|
||||
RefreshVersionNames();
|
||||
|
||||
m_CompressionHelperTypeNameIndex = 0;
|
||||
string[] compressionHelperTypeNames = m_Controller.GetCompressionHelperTypeNames();
|
||||
for (int i = 0; i < compressionHelperTypeNames.Length; i++)
|
||||
{
|
||||
if (m_Controller.CompressionHelperTypeName == compressionHelperTypeNames[i])
|
||||
{
|
||||
m_CompressionHelperTypeNameIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_Controller.RefreshCompressionHelper();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height));
|
||||
{
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.LabelField("Environment Information", EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Product Name", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.ProductName);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Company Name", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.CompanyName);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Game Identifier", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.GameIdentifier);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Game Framework Version", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.GameFrameworkVersion);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Unity Version", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.UnityVersion);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Applicable Game Version", GUILayout.Width(160f));
|
||||
EditorGUILayout.LabelField(m_Controller.ApplicableGameVersion);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
GUILayout.Space(5f);
|
||||
EditorGUILayout.LabelField("Build", EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Working Directory", GUILayout.Width(160f));
|
||||
string directory = EditorGUILayout.TextField(m_Controller.WorkingDirectory);
|
||||
if (m_Controller.WorkingDirectory != directory)
|
||||
{
|
||||
m_Controller.WorkingDirectory = directory;
|
||||
RefreshVersionNames();
|
||||
}
|
||||
if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
|
||||
{
|
||||
BrowseWorkingDirectory();
|
||||
RefreshVersionNames();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Platform", GUILayout.Width(160f));
|
||||
int platformIndex = EditorGUILayout.Popup(m_PlatformIndex, PlatformForDisplay);
|
||||
if (m_PlatformIndex != platformIndex)
|
||||
{
|
||||
m_PlatformIndex = platformIndex;
|
||||
m_Controller.Platform = (Platform)(1 << platformIndex);
|
||||
RefreshVersionNames();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Compression Helper", GUILayout.Width(160f));
|
||||
string[] names = m_Controller.GetCompressionHelperTypeNames();
|
||||
int selectedIndex = EditorGUILayout.Popup(m_CompressionHelperTypeNameIndex, names);
|
||||
if (selectedIndex != m_CompressionHelperTypeNameIndex)
|
||||
{
|
||||
m_CompressionHelperTypeNameIndex = selectedIndex;
|
||||
m_Controller.CompressionHelperTypeName = selectedIndex <= 0 ? string.Empty : names[selectedIndex];
|
||||
if (m_Controller.RefreshCompressionHelper())
|
||||
{
|
||||
Debug.Log("Set compression helper success.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Set compression helper failure.");
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
if (m_Controller.Platform == Platform.Undefined || string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName) || !m_Controller.IsValidWorkingDirectory)
|
||||
{
|
||||
string message = string.Empty;
|
||||
if (!m_Controller.IsValidWorkingDirectory)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
message += Environment.NewLine;
|
||||
}
|
||||
|
||||
message += "Working directory is invalid.";
|
||||
}
|
||||
|
||||
if (m_Controller.Platform == Platform.Undefined)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
message += Environment.NewLine;
|
||||
}
|
||||
|
||||
message += "Platform is invalid.";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
message += Environment.NewLine;
|
||||
}
|
||||
|
||||
message += "Compression helper is invalid.";
|
||||
}
|
||||
|
||||
EditorGUILayout.HelpBox(message, MessageType.Error);
|
||||
}
|
||||
else if (m_VersionNamesForTargetDisplay.Length <= 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("No version was found in the specified working directory and platform.", MessageType.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Source Path", GUILayout.Width(160f));
|
||||
GUILayout.Label(m_Controller.SourcePathForDisplay);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Output Path", GUILayout.Width(160f));
|
||||
GUILayout.Label(m_Controller.OutputPath);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Backup Diff", GUILayout.Width(160f));
|
||||
m_Controller.BackupDiff = EditorGUILayout.Toggle(m_Controller.BackupDiff);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
if (m_Controller.BackupDiff)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Backup Version", GUILayout.Width(160f));
|
||||
m_Controller.BackupVersion = EditorGUILayout.Toggle(m_Controller.BackupVersion);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Length Limit", GUILayout.Width(160f));
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
int lengthLimitIndex = EditorGUILayout.Popup(m_LengthLimitIndex, LengthLimitForDisplay);
|
||||
if (m_LengthLimitIndex != lengthLimitIndex)
|
||||
{
|
||||
m_LengthLimitIndex = lengthLimitIndex;
|
||||
if (m_LengthLimitIndex < LengthLimit.Length)
|
||||
{
|
||||
m_Controller.LengthLimit = LengthLimit[m_LengthLimitIndex];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_LengthLimitIndex >= LengthLimit.Length)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
m_Controller.LengthLimit = EditorGUILayout.IntField(m_Controller.LengthLimit);
|
||||
if (m_Controller.LengthLimit < 0)
|
||||
{
|
||||
m_Controller.LengthLimit = 0;
|
||||
}
|
||||
|
||||
GUILayout.Label(" MB", GUILayout.Width(30f));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Target Version", GUILayout.Width(160f));
|
||||
int value = EditorGUILayout.Popup(m_TargetVersionIndex, m_VersionNamesForTargetDisplay);
|
||||
if (m_TargetVersionIndex != value)
|
||||
{
|
||||
m_TargetVersionIndex = value;
|
||||
RefreshSourceVersionCount();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Source Version", GUILayout.Width(160f));
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField(m_SourceVersionCount.ToString() + (m_SourceVersionCount > 1 ? " items" : " item") + " selected.");
|
||||
if (GUILayout.Button("Select All Except <None>", GUILayout.Width(180f)))
|
||||
{
|
||||
m_SourceVersionIndexes[0] = false;
|
||||
for (int i = 1; i < m_SourceVersionIndexes.Length; i++)
|
||||
{
|
||||
m_SourceVersionIndexes[i] = true;
|
||||
}
|
||||
|
||||
RefreshSourceVersionCount();
|
||||
}
|
||||
if (GUILayout.Button("Select All", GUILayout.Width(100f)))
|
||||
{
|
||||
for (int i = 0; i < m_SourceVersionIndexes.Length; i++)
|
||||
{
|
||||
m_SourceVersionIndexes[i] = true;
|
||||
}
|
||||
|
||||
RefreshSourceVersionCount();
|
||||
}
|
||||
if (GUILayout.Button("Select None", GUILayout.Width(100f)))
|
||||
{
|
||||
for (int i = 0; i < m_SourceVersionIndexes.Length; i++)
|
||||
{
|
||||
m_SourceVersionIndexes[i] = false;
|
||||
}
|
||||
|
||||
RefreshSourceVersionCount();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
int count = m_VersionNamesForSourceDisplay.Length;
|
||||
int column = 5;
|
||||
int row = (count - 1) / column + 1;
|
||||
for (int i = 0; i < column && i < count; i++)
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
{
|
||||
for (int j = 0; j < row; j++)
|
||||
{
|
||||
int index = j * column + i;
|
||||
if (index < count)
|
||||
{
|
||||
bool isTarget = index - 1 == m_TargetVersionIndex;
|
||||
EditorGUI.BeginDisabledGroup(isTarget);
|
||||
{
|
||||
bool selected = GUILayout.Toggle(m_SourceVersionIndexes[index], isTarget ? m_VersionNamesForSourceDisplay[index] + " [Target]" : m_VersionNamesForSourceDisplay[index], "button");
|
||||
if (m_SourceVersionIndexes[index] != selected)
|
||||
{
|
||||
m_SourceVersionIndexes[index] = selected;
|
||||
RefreshSourceVersionCount();
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
GUILayout.Space(2f);
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
GUILayout.Space(2f);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(m_Controller.Platform == Platform.Undefined || string.IsNullOrEmpty(m_Controller.CompressionHelperTypeName) || !m_Controller.IsValidWorkingDirectory || m_SourceVersionCount <= 0);
|
||||
{
|
||||
if (GUILayout.Button("Start Build Resource Packs"))
|
||||
{
|
||||
string[] sourceVersions = new string[m_SourceVersionCount];
|
||||
int count = 0;
|
||||
for (int i = 0; i < m_SourceVersionIndexes.Length; i++)
|
||||
{
|
||||
if (m_SourceVersionIndexes[i])
|
||||
{
|
||||
sourceVersions[count++] = i > 0 ? m_VersionNames[i - 1] : null;
|
||||
}
|
||||
}
|
||||
|
||||
m_Controller.BuildResourcePacks(sourceVersions, m_VersionNames[m_TargetVersionIndex]);
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void BrowseWorkingDirectory()
|
||||
{
|
||||
string directory = EditorUtility.OpenFolderPanel("Select Working Directory", m_Controller.WorkingDirectory, string.Empty);
|
||||
if (!string.IsNullOrEmpty(directory))
|
||||
{
|
||||
m_Controller.WorkingDirectory = directory;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshVersionNames()
|
||||
{
|
||||
m_VersionNames = m_Controller.GetVersionNames();
|
||||
m_VersionNamesForTargetDisplay = new string[m_VersionNames.Length];
|
||||
m_VersionNamesForSourceDisplay = new string[m_VersionNames.Length + 1];
|
||||
m_VersionNamesForSourceDisplay[0] = "<None>";
|
||||
for (int i = 0; i < m_VersionNames.Length; i++)
|
||||
{
|
||||
string versionNameForDisplay = GetVersionNameForDisplay(m_VersionNames[i]);
|
||||
m_VersionNamesForTargetDisplay[i] = versionNameForDisplay;
|
||||
m_VersionNamesForSourceDisplay[i + 1] = versionNameForDisplay;
|
||||
}
|
||||
|
||||
m_TargetVersionIndex = m_VersionNames.Length - 1;
|
||||
m_SourceVersionIndexes = new bool[m_VersionNames.Length + 1];
|
||||
m_SourceVersionCount = 0;
|
||||
}
|
||||
|
||||
private void RefreshSourceVersionCount()
|
||||
{
|
||||
m_SourceVersionIndexes[m_TargetVersionIndex + 1] = false;
|
||||
m_SourceVersionCount = 0;
|
||||
if (m_SourceVersionIndexes == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_SourceVersionIndexes.Length; i++)
|
||||
{
|
||||
if (m_SourceVersionIndexes[i])
|
||||
{
|
||||
m_SourceVersionCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetVersionNameForDisplay(string versionName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(versionName))
|
||||
{
|
||||
return "<None>";
|
||||
}
|
||||
|
||||
string[] splitedVersionNames = versionName.Split('_');
|
||||
if (splitedVersionNames.Length < 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string text = splitedVersionNames[0];
|
||||
for (int i = 1; i < splitedVersionNames.Length - 1; i++)
|
||||
{
|
||||
text += "." + splitedVersionNames[i];
|
||||
}
|
||||
|
||||
return Utility.Text.Format("{0} ({1})", text, splitedVersionNames[splitedVersionNames.Length - 1]);
|
||||
}
|
||||
|
||||
private void OnBuildResourcePacksStarted(int count)
|
||||
{
|
||||
Debug.Log(Utility.Text.Format("Build resource packs started, '{0}' items to be built.", count));
|
||||
EditorUtility.DisplayProgressBar("Build Resource Packs", Utility.Text.Format("Build resource packs, {0} items to be built.", count), 0f);
|
||||
}
|
||||
|
||||
private void OnBuildResourcePacksCompleted(int successCount, int count)
|
||||
{
|
||||
int failureCount = count - successCount;
|
||||
string str = Utility.Text.Format("Build resource packs completed, '{0}' items, '{1}' success, '{2}' failure.", count, successCount, failureCount);
|
||||
if (failureCount > 0)
|
||||
{
|
||||
Debug.LogWarning(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log(str);
|
||||
}
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
private void OnBuildResourcePackSuccess(int index, int count, string sourceVersion, string targetVersion)
|
||||
{
|
||||
Debug.Log(Utility.Text.Format("Build resource packs success, source version '{0}', target version '{1}'.", GetVersionNameForDisplay(sourceVersion), GetVersionNameForDisplay(targetVersion)));
|
||||
EditorUtility.DisplayProgressBar("Build Resource Packs", Utility.Text.Format("Build resource packs, {0}/{1} completed.", index + 1, count), (float)index / count);
|
||||
}
|
||||
|
||||
private void OnBuildResourcePackFailure(int index, int count, string sourceVersion, string targetVersion)
|
||||
{
|
||||
Debug.LogWarning(Utility.Text.Format("Build resource packs failure, source version '{0}', target version '{1}'.", GetVersionNameForDisplay(sourceVersion), GetVersionNameForDisplay(targetVersion)));
|
||||
EditorUtility.DisplayProgressBar("Build Resource Packs", Utility.Text.Format("Build resource packs, {0}/{1} completed.", index + 1, count), (float)index / count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e260afdf322bd1f4897314c0d2c777d7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,558 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using GameFramework.Resource;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed class ResourcePackBuilderController
|
||||
{
|
||||
private const string DefaultResourcePackName = "GameFrameworkResourcePack";
|
||||
private const string DefaultExtension = "dat";
|
||||
private const string NoneOptionName = "<None>";
|
||||
private static readonly string[] EmptyStringArray = new string[0];
|
||||
private static readonly UpdatableVersionList.Resource[] EmptyResourceArray = new UpdatableVersionList.Resource[0];
|
||||
|
||||
private readonly string m_ConfigurationPath;
|
||||
private readonly List<string> m_CompressionHelperTypeNames;
|
||||
private readonly UpdatableVersionListSerializer m_UpdatableVersionListSerializer;
|
||||
private readonly ResourcePackVersionListSerializer m_ResourcePackVersionListSerializer;
|
||||
|
||||
public ResourcePackBuilderController()
|
||||
{
|
||||
m_ConfigurationPath = Type.GetConfigurationPath<ResourceBuilderConfigPathAttribute>() ?? Utility.Path.GetRegularPath(Path.Combine(Application.dataPath, "GameFramework/Configs/ResourceBuilder.xml"));
|
||||
|
||||
m_UpdatableVersionListSerializer = new UpdatableVersionListSerializer();
|
||||
m_UpdatableVersionListSerializer.RegisterDeserializeCallback(0, BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback_V0);
|
||||
m_UpdatableVersionListSerializer.RegisterDeserializeCallback(1, BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback_V1);
|
||||
m_UpdatableVersionListSerializer.RegisterDeserializeCallback(2, BuiltinVersionListSerializer.UpdatableVersionListDeserializeCallback_V2);
|
||||
|
||||
m_ResourcePackVersionListSerializer = new ResourcePackVersionListSerializer();
|
||||
m_ResourcePackVersionListSerializer.RegisterSerializeCallback(0, BuiltinVersionListSerializer.ResourcePackVersionListSerializeCallback_V0);
|
||||
|
||||
m_CompressionHelperTypeNames = new List<string>
|
||||
{
|
||||
NoneOptionName
|
||||
};
|
||||
|
||||
m_CompressionHelperTypeNames.AddRange(Type.GetRuntimeOrEditorTypeNames(typeof(Utility.Compression.ICompressionHelper)));
|
||||
|
||||
Platform = Platform.Windows;
|
||||
CompressionHelperTypeName = string.Empty;
|
||||
}
|
||||
|
||||
public string ProductName
|
||||
{
|
||||
get
|
||||
{
|
||||
return PlayerSettings.productName;
|
||||
}
|
||||
}
|
||||
|
||||
public string CompanyName
|
||||
{
|
||||
get
|
||||
{
|
||||
return PlayerSettings.companyName;
|
||||
}
|
||||
}
|
||||
|
||||
public string GameIdentifier
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
return PlayerSettings.applicationIdentifier;
|
||||
#else
|
||||
return PlayerSettings.bundleIdentifier;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public string GameFrameworkVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameFramework.Version.GameFrameworkVersion;
|
||||
}
|
||||
}
|
||||
|
||||
public string UnityVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Application.unityVersion;
|
||||
}
|
||||
}
|
||||
|
||||
public string ApplicableGameVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Application.version;
|
||||
}
|
||||
}
|
||||
|
||||
public string WorkingDirectory
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Platform Platform
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string CompressionHelperTypeName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool BackupDiff
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool BackupVersion
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public int LengthLimit
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool IsValidWorkingDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(WorkingDirectory))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(WorkingDirectory))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public string SourcePath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsValidWorkingDirectory)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Full/", WorkingDirectory)).FullName);
|
||||
}
|
||||
}
|
||||
|
||||
public string SourcePathForDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsValidWorkingDirectory)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/Full/*/{1}/", WorkingDirectory, Platform)).FullName);
|
||||
}
|
||||
}
|
||||
|
||||
public string OutputPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsValidWorkingDirectory)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return Utility.Path.GetRegularPath(new DirectoryInfo(Utility.Text.Format("{0}/ResourcePack/{1}/", WorkingDirectory, Platform)).FullName);
|
||||
}
|
||||
}
|
||||
|
||||
public event GameFrameworkAction<int> OnBuildResourcePacksStarted = null;
|
||||
|
||||
public event GameFrameworkAction<int, int> OnBuildResourcePacksCompleted = null;
|
||||
|
||||
public event GameFrameworkAction<int, int, string, string> OnBuildResourcePackSuccess = null;
|
||||
|
||||
public event GameFrameworkAction<int, int, string, string> OnBuildResourcePackFailure = null;
|
||||
|
||||
public bool Load()
|
||||
{
|
||||
if (!File.Exists(m_ConfigurationPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.Load(m_ConfigurationPath);
|
||||
XmlNode xmlRoot = xmlDocument.SelectSingleNode("UnityGameFramework");
|
||||
XmlNode xmlEditor = xmlRoot.SelectSingleNode("ResourceBuilder");
|
||||
XmlNode xmlSettings = xmlEditor.SelectSingleNode("Settings");
|
||||
|
||||
XmlNodeList xmlNodeList = null;
|
||||
XmlNode xmlNode = null;
|
||||
|
||||
xmlNodeList = xmlSettings.ChildNodes;
|
||||
for (int i = 0; i < xmlNodeList.Count; i++)
|
||||
{
|
||||
xmlNode = xmlNodeList.Item(i);
|
||||
switch (xmlNode.Name)
|
||||
{
|
||||
case "CompressionHelperTypeName":
|
||||
CompressionHelperTypeName = xmlNode.InnerText;
|
||||
break;
|
||||
|
||||
case "OutputDirectory":
|
||||
WorkingDirectory = xmlNode.InnerText;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public string[] GetCompressionHelperTypeNames()
|
||||
{
|
||||
return m_CompressionHelperTypeNames.ToArray();
|
||||
}
|
||||
|
||||
public string[] GetVersionNames()
|
||||
{
|
||||
if (Platform == Platform.Undefined || !IsValidWorkingDirectory)
|
||||
{
|
||||
return EmptyStringArray;
|
||||
}
|
||||
|
||||
string platformName = Platform.ToString();
|
||||
DirectoryInfo sourceDirectoryInfo = new DirectoryInfo(SourcePath);
|
||||
if (!sourceDirectoryInfo.Exists)
|
||||
{
|
||||
return EmptyStringArray;
|
||||
}
|
||||
|
||||
List<string> versionNames = new List<string>();
|
||||
foreach (DirectoryInfo directoryInfo in sourceDirectoryInfo.GetDirectories())
|
||||
{
|
||||
string[] splitedVersionNames = directoryInfo.Name.Split('_');
|
||||
if (splitedVersionNames.Length < 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool invalid = false;
|
||||
int value = 0;
|
||||
for (int i = 0; i < splitedVersionNames.Length; i++)
|
||||
{
|
||||
if (!int.TryParse(splitedVersionNames[i], out value))
|
||||
{
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DirectoryInfo platformDirectoryInfo = new DirectoryInfo(Path.Combine(directoryInfo.FullName, platformName));
|
||||
if (!platformDirectoryInfo.Exists)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FileInfo[] versionListFiles = platformDirectoryInfo.GetFiles("GameFrameworkVersion.*.dat", SearchOption.TopDirectoryOnly);
|
||||
if (versionListFiles.Length != 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
versionNames.Add(directoryInfo.Name);
|
||||
}
|
||||
|
||||
versionNames.Sort((x, y) =>
|
||||
{
|
||||
return int.Parse(x.Substring(x.LastIndexOf('_') + 1)).CompareTo(int.Parse(y.Substring(y.LastIndexOf('_') + 1)));
|
||||
});
|
||||
|
||||
return versionNames.ToArray();
|
||||
}
|
||||
|
||||
public bool RefreshCompressionHelper()
|
||||
{
|
||||
bool retVal = false;
|
||||
if (!string.IsNullOrEmpty(CompressionHelperTypeName) && m_CompressionHelperTypeNames.Contains(CompressionHelperTypeName))
|
||||
{
|
||||
System.Type compressionHelperType = Utility.Assembly.GetType(CompressionHelperTypeName);
|
||||
if (compressionHelperType != null)
|
||||
{
|
||||
Utility.Compression.ICompressionHelper compressionHelper = (Utility.Compression.ICompressionHelper)Activator.CreateInstance(compressionHelperType);
|
||||
if (compressionHelper != null)
|
||||
{
|
||||
Utility.Compression.SetCompressionHelper(compressionHelper);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
CompressionHelperTypeName = string.Empty;
|
||||
Utility.Compression.SetCompressionHelper(null);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public void BuildResourcePacks(string[] sourceVersions, string targetVersion)
|
||||
{
|
||||
int count = sourceVersions.Length;
|
||||
if (OnBuildResourcePacksStarted != null)
|
||||
{
|
||||
OnBuildResourcePacksStarted(count);
|
||||
}
|
||||
|
||||
int successCount = 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (BuildResourcePack(sourceVersions[i], targetVersion))
|
||||
{
|
||||
successCount++;
|
||||
if (OnBuildResourcePackSuccess != null)
|
||||
{
|
||||
OnBuildResourcePackSuccess(i, count, sourceVersions[i], targetVersion);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OnBuildResourcePackFailure != null)
|
||||
{
|
||||
OnBuildResourcePackFailure(i, count, sourceVersions[i], targetVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OnBuildResourcePacksCompleted != null)
|
||||
{
|
||||
OnBuildResourcePacksCompleted(successCount, count);
|
||||
}
|
||||
}
|
||||
|
||||
public bool BuildResourcePack(string sourceVersion, string targetVersion)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(OutputPath))
|
||||
{
|
||||
Directory.CreateDirectory(OutputPath);
|
||||
}
|
||||
|
||||
string defaultBackupDiffPath = Path.Combine(OutputPath, DefaultResourcePackName);
|
||||
string defaultResourcePackName = Utility.Text.Format("{0}.{1}", defaultBackupDiffPath, DefaultExtension);
|
||||
if (File.Exists(defaultResourcePackName))
|
||||
{
|
||||
File.Delete(defaultResourcePackName);
|
||||
}
|
||||
|
||||
if (BackupDiff)
|
||||
{
|
||||
if (Directory.Exists(defaultBackupDiffPath))
|
||||
{
|
||||
Directory.Delete(defaultBackupDiffPath, true);
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(defaultBackupDiffPath);
|
||||
}
|
||||
|
||||
UpdatableVersionList sourceUpdatableVersionList = default(UpdatableVersionList);
|
||||
if (sourceVersion != null)
|
||||
{
|
||||
DirectoryInfo sourceDirectoryInfo = new DirectoryInfo(Path.Combine(Path.Combine(SourcePath, sourceVersion), Platform.ToString()));
|
||||
FileInfo[] sourceVersionListFiles = sourceDirectoryInfo.GetFiles("GameFrameworkVersion.*.dat", SearchOption.TopDirectoryOnly);
|
||||
byte[] sourceVersionListBytes = File.ReadAllBytes(sourceVersionListFiles[0].FullName);
|
||||
sourceVersionListBytes = Utility.Compression.Decompress(sourceVersionListBytes);
|
||||
using (Stream stream = new MemoryStream(sourceVersionListBytes))
|
||||
{
|
||||
sourceUpdatableVersionList = m_UpdatableVersionListSerializer.Deserialize(stream);
|
||||
}
|
||||
}
|
||||
|
||||
UpdatableVersionList targetUpdatableVersionList = default(UpdatableVersionList);
|
||||
DirectoryInfo targetDirectoryInfo = new DirectoryInfo(Path.Combine(Path.Combine(SourcePath, targetVersion), Platform.ToString()));
|
||||
FileInfo[] targetVersionListFiles = targetDirectoryInfo.GetFiles("GameFrameworkVersion.*.dat", SearchOption.TopDirectoryOnly);
|
||||
byte[] targetVersionListBytes = File.ReadAllBytes(targetVersionListFiles[0].FullName);
|
||||
targetVersionListBytes = Utility.Compression.Decompress(targetVersionListBytes);
|
||||
using (Stream stream = new MemoryStream(targetVersionListBytes))
|
||||
{
|
||||
targetUpdatableVersionList = m_UpdatableVersionListSerializer.Deserialize(stream);
|
||||
}
|
||||
|
||||
List<ResourcePackVersionList.Resource> resources = new List<ResourcePackVersionList.Resource>();
|
||||
UpdatableVersionList.Resource[] sourceResources = sourceUpdatableVersionList.IsValid ? sourceUpdatableVersionList.GetResources() : EmptyResourceArray;
|
||||
UpdatableVersionList.Resource[] targetResources = targetUpdatableVersionList.GetResources();
|
||||
long offset = 0L;
|
||||
foreach (UpdatableVersionList.Resource targetResource in targetResources)
|
||||
{
|
||||
bool ready = false;
|
||||
foreach (UpdatableVersionList.Resource sourceResource in sourceResources)
|
||||
{
|
||||
if (sourceResource.Name != targetResource.Name || sourceResource.Variant != targetResource.Variant || sourceResource.Extension != targetResource.Extension)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sourceResource.LoadType == targetResource.LoadType && sourceResource.Length == targetResource.Length && sourceResource.HashCode == targetResource.HashCode)
|
||||
{
|
||||
ready = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ready)
|
||||
{
|
||||
resources.Add(new ResourcePackVersionList.Resource(targetResource.Name, targetResource.Variant, targetResource.Extension, targetResource.LoadType, offset, targetResource.Length, targetResource.HashCode, targetResource.CompressedLength, targetResource.CompressedHashCode));
|
||||
offset += targetResource.CompressedLength;
|
||||
}
|
||||
}
|
||||
|
||||
ResourcePackVersionList.Resource[] resourceArray = resources.ToArray();
|
||||
using (FileStream fileStream = new FileStream(defaultResourcePackName, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
if (!m_ResourcePackVersionListSerializer.Serialize(fileStream, new ResourcePackVersionList(0, 0L, 0, resourceArray)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int position = 0;
|
||||
int hashCode = 0;
|
||||
string targetDirectoryPath = targetDirectoryInfo.FullName;
|
||||
using (FileStream fileStream = new FileStream(defaultResourcePackName, FileMode.Open, FileAccess.ReadWrite))
|
||||
{
|
||||
position = (int)fileStream.Length;
|
||||
fileStream.Position = position;
|
||||
foreach (ResourcePackVersionList.Resource resource in resourceArray)
|
||||
{
|
||||
string resourceName = Path.Combine(targetDirectoryPath, GetResourceFullName(resource.Name, resource.Variant, resource.HashCode));
|
||||
if (!File.Exists(resourceName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] resourceBytes = File.ReadAllBytes(resourceName);
|
||||
fileStream.Write(resourceBytes, 0, resourceBytes.Length);
|
||||
if (BackupDiff)
|
||||
{
|
||||
string backupDiffName = Path.Combine(defaultBackupDiffPath, GetResourceFullName(resource.Name, resource.Variant, resource.HashCode));
|
||||
string directoryName = Path.GetDirectoryName(backupDiffName);
|
||||
if (!Directory.Exists(directoryName))
|
||||
{
|
||||
Directory.CreateDirectory(directoryName);
|
||||
}
|
||||
|
||||
File.WriteAllBytes(backupDiffName, resourceBytes);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileStream.Position - position != offset)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
fileStream.Position = position;
|
||||
hashCode = Utility.Verifier.GetCrc32(fileStream);
|
||||
|
||||
fileStream.Position = 0L;
|
||||
if (!m_ResourcePackVersionListSerializer.Serialize(fileStream, new ResourcePackVersionList(position, offset, hashCode, resourceArray)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
string backupDiffPath = Path.Combine(OutputPath, Utility.Text.Format("{0}-{1}-{2}", DefaultResourcePackName, sourceVersion ?? GetNoneVersion(targetVersion), targetVersion));
|
||||
string resourcePackName = Utility.Text.Format("{0}.{1:x8}.{2}", backupDiffPath, hashCode, DefaultExtension);
|
||||
if (File.Exists(resourcePackName))
|
||||
{
|
||||
File.Delete(resourcePackName);
|
||||
}
|
||||
|
||||
File.Move(defaultResourcePackName, resourcePackName);
|
||||
|
||||
if (BackupDiff)
|
||||
{
|
||||
if (BackupVersion)
|
||||
{
|
||||
File.Copy(targetVersionListFiles[0].FullName, Path.Combine(defaultBackupDiffPath, Path.GetFileName(targetVersionListFiles[0].FullName)));
|
||||
}
|
||||
|
||||
if (Directory.Exists(backupDiffPath))
|
||||
{
|
||||
Directory.Delete(backupDiffPath, true);
|
||||
}
|
||||
|
||||
Directory.Move(defaultBackupDiffPath, backupDiffPath);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetNoneVersion(string targetVersion)
|
||||
{
|
||||
string[] splitedVersionNames = targetVersion.Split('_');
|
||||
for (int i = 0; i < splitedVersionNames.Length; i++)
|
||||
{
|
||||
splitedVersionNames[i] = "0";
|
||||
}
|
||||
|
||||
return string.Join("_", splitedVersionNames);
|
||||
}
|
||||
|
||||
private string GetResourceFullName(string name, string variant, int hashCode)
|
||||
{
|
||||
return !string.IsNullOrEmpty(variant) ? Utility.Text.Format("{0}.{1}.{2:x8}.{3}", name, variant, hashCode, DefaultExtension) : Utility.Text.Format("{0}.{1:x8}.{2}", name, hashCode, DefaultExtension);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 886e7d3c19662474caeb030f5b2d9a4e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d96add3948f44049bb53f4207cdee15
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,115 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源同步工具。
|
||||
/// </summary>
|
||||
internal sealed class ResourceSyncTools : EditorWindow
|
||||
{
|
||||
private const float ButtonHeight = 60f;
|
||||
private const float ButtonSpace = 5f;
|
||||
private ResourceSyncToolsController m_Controller = null;
|
||||
|
||||
[MenuItem("Game Framework/Resource Tools/Resource Sync Tools", false, 44)]
|
||||
private static void Open()
|
||||
{
|
||||
ResourceSyncTools window = GetWindow<ResourceSyncTools>("Resource Sync Tools", true);
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
window.minSize = new Vector2(400, 195f);
|
||||
#else
|
||||
window.minSize = new Vector2(400, 205f);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_Controller = new ResourceSyncToolsController();
|
||||
m_Controller.OnLoadingResource += OnLoadingResource;
|
||||
m_Controller.OnLoadingAsset += OnLoadingAsset;
|
||||
m_Controller.OnCompleted += OnCompleted;
|
||||
m_Controller.OnResourceDataChanged += OnResourceDataChanged;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.BeginVertical(GUILayout.Width(position.width), GUILayout.Height(position.height));
|
||||
{
|
||||
GUILayout.Space(ButtonSpace);
|
||||
if (GUILayout.Button("Remove All Asset Bundle Names in Project", GUILayout.Height(ButtonHeight)))
|
||||
{
|
||||
if (!m_Controller.RemoveAllAssetBundleNames())
|
||||
{
|
||||
Debug.LogWarning("Remove All Asset Bundle Names in Project failure.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Remove All Asset Bundle Names in Project completed.");
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
GUILayout.Space(ButtonSpace);
|
||||
if (GUILayout.Button("Sync ResourceCollection.xml to Project", GUILayout.Height(ButtonHeight)))
|
||||
{
|
||||
if (!m_Controller.SyncToProject())
|
||||
{
|
||||
Debug.LogWarning("Sync ResourceCollection.xml to Project failure.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Sync ResourceCollection.xml to Project completed.");
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
GUILayout.Space(ButtonSpace);
|
||||
if (GUILayout.Button("Sync ResourceCollection.xml from Project", GUILayout.Height(ButtonHeight)))
|
||||
{
|
||||
if (!m_Controller.SyncFromProject())
|
||||
{
|
||||
Debug.LogWarning("Sync Project to ResourceCollection.xml failure.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Sync Project to ResourceCollection.xml completed.");
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void OnLoadingResource(int index, int count)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Loading Resources", Utility.Text.Format("Loading resources, {0}/{1} loaded.", index, count), (float)index / count);
|
||||
}
|
||||
|
||||
private void OnLoadingAsset(int index, int count)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Loading Assets", Utility.Text.Format("Loading assets, {0}/{1} loaded.", index, count), (float)index / count);
|
||||
}
|
||||
|
||||
private void OnCompleted()
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
private void OnResourceDataChanged(int index, int count, string assetName)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Processing Assets", Utility.Text.Format("({0}/{1}) {2}", index, count, assetName), (float)index / count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d691ed24af244ff41a3012f66ca3ef80
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,229 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityGameFramework.Editor.ResourceTools
|
||||
{
|
||||
public sealed class ResourceSyncToolsController
|
||||
{
|
||||
public ResourceSyncToolsController()
|
||||
{
|
||||
}
|
||||
|
||||
public event GameFrameworkAction<int, int> OnLoadingResource = null;
|
||||
|
||||
public event GameFrameworkAction<int, int> OnLoadingAsset = null;
|
||||
|
||||
public event GameFrameworkAction OnCompleted = null;
|
||||
|
||||
public event GameFrameworkAction<int, int, string> OnResourceDataChanged = null;
|
||||
|
||||
public string[] GetAllAssetBundleNames()
|
||||
{
|
||||
return AssetDatabase.GetAllAssetBundleNames();
|
||||
}
|
||||
|
||||
public string[] GetUsedAssetBundleNames()
|
||||
{
|
||||
HashSet<string> hashSet = new HashSet<string>(GetAllAssetBundleNames());
|
||||
hashSet.ExceptWith(GetUnusedAssetBundleNames());
|
||||
return hashSet.ToArray();
|
||||
}
|
||||
|
||||
public string[] GetUnusedAssetBundleNames()
|
||||
{
|
||||
return AssetDatabase.GetUnusedAssetBundleNames();
|
||||
}
|
||||
|
||||
public string[] GetAssetPathsFromAssetBundle(string assetBundleName)
|
||||
{
|
||||
return AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName);
|
||||
}
|
||||
|
||||
public string[] GetAssetPathsFromAssetBundleAndAssetName(string assetBundleName, string assetName)
|
||||
{
|
||||
return AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(assetBundleName, assetName);
|
||||
}
|
||||
|
||||
public bool RemoveAssetBundleName(string assetBundleName, bool forceRemove)
|
||||
{
|
||||
return AssetDatabase.RemoveAssetBundleName(assetBundleName, forceRemove);
|
||||
}
|
||||
|
||||
public void RemoveUnusedAssetBundleNames()
|
||||
{
|
||||
AssetDatabase.RemoveUnusedAssetBundleNames();
|
||||
}
|
||||
|
||||
public bool RemoveAllAssetBundleNames()
|
||||
{
|
||||
HashSet<string> allAssetNames = new HashSet<string>();
|
||||
string[] assetBundleNames = GetUsedAssetBundleNames();
|
||||
foreach (string assetBundleName in assetBundleNames)
|
||||
{
|
||||
string[] assetNames = GetAssetPathsFromAssetBundle(assetBundleName);
|
||||
foreach (string assetName in assetNames)
|
||||
{
|
||||
allAssetNames.Add(assetName);
|
||||
}
|
||||
}
|
||||
|
||||
int assetIndex = 0;
|
||||
int assetCount = allAssetNames.Count;
|
||||
foreach (string assetName in allAssetNames)
|
||||
{
|
||||
AssetImporter assetImporter = AssetImporter.GetAtPath(assetName);
|
||||
if (assetImporter == null)
|
||||
{
|
||||
if (OnCompleted != null)
|
||||
{
|
||||
OnCompleted();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
assetImporter.assetBundleVariant = null;
|
||||
assetImporter.assetBundleName = null;
|
||||
assetImporter.SaveAndReimport();
|
||||
|
||||
if (OnResourceDataChanged != null)
|
||||
{
|
||||
OnResourceDataChanged(++assetIndex, assetCount, assetName);
|
||||
}
|
||||
}
|
||||
|
||||
RemoveUnusedAssetBundleNames();
|
||||
|
||||
if (OnCompleted != null)
|
||||
{
|
||||
OnCompleted();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SyncToProject()
|
||||
{
|
||||
ResourceCollection resourceCollection = new ResourceCollection();
|
||||
|
||||
resourceCollection.OnLoadingResource += delegate (int index, int count)
|
||||
{
|
||||
if (OnLoadingResource != null)
|
||||
{
|
||||
OnLoadingResource(index, count);
|
||||
}
|
||||
};
|
||||
|
||||
resourceCollection.OnLoadingAsset += delegate (int index, int count)
|
||||
{
|
||||
if (OnLoadingAsset != null)
|
||||
{
|
||||
OnLoadingAsset(index, count);
|
||||
}
|
||||
};
|
||||
|
||||
resourceCollection.OnLoadCompleted += delegate ()
|
||||
{
|
||||
if (OnCompleted != null)
|
||||
{
|
||||
OnCompleted();
|
||||
}
|
||||
};
|
||||
|
||||
if (!resourceCollection.Load())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int assetIndex = 0;
|
||||
int assetCount = resourceCollection.AssetCount;
|
||||
Resource[] resources = resourceCollection.GetResources();
|
||||
foreach (Resource resource in resources)
|
||||
{
|
||||
if (resource.IsLoadFromBinary)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Asset[] assets = resource.GetAssets();
|
||||
foreach (Asset asset in assets)
|
||||
{
|
||||
AssetImporter assetImporter = AssetImporter.GetAtPath(asset.Name);
|
||||
if (assetImporter == null)
|
||||
{
|
||||
if (OnCompleted != null)
|
||||
{
|
||||
OnCompleted();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
assetImporter.assetBundleName = resource.Name;
|
||||
assetImporter.assetBundleVariant = resource.Variant;
|
||||
assetImporter.SaveAndReimport();
|
||||
|
||||
if (OnResourceDataChanged != null)
|
||||
{
|
||||
OnResourceDataChanged(++assetIndex, assetCount, asset.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OnCompleted != null)
|
||||
{
|
||||
OnCompleted();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SyncFromProject()
|
||||
{
|
||||
ResourceCollection resourceCollection = new ResourceCollection();
|
||||
string[] assetBundleNames = GetUsedAssetBundleNames();
|
||||
foreach (string assetBundleName in assetBundleNames)
|
||||
{
|
||||
string name = assetBundleName;
|
||||
string variant = null;
|
||||
int dotPosition = assetBundleName.LastIndexOf('.');
|
||||
if (dotPosition > 0 && dotPosition < assetBundleName.Length - 1)
|
||||
{
|
||||
name = assetBundleName.Substring(0, dotPosition);
|
||||
variant = assetBundleName.Substring(dotPosition + 1);
|
||||
}
|
||||
|
||||
if (!resourceCollection.AddResource(name, variant, null, LoadType.LoadFromFile, false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] assetNames = GetAssetPathsFromAssetBundle(assetBundleName);
|
||||
foreach (string assetName in assetNames)
|
||||
{
|
||||
string guid = AssetDatabase.AssetPathToGUID(assetName);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!resourceCollection.AssignAsset(guid, name, variant))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resourceCollection.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 210d0e0a522f6c540b17cf9fe64b71e4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Packages/com.bywaystudios.resourceloader/Runtime.meta
Normal file
8
Packages/com.bywaystudios.resourceloader/Runtime.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e2255dcc5c6cd5349819787a0ec15554
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "Byway.ResourceLoader"
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ed8c5c15f686974c93241dd368c4cc8
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c59a93bee4270d54994aa089a32b353d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,16 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace GameFramework.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用可更新模式并应用资源包资源完成时的回调函数。
|
||||
/// </summary>
|
||||
/// <param name="resourcePackPath">应用的资源包路径。</param>
|
||||
/// <param name="result">应用资源包资源结果,全部成功为 true,否则为 false。</param>
|
||||
public delegate void ApplyResourcesCompleteCallback(string resourcePackPath, bool result);
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9d27a65d627b6c4facd67c3371e85f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,19 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace GameFramework.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用可更新模式并检查资源完成时的回调函数。
|
||||
/// </summary>
|
||||
/// <param name="movedCount">已移动的资源数量。</param>
|
||||
/// <param name="removedCount">已移除的资源数量。</param>
|
||||
/// <param name="updateCount">可更新的资源数量。</param>
|
||||
/// <param name="updateTotalLength">可更新的资源总大小。</param>
|
||||
/// <param name="updateTotalCompressedLength">可更新的压缩后总大小。</param>
|
||||
public delegate void CheckResourcesCompleteCallback(int movedCount, int removedCount, int updateCount, long updateTotalLength, long updateTotalCompressedLength);
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44b378c75bd47654e8269f1a95775e36
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,25 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace GameFramework.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查版本资源列表结果。
|
||||
/// </summary>
|
||||
public enum CheckVersionListResult : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 已经是最新的。
|
||||
/// </summary>
|
||||
Updated = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 需要更新。
|
||||
/// </summary>
|
||||
NeedUpdate
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0011c07ad50f9d4428874a8b1191e5af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,20 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace GameFramework.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源相关常量。
|
||||
/// </summary>
|
||||
internal static class Constant
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认资源加载优先级。
|
||||
/// </summary>
|
||||
internal const int DefaultPriority = 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8568e897065730448853b7e92432a01a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,25 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace GameFramework.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// 解密资源回调函数。
|
||||
/// </summary>
|
||||
/// <param name="bytes">要解密的资源二进制流。</param>
|
||||
/// <param name="startIndex">解密二进制流的起始位置。</param>
|
||||
/// <param name="count">解密二进制流的长度。</param>
|
||||
/// <param name="name">资源名称。</param>
|
||||
/// <param name="variant">变体名称。</param>
|
||||
/// <param name="extension">扩展名称。</param>
|
||||
/// <param name="storageInReadOnly">资源是否在只读区。</param>
|
||||
/// <param name="fileSystem">文件系统名称。</param>
|
||||
/// <param name="loadType">资源加载方式。</param>
|
||||
/// <param name="length">资源大小。</param>
|
||||
/// <param name="hashCode">资源哈希值。</param>
|
||||
public delegate void DecryptResourceCallback(byte[] bytes, int startIndex, int count, string name, string variant, string extension, bool storageInReadOnly, string fileSystem, byte loadType, int length, int hashCode);
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ff1c45ec7e055346aab3793b995ce9c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user