New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using UnityEditor.Android; |
| | | using UnityEngine; |
| | | |
| | | public class AndroidPostBuildProcessor : IPostGenerateGradleAndroidProject |
| | | { |
| | | public int callbackOrder => 999; |
| | | |
| | | public void OnPostGenerateGradleAndroidProject(string path) |
| | | { |
| | | Debug.Log("AndroidPostBuildProcessor path : " + path); |
| | | |
| | | //导入当前渠道需要使用的第三方远程依赖库 |
| | | var versionConfig = VersionConfig.Get(); |
| | | var depsFile = StringUtility.Contact(ClientPackage.SDK_PLUGIN_PROJECT, "/Channel/Android/", versionConfig.appId, "/deps.gradle"); |
| | | if (File.Exists(depsFile)) |
| | | { |
| | | File.Copy(depsFile, path + "/deps.gradle"); |
| | | Debug.Log("渠道第三方远程依赖脚本已拷贝:" + depsFile); |
| | | } |
| | | else |
| | | Debug.Log("渠道第三方远程依赖脚本不存在:" + depsFile); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 654b18606f4e0b04d993cedb9538e995 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 8c37e9a99bc1d674ca851e33ca984797 |
| | | folderAsset: yes |
| | | timeCreated: 1503232241 |
| | | licenseType: Free |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEditor; |
| | | using UnityEditor.IMGUI.Controls; |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | |
| | | public class AssetBundleBrowserMain : EditorWindow, IHasCustomMenu |
| | | { |
| | | |
| | | public const float kButtonWidth = 150; |
| | | |
| | | enum Mode |
| | | { |
| | | Browser, |
| | | Builder, |
| | | Inspect, |
| | | } |
| | | [SerializeField] |
| | | Mode m_Mode; |
| | | |
| | | [SerializeField] |
| | | public AssetBundleManageTab m_ManageTab; |
| | | |
| | | [SerializeField] |
| | | public AssetBundleBuildTab m_BuildTab; |
| | | |
| | | [SerializeField] |
| | | public AssetBundleInspectTab m_InspectTab; |
| | | |
| | | private Texture2D m_RefreshTexture; |
| | | |
| | | const float k_ToolbarPadding = 15; |
| | | const float k_MenubarPadding = 32; |
| | | |
| | | [MenuItem("Tools/AssetBundle Browser", priority = 2050)] |
| | | static void ShowWindow() |
| | | { |
| | | var window = GetWindow<AssetBundleBrowserMain>(); |
| | | window.titleContent = new GUIContent("AssetBundles"); |
| | | window.Show(); |
| | | } |
| | | |
| | | [SerializeField] |
| | | public bool multiDataSource = false; |
| | | public virtual void AddItemsToMenu(GenericMenu menu) |
| | | { |
| | | //menu.AddSeparator(string.Empty); |
| | | menu.AddItem(new GUIContent("Custom Sources"), multiDataSource, FlipDataSource); |
| | | } |
| | | public void FlipDataSource() |
| | | { |
| | | multiDataSource = !multiDataSource; |
| | | } |
| | | |
| | | private void OnEnable() |
| | | { |
| | | |
| | | Rect subPos = GetSubWindowArea(); |
| | | if(m_ManageTab == null) |
| | | m_ManageTab = new AssetBundleManageTab(); |
| | | m_ManageTab.OnEnable(subPos, this); |
| | | if(m_BuildTab == null) |
| | | m_BuildTab = new AssetBundleBuildTab(); |
| | | m_BuildTab.OnEnable(subPos, this); |
| | | if (m_InspectTab == null) |
| | | m_InspectTab = new AssetBundleInspectTab(); |
| | | m_InspectTab.OnEnable(subPos, this); |
| | | |
| | | m_RefreshTexture = EditorGUIUtility.FindTexture("Refresh"); |
| | | |
| | | |
| | | //determine if we are "multi source" or not... |
| | | multiDataSource = false; |
| | | List<System.Type> types = AssetBundleDataSource.ABDataSourceProviderUtility.CustomABDataSourceTypes; |
| | | if (types.Count > 1) |
| | | multiDataSource = true; |
| | | } |
| | | private void OnDisable() |
| | | { |
| | | if (m_BuildTab != null) |
| | | m_BuildTab.OnDisable(); |
| | | if (m_InspectTab != null) |
| | | m_InspectTab.OnDisable(); |
| | | } |
| | | |
| | | private Rect GetSubWindowArea() |
| | | { |
| | | float padding = k_MenubarPadding; |
| | | if (multiDataSource) |
| | | padding += k_MenubarPadding * 0.5f; |
| | | Rect subPos = new Rect(0, padding, position.width, position.height - padding); |
| | | return subPos; |
| | | } |
| | | |
| | | private void Update() |
| | | { |
| | | switch (m_Mode) |
| | | { |
| | | case Mode.Builder: |
| | | break; |
| | | case Mode.Inspect: |
| | | break; |
| | | case Mode.Browser: |
| | | default: |
| | | m_ManageTab.Update(); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | private void OnGUI() |
| | | { |
| | | ModeToggle(); |
| | | |
| | | switch(m_Mode) |
| | | { |
| | | case Mode.Builder: |
| | | m_BuildTab.OnGUI(GetSubWindowArea()); |
| | | break; |
| | | case Mode.Inspect: |
| | | m_InspectTab.OnGUI(GetSubWindowArea()); |
| | | break; |
| | | case Mode.Browser: |
| | | default: |
| | | m_ManageTab.OnGUI(GetSubWindowArea()); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | void ModeToggle() |
| | | { |
| | | GUILayout.BeginHorizontal(); |
| | | GUILayout.Space(k_ToolbarPadding); |
| | | bool clicked = false; |
| | | switch(m_Mode) |
| | | { |
| | | case Mode.Browser: |
| | | clicked = GUILayout.Button(m_RefreshTexture); |
| | | if (clicked) |
| | | m_ManageTab.ForceReloadData(); |
| | | break; |
| | | case Mode.Builder: |
| | | GUILayout.Space(m_RefreshTexture.width + k_ToolbarPadding); |
| | | break; |
| | | case Mode.Inspect: |
| | | clicked = GUILayout.Button(m_RefreshTexture); |
| | | if (clicked) |
| | | m_InspectTab.RefreshBundles(); |
| | | break; |
| | | } |
| | | |
| | | float toolbarWidth = position.width - k_ToolbarPadding * 4 - m_RefreshTexture.width; |
| | | //string[] labels = new string[2] { "Configure", "Build"}; |
| | | string[] labels = new string[3] { "Configure", "Build", "Inspect" }; |
| | | m_Mode = (Mode)GUILayout.Toolbar((int)m_Mode, labels, "LargeButton", GUILayout.Width(toolbarWidth) ); |
| | | GUILayout.FlexibleSpace(); |
| | | GUILayout.EndHorizontal(); |
| | | if(multiDataSource) |
| | | { |
| | | //GUILayout.BeginArea(r); |
| | | GUILayout.BeginHorizontal(); |
| | | |
| | | using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar)) |
| | | { |
| | | GUILayout.Label("Bundle Data Source:"); |
| | | GUILayout.FlexibleSpace(); |
| | | var c = new GUIContent(string.Format("{0} ({1})", AssetBundleModel.Model.DataSource.Name, AssetBundleModel.Model.DataSource.ProviderName), "Select Asset Bundle Set"); |
| | | if (GUILayout.Button(c , EditorStyles.toolbarPopup) ) |
| | | { |
| | | GenericMenu menu = new GenericMenu(); |
| | | bool firstItem = true; |
| | | |
| | | foreach (var info in AssetBundleDataSource.ABDataSourceProviderUtility.CustomABDataSourceTypes) |
| | | { |
| | | List<AssetBundleDataSource.ABDataSource> dataSourceList = null; |
| | | dataSourceList = info.GetMethod("CreateDataSources").Invoke(null, null) as List<AssetBundleDataSource.ABDataSource>; |
| | | |
| | | |
| | | if (dataSourceList == null) |
| | | continue; |
| | | |
| | | if (!firstItem) |
| | | { |
| | | menu.AddSeparator(""); |
| | | } |
| | | |
| | | foreach (var ds in dataSourceList) |
| | | { |
| | | menu.AddItem(new GUIContent(string.Format("{0} ({1})", ds.Name, ds.ProviderName)), false, |
| | | () => |
| | | { |
| | | var thisDataSource = ds; |
| | | AssetBundleModel.Model.DataSource = thisDataSource; |
| | | m_ManageTab.ForceReloadData(); |
| | | } |
| | | ); |
| | | } |
| | | |
| | | firstItem = false; |
| | | } |
| | | |
| | | menu.ShowAsContext(); |
| | | } |
| | | |
| | | GUILayout.FlexibleSpace(); |
| | | if (AssetBundleModel.Model.DataSource.IsReadOnly()) |
| | | { |
| | | GUIStyle tbLabel = new GUIStyle(EditorStyles.toolbar); |
| | | tbLabel.alignment = TextAnchor.MiddleRight; |
| | | |
| | | GUILayout.Label("Read Only", tbLabel); |
| | | } |
| | | } |
| | | |
| | | GUILayout.EndHorizontal(); |
| | | //GUILayout.EndArea(); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 6783bbbd420e56a40b6b1b4f3edbd7d5 |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | using UnityEditor.IMGUI.Controls; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Runtime.Serialization.Formatters.Binary; |
| | | |
| | | using UnityEngine.AssetBundles.AssetBundleDataSource; |
| | | using Assets.Editor.Tool; |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | [System.Serializable] |
| | | public class AssetBundleBuildTab |
| | | { |
| | | const string k_BuildPrefPrefix = "ABBBuild:"; |
| | | // gui vars |
| | | //[SerializeField] |
| | | //private ValidBuildTarget m_BuildTarget = ValidBuildTarget.StandaloneWindows; |
| | | //[SerializeField] |
| | | //private CompressOptions m_Compression = CompressOptions.StandardCompression; |
| | | //private string m_OutputPath = string.Empty; |
| | | //[SerializeField] |
| | | //private bool m_UseDefaultPath = true; |
| | | private string m_streamingPath |
| | | { |
| | | get |
| | | { |
| | | switch (m_UserData.m_BuildTarget) |
| | | { |
| | | case ValidBuildTarget.Android: |
| | | return StringUtility.Contact("Assets/StreamingAssets", "/android"); |
| | | case ValidBuildTarget.iOS: |
| | | return StringUtility.Contact("Assets/StreamingAssets", "/ios"); |
| | | case ValidBuildTarget.StandaloneWindows: |
| | | case ValidBuildTarget.StandaloneWindows64: |
| | | return StringUtility.Contact("Assets/StreamingAssets", "/standalone"); |
| | | default: |
| | | return "Assets/StreamingAssets"; |
| | | } |
| | | } |
| | | } |
| | | |
| | | [SerializeField] |
| | | private bool m_AdvancedSettings; |
| | | |
| | | [SerializeField] |
| | | private Vector2 m_ScrollPosition; |
| | | |
| | | |
| | | class ToggleData |
| | | { |
| | | public ToggleData(bool s, |
| | | string title, |
| | | string tooltip, |
| | | List<string> onToggles, |
| | | BuildAssetBundleOptions opt = BuildAssetBundleOptions.None) |
| | | { |
| | | if (onToggles.Contains(title)) |
| | | state = true; |
| | | else |
| | | state = s; |
| | | content = new GUIContent(title, tooltip); |
| | | option = opt; |
| | | } |
| | | //public string prefsKey |
| | | //{ get { return k_BuildPrefPrefix + content.text; } } |
| | | public bool state; |
| | | public GUIContent content; |
| | | public BuildAssetBundleOptions option; |
| | | } |
| | | |
| | | [SerializeField] |
| | | private BuildTabData m_UserData; |
| | | |
| | | [SerializeField] int m_Version; |
| | | |
| | | public string ApkOutputPath |
| | | { |
| | | get { return LocalSave.GetString("APKOutPutPath"); } |
| | | set { LocalSave.SetString("APKOutPutPath", value); } |
| | | } |
| | | |
| | | public string publishers |
| | | { |
| | | get { return LocalSave.GetString("APKPublishers"); } |
| | | set { LocalSave.SetString("APKPublishers", value); } |
| | | } |
| | | |
| | | List<ToggleData> m_ToggleData; |
| | | ToggleData m_ForceRebuild; |
| | | ToggleData m_CopyToStreaming; |
| | | GUIContent m_TargetContent; |
| | | GUIContent m_CompressionContent; |
| | | public enum CompressOptions |
| | | { |
| | | Uncompressed = 0, |
| | | StandardCompression, |
| | | ChunkBasedCompression, |
| | | } |
| | | GUIContent[] m_CompressionOptions = |
| | | { |
| | | new GUIContent("No Compression"), |
| | | new GUIContent("Standard Compression (LZMA)"), |
| | | new GUIContent("Chunk Based Compression (LZ4)") |
| | | }; |
| | | int[] m_CompressionValues = { 0, 1, 2 }; |
| | | |
| | | int rechargeSkin = 1; |
| | | string createRoleLevel = "001"; |
| | | |
| | | public AssetBundleBuildTab() |
| | | { |
| | | m_AdvancedSettings = false; |
| | | m_UserData = new BuildTabData(); |
| | | m_UserData.m_OnToggles = new List<string>(); |
| | | m_UserData.m_UseDefaultPath = true; |
| | | } |
| | | |
| | | public void OnDisable() |
| | | { |
| | | var dataPath = System.IO.Path.GetFullPath("."); |
| | | dataPath = dataPath.Replace("\\", "/"); |
| | | dataPath += "/Library/AssetBundleBrowserBuild.dat"; |
| | | |
| | | BinaryFormatter bf = new BinaryFormatter(); |
| | | FileStream file = File.Create(dataPath); |
| | | |
| | | bf.Serialize(file, m_UserData); |
| | | file.Close(); |
| | | |
| | | } |
| | | public void OnEnable(Rect pos, EditorWindow parent) |
| | | { |
| | | |
| | | //LoadData... |
| | | var dataPath = System.IO.Path.GetFullPath("."); |
| | | dataPath = dataPath.Replace("\\", "/"); |
| | | dataPath += "/Library/AssetBundleBrowserBuild.dat"; |
| | | |
| | | if (File.Exists(dataPath)) |
| | | { |
| | | BinaryFormatter bf = new BinaryFormatter(); |
| | | FileStream file = File.Open(dataPath, FileMode.Open); |
| | | var data = bf.Deserialize(file) as BuildTabData; |
| | | if (data != null) |
| | | m_UserData = data; |
| | | file.Close(); |
| | | } |
| | | |
| | | m_ToggleData = new List<ToggleData>(); |
| | | m_ToggleData.Add(new ToggleData( |
| | | false, |
| | | "Exclude Type Information", |
| | | "不包含类型信息。发布web平台时,不能使用该选项。", |
| | | m_UserData.m_OnToggles, |
| | | BuildAssetBundleOptions.DisableWriteTypeTree)); |
| | | m_ToggleData.Add(new ToggleData( |
| | | false, |
| | | "Force Rebuild", |
| | | "强制重新build所有ab包。", |
| | | m_UserData.m_OnToggles, |
| | | BuildAssetBundleOptions.ForceRebuildAssetBundle)); |
| | | m_ToggleData.Add(new ToggleData( |
| | | false, |
| | | "Ignore Type Tree Changes", |
| | | "忽略typetree的变化,不能与DisableWriteTypeTree同时使用。", |
| | | m_UserData.m_OnToggles, |
| | | BuildAssetBundleOptions.IgnoreTypeTreeChanges)); |
| | | m_ToggleData.Add(new ToggleData( |
| | | false, |
| | | "Append Hash", |
| | | "附加hash到assetbundle名字中。", |
| | | m_UserData.m_OnToggles, |
| | | BuildAssetBundleOptions.AppendHashToAssetBundleName)); |
| | | m_ToggleData.Add(new ToggleData( |
| | | false, |
| | | "Strict Mode", |
| | | "使用严格模式build ab, 有任何非致命的error都不会build成功。", |
| | | m_UserData.m_OnToggles, |
| | | BuildAssetBundleOptions.StrictMode)); |
| | | m_ToggleData.Add(new ToggleData( |
| | | false, |
| | | "Dry Run Build", |
| | | "Do a dry run build.", |
| | | m_UserData.m_OnToggles, |
| | | BuildAssetBundleOptions.DryRunBuild)); |
| | | |
| | | |
| | | m_ForceRebuild = new ToggleData( |
| | | false, |
| | | "Rebuild", |
| | | "选中后会清空所有旧的资源,全部重新打包(建议测试时不勾选可加快打包速度)", |
| | | m_UserData.m_OnToggles); |
| | | m_CopyToStreaming = new ToggleData( |
| | | false, |
| | | "Copy to StreamingAssets", |
| | | "资源打包完成后,会将所有资源拷贝至:" + m_streamingPath + " for use in stand-alone player.", |
| | | m_UserData.m_OnToggles); |
| | | |
| | | m_TargetContent = new GUIContent("Build Target", "Choose target platform to build for."); |
| | | m_CompressionContent = new GUIContent("Compression", "Choose no compress, standard (LZMA), or chunk based (LZ4)"); |
| | | |
| | | if (m_UserData.m_UseDefaultPath) |
| | | { |
| | | ResetPathToDefault(); |
| | | } |
| | | } |
| | | |
| | | public void OnGUI(Rect pos) |
| | | { |
| | | m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition); |
| | | bool newState = false; |
| | | var centeredStyle = GUI.skin.GetStyle("Label"); |
| | | centeredStyle.alignment = TextAnchor.UpperCenter; |
| | | GUILayout.Label(new GUIContent("Example build setup"), centeredStyle); |
| | | //basic options |
| | | EditorGUILayout.Space(); |
| | | GUILayout.BeginVertical(); |
| | | |
| | | // build target |
| | | using (new EditorGUI.DisabledScope(!AssetBundleModel.Model.DataSource.CanSpecifyBuildTarget)) |
| | | { |
| | | ValidBuildTarget tgt = (ValidBuildTarget)EditorGUILayout.EnumPopup(m_TargetContent, m_UserData.m_BuildTarget); |
| | | if (tgt != m_UserData.m_BuildTarget) |
| | | { |
| | | m_UserData.m_BuildTarget = tgt; |
| | | if (m_UserData.m_UseDefaultPath) |
| | | { |
| | | m_UserData.m_OutputPath = "AssetBundles/"; |
| | | m_UserData.m_OutputPath += m_UserData.m_BuildTarget.ToString(); |
| | | //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | ////output path |
| | | using (new EditorGUI.DisabledScope(!AssetBundleModel.Model.DataSource.CanSpecifyBuildOutputDirectory)) |
| | | { |
| | | EditorGUILayout.Space(); |
| | | GUILayout.BeginHorizontal(); |
| | | var newPath = EditorGUILayout.TextField("Output Path", m_UserData.m_OutputPath); |
| | | if ((newPath != m_UserData.m_OutputPath) && |
| | | (newPath != string.Empty)) |
| | | { |
| | | m_UserData.m_UseDefaultPath = false; |
| | | m_UserData.m_OutputPath = newPath; |
| | | //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath); |
| | | } |
| | | GUILayout.EndHorizontal(); |
| | | GUILayout.BeginHorizontal(); |
| | | GUILayout.FlexibleSpace(); |
| | | if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f))) |
| | | BrowseForFolder(); |
| | | if (GUILayout.Button("Reset", GUILayout.MaxWidth(75f))) |
| | | ResetPathToDefault(); |
| | | //if (string.IsNullOrEmpty(m_OutputPath)) |
| | | // m_OutputPath = EditorUserBuildSettings.GetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath"); |
| | | GUILayout.EndHorizontal(); |
| | | EditorGUILayout.Space(); |
| | | |
| | | newState = GUILayout.Toggle( |
| | | m_ForceRebuild.state, |
| | | m_ForceRebuild.content); |
| | | if (newState != m_ForceRebuild.state) |
| | | { |
| | | if (newState) |
| | | m_UserData.m_OnToggles.Add(m_ForceRebuild.content.text); |
| | | else |
| | | m_UserData.m_OnToggles.Remove(m_ForceRebuild.content.text); |
| | | m_ForceRebuild.state = newState; |
| | | } |
| | | newState = GUILayout.Toggle( |
| | | m_CopyToStreaming.state, |
| | | m_CopyToStreaming.content); |
| | | if (newState != m_CopyToStreaming.state) |
| | | { |
| | | if (newState) |
| | | m_UserData.m_OnToggles.Add(m_CopyToStreaming.content.text); |
| | | else |
| | | m_UserData.m_OnToggles.Remove(m_CopyToStreaming.content.text); |
| | | m_CopyToStreaming.state = newState; |
| | | } |
| | | } |
| | | |
| | | // advanced options |
| | | using (new EditorGUI.DisabledScope(!AssetBundleModel.Model.DataSource.CanSpecifyBuildOptions)) |
| | | { |
| | | EditorGUILayout.Space(); |
| | | m_AdvancedSettings = EditorGUILayout.Foldout(m_AdvancedSettings, "Advanced Settings"); |
| | | if (m_AdvancedSettings) |
| | | { |
| | | var indent = EditorGUI.indentLevel; |
| | | EditorGUI.indentLevel = 1; |
| | | CompressOptions cmp = (CompressOptions)EditorGUILayout.IntPopup( |
| | | m_CompressionContent, |
| | | (int)m_UserData.m_Compression, |
| | | m_CompressionOptions, |
| | | m_CompressionValues); |
| | | |
| | | if (cmp != m_UserData.m_Compression) |
| | | { |
| | | m_UserData.m_Compression = cmp; |
| | | } |
| | | foreach (var tog in m_ToggleData) |
| | | { |
| | | newState = EditorGUILayout.ToggleLeft( |
| | | tog.content, |
| | | tog.state); |
| | | if (newState != tog.state) |
| | | { |
| | | |
| | | if (newState) |
| | | m_UserData.m_OnToggles.Add(tog.content.text); |
| | | else |
| | | m_UserData.m_OnToggles.Remove(tog.content.text); |
| | | tog.state = newState; |
| | | } |
| | | } |
| | | EditorGUILayout.Space(); |
| | | EditorGUI.indentLevel = indent; |
| | | } |
| | | } |
| | | |
| | | // build. |
| | | EditorGUILayout.Space(); |
| | | if (GUILayout.Button("Build All Assets")) |
| | | { |
| | | EditorApplication.delayCall += ExecuteBuildAll; |
| | | } |
| | | |
| | | EditorGUILayout.BeginHorizontal(); |
| | | |
| | | if (GUILayout.Button("Config")) |
| | | { |
| | | EditorApplication.delayCall += ExcuteBuildConfig; |
| | | } |
| | | |
| | | if (GUILayout.Button("Lua")) |
| | | { |
| | | EditorApplication.delayCall += ExcuteBuildLua; |
| | | } |
| | | |
| | | if (GUILayout.Button("UI")) |
| | | { |
| | | EditorApplication.delayCall += ExcuteBuildUI; |
| | | } |
| | | |
| | | if (GUILayout.Button("BuiltIn")) |
| | | { |
| | | EditorApplication.delayCall += ExcuteBuildBuiltIn; |
| | | } |
| | | |
| | | if (GUILayout.Button("Audio")) |
| | | { |
| | | EditorApplication.delayCall += ExcuteBuildAudio; |
| | | } |
| | | |
| | | if (GUILayout.Button("Levels")) |
| | | { |
| | | EditorApplication.delayCall += ExcuteBuildLevels; |
| | | } |
| | | |
| | | if (GUILayout.Button("MobEffectShader")) |
| | | { |
| | | EditorApplication.delayCall += ExcuteBuildMobEffectShader; |
| | | } |
| | | |
| | | EditorGUILayout.EndHorizontal(); |
| | | |
| | | EditorGUILayout.Space(); |
| | | |
| | | |
| | | EditorGUILayout.Space(); |
| | | |
| | | EditorGUILayout.BeginHorizontal(); |
| | | |
| | | if (GUILayout.Button("Make VersionFile")) |
| | | { |
| | | EditorApplication.delayCall += MakeAssetsVersionFile; |
| | | } |
| | | |
| | | EditorGUILayout.EndHorizontal(); |
| | | |
| | | EditorGUILayout.Space(); |
| | | EditorGUILayout.Space(); |
| | | EditorGUILayout.Space(); |
| | | #if UNITY_ANDROID |
| | | GUILayout.BeginHorizontal(); |
| | | EditorGUILayout.TextField("Apk Output Path", ApkOutputPath); |
| | | if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f))) |
| | | { |
| | | BrowseForApkOutput(); |
| | | } |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | EditorGUILayout.Space(); |
| | | #endif |
| | | |
| | | #if UNITY_STANDALONE |
| | | GUILayout.BeginHorizontal(); |
| | | EditorGUILayout.TextField("EXE Output Path", ApkOutputPath); |
| | | if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f))) |
| | | { |
| | | BrowseForApkOutput(); |
| | | } |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | EditorGUILayout.Space(); |
| | | #endif |
| | | |
| | | GUILayout.BeginHorizontal(); |
| | | EditorGUILayout.TextField("SDK Project Path", ClientPackage.SDK_PLUGIN_PROJECT); |
| | | if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f))) |
| | | { |
| | | BrowseForSDKProject(); |
| | | } |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | EditorGUILayout.Space(); |
| | | |
| | | #if UNITY_IOS |
| | | ClientPackage.auditOutTime = EditorGUILayout.TextField("AppStore OutTime", ClientPackage.auditOutTime, GUILayout.Height(20)); |
| | | EditorGUILayout.Space(); |
| | | #endif |
| | | GUILayout.BeginHorizontal(); |
| | | |
| | | ClientPackage.AssetPrior = EditorGUILayout.IntField("AssetPrior", ClientPackage.AssetPrior, GUILayout.Height(50), GUILayout.Width(250)); |
| | | publishers = EditorGUILayout.TextField("Publishers", publishers, GUILayout.Height(50)); |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | EditorGUILayout.Space(); |
| | | GUILayout.BeginHorizontal(); |
| | | |
| | | ClientPackage.obfuscatorEnabled = EditorGUILayout.Toggle("Obfuscator Enable ", ClientPackage.obfuscatorEnabled, GUILayout.Width(250)); |
| | | |
| | | #if UNITY_STANDALONE |
| | | if (GUILayout.Button("EXE")) |
| | | { |
| | | EditorApplication.delayCall += ExecuteBuildClientPackageStandalone; |
| | | } |
| | | #elif UNITY_ANDROID |
| | | if (GUILayout.Button("APK")) |
| | | { |
| | | EditorApplication.delayCall += ExecuteBuildClientPackageApk; |
| | | } |
| | | #elif UNITY_IOS |
| | | if (GUILayout.Button("IPA_Append ")) |
| | | { |
| | | EditorApplication.delayCall += ExecuteBuildClientPackageIpaAppend; |
| | | } |
| | | #endif |
| | | |
| | | #if UNITY_STANDALONE |
| | | if (GUILayout.Button("EXE Development ")) |
| | | { |
| | | EditorApplication.delayCall += ExecuteBuildClientPackageStandaloneDevelopment; |
| | | } |
| | | #elif UNITY_ANDROID |
| | | if (GUILayout.Button("APK Development")) |
| | | { |
| | | EditorApplication.delayCall += ExecuteBuildClientPackageDevelopApk; |
| | | } |
| | | #elif UNITY_IOS |
| | | if (GUILayout.Button("IPA_Replace")) |
| | | { |
| | | EditorApplication.delayCall += ExecuteBuildClientPackageIpaReplace; |
| | | } |
| | | #endif |
| | | |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | GUILayout.Space(20); |
| | | if (GUILayout.Button("SwitchVersionConfig")) |
| | | { |
| | | EditorApplication.delayCall += ExecuteSwitchVersionConfig; |
| | | } |
| | | |
| | | GUILayout.Space(20); |
| | | GUILayout.BeginHorizontal(); |
| | | rechargeSkin = EditorGUILayout.IntField("Recharge Skin", rechargeSkin, GUILayout.Width(250)); |
| | | if (GUILayout.Button("Switch")) |
| | | { |
| | | UpdateSpriteSetting.SetRechargeSkin(rechargeSkin); |
| | | AssetDatabase.Refresh(); |
| | | UpdateSpritePackingSetting.UpdateAllSpritePackingSetting(); |
| | | } |
| | | |
| | | createRoleLevel = EditorGUILayout.TextField("CreateRole Level", createRoleLevel, GUILayout.Width(250)); |
| | | if (GUILayout.Button("Switch")) |
| | | { |
| | | UpdateLevelSetting.SetCreateRoleLevel(createRoleLevel); |
| | | AssetDatabase.Refresh(); |
| | | } |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | GUILayout.EndVertical(); |
| | | EditorGUILayout.EndScrollView(); |
| | | } |
| | | |
| | | private void ExecuteBuildAll() |
| | | { |
| | | |
| | | if (AssetBundleModel.Model.DataSource.CanSpecifyBuildOutputDirectory) |
| | | { |
| | | if (string.IsNullOrEmpty(m_UserData.m_OutputPath)) |
| | | { |
| | | BrowseForFolder(); |
| | | } |
| | | |
| | | if (string.IsNullOrEmpty(m_UserData.m_OutputPath)) //in case they hit "cancel" on the open browser |
| | | { |
| | | Debug.LogError("AssetBundle Build: No valid output path for build."); |
| | | return; |
| | | } |
| | | |
| | | if (m_ForceRebuild.state) |
| | | { |
| | | try |
| | | { |
| | | if (Directory.Exists(m_UserData.m_OutputPath)) |
| | | { |
| | | Directory.Delete(m_UserData.m_OutputPath, true); |
| | | } |
| | | |
| | | if (m_CopyToStreaming.state) |
| | | { |
| | | if (Directory.Exists(m_streamingPath)) |
| | | { |
| | | Directory.Delete(m_streamingPath, true); |
| | | } |
| | | } |
| | | } |
| | | catch (System.Exception e) |
| | | { |
| | | Debug.LogException(e); |
| | | } |
| | | } |
| | | |
| | | if (!Directory.Exists(m_UserData.m_OutputPath)) |
| | | { |
| | | Directory.CreateDirectory(m_UserData.m_OutputPath); |
| | | } |
| | | } |
| | | |
| | | ExcuteBuildAudio(); |
| | | ExcuteBuildMobEffectShader(); |
| | | ExcuteBuildConfig(); |
| | | ExcuteBuildLevels(); |
| | | ExcuteBuildUI(); |
| | | ExcuteBuildBuiltIn(); |
| | | ExcuteBuildLua(); |
| | | |
| | | AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); |
| | | |
| | | MakeAssetsVersionFile(); |
| | | |
| | | if (m_CopyToStreaming.state) |
| | | { |
| | | if (Directory.Exists(m_streamingPath)) |
| | | Directory.Delete(m_streamingPath, true); |
| | | DirectoryCopy(m_UserData.m_OutputPath, m_streamingPath); |
| | | } |
| | | } |
| | | |
| | | private void ExcuteBuildAsset(string _category) |
| | | { |
| | | BuildAssetBundleOptions opt = BuildAssetBundleOptions.None; |
| | | if (AssetBundleModel.Model.DataSource.CanSpecifyBuildOptions) |
| | | { |
| | | if (m_UserData.m_Compression == CompressOptions.Uncompressed) |
| | | { |
| | | opt |= BuildAssetBundleOptions.UncompressedAssetBundle; |
| | | } |
| | | else if (m_UserData.m_Compression == CompressOptions.ChunkBasedCompression) |
| | | { |
| | | opt |= BuildAssetBundleOptions.ChunkBasedCompression; |
| | | } |
| | | |
| | | opt |= BuildAssetBundleOptions.DeterministicAssetBundle; |
| | | |
| | | foreach (var tog in m_ToggleData) |
| | | { |
| | | if (tog.state) |
| | | { |
| | | opt |= tog.option; |
| | | } |
| | | } |
| | | } |
| | | |
| | | var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath); |
| | | AssetBundleBuildExtersion.Build(outputPath, _category, opt, (BuildTarget)m_UserData.m_BuildTarget, m_ForceRebuild.state); |
| | | } |
| | | |
| | | private void ExcuteBuildBuiltIn() |
| | | { |
| | | BuiltInResourceSetting.SetLaunchBackGround(publishers.Split('|')[0], (BuildTarget)m_UserData.m_BuildTarget); |
| | | BuiltInResourceSetting.SetLoginBackGround(publishers.Split('|')[0], (BuildTarget)m_UserData.m_BuildTarget); |
| | | BuiltInResourceSetting.SetLoginLogo(publishers.Split('|')[0], (BuildTarget)m_UserData.m_BuildTarget); |
| | | UpdateBuiltInSetting.SetBuiltinAssetBundleName(); |
| | | ExcuteBuildAsset("builtin"); |
| | | } |
| | | |
| | | private void ExcuteBuildAudio() |
| | | { |
| | | UpdateAudioSetting.SetAllAudioAssetBundleName(); |
| | | ExcuteBuildAsset("audio"); |
| | | |
| | | // UpdateVideoSetting.SetAllVideoAssetBundleName(); |
| | | // ExcuteBuildAsset("video"); |
| | | } |
| | | |
| | | private void ExcuteBuildMobEffectShader() |
| | | { |
| | | UpdateEffectPrefabSetting.SetAllEffectPrefabAssetBundleName(); |
| | | UpdateMobSetting.SetAllMobAssetBundleName(); |
| | | UpdateShaderSetting.SetAllShaderAssetBundleName(); |
| | | ExcuteBuildAsset("mobeffectshader"); |
| | | } |
| | | |
| | | private void ExcuteBuildConfig() |
| | | { |
| | | UpdateScriptableObjectsSetting.SetAllScriptableObjectAssetBundleName(); |
| | | ExcuteBuildAsset("config"); |
| | | TableTool.CopyConfigsToOutPutPath(StringUtility.Contact(m_UserData.m_OutputPath, "/config")); |
| | | } |
| | | |
| | | private void ExcuteBuildLua() |
| | | { |
| | | LuaBuildHelper.OnPreBuild(); |
| | | UpdateLuaSetting.SetAllLuaAssetBundleName(); |
| | | ExcuteBuildAsset("lua"); |
| | | LuaBuildHelper.OnPostBuild(); |
| | | } |
| | | |
| | | private void ExcuteBuildLevels() |
| | | { |
| | | UpdateLevelSetting.SetAllLevelAssetBundleName(); |
| | | ExcuteBuildAsset("maps"); |
| | | } |
| | | |
| | | private void ExcuteBuildUI() |
| | | { |
| | | AssetSource.allFromEditor = true; |
| | | //CheckFontSwitch.CheckAndReplaceFontSwitch(); |
| | | UpdateUIPrefabSetting.SetAllUIPrefabAssetBundleName(); |
| | | UpdateUIWindowSetting.SetAllUIWindowAssetBundleName(); |
| | | UpdateSpriteSetting.SetAllSpriteAssetBundleName(); |
| | | ExcuteBuildAsset("ui"); |
| | | } |
| | | |
| | | private void SetAssetsVersion() |
| | | { |
| | | var fileInfos = new List<FileInfo>(); |
| | | FileExtersion.GetAllDirectoryFileInfos(m_UserData.m_OutputPath, fileInfos); |
| | | for (int i = 0; i < fileInfos.Count; i++) |
| | | { |
| | | var fileInfo = fileInfos[i]; |
| | | var fullName = FileExtersion.RemoveVersionFromFileFullName(fileInfo.FullName); |
| | | var newFullName = FileExtersion.AddVersionToFileFullName(fullName, m_Version); |
| | | if (fullName != newFullName) |
| | | { |
| | | File.Copy(fullName, newFullName, true); |
| | | File.Delete(fullName); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void RemoveAssetsVersion() |
| | | { |
| | | var fileInfos = new List<FileInfo>(); |
| | | FileExtersion.GetAllDirectoryFileInfos(m_UserData.m_OutputPath, fileInfos); |
| | | for (int i = 0; i < fileInfos.Count; i++) |
| | | { |
| | | var fileInfo = fileInfos[i]; |
| | | var fullName = FileExtersion.RemoveVersionFromFileFullName(fileInfo.FullName); |
| | | if (fullName != fileInfo.FullName) |
| | | { |
| | | File.Copy(fileInfo.FullName, fullName, true); |
| | | File.Delete(fileInfo.FullName); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void MakeAssetsVersionFile() |
| | | { |
| | | var fileInfos = new List<FileInfo>(); |
| | | FileExtersion.GetAllDirectoryFileInfos(m_UserData.m_OutputPath, fileInfos); |
| | | AssetsVersionMaker.WriteAssetsVersionFile(Path.Combine(Directory.GetParent(Application.dataPath).FullName, m_UserData.m_OutputPath), fileInfos); |
| | | } |
| | | |
| | | static int packageIndex |
| | | { |
| | | get { return LocalSave.GetInt("ClientPackageIndex", 1); } |
| | | set { LocalSave.SetInt("ClientPackageIndex", value); } |
| | | } |
| | | |
| | | private void ExecuteBuildClientPackageIpaAppend() |
| | | { |
| | | packageIndex++; |
| | | var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath); |
| | | ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, false, false); |
| | | } |
| | | |
| | | private void ExecuteBuildClientPackageIpaReplace() |
| | | { |
| | | packageIndex++; |
| | | var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath); |
| | | ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, false, true); |
| | | } |
| | | |
| | | private void ExecuteBuildClientPackageApk() |
| | | { |
| | | packageIndex++; |
| | | var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath); |
| | | ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, false, false); |
| | | } |
| | | |
| | | private void ExecuteBuildClientPackageDevelopApk() |
| | | { |
| | | packageIndex++; |
| | | var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath); |
| | | ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, true, false); |
| | | } |
| | | |
| | | private void ExecuteBuildClientPackageStandalone() |
| | | { |
| | | packageIndex++; |
| | | var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath); |
| | | ClientPackage_Standalone.Build(new ClientPackage_Standalone.BuildParams() |
| | | { |
| | | assetBundle = outputPath, |
| | | output = ApkOutputPath, |
| | | buildIndex = packageIndex, |
| | | development = false, |
| | | publisher = publishers, |
| | | }); |
| | | } |
| | | |
| | | private void ExecuteBuildClientPackageStandaloneDevelopment() |
| | | { |
| | | packageIndex++; |
| | | var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath); |
| | | ClientPackage_Standalone.Build(new ClientPackage_Standalone.BuildParams() |
| | | { |
| | | assetBundle = outputPath, |
| | | output = ApkOutputPath, |
| | | buildIndex = packageIndex, |
| | | development = true, |
| | | publisher = publishers, |
| | | }); |
| | | } |
| | | |
| | | private void ExecuteSwitchVersionConfig() |
| | | { |
| | | var newVersionConfigPath = StringUtility.Contact("Assets/Resources/ScriptableObject/Config/VersionConfig", ".asset"); |
| | | var versionsFilePath = Application.dataPath + Path.DirectorySeparatorChar + "Editor/VersionConfigs/Versions.txt"; |
| | | |
| | | var lines = File.ReadAllLines(versionsFilePath); |
| | | for (int i = 2; i < lines.Length; i++) |
| | | { |
| | | var line = lines[i]; |
| | | var lineStrings = line.Split('\t'); |
| | | if (lineStrings[0] == publishers) |
| | | { |
| | | VersionConfig.Get().Read(line); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static void DirectoryCopy(string sourceDirName, string destDirName) |
| | | { |
| | | // Get the subdirectories for the specified directory. |
| | | DirectoryInfo dir = new DirectoryInfo(sourceDirName); |
| | | |
| | | // If the destination directory doesn't exist, create it. |
| | | if (!Directory.Exists(destDirName)) |
| | | { |
| | | Directory.CreateDirectory(destDirName); |
| | | } |
| | | |
| | | // Get the files in the directory and copy them to the new location. |
| | | FileInfo[] files = dir.GetFiles(); |
| | | foreach (FileInfo file in files) |
| | | { |
| | | string temppath = Path.Combine(destDirName, file.Name); |
| | | file.CopyTo(temppath, false); |
| | | } |
| | | |
| | | DirectoryInfo[] dirs = dir.GetDirectories(); |
| | | foreach (DirectoryInfo subdir in dirs) |
| | | { |
| | | string temppath = Path.Combine(destDirName, subdir.Name); |
| | | DirectoryCopy(subdir.FullName, temppath); |
| | | } |
| | | } |
| | | |
| | | private void BrowseForFolder() |
| | | { |
| | | m_UserData.m_UseDefaultPath = false; |
| | | var newPath = EditorUtility.OpenFolderPanel("Bundle Folder", m_UserData.m_OutputPath, string.Empty); |
| | | if (!string.IsNullOrEmpty(newPath)) |
| | | { |
| | | var gamePath = System.IO.Path.GetFullPath("."); |
| | | gamePath = gamePath.Replace("\\", "/"); |
| | | if (newPath.StartsWith(gamePath) && newPath.Length > gamePath.Length) |
| | | newPath = newPath.Remove(0, gamePath.Length + 1); |
| | | m_UserData.m_OutputPath = newPath; |
| | | //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath); |
| | | } |
| | | } |
| | | |
| | | private void BrowseForApkOutput() |
| | | { |
| | | var newPath = EditorUtility.OpenFolderPanel("Apk Folder", ApkOutputPath, string.Empty); |
| | | if (!string.IsNullOrEmpty(newPath)) |
| | | { |
| | | var gamePath = System.IO.Path.GetFullPath("."); |
| | | gamePath = gamePath.Replace("\\", "/"); |
| | | if (newPath.StartsWith(gamePath) && newPath.Length > gamePath.Length) |
| | | newPath = newPath.Remove(0, gamePath.Length + 1); |
| | | ApkOutputPath = newPath; |
| | | } |
| | | } |
| | | |
| | | private void BrowseForSDKProject() |
| | | { |
| | | var newPath = EditorUtility.OpenFolderPanel("Apk Folder", ClientPackage.SDK_PLUGIN_PROJECT, string.Empty); |
| | | if (!string.IsNullOrEmpty(newPath)) |
| | | { |
| | | var gamePath = System.IO.Path.GetFullPath("."); |
| | | gamePath = gamePath.Replace("\\", "/"); |
| | | if (newPath.StartsWith(gamePath) && newPath.Length > gamePath.Length) |
| | | newPath = newPath.Remove(0, gamePath.Length + 1); |
| | | ClientPackage.SDK_PLUGIN_PROJECT = newPath; |
| | | } |
| | | } |
| | | |
| | | private void ResetPathToDefault() |
| | | { |
| | | m_UserData.m_UseDefaultPath = true; |
| | | m_UserData.m_OutputPath = "AssetBundles/"; |
| | | m_UserData.m_OutputPath += m_UserData.m_BuildTarget.ToString(); |
| | | //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath); |
| | | } |
| | | |
| | | //Note: this is the provided BuildTarget enum with some entries removed as they are invalid in the dropdown |
| | | public enum ValidBuildTarget |
| | | { |
| | | //NoTarget = -2, --doesn't make sense |
| | | //iPhone = -1, --deprecated |
| | | //BB10 = -1, --deprecated |
| | | //MetroPlayer = -1, --deprecated |
| | | StandaloneOSXUniversal = 2, |
| | | StandaloneOSXIntel = 4, |
| | | StandaloneWindows = 5, |
| | | WebPlayer = 6, |
| | | WebPlayerStreamed = 7, |
| | | iOS = 9, |
| | | PS3 = 10, |
| | | XBOX360 = 11, |
| | | Android = 13, |
| | | StandaloneLinux = 17, |
| | | StandaloneWindows64 = 19, |
| | | WebGL = 20, |
| | | WSAPlayer = 21, |
| | | StandaloneLinux64 = 24, |
| | | StandaloneLinuxUniversal = 25, |
| | | WP8Player = 26, |
| | | StandaloneOSXIntel64 = 27, |
| | | BlackBerry = 28, |
| | | Tizen = 29, |
| | | PSP2 = 30, |
| | | PS4 = 31, |
| | | PSM = 32, |
| | | XboxOne = 33, |
| | | SamsungTV = 34, |
| | | N3DS = 35, |
| | | WiiU = 36, |
| | | tvOS = 37, |
| | | Switch = 38 |
| | | } |
| | | |
| | | [System.Serializable] |
| | | public class BuildTabData |
| | | { |
| | | public List<string> m_OnToggles; |
| | | public ValidBuildTarget m_BuildTarget = ValidBuildTarget.StandaloneWindows; |
| | | public CompressOptions m_Compression = CompressOptions.StandardCompression; |
| | | public string m_OutputPath = string.Empty; |
| | | public bool m_UseDefaultPath = true; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: b1e018d921bf6e941ba3518ba24c14ac |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: af0d51c3f04e6084e8088753c93d3fff |
| | | folderAsset: yes |
| | | timeCreated: 1499908885 |
| | | licenseType: Pro |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | |
| | | namespace UnityEngine.AssetBundles.AssetBundleDataSource |
| | | { |
| | | public partial struct ABBuildInfo |
| | | { |
| | | public string outputDirectory; |
| | | public BuildAssetBundleOptions options; |
| | | public BuildTarget buildTarget; |
| | | } |
| | | |
| | | public partial interface ABDataSource |
| | | { |
| | | //public static List<ABDataSource> CreateDataSources(); |
| | | string Name { get; } |
| | | string ProviderName { get; } |
| | | |
| | | string[] GetAssetPathsFromAssetBundle (string assetBundleName); |
| | | string GetAssetBundleName(string assetPath); |
| | | string GetImplicitAssetBundleName(string assetPath); |
| | | string[] GetAllAssetBundleNames(); |
| | | bool IsReadOnly(); |
| | | |
| | | void SetAssetBundleNameAndVariant (string assetPath, string bundleName, string variantName); |
| | | void RemoveUnusedAssetBundleNames(); |
| | | |
| | | bool CanSpecifyBuildTarget { get; } |
| | | bool CanSpecifyBuildOutputDirectory { get; } |
| | | bool CanSpecifyBuildOptions { get; } |
| | | |
| | | bool BuildAssetBundles (ABBuildInfo info); |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 27cff74fd1bba9146bcfc85f4c159b2b |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Reflection; |
| | | |
| | | namespace UnityEngine.AssetBundles.AssetBundleDataSource |
| | | { |
| | | public class ABDataSourceProviderUtility { |
| | | |
| | | private static List<Type> s_customNodes; |
| | | |
| | | public static List<Type> CustomABDataSourceTypes { |
| | | get { |
| | | if(s_customNodes == null) { |
| | | s_customNodes = BuildCustomABDataSourceList(); |
| | | } |
| | | return s_customNodes; |
| | | } |
| | | } |
| | | |
| | | private static List<Type> BuildCustomABDataSourceList() { |
| | | var list = new List<Type>(Assembly |
| | | .GetExecutingAssembly() |
| | | .GetTypes() |
| | | .Where(t => t != typeof(ABDataSource)) |
| | | .Where(t => typeof(ABDataSource).IsAssignableFrom(t)) ); |
| | | |
| | | |
| | | var properList = new List<Type>(); |
| | | properList.Add(null); //empty spot for "default" |
| | | for(int count = 0; count < list.Count; count++) |
| | | { |
| | | if(list[count].Name == "AssetDatabaseABDataSource") |
| | | properList[0] = list[count]; |
| | | else |
| | | properList.Add(list[count]); |
| | | } |
| | | |
| | | return properList; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: e6e4b74c22791a74598a5887a4dde4f1 |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using UnityEngine; |
| | | using UnityEditor; |
| | | using UnityEngine.Assertions; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using UnityEditor.IMGUI.Controls; |
| | | |
| | | namespace UnityEngine.AssetBundles.AssetBundleDataSource |
| | | { |
| | | public class AssetDatabaseABDataSource : ABDataSource |
| | | { |
| | | public static List<ABDataSource> CreateDataSources() |
| | | { |
| | | var op = new AssetDatabaseABDataSource(); |
| | | var retList = new List<ABDataSource>(); |
| | | retList.Add(op); |
| | | return retList; |
| | | } |
| | | |
| | | public string Name { |
| | | get { |
| | | return "Default"; |
| | | } |
| | | } |
| | | |
| | | public string ProviderName { |
| | | get { |
| | | return "Built-in"; |
| | | } |
| | | } |
| | | |
| | | public string[] GetAssetPathsFromAssetBundle (string assetBundleName) { |
| | | return AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName); |
| | | } |
| | | |
| | | public string GetAssetBundleName(string assetPath) { |
| | | var importer = AssetImporter.GetAtPath(assetPath); |
| | | if (importer == null) { |
| | | return string.Empty; |
| | | } |
| | | var bundleName = importer.assetBundleName; |
| | | if (importer.assetBundleVariant.Length > 0) { |
| | | bundleName = bundleName + "." + importer.assetBundleVariant; |
| | | } |
| | | return bundleName; |
| | | } |
| | | |
| | | public string GetImplicitAssetBundleName(string assetPath) { |
| | | return AssetDatabase.GetImplicitAssetBundleName (assetPath); |
| | | } |
| | | |
| | | public string[] GetAllAssetBundleNames() { |
| | | return AssetDatabase.GetAllAssetBundleNames (); |
| | | } |
| | | |
| | | public bool IsReadOnly() { |
| | | return false; |
| | | } |
| | | |
| | | public void SetAssetBundleNameAndVariant (string assetPath, string bundleName, string variantName) { |
| | | AssetImporter.GetAtPath(assetPath).SetAssetBundleNameAndVariant(bundleName, variantName); |
| | | } |
| | | |
| | | public void RemoveUnusedAssetBundleNames() { |
| | | AssetDatabase.RemoveUnusedAssetBundleNames (); |
| | | } |
| | | |
| | | public bool CanSpecifyBuildTarget { |
| | | get { return true; } |
| | | } |
| | | public bool CanSpecifyBuildOutputDirectory { |
| | | get { return true; } |
| | | } |
| | | |
| | | public bool CanSpecifyBuildOptions { |
| | | get { return true; } |
| | | } |
| | | |
| | | public bool BuildAssetBundles (ABBuildInfo info) { |
| | | BuildPipeline.BuildAssetBundles(info.outputDirectory, info.options, info.buildTarget); |
| | | return true; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 92f8c138ab1fcfc4397b6fe1f8ac2337 |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | using UnityEditor.IMGUI.Controls; |
| | | using System.Collections.Generic; |
| | | |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | [System.Serializable] |
| | | public class AssetBundleManageTab |
| | | { |
| | | [SerializeField] |
| | | TreeViewState m_BundleTreeState; |
| | | [SerializeField] |
| | | TreeViewState m_AssetListState; |
| | | [SerializeField] |
| | | MultiColumnHeaderState m_AssetListMCHState; |
| | | [SerializeField] |
| | | TreeViewState m_BundleDetailState; |
| | | |
| | | Rect m_Position; |
| | | |
| | | AssetBundleTree m_BundleTree; |
| | | AssetListTree m_AssetList; |
| | | MessageList m_MessageList; |
| | | BundleDetailList m_DetailsList; |
| | | bool m_ResizingHorizontalSplitter = false; |
| | | bool m_ResizingVerticalSplitterRight = false; |
| | | bool m_ResizingVerticalSplitterLeft = false; |
| | | Rect m_HorizontalSplitterRect, m_VerticalSplitterRectRight, m_VerticalSplitterRectLeft; |
| | | [SerializeField] |
| | | float m_HorizontalSplitterPercent; |
| | | [SerializeField] |
| | | float m_VerticalSplitterPercentRight; |
| | | [SerializeField] |
| | | float m_VerticalSplitterPercentLeft; |
| | | const float k_SplitterWidth = 3f; |
| | | private static float m_UpdateDelay = 0f; |
| | | |
| | | |
| | | EditorWindow m_Parent = null; |
| | | |
| | | public AssetBundleManageTab() |
| | | { |
| | | m_HorizontalSplitterPercent = 0.4f; |
| | | m_VerticalSplitterPercentRight = 0.7f; |
| | | m_VerticalSplitterPercentLeft = 0.85f; |
| | | } |
| | | |
| | | public void OnEnable(Rect pos, EditorWindow parent) |
| | | { |
| | | m_Parent = parent; |
| | | m_Position = pos; |
| | | m_HorizontalSplitterRect = new Rect( |
| | | (int)(m_Position.x + m_Position.width * m_HorizontalSplitterPercent), |
| | | m_Position.y, |
| | | k_SplitterWidth, |
| | | m_Position.height); |
| | | m_VerticalSplitterRectRight = new Rect( |
| | | m_HorizontalSplitterRect.x, |
| | | (int)(m_Position.y + m_HorizontalSplitterRect.height * m_VerticalSplitterPercentRight), |
| | | (m_Position.width - m_HorizontalSplitterRect.width) - k_SplitterWidth, |
| | | k_SplitterWidth); |
| | | m_VerticalSplitterRectLeft = new Rect( |
| | | m_Position.x, |
| | | (int)(m_Position.y + m_HorizontalSplitterRect.height * m_VerticalSplitterPercentLeft), |
| | | (m_HorizontalSplitterRect.width) - k_SplitterWidth, |
| | | k_SplitterWidth); |
| | | } |
| | | |
| | | |
| | | |
| | | public void Update() |
| | | { |
| | | if(Time.realtimeSinceStartup - m_UpdateDelay > 0.1f) |
| | | { |
| | | m_UpdateDelay = Time.realtimeSinceStartup; |
| | | |
| | | if(AssetBundleModel.Model.Update()) |
| | | { |
| | | m_Parent.Repaint(); |
| | | } |
| | | |
| | | if (m_DetailsList != null) |
| | | m_DetailsList.Update(); |
| | | |
| | | if (m_AssetList != null) |
| | | m_AssetList.Update(); |
| | | |
| | | } |
| | | } |
| | | |
| | | public void ForceReloadData() |
| | | { |
| | | UpdateSelectedBundles(new List<AssetBundleModel.BundleInfo>()); |
| | | SetSelectedItems(new List<AssetBundleModel.AssetInfo>()); |
| | | AssetBundleModel.Model.ForceReloadData(m_BundleTree); |
| | | m_Parent.Repaint(); |
| | | } |
| | | |
| | | public void OnGUI(Rect pos) |
| | | { |
| | | m_Position = pos; |
| | | |
| | | if(m_BundleTree == null) |
| | | { |
| | | if (m_AssetListState == null) |
| | | m_AssetListState = new TreeViewState(); |
| | | |
| | | var headerState = AssetListTree.CreateDefaultMultiColumnHeaderState();// multiColumnTreeViewRect.width); |
| | | if (MultiColumnHeaderState.CanOverwriteSerializedFields(m_AssetListMCHState, headerState)) |
| | | MultiColumnHeaderState.OverwriteSerializedFields(m_AssetListMCHState, headerState); |
| | | m_AssetListMCHState = headerState; |
| | | |
| | | |
| | | m_AssetList = new AssetListTree(m_AssetListState, m_AssetListMCHState, this); |
| | | m_AssetList.Reload(); |
| | | m_MessageList = new MessageList(); |
| | | |
| | | if (m_BundleDetailState == null) |
| | | m_BundleDetailState = new TreeViewState(); |
| | | m_DetailsList = new BundleDetailList(m_BundleDetailState); |
| | | m_DetailsList.Reload(); |
| | | |
| | | if (m_BundleTreeState == null) |
| | | m_BundleTreeState = new TreeViewState(); |
| | | m_BundleTree = new AssetBundleTree(m_BundleTreeState, this); |
| | | m_BundleTree.Refresh(); |
| | | m_Parent.Repaint(); |
| | | } |
| | | |
| | | HandleHorizontalResize(); |
| | | HandleVerticalResize(); |
| | | |
| | | |
| | | if (AssetBundleModel.Model.BundleListIsEmpty()) |
| | | { |
| | | m_BundleTree.OnGUI(m_Position); |
| | | var style = GUI.skin.label; |
| | | style.alignment = TextAnchor.MiddleCenter; |
| | | style.wordWrap = true; |
| | | GUI.Label( |
| | | new Rect(m_Position.x + 1f, m_Position.y + 1f, m_Position.width - 2f, m_Position.height - 2f), |
| | | new GUIContent(AssetBundleModel.Model.GetEmptyMessage()), |
| | | style); |
| | | } |
| | | else |
| | | { |
| | | |
| | | //Left half |
| | | var bundleTreeRect = new Rect( |
| | | m_Position.x, |
| | | m_Position.y, |
| | | m_HorizontalSplitterRect.x, |
| | | m_VerticalSplitterRectLeft.y - m_Position.y); |
| | | |
| | | m_BundleTree.OnGUI(bundleTreeRect); |
| | | m_DetailsList.OnGUI(new Rect( |
| | | bundleTreeRect.x, |
| | | bundleTreeRect.y + bundleTreeRect.height + k_SplitterWidth, |
| | | bundleTreeRect.width, |
| | | m_Position.height - bundleTreeRect.height - k_SplitterWidth*2)); |
| | | |
| | | |
| | | //Right half. |
| | | float panelLeft = m_HorizontalSplitterRect.x + k_SplitterWidth; |
| | | float panelWidth = m_VerticalSplitterRectRight.width - k_SplitterWidth * 2; |
| | | float panelHeight = m_VerticalSplitterRectRight.y - m_Position.y; |
| | | m_AssetList.OnGUI(new Rect( |
| | | panelLeft, |
| | | m_Position.y, |
| | | panelWidth, |
| | | panelHeight)); |
| | | m_MessageList.OnGUI(new Rect( |
| | | panelLeft, |
| | | m_Position.y + panelHeight + k_SplitterWidth, |
| | | panelWidth, |
| | | (m_Position.height - panelHeight) - k_SplitterWidth * 2)); |
| | | |
| | | if (m_ResizingHorizontalSplitter || m_ResizingVerticalSplitterRight || m_ResizingVerticalSplitterLeft) |
| | | m_Parent.Repaint(); |
| | | } |
| | | } |
| | | |
| | | |
| | | private void HandleHorizontalResize() |
| | | { |
| | | m_HorizontalSplitterRect.x = (int)(m_Position.width * m_HorizontalSplitterPercent); |
| | | m_HorizontalSplitterRect.height = m_Position.height; |
| | | |
| | | EditorGUIUtility.AddCursorRect(m_HorizontalSplitterRect, MouseCursor.ResizeHorizontal); |
| | | if (Event.current.type == EventType.MouseDown && m_HorizontalSplitterRect.Contains(Event.current.mousePosition)) |
| | | m_ResizingHorizontalSplitter = true; |
| | | |
| | | if (m_ResizingHorizontalSplitter) |
| | | { |
| | | m_HorizontalSplitterPercent = Mathf.Clamp(Event.current.mousePosition.x / m_Position.width, 0.1f, 0.9f); |
| | | m_HorizontalSplitterRect.x = (int)(m_Position.width * m_HorizontalSplitterPercent); |
| | | } |
| | | |
| | | if (Event.current.type == EventType.MouseUp) |
| | | m_ResizingHorizontalSplitter = false; |
| | | } |
| | | |
| | | private void HandleVerticalResize() |
| | | { |
| | | m_VerticalSplitterRectRight.x = m_HorizontalSplitterRect.x; |
| | | m_VerticalSplitterRectRight.y = (int)(m_HorizontalSplitterRect.height * m_VerticalSplitterPercentRight); |
| | | m_VerticalSplitterRectRight.width = m_Position.width - m_HorizontalSplitterRect.x; |
| | | m_VerticalSplitterRectLeft.y = (int)(m_HorizontalSplitterRect.height * m_VerticalSplitterPercentLeft); |
| | | m_VerticalSplitterRectLeft.width = m_VerticalSplitterRectRight.width; |
| | | |
| | | |
| | | EditorGUIUtility.AddCursorRect(m_VerticalSplitterRectRight, MouseCursor.ResizeVertical); |
| | | if (Event.current.type == EventType.MouseDown && m_VerticalSplitterRectRight.Contains(Event.current.mousePosition)) |
| | | m_ResizingVerticalSplitterRight = true; |
| | | |
| | | EditorGUIUtility.AddCursorRect(m_VerticalSplitterRectLeft, MouseCursor.ResizeVertical); |
| | | if (Event.current.type == EventType.MouseDown && m_VerticalSplitterRectLeft.Contains(Event.current.mousePosition)) |
| | | m_ResizingVerticalSplitterLeft = true; |
| | | |
| | | |
| | | if (m_ResizingVerticalSplitterRight) |
| | | { |
| | | m_VerticalSplitterPercentRight = Mathf.Clamp(Event.current.mousePosition.y / m_HorizontalSplitterRect.height, 0.2f, 0.98f); |
| | | m_VerticalSplitterRectRight.y = (int)(m_HorizontalSplitterRect.height * m_VerticalSplitterPercentRight); |
| | | } |
| | | else if (m_ResizingVerticalSplitterLeft) |
| | | { |
| | | m_VerticalSplitterPercentLeft = Mathf.Clamp(Event.current.mousePosition.y / m_HorizontalSplitterRect.height, 0.25f, 0.98f); |
| | | m_VerticalSplitterRectLeft.y = (int)(m_HorizontalSplitterRect.height * m_VerticalSplitterPercentLeft); |
| | | } |
| | | |
| | | |
| | | if (Event.current.type == EventType.MouseUp) |
| | | { |
| | | m_ResizingVerticalSplitterRight = false; |
| | | m_ResizingVerticalSplitterLeft = false; |
| | | } |
| | | } |
| | | |
| | | public void UpdateSelectedBundles(IEnumerable<AssetBundleModel.BundleInfo> bundles) |
| | | { |
| | | AssetBundleModel.Model.AddBundlesToUpdate(bundles); |
| | | m_AssetList.SetSelectedBundles(bundles); |
| | | m_DetailsList.SetItems(bundles); |
| | | m_MessageList.SetItems(null); |
| | | } |
| | | |
| | | public void SetSelectedItems(IEnumerable<AssetBundleModel.AssetInfo> items) |
| | | { |
| | | m_MessageList.SetItems(items); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 09f21df0ffab0e841b69215a8a139ff6 |
| | | timeCreated: 1499908885 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: f303c377c98172b43800b835b4b1f4f2 |
| | | folderAsset: yes |
| | | timeCreated: 1499908885 |
| | | licenseType: Pro |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using UnityEngine; |
| | | using UnityEditor; |
| | | using UnityEngine.Assertions; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using UnityEditor.IMGUI.Controls; |
| | | |
| | | using UnityEngine.AssetBundles.AssetBundleDataSource; |
| | | |
| | | namespace UnityEngine.AssetBundles.AssetBundleModel |
| | | { |
| | | public class Model |
| | | { |
| | | const string k_NewBundleBaseName = "newbundle"; |
| | | const string k_NewVariantBaseName = "newvariant"; |
| | | public static /*const*/ Color k_LightGrey = Color.grey * 1.5f; |
| | | |
| | | private static ABDataSource m_DataSource; |
| | | private static BundleFolderConcreteInfo m_RootLevelBundles = new BundleFolderConcreteInfo("", null); |
| | | private static List<ABMoveData> m_MoveData = new List<ABMoveData>(); |
| | | private static List<BundleInfo> m_BundlesToUpdate = new List<BundleInfo>(); |
| | | private static Dictionary<string, AssetInfo> m_GlobalAssetList = new Dictionary<string, AssetInfo>(); |
| | | private static Dictionary<string, HashSet<string>> m_DependencyTracker = new Dictionary<string, HashSet<string>>(); |
| | | |
| | | private static bool m_InErrorState = false; |
| | | const string k_DefaultEmptyMessage = "Drag assets here or right-click to begin creating bundles."; |
| | | const string k_ProblemEmptyMessage = "There was a problem parsing the list of bundles. See console."; |
| | | private static string m_EmptyMessageString; |
| | | |
| | | static private Texture2D m_folderIcon = null; |
| | | static private Texture2D m_bundleIcon = null; |
| | | static private Texture2D m_sceneIcon = null; |
| | | |
| | | public static ABDataSource DataSource |
| | | { |
| | | get |
| | | { |
| | | if (m_DataSource == null) |
| | | { |
| | | m_DataSource = new AssetDatabaseABDataSource (); |
| | | } |
| | | return m_DataSource; |
| | | } |
| | | set { m_DataSource = value; } |
| | | } |
| | | |
| | | public static bool Update() |
| | | { |
| | | bool shouldRepaint = false; |
| | | ExecuteAssetMove(false); //this should never do anything. just a safety check. |
| | | |
| | | //TODO - look into EditorApplication callback functions. |
| | | |
| | | int size = m_BundlesToUpdate.Count; |
| | | if (size > 0) |
| | | { |
| | | m_BundlesToUpdate[size - 1].Update(); |
| | | m_BundlesToUpdate.RemoveAll(item => item.doneUpdating == true); |
| | | if (m_BundlesToUpdate.Count == 0) |
| | | { |
| | | shouldRepaint = true; |
| | | foreach(var bundle in m_RootLevelBundles.GetChildList()) |
| | | { |
| | | bundle.RefreshDupeAssetWarning(); |
| | | } |
| | | } |
| | | } |
| | | return shouldRepaint; |
| | | } |
| | | |
| | | public static void ForceReloadData(TreeView tree) |
| | | { |
| | | m_InErrorState = false; |
| | | Rebuild(); |
| | | tree.Reload(); |
| | | bool doneUpdating = m_BundlesToUpdate.Count == 0; |
| | | |
| | | EditorUtility.DisplayProgressBar("Updating Bundles", "", 0); |
| | | int fullBundleCount = m_BundlesToUpdate.Count; |
| | | while (!doneUpdating && !m_InErrorState) |
| | | { |
| | | int currCount = m_BundlesToUpdate.Count; |
| | | EditorUtility.DisplayProgressBar("Updating Bundles", m_BundlesToUpdate[currCount-1].displayName, (float)(fullBundleCount- currCount) / (float)fullBundleCount); |
| | | doneUpdating = Update(); |
| | | } |
| | | EditorUtility.ClearProgressBar(); |
| | | } |
| | | |
| | | public static void Rebuild() |
| | | { |
| | | m_RootLevelBundles = new BundleFolderConcreteInfo("", null); |
| | | m_MoveData = new List<ABMoveData>(); |
| | | m_BundlesToUpdate = new List<BundleInfo>(); |
| | | m_GlobalAssetList = new Dictionary<string, AssetInfo>(); |
| | | Refresh(); |
| | | } |
| | | |
| | | public static void AddBundlesToUpdate(IEnumerable<BundleInfo> bundles) |
| | | { |
| | | foreach(var bundle in bundles) |
| | | { |
| | | bundle.ForceNeedUpdate(); |
| | | m_BundlesToUpdate.Add(bundle); |
| | | } |
| | | } |
| | | |
| | | public static void Refresh() |
| | | { |
| | | m_EmptyMessageString = k_ProblemEmptyMessage; |
| | | if (m_InErrorState) |
| | | return; |
| | | |
| | | var bundleList = ValidateBundleList(); |
| | | if(bundleList != null) |
| | | { |
| | | m_EmptyMessageString = k_DefaultEmptyMessage; |
| | | foreach (var bundleName in bundleList) |
| | | { |
| | | AddBundleToModel(bundleName); |
| | | } |
| | | AddBundlesToUpdate(m_RootLevelBundles.GetChildList()); |
| | | } |
| | | |
| | | if(m_InErrorState) |
| | | { |
| | | m_RootLevelBundles = new BundleFolderConcreteInfo("", null); |
| | | m_EmptyMessageString = k_ProblemEmptyMessage; |
| | | } |
| | | } |
| | | |
| | | public static string[] ValidateBundleList() |
| | | { |
| | | var bundleList = DataSource.GetAllAssetBundleNames(); |
| | | bool valid = true; |
| | | HashSet<string> bundleSet = new HashSet<string>(); |
| | | int index = 0; |
| | | bool attemptedBundleReset = false; |
| | | while(index < bundleList.Length) |
| | | { |
| | | var name = bundleList[index]; |
| | | if (!bundleSet.Add(name)) |
| | | { |
| | | LogError("Two bundles share the same name: " + name); |
| | | valid = false; |
| | | } |
| | | |
| | | int lastDot = name.LastIndexOf('.'); |
| | | if (lastDot > -1) |
| | | { |
| | | var bunName = name.Substring(0, lastDot); |
| | | var extraDot = bunName.LastIndexOf('.'); |
| | | if(extraDot > -1) |
| | | { |
| | | if(attemptedBundleReset) |
| | | { |
| | | var message = "Bundle name '" + bunName + "' contains a period."; |
| | | message += " Internally Unity keeps 'bundleName' and 'variantName' separate, but externally treat them as 'bundleName.variantName'."; |
| | | message += " If a bundleName contains a period, the build will (probably) succeed, but this tool cannot tell which portion is bundle and which portion is variant."; |
| | | LogError(message); |
| | | valid = false; |
| | | } |
| | | else |
| | | { |
| | | if (!DataSource.IsReadOnly ()) |
| | | { |
| | | DataSource.RemoveUnusedAssetBundleNames(); |
| | | } |
| | | index = 0; |
| | | bundleSet.Clear(); |
| | | bundleList = DataSource.GetAllAssetBundleNames(); |
| | | attemptedBundleReset = true; |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | |
| | | if (bundleList.Contains(bunName)) |
| | | { |
| | | //there is a bundle.none and a bundle.variant coexisting. Need to fix that or return an error. |
| | | if (attemptedBundleReset) |
| | | { |
| | | valid = false; |
| | | var message = "Bundle name '" + bunName + "' exists without a variant as well as with variant '" + name.Substring(lastDot+1) + "'."; |
| | | message += " That is an illegal state that will not build and must be cleaned up."; |
| | | LogError(message); |
| | | } |
| | | else |
| | | { |
| | | if (!DataSource.IsReadOnly ()) |
| | | { |
| | | DataSource.RemoveUnusedAssetBundleNames(); |
| | | } |
| | | index = 0; |
| | | bundleSet.Clear(); |
| | | bundleList = DataSource.GetAllAssetBundleNames(); |
| | | attemptedBundleReset = true; |
| | | continue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | index++; |
| | | } |
| | | |
| | | if (valid) |
| | | return bundleList; |
| | | else |
| | | return null; |
| | | } |
| | | |
| | | public static bool BundleListIsEmpty() |
| | | { |
| | | return (m_RootLevelBundles.GetChildList().Count() == 0); |
| | | } |
| | | |
| | | public static string GetEmptyMessage() |
| | | { |
| | | return m_EmptyMessageString; |
| | | } |
| | | |
| | | public static BundleInfo CreateEmptyBundle(BundleFolderInfo folder = null, string newName = null) |
| | | { |
| | | if ((folder as BundleVariantFolderInfo) != null) |
| | | return CreateEmptyVariant(folder as BundleVariantFolderInfo); |
| | | |
| | | folder = (folder == null) ? m_RootLevelBundles : folder; |
| | | string name = GetUniqueName(folder, newName); |
| | | BundleNameData nameData; |
| | | nameData = new BundleNameData(folder.m_Name.bundleName, name); |
| | | return AddBundleToFolder(folder, nameData); |
| | | } |
| | | |
| | | public static BundleInfo CreateEmptyVariant(BundleVariantFolderInfo folder) |
| | | { |
| | | string name = GetUniqueName(folder, k_NewVariantBaseName); |
| | | string variantName = folder.m_Name.bundleName + "." + name; |
| | | BundleNameData nameData = new BundleNameData(variantName); |
| | | return AddBundleToFolder(folder.parent, nameData); |
| | | } |
| | | |
| | | public static BundleFolderInfo CreateEmptyBundleFolder(BundleFolderConcreteInfo folder = null) |
| | | { |
| | | folder = (folder == null) ? m_RootLevelBundles : folder; |
| | | string name = GetUniqueName(folder) + "/dummy"; |
| | | BundleNameData nameData = new BundleNameData(folder.m_Name.bundleName, name); |
| | | return AddFoldersToBundle(m_RootLevelBundles, nameData); |
| | | } |
| | | |
| | | private static BundleInfo AddBundleToModel(string name) |
| | | { |
| | | if (name == null) |
| | | return null; |
| | | |
| | | BundleNameData nameData = new BundleNameData(name); |
| | | |
| | | BundleFolderInfo folder = AddFoldersToBundle(m_RootLevelBundles, nameData); |
| | | BundleInfo currInfo = AddBundleToFolder(folder, nameData); |
| | | |
| | | return currInfo; |
| | | } |
| | | |
| | | private static BundleFolderConcreteInfo AddFoldersToBundle(BundleFolderInfo root, BundleNameData nameData) |
| | | { |
| | | BundleInfo currInfo = root; |
| | | var folder = currInfo as BundleFolderConcreteInfo; |
| | | var size = nameData.pathTokens.Count; |
| | | for (var index = 0; index < size; index++) |
| | | { |
| | | if (folder != null) |
| | | { |
| | | currInfo = folder.GetChild(nameData.pathTokens[index]); |
| | | if (currInfo == null) |
| | | { |
| | | currInfo = new BundleFolderConcreteInfo(nameData.pathTokens, index + 1, folder); |
| | | folder.AddChild(currInfo); |
| | | } |
| | | |
| | | folder = currInfo as BundleFolderConcreteInfo; |
| | | if (folder == null) |
| | | { |
| | | m_InErrorState = true; |
| | | LogFolderAndBundleNameConflict(currInfo.m_Name.fullNativeName); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | return currInfo as BundleFolderConcreteInfo; |
| | | } |
| | | |
| | | private static void LogFolderAndBundleNameConflict(string name) |
| | | { |
| | | var message = "Bundle '"; |
| | | message += name; |
| | | message += "' has a name conflict with a bundle-folder."; |
| | | message += "Display of bundle data and building of bundles will not work."; |
| | | message += "\nDetails: If you name a bundle 'x/y', then the result of your build will be a bundle named 'y' in a folder named 'x'. You thus cannot also have a bundle named 'x' at the same level as the folder named 'x'."; |
| | | LogError(message); |
| | | } |
| | | |
| | | private static BundleInfo AddBundleToFolder(BundleFolderInfo root, BundleNameData nameData) |
| | | { |
| | | BundleInfo currInfo = root.GetChild(nameData.shortName); |
| | | if (nameData.variant != string.Empty) |
| | | { |
| | | if(currInfo == null) |
| | | { |
| | | currInfo = new BundleVariantFolderInfo(nameData.bundleName, root); |
| | | root.AddChild(currInfo); |
| | | } |
| | | var folder = currInfo as BundleVariantFolderInfo; |
| | | if (folder == null) |
| | | { |
| | | var message = "Bundle named " + nameData.shortName; |
| | | message += " exists both as a standard bundle, and a bundle with variants. "; |
| | | message += "This message is not supported for display or actual bundle building. "; |
| | | message += "You must manually fix bundle naming in the inspector."; |
| | | |
| | | LogError(message); |
| | | return null; |
| | | } |
| | | |
| | | |
| | | currInfo = folder.GetChild(nameData.variant); |
| | | if (currInfo == null) |
| | | { |
| | | currInfo = new BundleVariantDataInfo(nameData.fullNativeName, folder); |
| | | folder.AddChild(currInfo); |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | if (currInfo == null) |
| | | { |
| | | currInfo = new BundleDataInfo(nameData.fullNativeName, root); |
| | | root.AddChild(currInfo); |
| | | } |
| | | else |
| | | { |
| | | var dataInfo = currInfo as BundleDataInfo; |
| | | if (dataInfo == null) |
| | | { |
| | | m_InErrorState = true; |
| | | LogFolderAndBundleNameConflict(nameData.fullNativeName); |
| | | } |
| | | } |
| | | } |
| | | return currInfo; |
| | | } |
| | | |
| | | private static string GetUniqueName(BundleFolderInfo folder, string suggestedName = null) |
| | | { |
| | | suggestedName = (suggestedName == null) ? k_NewBundleBaseName : suggestedName; |
| | | string name = suggestedName; |
| | | int index = 1; |
| | | bool foundExisting = (folder.GetChild(name) != null); |
| | | while (foundExisting) |
| | | { |
| | | name = suggestedName + index; |
| | | index++; |
| | | foundExisting = (folder.GetChild(name) != null); |
| | | } |
| | | return name; |
| | | } |
| | | |
| | | public static BundleTreeItem CreateBundleTreeView() |
| | | { |
| | | return m_RootLevelBundles.CreateTreeView(-1); |
| | | } |
| | | |
| | | public static AssetTreeItem CreateAssetListTreeView(IEnumerable<AssetBundleModel.BundleInfo> selectedBundles) |
| | | { |
| | | var root = new AssetTreeItem(); |
| | | if (selectedBundles != null) |
| | | { |
| | | foreach (var bundle in selectedBundles) |
| | | { |
| | | bundle.AddAssetsToNode(root); |
| | | } |
| | | } |
| | | return root; |
| | | } |
| | | |
| | | public static bool HandleBundleRename(BundleTreeItem item, string newName) |
| | | { |
| | | var originalName = new BundleNameData(item.bundle.m_Name.fullNativeName); |
| | | |
| | | var findDot = newName.LastIndexOf('.'); |
| | | var findSlash = newName.LastIndexOf('/'); |
| | | var findBSlash = newName.LastIndexOf('\\'); |
| | | if (findDot == 0 || findSlash == 0 || findBSlash == 0) |
| | | return false; //can't start a bundle with a / or . |
| | | |
| | | bool result = item.bundle.HandleRename(newName, 0); |
| | | |
| | | if (findDot > 0 || findSlash > 0 || findBSlash > 0) |
| | | { |
| | | item.bundle.parent.HandleChildRename(newName, string.Empty); |
| | | } |
| | | |
| | | ExecuteAssetMove(); |
| | | |
| | | var node = FindBundle(originalName); |
| | | if (node != null) |
| | | { |
| | | var message = "Failed to rename bundle named: "; |
| | | message += originalName.fullNativeName; |
| | | message += ". Most likely this is due to the bundle being assigned to a folder in your Assets directory, AND that folder is either empty or only contains assets that are explicitly assigned elsewhere."; |
| | | Debug.LogError(message); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | public static void HandleBundleReparent(IEnumerable<BundleInfo> bundles, BundleFolderInfo parent) |
| | | { |
| | | parent = (parent == null) ? m_RootLevelBundles : parent; |
| | | foreach (var bundle in bundles) |
| | | { |
| | | bundle.HandleReparent(parent.m_Name.bundleName, parent); |
| | | } |
| | | ExecuteAssetMove(); |
| | | } |
| | | |
| | | public static void HandleBundleMerge(IEnumerable<BundleInfo> bundles, BundleDataInfo target) |
| | | { |
| | | foreach (var bundle in bundles) |
| | | { |
| | | bundle.HandleDelete(true, target.m_Name.bundleName, target.m_Name.variant); |
| | | } |
| | | ExecuteAssetMove(); |
| | | } |
| | | |
| | | public static void HandleBundleDelete(IEnumerable<BundleInfo> bundles) |
| | | { |
| | | var nameList = new List<BundleNameData>(); |
| | | foreach (var bundle in bundles) |
| | | { |
| | | nameList.Add(bundle.m_Name); |
| | | bundle.HandleDelete(true); |
| | | } |
| | | ExecuteAssetMove(); |
| | | |
| | | //check to see if any bundles are still there... |
| | | foreach(var name in nameList) |
| | | { |
| | | var node = FindBundle(name); |
| | | if(node != null) |
| | | { |
| | | var message = "Failed to delete bundle named: "; |
| | | message += name.fullNativeName; |
| | | message += ". Most likely this is due to the bundle being assigned to a folder in your Assets directory, AND that folder is either empty or only contains assets that are explicitly assigned elsewhere."; |
| | | Debug.LogError(message); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static BundleInfo FindBundle(BundleNameData name) |
| | | { |
| | | BundleInfo currNode = m_RootLevelBundles; |
| | | foreach (var token in name.pathTokens) |
| | | { |
| | | if(currNode is BundleFolderInfo) |
| | | { |
| | | currNode = (currNode as BundleFolderInfo).GetChild(token); |
| | | if (currNode == null) |
| | | return null; |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | if(currNode is BundleFolderInfo) |
| | | { |
| | | currNode = (currNode as BundleFolderInfo).GetChild(name.shortName); |
| | | if(currNode is BundleVariantFolderInfo) |
| | | { |
| | | currNode = (currNode as BundleVariantFolderInfo).GetChild(name.variant); |
| | | } |
| | | return currNode; |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | public static BundleInfo HandleDedupeBundles(IEnumerable<BundleInfo> bundles, bool onlyOverlappedAssets) |
| | | { |
| | | var newBundle = CreateEmptyBundle(); |
| | | HashSet<string> dupeAssets = new HashSet<string>(); |
| | | HashSet<string> fullAssetList = new HashSet<string>(); |
| | | |
| | | //if they were just selected, then they may still be updating. |
| | | bool doneUpdating = m_BundlesToUpdate.Count == 0; |
| | | while (!doneUpdating) |
| | | doneUpdating = Update(); |
| | | |
| | | foreach (var bundle in bundles) |
| | | { |
| | | foreach (var asset in bundle.GetDependencies()) |
| | | { |
| | | if (onlyOverlappedAssets) |
| | | { |
| | | if (!fullAssetList.Add(asset.fullAssetName)) |
| | | dupeAssets.Add(asset.fullAssetName); |
| | | } |
| | | else |
| | | { |
| | | if (asset.IsMessageSet(MessageSystem.MessageFlag.AssetsDuplicatedInMultBundles)) |
| | | dupeAssets.Add(asset.fullAssetName); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (dupeAssets.Count == 0) |
| | | return null; |
| | | |
| | | MoveAssetToBundle(dupeAssets, newBundle.m_Name.bundleName, string.Empty); |
| | | ExecuteAssetMove(); |
| | | return newBundle; |
| | | } |
| | | |
| | | public static BundleInfo HandleConvertToVariant(BundleDataInfo bundle) |
| | | { |
| | | bundle.HandleDelete(true, bundle.m_Name.bundleName, k_NewVariantBaseName); |
| | | ExecuteAssetMove(); |
| | | var root = bundle.parent.GetChild(bundle.m_Name.shortName) as BundleVariantFolderInfo; |
| | | |
| | | if (root != null) |
| | | return root.GetChild(k_NewVariantBaseName); |
| | | else |
| | | { |
| | | //we got here because the converted bundle was empty. |
| | | var vfolder = new BundleVariantFolderInfo(bundle.m_Name.bundleName, bundle.parent); |
| | | var vdata = new BundleVariantDataInfo(bundle.m_Name.bundleName + "." + k_NewVariantBaseName, vfolder); |
| | | bundle.parent.AddChild(vfolder); |
| | | vfolder.AddChild(vdata); |
| | | return vdata; |
| | | } |
| | | } |
| | | |
| | | class ABMoveData |
| | | { |
| | | public string assetName; |
| | | public string bundleName; |
| | | public string variantName; |
| | | public ABMoveData(string asset, string bundle, string variant) |
| | | { |
| | | assetName = asset; |
| | | bundleName = bundle; |
| | | variantName = variant; |
| | | } |
| | | public void Apply() |
| | | { |
| | | if (!DataSource.IsReadOnly ()) |
| | | { |
| | | DataSource.SetAssetBundleNameAndVariant(assetName, bundleName, variantName); |
| | | } |
| | | } |
| | | } |
| | | public static void MoveAssetToBundle(AssetInfo asset, string bundleName, string variant) |
| | | { |
| | | m_MoveData.Add(new ABMoveData(asset.fullAssetName, bundleName, variant)); |
| | | } |
| | | public static void MoveAssetToBundle(string assetName, string bundleName, string variant) |
| | | { |
| | | m_MoveData.Add(new ABMoveData(assetName, bundleName, variant)); |
| | | } |
| | | public static void MoveAssetToBundle(IEnumerable<AssetInfo> assets, string bundleName, string variant) |
| | | { |
| | | foreach (var asset in assets) |
| | | MoveAssetToBundle(asset, bundleName, variant); |
| | | } |
| | | public static void MoveAssetToBundle(IEnumerable<string> assetNames, string bundleName, string variant) |
| | | { |
| | | foreach (var assetName in assetNames) |
| | | MoveAssetToBundle(assetName, bundleName, variant); |
| | | } |
| | | |
| | | public static void ExecuteAssetMove(bool forceAct=true) |
| | | { |
| | | var size = m_MoveData.Count; |
| | | if(forceAct) |
| | | { |
| | | if (size > 0) |
| | | { |
| | | bool autoRefresh = EditorPrefs.GetBool("kAutoRefresh"); |
| | | EditorPrefs.SetBool("kAutoRefresh", false); |
| | | EditorUtility.DisplayProgressBar("Moving assets to bundles", "", 0); |
| | | for (int i = 0; i < size; i++) |
| | | { |
| | | EditorUtility.DisplayProgressBar("Moving assets to bundle " + m_MoveData[i].bundleName, System.IO.Path.GetFileNameWithoutExtension(m_MoveData[i].assetName), (float)i / (float)size); |
| | | m_MoveData[i].Apply(); |
| | | } |
| | | EditorUtility.ClearProgressBar(); |
| | | EditorPrefs.SetBool("kAutoRefresh", autoRefresh); |
| | | m_MoveData.Clear(); |
| | | } |
| | | if (!DataSource.IsReadOnly ()) |
| | | { |
| | | DataSource.RemoveUnusedAssetBundleNames(); |
| | | } |
| | | Refresh(); |
| | | } |
| | | } |
| | | |
| | | //this version of CreateAsset is only used for dependent assets. |
| | | public static AssetInfo CreateAsset(string name, AssetInfo parent) |
| | | { |
| | | if (ValidateAsset(name)) |
| | | { |
| | | var bundleName = GetBundleName(name); |
| | | return CreateAsset(name, bundleName, parent); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static AssetInfo CreateAsset(string name, string bundleName) |
| | | { |
| | | if(ValidateAsset(name)) |
| | | { |
| | | return CreateAsset(name, bundleName, null); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private static AssetInfo CreateAsset(string name, string bundleName, AssetInfo parent) |
| | | { |
| | | if(bundleName != string.Empty) |
| | | { |
| | | return new AssetInfo(name, bundleName); |
| | | } |
| | | else |
| | | { |
| | | AssetInfo info = null; |
| | | if(!m_GlobalAssetList.TryGetValue(name, out info)) |
| | | { |
| | | info = new AssetInfo(name, string.Empty); |
| | | m_GlobalAssetList.Add(name, info); |
| | | } |
| | | info.AddParent(parent.displayName); |
| | | return info; |
| | | } |
| | | |
| | | } |
| | | |
| | | public static bool ValidateAsset(string name) |
| | | { |
| | | if (!name.StartsWith("Assets/")) |
| | | return false; |
| | | string ext = System.IO.Path.GetExtension(name); |
| | | if (ext == ".dll" || ext == ".cs" || ext == ".meta" || ext == ".js" || ext == ".boo") |
| | | return false; |
| | | |
| | | return true; |
| | | } |
| | | |
| | | internal static string GetBundleName(string asset) |
| | | { |
| | | return DataSource.GetAssetBundleName (asset); |
| | | } |
| | | |
| | | public static int RegisterAsset(AssetInfo asset, string bundle) |
| | | { |
| | | if(m_DependencyTracker.ContainsKey(asset.fullAssetName)) |
| | | { |
| | | m_DependencyTracker[asset.fullAssetName].Add(bundle); |
| | | int count = m_DependencyTracker[asset.fullAssetName].Count; |
| | | if (count > 1) |
| | | asset.SetMessageFlag(MessageSystem.MessageFlag.AssetsDuplicatedInMultBundles, true); |
| | | return count; |
| | | } |
| | | |
| | | var bundles = new HashSet<string>(); |
| | | bundles.Add(bundle); |
| | | m_DependencyTracker.Add(asset.fullAssetName, bundles); |
| | | return 1; |
| | | } |
| | | |
| | | public static void UnRegisterAsset(AssetInfo asset, string bundle) |
| | | { |
| | | if (m_DependencyTracker == null || asset == null) |
| | | return; |
| | | |
| | | if (m_DependencyTracker.ContainsKey(asset.fullAssetName)) |
| | | { |
| | | m_DependencyTracker[asset.fullAssetName].Remove(bundle); |
| | | int count = m_DependencyTracker[asset.fullAssetName].Count; |
| | | switch (count) |
| | | { |
| | | case 0: |
| | | m_DependencyTracker.Remove(asset.fullAssetName); |
| | | break; |
| | | case 1: |
| | | asset.SetMessageFlag(MessageSystem.MessageFlag.AssetsDuplicatedInMultBundles, false); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static IEnumerable<string> CheckDependencyTracker(AssetInfo asset) |
| | | { |
| | | if (m_DependencyTracker.ContainsKey(asset.fullAssetName)) |
| | | { |
| | | return m_DependencyTracker[asset.fullAssetName]; |
| | | } |
| | | return new HashSet<string>(); |
| | | } |
| | | |
| | | //TODO - switch local cache server on and utilize this method to stay up to date. |
| | | //static List<string> m_importedAssets = new List<string>(); |
| | | //static List<string> m_deletedAssets = new List<string>(); |
| | | //static List<KeyValuePair<string, string>> m_movedAssets = new List<KeyValuePair<string, string>>(); |
| | | //class AssetBundleChangeListener : AssetPostprocessor |
| | | //{ |
| | | // static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) |
| | | // { |
| | | // m_importedAssets.AddRange(importedAssets); |
| | | // m_deletedAssets.AddRange(deletedAssets); |
| | | // for (int i = 0; i < movedAssets.Length; i++) |
| | | // m_movedAssets.Add(new KeyValuePair<string, string>(movedFromAssetPaths[i], movedAssets[i])); |
| | | // //m_dirty = true; |
| | | // } |
| | | //} |
| | | |
| | | static public void LogError(string message) |
| | | { |
| | | Debug.LogError("AssetBundleBrowser: " + message); |
| | | } |
| | | static public void LogWarning(string message) |
| | | { |
| | | DebugEx.LogWarning("AssetBundleBrowser: " + message); |
| | | } |
| | | |
| | | static public Texture2D GetFolderIcon() |
| | | { |
| | | if (m_folderIcon == null) |
| | | FindBundleIcons(); |
| | | return m_folderIcon; |
| | | } |
| | | static public Texture2D GetBundleIcon() |
| | | { |
| | | if (m_bundleIcon == null) |
| | | FindBundleIcons(); |
| | | return m_bundleIcon; |
| | | } |
| | | static public Texture2D GetSceneIcon() |
| | | { |
| | | if (m_sceneIcon == null) |
| | | FindBundleIcons(); |
| | | return m_sceneIcon; |
| | | } |
| | | static private void FindBundleIcons() |
| | | { |
| | | m_folderIcon = EditorGUIUtility.FindTexture("Folder Icon"); |
| | | string[] icons = AssetDatabase.FindAssets("ABundleBrowserIconY1756"); |
| | | foreach (string i in icons) |
| | | { |
| | | string name = AssetDatabase.GUIDToAssetPath(i); |
| | | if (name.Contains("ABundleBrowserIconY1756Basic.png")) |
| | | m_bundleIcon = (Texture2D)AssetDatabase.LoadAssetAtPath(name, typeof(Texture2D)); |
| | | else if (name.Contains("ABundleBrowserIconY1756Scene.png")) |
| | | m_sceneIcon = (Texture2D)AssetDatabase.LoadAssetAtPath(name, typeof(Texture2D)); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 2d70d587215726c40ad3dd9d300187b4 |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using UnityEngine; |
| | | using UnityEditor; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using UnityEditor.IMGUI.Controls; |
| | | |
| | | namespace UnityEngine.AssetBundles.AssetBundleModel |
| | | { |
| | | public class AssetTreeItem : TreeViewItem |
| | | { |
| | | private AssetInfo m_asset; |
| | | public AssetInfo asset |
| | | { |
| | | get { return m_asset; } |
| | | } |
| | | public AssetTreeItem() : base(-1, -1) { } |
| | | public AssetTreeItem(AssetInfo a) : base(a != null ? a.fullAssetName.GetHashCode() : Random.Range(int.MinValue, int.MaxValue), 0, a != null ? a.displayName : "failed") |
| | | { |
| | | m_asset = a; |
| | | if (a != null) |
| | | icon = AssetDatabase.GetCachedIcon(a.fullAssetName) as Texture2D; |
| | | } |
| | | |
| | | private Color m_color = new Color(0, 0, 0, 0); |
| | | public Color itemColor |
| | | { |
| | | get |
| | | { |
| | | if (m_color.a == 0.0f && m_asset != null) |
| | | { |
| | | m_color = m_asset.GetColor(); |
| | | } |
| | | return m_color; |
| | | } |
| | | set { m_color = value; } |
| | | } |
| | | public Texture2D MessageIcon() |
| | | { |
| | | return MessageSystem.GetIcon(HighestMessageLevel()); |
| | | } |
| | | public MessageType HighestMessageLevel() |
| | | { |
| | | return m_asset != null ? |
| | | m_asset.HighestMessageLevel() : MessageType.Error; |
| | | } |
| | | |
| | | public bool ContainsChild(AssetInfo asset) |
| | | { |
| | | bool contains = false; |
| | | if (children == null) |
| | | return contains; |
| | | |
| | | if (asset == null) |
| | | return false; |
| | | foreach (var child in children) |
| | | { |
| | | var c = child as AssetTreeItem; |
| | | if (c != null && c.asset != null && c.asset.fullAssetName == asset.fullAssetName) |
| | | { |
| | | contains = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | return contains; |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | public class AssetInfo |
| | | { |
| | | public bool isScene { get; set; } |
| | | public bool isFolder { get; set; } |
| | | public long fileSize; |
| | | |
| | | private HashSet<string> m_Parents; |
| | | private string m_AssetName; |
| | | private string m_DisplayName; |
| | | private string m_BundleName; |
| | | private MessageSystem.MessageState m_AssetMessages = new MessageSystem.MessageState(); |
| | | |
| | | public AssetInfo(string inName, string bundleName="") |
| | | { |
| | | fullAssetName = inName; |
| | | m_BundleName = bundleName; |
| | | m_Parents = new HashSet<string>(); |
| | | isScene = false; |
| | | isFolder = false; |
| | | } |
| | | |
| | | public string fullAssetName |
| | | { |
| | | get { return m_AssetName; } |
| | | set |
| | | { |
| | | m_AssetName = value; |
| | | m_DisplayName = System.IO.Path.GetFileNameWithoutExtension(m_AssetName); |
| | | |
| | | //TODO - maybe there's a way to ask the AssetDatabase for this size info. |
| | | System.IO.FileInfo fileInfo = new System.IO.FileInfo(m_AssetName); |
| | | if (fileInfo.Exists) |
| | | fileSize = fileInfo.Length; |
| | | else |
| | | fileSize = 0; |
| | | } |
| | | } |
| | | public string displayName |
| | | { |
| | | get { return m_DisplayName; } |
| | | } |
| | | public string bundleName |
| | | { get { return m_BundleName == "" ? "auto" : m_BundleName; } } |
| | | |
| | | public Color GetColor() |
| | | { |
| | | if (m_BundleName == "") |
| | | return Model.k_LightGrey; |
| | | else |
| | | return Color.white; |
| | | } |
| | | |
| | | public bool IsMessageSet(MessageSystem.MessageFlag flag) |
| | | { |
| | | return m_AssetMessages.IsSet(flag); |
| | | } |
| | | public void SetMessageFlag(MessageSystem.MessageFlag flag, bool on) |
| | | { |
| | | m_AssetMessages.SetFlag(flag, on); |
| | | } |
| | | public MessageType HighestMessageLevel() |
| | | { |
| | | return m_AssetMessages.HighestMessageLevel(); |
| | | } |
| | | public IEnumerable<MessageSystem.Message> GetMessages() |
| | | { |
| | | List<MessageSystem.Message> messages = new List<MessageSystem.Message>(); |
| | | if(IsMessageSet(MessageSystem.MessageFlag.SceneBundleConflict)) |
| | | { |
| | | var message = displayName + "\n"; |
| | | if (isScene) |
| | | message += "Is a scene that is in a bundle with non-scene assets. Scene bundles must have only one or more scene assets."; |
| | | else |
| | | message += "Is included in a bundle with a scene. Scene bundles must have only one or more scene assets."; |
| | | messages.Add(new MessageSystem.Message(message, MessageType.Error)); |
| | | } |
| | | if(IsMessageSet(MessageSystem.MessageFlag.DependencySceneConflict)) |
| | | { |
| | | var message = displayName + "\n"; |
| | | message += MessageSystem.GetMessage(MessageSystem.MessageFlag.DependencySceneConflict).message; |
| | | messages.Add(new MessageSystem.Message(message, MessageType.Error)); |
| | | } |
| | | if (IsMessageSet(MessageSystem.MessageFlag.AssetsDuplicatedInMultBundles)) |
| | | { |
| | | var bundleNames = AssetBundleModel.Model.CheckDependencyTracker(this); |
| | | string message = displayName + "\n" + "Is auto-included in multiple bundles:\n"; |
| | | foreach(var bundleName in bundleNames) |
| | | { |
| | | message += bundleName + ", "; |
| | | } |
| | | message = message.Substring(0, message.Length - 2);//remove trailing comma. |
| | | messages.Add(new MessageSystem.Message(message, MessageType.Warning)); |
| | | } |
| | | |
| | | if (m_BundleName == string.Empty && m_Parents.Count > 0) |
| | | { |
| | | //TODO - refine the parent list to only include those in the current asset list |
| | | var message = displayName + "\n" + "Is auto included in bundle(s) due to parent(s): \n"; |
| | | foreach (var parent in m_Parents) |
| | | { |
| | | message += parent + ", "; |
| | | } |
| | | message = message.Substring(0, message.Length - 2);//remove trailing comma. |
| | | messages.Add(new MessageSystem.Message(message, MessageType.Info)); |
| | | } |
| | | |
| | | messages.Add(new MessageSystem.Message(displayName + "\n" + "Path: " + fullAssetName, MessageType.Info)); |
| | | |
| | | return messages; |
| | | } |
| | | public void AddParent(string name) |
| | | { |
| | | m_Parents.Add(name); |
| | | } |
| | | public void RemoveParent(string name) |
| | | { |
| | | m_Parents.Remove(name); |
| | | } |
| | | |
| | | public string GetSizeString() |
| | | { |
| | | if (fileSize == 0) |
| | | return "--"; |
| | | return EditorUtility.FormatBytes(fileSize); |
| | | } |
| | | |
| | | List<AssetInfo> m_dependencies = null; |
| | | public List<AssetInfo> GetDependencies() |
| | | { |
| | | //TODO - not sure this refreshes enough. need to build tests around that. |
| | | if (m_dependencies == null) |
| | | { |
| | | m_dependencies = new List<AssetInfo>(); |
| | | if (AssetDatabase.IsValidFolder(m_AssetName)) |
| | | { |
| | | //if we have a folder, its dependencies were already pulled in through alternate means. no need to GatherFoldersAndFiles |
| | | //GatherFoldersAndFiles(); |
| | | } |
| | | else |
| | | { |
| | | foreach (var dep in AssetDatabase.GetDependencies(m_AssetName, true)) |
| | | { |
| | | if (dep != m_AssetName) |
| | | { |
| | | var asset = Model.CreateAsset(dep, this); |
| | | if (asset != null) |
| | | m_dependencies.Add(asset); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return m_dependencies; |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: fa05db261cceb4f4e866a0d21a2bf0bd |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using UnityEngine; |
| | | using UnityEditor; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using UnityEditor.IMGUI.Controls; |
| | | |
| | | namespace UnityEngine.AssetBundles.AssetBundleModel |
| | | { |
| | | public class BundleTreeItem : TreeViewItem |
| | | { |
| | | private BundleInfo m_Bundle; |
| | | public BundleInfo bundle |
| | | { |
| | | get { return m_Bundle; } |
| | | } |
| | | public BundleTreeItem(BundleInfo b, int depth, Texture2D iconTexture) : base(b.nameHashCode, depth, b.displayName) |
| | | { |
| | | m_Bundle = b; |
| | | icon = iconTexture; |
| | | children = new List<TreeViewItem>(); |
| | | } |
| | | |
| | | public MessageSystem.Message BundleMessage() |
| | | { |
| | | return m_Bundle.HighestMessage(); |
| | | } |
| | | } |
| | | |
| | | public class BundleNameData |
| | | { |
| | | private List<string> m_PathTokens; |
| | | private string m_FullBundleName; |
| | | private string m_ShortName; |
| | | private string m_VariantName; |
| | | private string m_FullNativeName; |
| | | |
| | | //input (received from native) is a string of format: |
| | | // /folder0/.../folderN/name.variant |
| | | //it's broken into: |
| | | // /m_pathTokens[0]/.../m_pathTokens[n]/m_shortName.m_variantName |
| | | // and... |
| | | // m_fullBundleName = /m_pathTokens[0]/.../m_pathTokens[n]/m_shortName |
| | | // and... |
| | | // m_fullNativeName = m_fullBundleName.m_variantName which is the same as the initial input. |
| | | public BundleNameData(string name) { SetName(name); } |
| | | public BundleNameData(string path, string name) |
| | | { |
| | | string finalName = path == "" ? "" : path + '/'; |
| | | finalName += name; |
| | | SetName(finalName); |
| | | } |
| | | public override int GetHashCode() |
| | | { |
| | | return fullNativeName.GetHashCode(); |
| | | } |
| | | public string fullNativeName |
| | | { get { return m_FullNativeName; } } |
| | | |
| | | public void SetBundleName(string bundleName, string variantName) |
| | | { |
| | | string name = bundleName; |
| | | name += (variantName == "") ? "" : "." + variantName; |
| | | SetName(name); |
| | | } |
| | | public string bundleName |
| | | { |
| | | get { return m_FullBundleName; } |
| | | //set { SetName(value); } |
| | | } |
| | | public string shortName |
| | | { |
| | | get { return m_ShortName; } |
| | | } |
| | | public string variant |
| | | { |
| | | get { return m_VariantName; } |
| | | set |
| | | { |
| | | m_VariantName = value; |
| | | m_FullNativeName = m_FullBundleName; |
| | | m_FullNativeName += (m_VariantName == "") ? "" : "." + m_VariantName; |
| | | } |
| | | } |
| | | public List<string> pathTokens |
| | | { |
| | | get { return m_PathTokens; } |
| | | set |
| | | { |
| | | m_PathTokens = value.GetRange(0, value.Count-1); |
| | | SetShortName(value.Last()); |
| | | GenerateFullName(); |
| | | } |
| | | } |
| | | |
| | | private void SetName(string name) |
| | | { |
| | | if(m_PathTokens == null) |
| | | m_PathTokens = new List<string>(); |
| | | else |
| | | m_PathTokens.Clear(); |
| | | |
| | | int indexOfSlash = name.IndexOf('/'); |
| | | int previousIndex = 0; |
| | | while(indexOfSlash != -1) |
| | | { |
| | | m_PathTokens.Add(name.Substring(previousIndex, (indexOfSlash - previousIndex))); |
| | | previousIndex = indexOfSlash + 1; |
| | | indexOfSlash = name.IndexOf('/', previousIndex); |
| | | } |
| | | SetShortName(name.Substring(previousIndex)); |
| | | GenerateFullName(); |
| | | } |
| | | private void SetShortName(string inputName) |
| | | { |
| | | m_ShortName = inputName; |
| | | int indexOfDot = m_ShortName.LastIndexOf('.'); |
| | | if (indexOfDot > -1) |
| | | { |
| | | m_VariantName = m_ShortName.Substring(indexOfDot + 1); |
| | | m_ShortName = m_ShortName.Substring(0, indexOfDot); |
| | | } |
| | | else |
| | | m_VariantName = string.Empty; |
| | | } |
| | | |
| | | public void PartialNameChange(string newToken, int indexFromBack) |
| | | { |
| | | if(indexFromBack == 0) |
| | | { |
| | | SetShortName(newToken); |
| | | } |
| | | else if(indexFromBack-1 < m_PathTokens.Count) |
| | | { |
| | | m_PathTokens[m_PathTokens.Count - indexFromBack] = newToken; |
| | | } |
| | | GenerateFullName(); |
| | | } |
| | | |
| | | private void GenerateFullName() |
| | | { |
| | | m_FullBundleName = string.Empty; |
| | | for(int i = 0; i < m_PathTokens.Count; i++) |
| | | { |
| | | m_FullBundleName += m_PathTokens[i]; |
| | | m_FullBundleName += '/'; |
| | | } |
| | | m_FullBundleName += m_ShortName; |
| | | m_FullNativeName = m_FullBundleName; |
| | | m_FullNativeName += (m_VariantName == "") ? "" : "." + m_VariantName; |
| | | } |
| | | } |
| | | |
| | | public abstract class BundleInfo |
| | | { |
| | | protected BundleFolderInfo m_Parent; |
| | | protected bool m_DoneUpdating; |
| | | protected bool m_Dirty; |
| | | public BundleNameData m_Name; |
| | | protected MessageSystem.MessageState m_BundleMessages = new MessageSystem.MessageState(); |
| | | protected MessageSystem.Message m_CachedHighMessage = null; |
| | | |
| | | public BundleInfo(string name, BundleFolderInfo parent) |
| | | { |
| | | m_Name = new BundleNameData(name); |
| | | m_Parent = parent; |
| | | } |
| | | |
| | | public BundleFolderInfo parent |
| | | { get { return m_Parent; } } |
| | | public virtual string displayName |
| | | { |
| | | get { return m_Name.shortName; } |
| | | } |
| | | public virtual int nameHashCode |
| | | { |
| | | get { return m_Name.GetHashCode(); } |
| | | } |
| | | public abstract BundleTreeItem CreateTreeView(int depth); |
| | | |
| | | protected virtual void RefreshMessages() |
| | | { |
| | | RefreshEmptyStatus(); |
| | | RefreshDupeAssetWarning(); |
| | | var flag = m_BundleMessages.HighestMessageFlag(); |
| | | m_CachedHighMessage = MessageSystem.GetMessage(flag); |
| | | } |
| | | public abstract bool RefreshEmptyStatus(); |
| | | public abstract bool RefreshDupeAssetWarning(); |
| | | public virtual MessageSystem.Message HighestMessage() |
| | | { |
| | | if (m_CachedHighMessage == null) |
| | | RefreshMessages(); |
| | | return m_CachedHighMessage; |
| | | } |
| | | public bool IsMessageSet(MessageSystem.MessageFlag flag) |
| | | { |
| | | return m_BundleMessages.IsSet(flag); |
| | | } |
| | | public void SetMessageFlag(MessageSystem.MessageFlag flag, bool on) |
| | | { |
| | | m_BundleMessages.SetFlag(flag, on); |
| | | } |
| | | public List<MessageSystem.Message> GetMessages() |
| | | { |
| | | return m_BundleMessages.GetMessages(); |
| | | } |
| | | public bool HasMessages() |
| | | { |
| | | return m_BundleMessages.HasMessages(); |
| | | } |
| | | |
| | | public virtual bool HandleRename(string newName, int reverseDepth) |
| | | { |
| | | if (reverseDepth == 0) |
| | | { |
| | | if (!m_Parent.HandleChildRename(m_Name.shortName, newName)) |
| | | return false; |
| | | } |
| | | m_Name.PartialNameChange(newName, reverseDepth); |
| | | return true; |
| | | } |
| | | public virtual void HandleDelete(bool isRootOfDelete, string forcedNewName="", string forcedNewVariant = "") |
| | | { |
| | | if(isRootOfDelete) |
| | | { |
| | | m_Parent.HandleChildRename(m_Name.shortName, string.Empty); |
| | | } |
| | | } |
| | | abstract public void RefreshAssetList(); |
| | | abstract public void AddAssetsToNode(AssetTreeItem node); |
| | | abstract public void Update(); |
| | | public virtual bool doneUpdating |
| | | { get { return m_DoneUpdating; } } |
| | | public virtual bool dirty |
| | | { get { return m_Dirty; } } |
| | | public void ForceNeedUpdate() |
| | | { |
| | | m_DoneUpdating = false; |
| | | m_Dirty = true; |
| | | } |
| | | |
| | | abstract public void HandleReparent(string parentName, BundleFolderInfo newParent = null); |
| | | abstract public List<AssetInfo> GetDependencies(); |
| | | } |
| | | |
| | | public class BundleDataInfo : BundleInfo |
| | | { |
| | | protected List<AssetInfo> m_ConcreteAssets; |
| | | protected List<AssetInfo> m_DependentAssets; |
| | | protected HashSet<string> m_BundleDependencies; |
| | | protected int m_ConcreteCounter; |
| | | protected int m_DependentCounter; |
| | | protected bool m_IsSceneBundle; |
| | | protected long m_TotalSize; |
| | | |
| | | public BundleDataInfo(string name, BundleFolderInfo parent) : base(name, parent) |
| | | { |
| | | m_ConcreteAssets = new List<AssetInfo>(); |
| | | m_DependentAssets = new List<AssetInfo>(); |
| | | m_BundleDependencies = new HashSet<string>(); |
| | | m_ConcreteCounter = 0; |
| | | m_DependentCounter = 0; |
| | | } |
| | | ~BundleDataInfo() |
| | | { |
| | | foreach (var asset in m_DependentAssets) |
| | | { |
| | | AssetBundleModel.Model.UnRegisterAsset(asset, m_Name.fullNativeName); |
| | | } |
| | | } |
| | | public override bool HandleRename(string newName, int reverseDepth) |
| | | { |
| | | RefreshAssetList(); |
| | | if (!base.HandleRename(newName, reverseDepth)) |
| | | return false; |
| | | Model.MoveAssetToBundle(m_ConcreteAssets, m_Name.bundleName, m_Name.variant); |
| | | return true; |
| | | } |
| | | public override void HandleDelete(bool isRootOfDelete, string forcedNewName="", string forcedNewVariant="") |
| | | { |
| | | RefreshAssetList(); |
| | | base.HandleDelete(isRootOfDelete); |
| | | Model.MoveAssetToBundle(m_ConcreteAssets, forcedNewName, forcedNewVariant); |
| | | } |
| | | |
| | | public string TotalSize() |
| | | { |
| | | if (m_TotalSize == 0) |
| | | return "--"; |
| | | return EditorUtility.FormatBytes(m_TotalSize); |
| | | } |
| | | |
| | | public override void RefreshAssetList() |
| | | { |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.AssetsDuplicatedInMultBundles, false); |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.SceneBundleConflict, false); |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.DependencySceneConflict, false); |
| | | |
| | | m_ConcreteAssets.Clear(); |
| | | m_TotalSize = 0; |
| | | m_IsSceneBundle = false; |
| | | |
| | | foreach (var asset in m_DependentAssets) |
| | | { |
| | | AssetBundleModel.Model.UnRegisterAsset(asset, m_Name.fullNativeName); |
| | | } |
| | | m_DependentAssets.Clear(); |
| | | m_BundleDependencies.Clear(); |
| | | |
| | | bool assetInBundle = false; |
| | | bool sceneError = false; |
| | | var assets = AssetBundleModel.Model.DataSource.GetAssetPathsFromAssetBundle(m_Name.fullNativeName); |
| | | foreach(var assetName in assets) |
| | | { |
| | | if (AssetDatabase.GetMainAssetTypeAtPath(assetName) == typeof(SceneAsset)) |
| | | { |
| | | m_IsSceneBundle = true; |
| | | if(assetInBundle) |
| | | sceneError = true; |
| | | } |
| | | else |
| | | { |
| | | assetInBundle = true; |
| | | if (m_IsSceneBundle) |
| | | sceneError = true; |
| | | } |
| | | |
| | | var bundleName = Model.GetBundleName(assetName); |
| | | if (bundleName == string.Empty) |
| | | { |
| | | ///we get here if the current asset is only added due to being in an explicitly added folder |
| | | |
| | | |
| | | var partialPath = assetName; |
| | | while( |
| | | partialPath != string.Empty && |
| | | partialPath != "Assets" && |
| | | bundleName == string.Empty) |
| | | { |
| | | partialPath = partialPath.Substring(0, partialPath.LastIndexOf('/')); |
| | | bundleName = Model.GetBundleName(partialPath); |
| | | } |
| | | if(bundleName != string.Empty) |
| | | { |
| | | var folderAsset = Model.CreateAsset(partialPath, bundleName); |
| | | folderAsset.isFolder = true; |
| | | if (m_ConcreteAssets.FindIndex(a => a.displayName == folderAsset.displayName) == -1) |
| | | { |
| | | m_ConcreteAssets.Add(folderAsset); |
| | | } |
| | | |
| | | m_DependentAssets.Add(Model.CreateAsset(assetName, folderAsset)); |
| | | if (m_DependentAssets != null && m_DependentAssets.Count > 0) |
| | | { |
| | | var last = m_DependentAssets.Last(); |
| | | if (last != null) |
| | | m_TotalSize += last.fileSize; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | var newAsset = Model.CreateAsset (assetName, m_Name.fullNativeName); |
| | | if (newAsset != null) |
| | | { |
| | | m_ConcreteAssets.Add(newAsset); |
| | | m_TotalSize += m_ConcreteAssets.Last().fileSize; |
| | | if (AssetDatabase.GetMainAssetTypeAtPath(assetName) == typeof(SceneAsset)) |
| | | { |
| | | m_IsSceneBundle = true; |
| | | m_ConcreteAssets.Last().isScene = true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(sceneError) |
| | | { |
| | | foreach (var asset in m_ConcreteAssets) |
| | | { |
| | | if (asset.isFolder) |
| | | { |
| | | asset.SetMessageFlag(MessageSystem.MessageFlag.DependencySceneConflict, true); |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.DependencySceneConflict, true); |
| | | } |
| | | else |
| | | { |
| | | asset.SetMessageFlag(MessageSystem.MessageFlag.SceneBundleConflict, true); |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.SceneBundleConflict, true); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | m_ConcreteCounter = 0; |
| | | m_DependentCounter = 0; |
| | | m_Dirty = true; |
| | | } |
| | | |
| | | public override void AddAssetsToNode(AssetTreeItem node) |
| | | { |
| | | foreach (var asset in m_ConcreteAssets) |
| | | node.AddChild(new AssetTreeItem(asset)); |
| | | |
| | | foreach (var asset in m_DependentAssets) |
| | | { |
| | | if(!node.ContainsChild(asset)) |
| | | node.AddChild(new AssetTreeItem(asset)); |
| | | } |
| | | |
| | | m_Dirty = false; |
| | | } |
| | | public HashSet<string> GetBundleDependencies() |
| | | { |
| | | return m_BundleDependencies; |
| | | } |
| | | |
| | | public override void Update() |
| | | { |
| | | int dependents = m_DependentAssets.Count; |
| | | int bundleDep = m_BundleDependencies.Count; |
| | | if(m_ConcreteCounter < m_ConcreteAssets.Count) |
| | | { |
| | | GatherDependencies(m_ConcreteAssets[m_ConcreteCounter]); |
| | | m_ConcreteCounter++; |
| | | m_DoneUpdating = false; |
| | | } |
| | | else if (m_DependentCounter < m_DependentAssets.Count) |
| | | { |
| | | GatherDependencies(m_DependentAssets[m_DependentCounter], m_Name.fullNativeName); |
| | | m_DependentCounter++; |
| | | m_DoneUpdating = false; |
| | | } |
| | | else |
| | | { |
| | | m_DoneUpdating = true; |
| | | } |
| | | m_Dirty = (dependents != m_DependentAssets.Count) || (bundleDep != m_BundleDependencies.Count); |
| | | if (m_Dirty || m_DoneUpdating) |
| | | RefreshMessages(); |
| | | } |
| | | |
| | | private void GatherDependencies(AssetInfo asset, string parentBundle = "") |
| | | { |
| | | if (parentBundle == string.Empty) |
| | | parentBundle = asset.bundleName; |
| | | |
| | | if (asset == null) |
| | | return; |
| | | |
| | | var deps = asset.GetDependencies(); |
| | | if (deps == null) |
| | | return; |
| | | |
| | | foreach (var ai in deps) |
| | | { |
| | | if (ai == asset || m_ConcreteAssets.Contains(ai) || m_DependentAssets.Contains(ai)) |
| | | continue; |
| | | |
| | | var bundleName = AssetBundleModel.Model.DataSource.GetImplicitAssetBundleName(ai.fullAssetName); |
| | | if (string.IsNullOrEmpty(bundleName)) |
| | | { |
| | | m_DependentAssets.Add(ai); |
| | | m_TotalSize += ai.fileSize; |
| | | if (Model.RegisterAsset(ai, parentBundle) > 1) |
| | | { |
| | | SetDuplicateWarning(); |
| | | } |
| | | } |
| | | else if(bundleName != m_Name.fullNativeName) |
| | | { |
| | | m_BundleDependencies.Add(bundleName); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public override bool RefreshDupeAssetWarning() |
| | | { |
| | | foreach(var asset in m_DependentAssets) |
| | | { |
| | | if (asset != null && asset.IsMessageSet(MessageSystem.MessageFlag.AssetsDuplicatedInMultBundles)) |
| | | { |
| | | SetDuplicateWarning(); |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public bool IsEmpty() |
| | | { |
| | | return (m_ConcreteAssets.Count == 0); |
| | | } |
| | | |
| | | public override bool RefreshEmptyStatus() |
| | | { |
| | | bool empty = IsEmpty(); |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.EmptyBundle, empty); |
| | | return empty; |
| | | } |
| | | |
| | | protected void SetDuplicateWarning() |
| | | { |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.AssetsDuplicatedInMultBundles, true); |
| | | m_Dirty = true; |
| | | } |
| | | |
| | | public bool isSceneBundle |
| | | { get { return m_IsSceneBundle; } } |
| | | |
| | | public override BundleTreeItem CreateTreeView(int depth) |
| | | { |
| | | RefreshAssetList(); |
| | | RefreshMessages(); |
| | | if (isSceneBundle) |
| | | return new BundleTreeItem(this, depth, Model.GetSceneIcon()); |
| | | else |
| | | return new BundleTreeItem(this, depth, Model.GetBundleIcon()); |
| | | } |
| | | |
| | | public override void HandleReparent(string parentName, BundleFolderInfo newParent = null) |
| | | { |
| | | RefreshAssetList(); |
| | | string newName = (parentName=="") ? "" : parentName + '/'; |
| | | newName += m_Name.shortName; |
| | | if (newName == m_Name.bundleName) |
| | | return; |
| | | |
| | | foreach (var asset in m_ConcreteAssets) |
| | | { |
| | | Model.MoveAssetToBundle(asset, newName, m_Name.variant); |
| | | } |
| | | |
| | | if (newParent != null) |
| | | { |
| | | m_Parent.HandleChildRename(m_Name.shortName, string.Empty); |
| | | m_Parent = newParent; |
| | | m_Parent.AddChild(this); |
| | | } |
| | | m_Name.SetBundleName(newName, m_Name.variant); |
| | | } |
| | | |
| | | public override List<AssetInfo> GetDependencies() |
| | | { |
| | | return m_DependentAssets; |
| | | } |
| | | } |
| | | |
| | | public class BundleVariantDataInfo : BundleDataInfo |
| | | { |
| | | protected List<AssetInfo> m_FolderIncludeAssets = new List<AssetInfo>(); |
| | | public BundleVariantDataInfo(string name, BundleFolderInfo parent) : base(name, parent) |
| | | { |
| | | } |
| | | ~BundleVariantDataInfo() |
| | | { |
| | | //parent should be auto called |
| | | } |
| | | public override string displayName |
| | | { |
| | | get { return m_Name.variant; } |
| | | } |
| | | public override void Update() |
| | | { |
| | | base.Update(); |
| | | (m_Parent as BundleVariantFolderInfo).ValidateVariants(); |
| | | } |
| | | public override void RefreshAssetList() |
| | | { |
| | | m_FolderIncludeAssets.Clear(); |
| | | base.RefreshAssetList(); |
| | | if(m_DependentAssets.Count > 0) |
| | | m_FolderIncludeAssets = new List<AssetInfo>(m_DependentAssets); |
| | | } |
| | | public bool IsSceneVariant() |
| | | { |
| | | RefreshAssetList(); |
| | | return isSceneBundle; |
| | | } |
| | | public override bool HandleRename(string newName, int reverseDepth) |
| | | { |
| | | if (reverseDepth == 0) |
| | | { |
| | | RefreshAssetList(); |
| | | if (!m_Parent.HandleChildRename(m_Name.variant, newName)) |
| | | return false; |
| | | m_Name.variant = newName; |
| | | Model.MoveAssetToBundle(m_ConcreteAssets, m_Name.bundleName, m_Name.variant); |
| | | } |
| | | else if (reverseDepth == 1) |
| | | { |
| | | RefreshAssetList(); |
| | | m_Name.PartialNameChange(newName + "." + m_Name.variant, 0); |
| | | Model.MoveAssetToBundle(m_ConcreteAssets, m_Name.bundleName, m_Name.variant); |
| | | } |
| | | else |
| | | { |
| | | return base.HandleRename(newName, reverseDepth-1); |
| | | } |
| | | return true; |
| | | } |
| | | public override void HandleDelete(bool isRootOfDelete, string forcedNewName = "", string forcedNewVariant = "") |
| | | { |
| | | RefreshAssetList(); |
| | | if (isRootOfDelete) |
| | | { |
| | | m_Parent.HandleChildRename(m_Name.variant, string.Empty); |
| | | } |
| | | Model.MoveAssetToBundle(m_ConcreteAssets, forcedNewName, forcedNewVariant); |
| | | } |
| | | |
| | | public bool FindContentMismatch(BundleVariantDataInfo other) |
| | | { |
| | | bool result = false; |
| | | |
| | | if (m_FolderIncludeAssets.Count != 0 || other.m_FolderIncludeAssets.Count != 0) |
| | | { |
| | | var myUniqueAssets = new HashSet<string>(); |
| | | var otherUniqueAssets = new HashSet<string>(other.m_FolderIncludeAssets.Select(x => x.displayName)); |
| | | |
| | | foreach (var asset in m_FolderIncludeAssets) |
| | | { |
| | | if (!otherUniqueAssets.Remove(asset.displayName)) |
| | | { |
| | | myUniqueAssets.Add(asset.displayName); |
| | | } |
| | | } |
| | | |
| | | if (myUniqueAssets.Count > 0) |
| | | { |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.VariantBundleMismatch, true); |
| | | result = true; |
| | | } |
| | | if (otherUniqueAssets.Count > 0) |
| | | { |
| | | other.m_BundleMessages.SetFlag(MessageSystem.MessageFlag.VariantBundleMismatch, true); |
| | | result = true; |
| | | } |
| | | } |
| | | else //this doesn't cover the super weird case of including a folder and some explicit assets. TODO - fix that. |
| | | { |
| | | var myUniqueAssets = new HashSet<string>(); |
| | | var otherUniqueAssets = new HashSet<string>(other.m_ConcreteAssets.Select(x => x.displayName)); |
| | | |
| | | foreach (var asset in m_ConcreteAssets) |
| | | { |
| | | if (!otherUniqueAssets.Remove(asset.displayName)) |
| | | { |
| | | myUniqueAssets.Add(asset.displayName); |
| | | } |
| | | } |
| | | |
| | | if (myUniqueAssets.Count > 0) |
| | | { |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.VariantBundleMismatch, true); |
| | | result = true; |
| | | } |
| | | if (otherUniqueAssets.Count > 0) |
| | | { |
| | | other.m_BundleMessages.SetFlag(MessageSystem.MessageFlag.VariantBundleMismatch, true); |
| | | result = true; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | |
| | | public abstract class BundleFolderInfo : BundleInfo |
| | | { |
| | | protected Dictionary<string, BundleInfo> m_Children; |
| | | |
| | | public BundleFolderInfo(string name, BundleFolderInfo parent) : base(name, parent) |
| | | { |
| | | m_Children = new Dictionary<string, BundleInfo>(); |
| | | } |
| | | |
| | | public BundleFolderInfo(List<string> path, int depth, BundleFolderInfo parent) : base("", parent) |
| | | { |
| | | m_Children = new Dictionary<string, BundleInfo>(); |
| | | m_Name = new BundleNameData(""); |
| | | m_Name.pathTokens = path.GetRange(0, depth); |
| | | } |
| | | |
| | | public BundleInfo GetChild(string name) |
| | | { |
| | | if (name == null) |
| | | return null; |
| | | |
| | | BundleInfo info = null; |
| | | if (m_Children.TryGetValue(name, out info)) |
| | | return info; |
| | | return null; |
| | | } |
| | | public Dictionary<string, BundleInfo>.ValueCollection GetChildList() |
| | | { |
| | | return m_Children.Values; |
| | | } |
| | | public abstract void AddChild(BundleInfo info); |
| | | |
| | | public override bool HandleRename(string newName, int reverseDepth) |
| | | { |
| | | if (!base.HandleRename(newName, reverseDepth)) |
| | | return false; |
| | | |
| | | foreach (var child in m_Children) |
| | | { |
| | | child.Value.HandleRename(newName, reverseDepth + 1); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public override void HandleDelete(bool isRootOfDelete, string forcedNewName="", string forcedNewVariant = "") |
| | | { |
| | | base.HandleDelete(isRootOfDelete); |
| | | foreach (var child in m_Children) |
| | | { |
| | | child.Value.HandleDelete(false, forcedNewName, forcedNewVariant); |
| | | } |
| | | m_Children.Clear(); |
| | | } |
| | | |
| | | protected override void RefreshMessages() |
| | | { |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.ErrorInChildren, false); |
| | | foreach(var child in m_Children) |
| | | { |
| | | if (child.Value.IsMessageSet(MessageSystem.MessageFlag.Error)) |
| | | { |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.ErrorInChildren, true); |
| | | break; |
| | | } |
| | | } |
| | | base.RefreshMessages(); |
| | | } |
| | | public override bool RefreshEmptyStatus() |
| | | { |
| | | bool empty = m_Children.Count == 0; |
| | | foreach (var child in m_Children) |
| | | { |
| | | empty |= child.Value.RefreshEmptyStatus(); |
| | | } |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.EmptyFolder, empty); |
| | | return empty; |
| | | } |
| | | |
| | | public override void RefreshAssetList() |
| | | { |
| | | foreach (var child in m_Children) |
| | | { |
| | | child.Value.RefreshAssetList(); |
| | | } |
| | | } |
| | | public override bool RefreshDupeAssetWarning() |
| | | { |
| | | bool dupeWarning = false; |
| | | foreach (var child in m_Children) |
| | | { |
| | | dupeWarning |= child.Value.RefreshDupeAssetWarning(); |
| | | } |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.WarningInChildren, dupeWarning); |
| | | return dupeWarning; |
| | | } |
| | | public override void AddAssetsToNode(AssetTreeItem node) |
| | | { |
| | | foreach (var child in m_Children) |
| | | { |
| | | child.Value.AddAssetsToNode(node); |
| | | } |
| | | m_Dirty = false; |
| | | } |
| | | public virtual bool HandleChildRename(string oldName, string newName) |
| | | { |
| | | |
| | | if (newName != string.Empty && m_Children.ContainsKey(newName)) |
| | | { |
| | | Model.LogWarning("Attempting to name an item '" + newName + "' which matches existing name at this level in hierarchy. If your desire is to merge bundles, drag one on top of the other."); |
| | | return false; |
| | | } |
| | | |
| | | BundleInfo info = null; |
| | | if (m_Children.TryGetValue(oldName, out info)) |
| | | { |
| | | m_Children.Remove(oldName); |
| | | if (newName != string.Empty) |
| | | m_Children.Add(newName, info); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public override void Update() |
| | | { |
| | | m_Dirty = false; |
| | | m_DoneUpdating = true; |
| | | foreach (var child in m_Children) |
| | | { |
| | | child.Value.Update(); |
| | | m_Dirty |= child.Value.dirty; |
| | | m_DoneUpdating &= child.Value.doneUpdating; |
| | | } |
| | | |
| | | if (m_Dirty || m_DoneUpdating) |
| | | RefreshMessages(); |
| | | } |
| | | public override bool doneUpdating |
| | | { |
| | | get |
| | | { |
| | | foreach (var child in m_Children) |
| | | { |
| | | m_DoneUpdating &= child.Value.doneUpdating; |
| | | } |
| | | return base.doneUpdating; |
| | | } |
| | | } |
| | | |
| | | |
| | | public override List<AssetInfo> GetDependencies() |
| | | { |
| | | List<AssetInfo> assets = new List<AssetInfo>(); |
| | | foreach (var child in m_Children) |
| | | { |
| | | assets.AddRange(child.Value.GetDependencies()); |
| | | } |
| | | return assets; |
| | | } |
| | | } |
| | | |
| | | public class BundleFolderConcreteInfo : BundleFolderInfo |
| | | { |
| | | public BundleFolderConcreteInfo(string name, BundleFolderInfo parent) : base(name, parent) |
| | | { |
| | | } |
| | | |
| | | public BundleFolderConcreteInfo(List<string> path, int depth, BundleFolderInfo parent) : base(path, depth, parent) |
| | | { |
| | | } |
| | | |
| | | public override void AddChild(BundleInfo info) |
| | | { |
| | | m_Children.Add(info.displayName, info); |
| | | } |
| | | public override BundleTreeItem CreateTreeView(int depth) |
| | | { |
| | | RefreshMessages(); |
| | | var result = new BundleTreeItem(this, depth, Model.GetFolderIcon()); |
| | | foreach (var child in m_Children) |
| | | { |
| | | result.AddChild(child.Value.CreateTreeView(depth + 1)); |
| | | } |
| | | return result; |
| | | } |
| | | public override void HandleReparent(string parentName, BundleFolderInfo newParent = null) |
| | | { |
| | | string newName = (parentName == "") ? "" : parentName + '/'; |
| | | newName += displayName; |
| | | if (newName == m_Name.bundleName) |
| | | return; |
| | | foreach (var child in m_Children) |
| | | { |
| | | child.Value.HandleReparent(newName); |
| | | } |
| | | |
| | | if (newParent != null) |
| | | { |
| | | m_Parent.HandleChildRename(m_Name.shortName, string.Empty); |
| | | m_Parent = newParent; |
| | | m_Parent.AddChild(this); |
| | | } |
| | | m_Name.SetBundleName(newName, m_Name.variant); |
| | | } |
| | | } |
| | | |
| | | |
| | | public class BundleVariantFolderInfo : BundleFolderInfo |
| | | { |
| | | public BundleVariantFolderInfo(string name, BundleFolderInfo parent) : base(name, parent) |
| | | { |
| | | } |
| | | public override void AddChild(BundleInfo info) |
| | | { |
| | | m_Children.Add(info.m_Name.variant, info); |
| | | } |
| | | private bool m_validated; |
| | | public override void Update() |
| | | { |
| | | m_validated = false; |
| | | base.Update(); |
| | | if(!m_validated) |
| | | ValidateVariants(); |
| | | } |
| | | public void ValidateVariants() |
| | | { |
| | | m_validated = true; |
| | | bool childMismatch = false; |
| | | if(m_Children.Count > 1) |
| | | { |
| | | BundleVariantDataInfo goldChild = null; |
| | | foreach(var c in m_Children) |
| | | { |
| | | var child = c.Value as BundleVariantDataInfo; |
| | | child.SetMessageFlag(MessageSystem.MessageFlag.VariantBundleMismatch, false); |
| | | if (goldChild == null) |
| | | { |
| | | goldChild = child; |
| | | continue; |
| | | } |
| | | childMismatch |= goldChild.FindContentMismatch(child); |
| | | } |
| | | } |
| | | m_BundleMessages.SetFlag(MessageSystem.MessageFlag.VariantBundleMismatch, childMismatch); |
| | | |
| | | } |
| | | |
| | | public override BundleTreeItem CreateTreeView(int depth) |
| | | { |
| | | RefreshMessages(); |
| | | Texture2D icon = null; |
| | | if ((m_Children.Count > 0) && |
| | | ((m_Children.First().Value as BundleVariantDataInfo).IsSceneVariant())) |
| | | { |
| | | icon = Model.GetSceneIcon(); |
| | | } |
| | | else |
| | | icon = Model.GetBundleIcon(); |
| | | |
| | | var result = new BundleTreeItem(this, depth, icon); |
| | | foreach (var child in m_Children) |
| | | { |
| | | result.AddChild(child.Value.CreateTreeView(depth + 1)); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public override void HandleReparent(string parentName, BundleFolderInfo newParent = null) |
| | | { |
| | | string newName = (parentName == "") ? "" : parentName + '/'; |
| | | newName += displayName; |
| | | if (newName == m_Name.bundleName) |
| | | return; |
| | | foreach (var child in m_Children) |
| | | { |
| | | child.Value.HandleReparent(parentName); |
| | | } |
| | | |
| | | if (newParent != null) |
| | | { |
| | | m_Parent.HandleChildRename(m_Name.shortName, string.Empty); |
| | | m_Parent = newParent; |
| | | m_Parent.AddChild(this); |
| | | } |
| | | m_Name.SetBundleName(newName, string.Empty) ; |
| | | } |
| | | public override bool HandleChildRename(string oldName, string newName) |
| | | { |
| | | var result = base.HandleChildRename(oldName, newName); |
| | | if (m_Children.Count == 0) |
| | | HandleDelete(true); |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 5221bce31edb15f4b929b93f967fe170 |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | using UnityEditorInternal; |
| | | using System.Collections.Generic; |
| | | using UnityEditor.IMGUI.Controls; |
| | | using System.Linq; |
| | | using System; |
| | | |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | internal class AssetBundleTree : TreeView |
| | | { |
| | | AssetBundleManageTab m_Controller; |
| | | private bool m_ContextOnItem = false; |
| | | List<UnityEngine.Object> m_EmptyObjectList = new List<Object>(); |
| | | |
| | | public AssetBundleTree(TreeViewState state, AssetBundleManageTab ctrl) : base(state) |
| | | { |
| | | AssetBundleModel.Model.Rebuild(); |
| | | m_Controller = ctrl; |
| | | showBorder = true; |
| | | } |
| | | |
| | | protected override bool CanMultiSelect(TreeViewItem item) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | protected override bool CanRename(TreeViewItem item) |
| | | { |
| | | return item.displayName.Length > 0; |
| | | } |
| | | |
| | | protected override void RowGUI(RowGUIArgs args) |
| | | { |
| | | var bundleItem = (args.item as AssetBundleModel.BundleTreeItem); |
| | | if (args.item.icon == null) |
| | | extraSpaceBeforeIconAndLabel = 16f; |
| | | else |
| | | extraSpaceBeforeIconAndLabel = 0f; |
| | | |
| | | Color old = GUI.color; |
| | | if ((bundleItem.bundle as AssetBundleModel.BundleVariantFolderInfo) != null) |
| | | GUI.color = AssetBundleModel.Model.k_LightGrey; //new Color(0.3f, 0.5f, 0.85f); |
| | | base.RowGUI(args); |
| | | GUI.color = old; |
| | | |
| | | var message = bundleItem.BundleMessage(); |
| | | if(message.severity != MessageType.None) |
| | | { |
| | | var size = args.rowRect.height; |
| | | var right = args.rowRect.xMax; |
| | | Rect messageRect = new Rect(right - size, args.rowRect.yMin, size, size); |
| | | GUI.Label(messageRect, new GUIContent(message.icon, message.message )); |
| | | } |
| | | } |
| | | |
| | | protected override void RenameEnded(RenameEndedArgs args) |
| | | { |
| | | base.RenameEnded(args); |
| | | if (args.newName.Length > 0 && args.newName != args.originalName) |
| | | { |
| | | args.newName = args.newName.ToLower(); |
| | | args.acceptedRename = true; |
| | | |
| | | AssetBundleModel.BundleTreeItem renamedItem = FindItem(args.itemID, rootItem) as AssetBundleModel.BundleTreeItem; |
| | | args.acceptedRename = AssetBundleModel.Model.HandleBundleRename(renamedItem, args.newName); |
| | | ReloadAndSelect(renamedItem.bundle.nameHashCode, false); |
| | | } |
| | | else |
| | | { |
| | | args.acceptedRename = false; |
| | | } |
| | | } |
| | | |
| | | protected override TreeViewItem BuildRoot() |
| | | { |
| | | AssetBundleModel.Model.Refresh(); |
| | | var root = AssetBundleModel.Model.CreateBundleTreeView(); |
| | | return root; |
| | | } |
| | | |
| | | protected override void SelectionChanged(IList<int> selectedIds) |
| | | { |
| | | |
| | | var selectedBundles = new List<AssetBundleModel.BundleInfo>(); |
| | | if (selectedIds != null) |
| | | { |
| | | foreach (var id in selectedIds) |
| | | { |
| | | var item = FindItem(id, rootItem) as AssetBundleModel.BundleTreeItem; |
| | | if(item != null && item.bundle != null) |
| | | { |
| | | item.bundle.RefreshAssetList(); |
| | | selectedBundles.Add(item.bundle); |
| | | } |
| | | } |
| | | } |
| | | |
| | | m_Controller.UpdateSelectedBundles(selectedBundles); |
| | | } |
| | | |
| | | public override void OnGUI(Rect rect) |
| | | { |
| | | base.OnGUI(rect); |
| | | if(Event.current.type == EventType.MouseDown && Event.current.button == 0 && rect.Contains(Event.current.mousePosition)) |
| | | { |
| | | SetSelection(new int[0], TreeViewSelectionOptions.FireSelectionChanged); |
| | | } |
| | | } |
| | | |
| | | |
| | | protected override void ContextClicked() |
| | | { |
| | | if (m_ContextOnItem) |
| | | { |
| | | m_ContextOnItem = false; |
| | | return; |
| | | } |
| | | |
| | | List<AssetBundleModel.BundleTreeItem> selectedNodes = new List<AssetBundleModel.BundleTreeItem>(); |
| | | GenericMenu menu = new GenericMenu(); |
| | | |
| | | if (!AssetBundleModel.Model.DataSource.IsReadOnly ()) { |
| | | menu.AddItem(new GUIContent("Add new bundle"), false, CreateNewBundle, selectedNodes); |
| | | menu.AddItem(new GUIContent("Add new folder"), false, CreateFolder, selectedNodes); |
| | | } |
| | | |
| | | menu.AddItem(new GUIContent("Reload all data"), false, ForceReloadData, selectedNodes); |
| | | menu.ShowAsContext(); |
| | | } |
| | | |
| | | protected override void ContextClickedItem(int id) |
| | | { |
| | | if (AssetBundleModel.Model.DataSource.IsReadOnly ()) { |
| | | return; |
| | | } |
| | | |
| | | m_ContextOnItem = true; |
| | | List<AssetBundleModel.BundleTreeItem> selectedNodes = new List<AssetBundleModel.BundleTreeItem>(); |
| | | foreach (var nodeID in GetSelection()) |
| | | { |
| | | selectedNodes.Add(FindItem(nodeID, rootItem) as AssetBundleModel.BundleTreeItem); |
| | | } |
| | | |
| | | GenericMenu menu = new GenericMenu(); |
| | | |
| | | if(selectedNodes.Count == 1) |
| | | { |
| | | if ((selectedNodes[0].bundle as AssetBundleModel.BundleFolderConcreteInfo) != null) |
| | | { |
| | | menu.AddItem(new GUIContent("Add Child/New Bundle"), false, CreateNewBundle, selectedNodes); |
| | | menu.AddItem(new GUIContent("Add Child/New Folder"), false, CreateFolder, selectedNodes); |
| | | menu.AddItem(new GUIContent("Add Sibling/New Bundle"), false, CreateNewSiblingBundle, selectedNodes); |
| | | menu.AddItem(new GUIContent("Add Sibling/New Folder"), false, CreateNewSiblingFolder, selectedNodes); |
| | | } |
| | | else if( (selectedNodes[0].bundle as AssetBundleModel.BundleVariantFolderInfo) != null) |
| | | { |
| | | menu.AddItem(new GUIContent("Add Child/New Variant"), false, CreateNewVariant, selectedNodes); |
| | | menu.AddItem(new GUIContent("Add Sibling/New Bundle"), false, CreateNewSiblingBundle, selectedNodes); |
| | | menu.AddItem(new GUIContent("Add Sibling/New Folder"), false, CreateNewSiblingFolder, selectedNodes); |
| | | } |
| | | else |
| | | { |
| | | var variant = selectedNodes[0].bundle as AssetBundleModel.BundleVariantDataInfo; |
| | | if (variant == null) |
| | | { |
| | | menu.AddItem(new GUIContent("Add Sibling/New Bundle"), false, CreateNewSiblingBundle, selectedNodes); |
| | | menu.AddItem(new GUIContent("Add Sibling/New Folder"), false, CreateNewSiblingFolder, selectedNodes); |
| | | menu.AddItem(new GUIContent("Convert to variant"), false, ConvertToVariant, selectedNodes); |
| | | } |
| | | else |
| | | { |
| | | menu.AddItem(new GUIContent("Add Sibling/New Variant"), false, CreateNewSiblingVariant, selectedNodes); |
| | | } |
| | | } |
| | | if(selectedNodes[0].bundle.IsMessageSet(MessageSystem.MessageFlag.AssetsDuplicatedInMultBundles)) |
| | | menu.AddItem(new GUIContent("Move duplicates to new bundle"), false, DedupeAllBundles, selectedNodes); |
| | | menu.AddItem(new GUIContent("Rename"), false, RenameBundle, selectedNodes); |
| | | menu.AddItem(new GUIContent("Delete " + selectedNodes[0].displayName), false, DeleteBundles, selectedNodes); |
| | | |
| | | } |
| | | else if (selectedNodes.Count > 1) |
| | | { |
| | | menu.AddItem(new GUIContent("Move duplicates shared by selected"), false, DedupeOverlappedBundles, selectedNodes); |
| | | menu.AddItem(new GUIContent("Move duplicates existing in any selected"), false, DedupeAllBundles, selectedNodes); |
| | | menu.AddItem(new GUIContent("Delete " + selectedNodes.Count + " selected bundles"), false, DeleteBundles, selectedNodes); |
| | | } |
| | | menu.ShowAsContext(); |
| | | } |
| | | void ForceReloadData(object context) |
| | | { |
| | | AssetBundleModel.Model.ForceReloadData(this); |
| | | } |
| | | |
| | | void CreateNewSiblingFolder(object context) |
| | | { |
| | | var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>; |
| | | if (selectedNodes != null && selectedNodes.Count > 0) |
| | | { |
| | | AssetBundleModel.BundleFolderConcreteInfo folder = null; |
| | | folder = selectedNodes[0].bundle.parent as AssetBundleModel.BundleFolderConcreteInfo; |
| | | CreateFolderUnderParent(folder); |
| | | } |
| | | else |
| | | Debug.LogError("could not add 'sibling' with no bundles selected"); |
| | | } |
| | | void CreateFolder(object context) |
| | | { |
| | | AssetBundleModel.BundleFolderConcreteInfo folder = null; |
| | | var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>; |
| | | if (selectedNodes != null && selectedNodes.Count > 0) |
| | | { |
| | | folder = selectedNodes[0].bundle as AssetBundleModel.BundleFolderConcreteInfo; |
| | | } |
| | | CreateFolderUnderParent(folder); |
| | | } |
| | | void CreateFolderUnderParent(AssetBundleModel.BundleFolderConcreteInfo folder) |
| | | { |
| | | var newBundle = AssetBundleModel.Model.CreateEmptyBundleFolder(folder); |
| | | ReloadAndSelect(newBundle.nameHashCode, true); |
| | | } |
| | | void RenameBundle(object context) |
| | | { |
| | | var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>; |
| | | if (selectedNodes != null && selectedNodes.Count > 0) |
| | | { |
| | | BeginRename(FindItem(selectedNodes[0].bundle.nameHashCode, rootItem)); |
| | | } |
| | | } |
| | | |
| | | void CreateNewSiblingBundle(object context) |
| | | { |
| | | var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>; |
| | | if (selectedNodes != null && selectedNodes.Count > 0) |
| | | { |
| | | AssetBundleModel.BundleFolderConcreteInfo folder = null; |
| | | folder = selectedNodes[0].bundle.parent as AssetBundleModel.BundleFolderConcreteInfo; |
| | | CreateBundleUnderParent(folder); |
| | | } |
| | | else |
| | | Debug.LogError("could not add 'sibling' with no bundles selected"); |
| | | } |
| | | void CreateNewBundle(object context) |
| | | { |
| | | AssetBundleModel.BundleFolderConcreteInfo folder = null; |
| | | var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>; |
| | | if (selectedNodes != null && selectedNodes.Count > 0) |
| | | { |
| | | folder = selectedNodes[0].bundle as AssetBundleModel.BundleFolderConcreteInfo; |
| | | } |
| | | CreateBundleUnderParent(folder); |
| | | } |
| | | |
| | | void CreateBundleUnderParent(AssetBundleModel.BundleFolderInfo folder) |
| | | { |
| | | var newBundle = AssetBundleModel.Model.CreateEmptyBundle(folder); |
| | | ReloadAndSelect(newBundle.nameHashCode, true); |
| | | } |
| | | |
| | | |
| | | void CreateNewSiblingVariant(object context) |
| | | { |
| | | var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>; |
| | | if (selectedNodes != null && selectedNodes.Count > 0) |
| | | { |
| | | AssetBundleModel.BundleVariantFolderInfo folder = null; |
| | | folder = selectedNodes[0].bundle.parent as AssetBundleModel.BundleVariantFolderInfo; |
| | | CreateVariantUnderParent(folder); |
| | | } |
| | | else |
| | | Debug.LogError("could not add 'sibling' with no bundles selected"); |
| | | } |
| | | void CreateNewVariant(object context) |
| | | { |
| | | AssetBundleModel.BundleVariantFolderInfo folder = null; |
| | | var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>; |
| | | if (selectedNodes != null && selectedNodes.Count == 1) |
| | | { |
| | | folder = selectedNodes[0].bundle as AssetBundleModel.BundleVariantFolderInfo; |
| | | CreateVariantUnderParent(folder); |
| | | } |
| | | } |
| | | void CreateVariantUnderParent(AssetBundleModel.BundleVariantFolderInfo folder) |
| | | { |
| | | if (folder != null) |
| | | { |
| | | var newBundle = AssetBundleModel.Model.CreateEmptyVariant(folder); |
| | | ReloadAndSelect(newBundle.nameHashCode, true); |
| | | } |
| | | } |
| | | |
| | | void ConvertToVariant(object context) |
| | | { |
| | | var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>; |
| | | if (selectedNodes.Count == 1) |
| | | { |
| | | var bundle = selectedNodes[0].bundle as AssetBundleModel.BundleDataInfo; |
| | | var newBundle = AssetBundleModel.Model.HandleConvertToVariant(bundle); |
| | | int hash = 0; |
| | | if (newBundle != null) |
| | | hash = newBundle.nameHashCode; |
| | | ReloadAndSelect(hash, true); |
| | | } |
| | | } |
| | | |
| | | void DedupeOverlappedBundles(object context) |
| | | { |
| | | DedupeBundles(context, true); |
| | | } |
| | | void DedupeAllBundles(object context) |
| | | { |
| | | DedupeBundles(context, false); |
| | | } |
| | | void DedupeBundles(object context, bool onlyOverlappedAssets) |
| | | { |
| | | var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>; |
| | | var newBundle = AssetBundleModel.Model.HandleDedupeBundles(selectedNodes.Select(item => item.bundle), onlyOverlappedAssets); |
| | | if(newBundle != null) |
| | | { |
| | | var selection = new List<int>(); |
| | | selection.Add(newBundle.nameHashCode); |
| | | ReloadAndSelect(selection); |
| | | } |
| | | else |
| | | { |
| | | if (onlyOverlappedAssets) |
| | | DebugEx.LogWarning("There were no duplicated assets that existed across all selected bundles."); |
| | | else |
| | | DebugEx.LogWarning("No duplicate assets found after refreshing bundle contents."); |
| | | } |
| | | } |
| | | |
| | | void DeleteBundles(object b) |
| | | { |
| | | var selectedNodes = b as List<AssetBundleModel.BundleTreeItem>; |
| | | AssetBundleModel.Model.HandleBundleDelete(selectedNodes.Select(item => item.bundle)); |
| | | ReloadAndSelect(new List<int>()); |
| | | |
| | | |
| | | } |
| | | protected override void KeyEvent() |
| | | { |
| | | if (Event.current.keyCode == KeyCode.Delete && GetSelection().Count > 0) |
| | | { |
| | | List<AssetBundleModel.BundleTreeItem> selectedNodes = new List<AssetBundleModel.BundleTreeItem>(); |
| | | foreach (var nodeID in GetSelection()) |
| | | { |
| | | selectedNodes.Add(FindItem(nodeID, rootItem) as AssetBundleModel.BundleTreeItem); |
| | | } |
| | | DeleteBundles(selectedNodes); |
| | | } |
| | | } |
| | | |
| | | class DragAndDropData |
| | | { |
| | | public bool hasBundleFolder = false; |
| | | public bool hasScene = false; |
| | | public bool hasNonScene = false; |
| | | public bool hasVariantChild = false; |
| | | public List<AssetBundleModel.BundleInfo> draggedNodes; |
| | | public AssetBundleModel.BundleTreeItem targetNode; |
| | | public DragAndDropArgs args; |
| | | public string[] paths; |
| | | |
| | | public DragAndDropData(DragAndDropArgs a) |
| | | { |
| | | args = a; |
| | | draggedNodes = DragAndDrop.GetGenericData("AssetBundleModel.BundleInfo") as List<AssetBundleModel.BundleInfo>; |
| | | targetNode = args.parentItem as AssetBundleModel.BundleTreeItem; |
| | | paths = DragAndDrop.paths; |
| | | |
| | | if (draggedNodes != null) |
| | | { |
| | | foreach (var bundle in draggedNodes) |
| | | { |
| | | if ((bundle as AssetBundleModel.BundleFolderInfo) != null) |
| | | { |
| | | hasBundleFolder = true; |
| | | } |
| | | else |
| | | { |
| | | var dataBundle = bundle as AssetBundleModel.BundleDataInfo; |
| | | if (dataBundle != null) |
| | | { |
| | | if (dataBundle.isSceneBundle) |
| | | hasScene = true; |
| | | else |
| | | hasNonScene = true; |
| | | |
| | | if ( (dataBundle as AssetBundleModel.BundleVariantDataInfo) != null) |
| | | hasVariantChild = true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else if (DragAndDrop.paths != null) |
| | | { |
| | | foreach (var assetPath in DragAndDrop.paths) |
| | | { |
| | | if (AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(SceneAsset)) |
| | | hasScene = true; |
| | | else |
| | | hasNonScene = true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | protected override DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args) |
| | | { |
| | | DragAndDropVisualMode visualMode = DragAndDropVisualMode.None; |
| | | DragAndDropData data = new DragAndDropData(args); |
| | | |
| | | if (AssetBundleModel.Model.DataSource.IsReadOnly ()) { |
| | | return DragAndDropVisualMode.Rejected; |
| | | } |
| | | |
| | | if ( (data.hasScene && data.hasNonScene) || |
| | | (data.hasVariantChild) ) |
| | | return DragAndDropVisualMode.Rejected; |
| | | |
| | | switch (args.dragAndDropPosition) |
| | | { |
| | | case DragAndDropPosition.UponItem: |
| | | visualMode = HandleDragDropUpon(data); |
| | | break; |
| | | case DragAndDropPosition.BetweenItems: |
| | | visualMode = HandleDragDropBetween(data); |
| | | break; |
| | | case DragAndDropPosition.OutsideItems: |
| | | if (data.draggedNodes != null) |
| | | { |
| | | visualMode = DragAndDropVisualMode.Copy; |
| | | if (data.args.performDrop) |
| | | { |
| | | AssetBundleModel.Model.HandleBundleReparent(data.draggedNodes, null); |
| | | Reload(); |
| | | } |
| | | } |
| | | else if(data.paths != null) |
| | | { |
| | | visualMode = DragAndDropVisualMode.Copy; |
| | | if (data.args.performDrop) |
| | | { |
| | | DragPathsToNewSpace(data.paths, null); |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | return visualMode; |
| | | } |
| | | |
| | | private DragAndDropVisualMode HandleDragDropUpon(DragAndDropData data) |
| | | { |
| | | DragAndDropVisualMode visualMode = DragAndDropVisualMode.Copy;//Move; |
| | | var targetDataBundle = data.targetNode.bundle as AssetBundleModel.BundleDataInfo; |
| | | if (targetDataBundle != null) |
| | | { |
| | | if (targetDataBundle.isSceneBundle) |
| | | { |
| | | if(data.hasNonScene) |
| | | return DragAndDropVisualMode.Rejected; |
| | | } |
| | | else |
| | | { |
| | | if (data.hasBundleFolder) |
| | | { |
| | | return DragAndDropVisualMode.Rejected; |
| | | } |
| | | else if (data.hasScene && !targetDataBundle.IsEmpty()) |
| | | { |
| | | return DragAndDropVisualMode.Rejected; |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | if (data.args.performDrop) |
| | | { |
| | | if (data.draggedNodes != null) |
| | | { |
| | | AssetBundleModel.Model.HandleBundleMerge(data.draggedNodes, targetDataBundle); |
| | | ReloadAndSelect(targetDataBundle.nameHashCode, false); |
| | | } |
| | | else if (data.paths != null) |
| | | { |
| | | AssetBundleModel.Model.MoveAssetToBundle(data.paths, targetDataBundle.m_Name.bundleName, targetDataBundle.m_Name.variant); |
| | | AssetBundleModel.Model.ExecuteAssetMove(); |
| | | ReloadAndSelect(targetDataBundle.nameHashCode, false); |
| | | } |
| | | } |
| | | |
| | | } |
| | | else |
| | | { |
| | | var folder = data.targetNode.bundle as AssetBundleModel.BundleFolderInfo; |
| | | if (folder != null) |
| | | { |
| | | if (data.args.performDrop) |
| | | { |
| | | if (data.draggedNodes != null) |
| | | { |
| | | AssetBundleModel.Model.HandleBundleReparent(data.draggedNodes, folder); |
| | | Reload(); |
| | | } |
| | | else if (data.paths != null) |
| | | { |
| | | DragPathsToNewSpace(data.paths, folder); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | visualMode = DragAndDropVisualMode.Rejected; //must be a variantfolder |
| | | |
| | | } |
| | | return visualMode; |
| | | } |
| | | private DragAndDropVisualMode HandleDragDropBetween(DragAndDropData data) |
| | | { |
| | | DragAndDropVisualMode visualMode = DragAndDropVisualMode.Copy;//Move; |
| | | |
| | | var parent = (data.args.parentItem as AssetBundleModel.BundleTreeItem); |
| | | |
| | | if (parent != null) |
| | | { |
| | | var variantFolder = parent.bundle as AssetBundleModel.BundleVariantFolderInfo; |
| | | if (variantFolder != null) |
| | | return DragAndDropVisualMode.Rejected; |
| | | |
| | | if (data.args.performDrop) |
| | | { |
| | | var folder = parent.bundle as AssetBundleModel.BundleFolderConcreteInfo; |
| | | if (folder != null) |
| | | { |
| | | if (data.draggedNodes != null) |
| | | { |
| | | AssetBundleModel.Model.HandleBundleReparent(data.draggedNodes, folder); |
| | | Reload(); |
| | | } |
| | | else if (data.paths != null) |
| | | { |
| | | DragPathsToNewSpace(data.paths, folder); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return visualMode; |
| | | } |
| | | |
| | | private string[] dragToNewSpacePaths = null; |
| | | private AssetBundleModel.BundleFolderInfo dragToNewSpaceRoot = null; |
| | | private void DragPathsAsOneBundle() |
| | | { |
| | | var newBundle = AssetBundleModel.Model.CreateEmptyBundle(dragToNewSpaceRoot); |
| | | AssetBundleModel.Model.MoveAssetToBundle(dragToNewSpacePaths, newBundle.m_Name.bundleName, newBundle.m_Name.variant); |
| | | AssetBundleModel.Model.ExecuteAssetMove(); |
| | | ReloadAndSelect(newBundle.nameHashCode, true); |
| | | } |
| | | private void DragPathsAsManyBundles() |
| | | { |
| | | List<int> hashCodes = new List<int>(); |
| | | foreach (var assetPath in dragToNewSpacePaths) |
| | | { |
| | | var newBundle = AssetBundleModel.Model.CreateEmptyBundle(dragToNewSpaceRoot, System.IO.Path.GetFileNameWithoutExtension(assetPath).ToLower()); |
| | | AssetBundleModel.Model.MoveAssetToBundle(assetPath, newBundle.m_Name.bundleName, newBundle.m_Name.variant); |
| | | hashCodes.Add(newBundle.nameHashCode); |
| | | } |
| | | AssetBundleModel.Model.ExecuteAssetMove(); |
| | | ReloadAndSelect(hashCodes); |
| | | } |
| | | |
| | | private void DragPathsToNewSpace(string[] paths, AssetBundleModel.BundleFolderInfo root) |
| | | { |
| | | dragToNewSpacePaths = paths; |
| | | dragToNewSpaceRoot = root; |
| | | if (paths.Length > 1) |
| | | { |
| | | GenericMenu menu = new GenericMenu(); |
| | | menu.AddItem(new GUIContent("Create 1 Bundle"), false, DragPathsAsOneBundle); |
| | | var message = "Create "; |
| | | message += paths.Length; |
| | | message += " Bundles"; |
| | | menu.AddItem(new GUIContent(message), false, DragPathsAsManyBundles); |
| | | menu.ShowAsContext(); |
| | | } |
| | | else |
| | | DragPathsAsManyBundles(); |
| | | } |
| | | |
| | | protected override void SetupDragAndDrop(SetupDragAndDropArgs args) |
| | | { |
| | | DragAndDrop.PrepareStartDrag(); |
| | | |
| | | var selectedBundles = new List<AssetBundleModel.BundleInfo>(); |
| | | foreach (var id in args.draggedItemIDs) |
| | | { |
| | | var item = FindItem(id, rootItem) as AssetBundleModel.BundleTreeItem; |
| | | selectedBundles.Add(item.bundle); |
| | | } |
| | | DragAndDrop.paths = null; |
| | | DragAndDrop.objectReferences = m_EmptyObjectList.ToArray(); |
| | | DragAndDrop.SetGenericData("AssetBundleModel.BundleInfo", selectedBundles); |
| | | DragAndDrop.visualMode = DragAndDropVisualMode.Copy;//Move; |
| | | DragAndDrop.StartDrag("AssetBundleTree"); |
| | | } |
| | | |
| | | protected override bool CanStartDrag(CanStartDragArgs args) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | internal void Refresh() |
| | | { |
| | | var selection = GetSelection(); |
| | | Reload(); |
| | | SelectionChanged(selection); |
| | | } |
| | | |
| | | private void ReloadAndSelect(int hashCode, bool rename) |
| | | { |
| | | var selection = new List<int>(); |
| | | selection.Add(hashCode); |
| | | ReloadAndSelect(selection); |
| | | if(rename) |
| | | { |
| | | BeginRename(FindItem(hashCode, rootItem), 0.25f); |
| | | } |
| | | } |
| | | private void ReloadAndSelect(IList<int> hashCodes) |
| | | { |
| | | Reload(); |
| | | SetSelection(hashCodes, TreeViewSelectionOptions.RevealAndFrame); |
| | | SelectionChanged(hashCodes); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 32cb0432916e2e94f991f14040535d8d |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | using UnityEditorInternal; |
| | | using System.Collections.Generic; |
| | | using UnityEditor.IMGUI.Controls; |
| | | using System.Linq; |
| | | using System; |
| | | |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | internal class AssetListTree : TreeView |
| | | { |
| | | List<AssetBundleModel.BundleInfo> m_SourceBundles = new List<AssetBundleModel.BundleInfo>(); |
| | | AssetBundleManageTab m_Controller; |
| | | List<UnityEngine.Object> m_EmptyObjectList = new List<Object>(); |
| | | |
| | | public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState() |
| | | { |
| | | return new MultiColumnHeaderState(GetColumns()); |
| | | } |
| | | private static MultiColumnHeaderState.Column[] GetColumns() |
| | | { |
| | | var retVal = new MultiColumnHeaderState.Column[] { |
| | | new MultiColumnHeaderState.Column(), |
| | | new MultiColumnHeaderState.Column(), |
| | | new MultiColumnHeaderState.Column(), |
| | | new MultiColumnHeaderState.Column() |
| | | }; |
| | | retVal[0].headerContent = new GUIContent("Asset", "Short name of asset. For full name select asset and see message below"); |
| | | retVal[0].minWidth = 50; |
| | | retVal[0].width = 100; |
| | | retVal[0].maxWidth = 300; |
| | | retVal[0].headerTextAlignment = TextAlignment.Left; |
| | | retVal[0].canSort = true; |
| | | retVal[0].autoResize = true; |
| | | |
| | | retVal[1].headerContent = new GUIContent("Bundle", "Bundle name. 'auto' means asset was pulled in due to dependency"); |
| | | retVal[1].minWidth = 50; |
| | | retVal[1].width = 100; |
| | | retVal[1].maxWidth = 300; |
| | | retVal[1].headerTextAlignment = TextAlignment.Left; |
| | | retVal[1].canSort = true; |
| | | retVal[1].autoResize = true; |
| | | |
| | | retVal[2].headerContent = new GUIContent("Size", "Size on disk"); |
| | | retVal[2].minWidth = 30; |
| | | retVal[2].width = 75; |
| | | retVal[2].maxWidth = 100; |
| | | retVal[2].headerTextAlignment = TextAlignment.Left; |
| | | retVal[2].canSort = true; |
| | | retVal[2].autoResize = true; |
| | | |
| | | retVal[3].headerContent = new GUIContent("!", "Errors, Warnings, or Info"); |
| | | retVal[3].minWidth = 16; |
| | | retVal[3].width = 16; |
| | | retVal[3].maxWidth = 16; |
| | | retVal[3].headerTextAlignment = TextAlignment.Left; |
| | | retVal[3].canSort = true; |
| | | retVal[3].autoResize = false; |
| | | |
| | | return retVal; |
| | | } |
| | | enum MyColumns |
| | | { |
| | | Asset, |
| | | Bundle, |
| | | Size, |
| | | Message |
| | | } |
| | | public enum SortOption |
| | | { |
| | | Asset, |
| | | Bundle, |
| | | Size, |
| | | Message |
| | | } |
| | | SortOption[] m_SortOptions = |
| | | { |
| | | SortOption.Asset, |
| | | SortOption.Bundle, |
| | | SortOption.Size, |
| | | SortOption.Message |
| | | }; |
| | | |
| | | public AssetListTree(TreeViewState state, MultiColumnHeaderState mchs, AssetBundleManageTab ctrl ) : base(state, new MultiColumnHeader(mchs)) |
| | | { |
| | | m_Controller = ctrl; |
| | | showBorder = true; |
| | | showAlternatingRowBackgrounds = true; |
| | | DefaultStyles.label.richText = true; |
| | | multiColumnHeader.sortingChanged += OnSortingChanged; |
| | | } |
| | | |
| | | |
| | | public void Update() |
| | | { |
| | | bool dirty = false; |
| | | foreach (var bundle in m_SourceBundles) |
| | | { |
| | | dirty |= bundle.dirty; |
| | | } |
| | | if (dirty) |
| | | Reload(); |
| | | } |
| | | public override void OnGUI(Rect rect) |
| | | { |
| | | base.OnGUI(rect); |
| | | if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && rect.Contains(Event.current.mousePosition)) |
| | | { |
| | | SetSelection(new int[0], TreeViewSelectionOptions.FireSelectionChanged); |
| | | } |
| | | } |
| | | |
| | | |
| | | protected override IList<TreeViewItem> BuildRows(TreeViewItem root) |
| | | { |
| | | var rows = base.BuildRows(root); |
| | | SortIfNeeded(root, rows); |
| | | return rows; |
| | | } |
| | | |
| | | internal void SetSelectedBundles(IEnumerable<AssetBundleModel.BundleInfo> bundles) |
| | | { |
| | | m_Controller.SetSelectedItems(null); |
| | | m_SourceBundles = bundles.ToList(); |
| | | SetSelection(new List<int>()); |
| | | Reload(); |
| | | } |
| | | protected override TreeViewItem BuildRoot() |
| | | { |
| | | var root = AssetBundleModel.Model.CreateAssetListTreeView(m_SourceBundles); |
| | | return root; |
| | | } |
| | | |
| | | protected override void RowGUI(RowGUIArgs args) |
| | | { |
| | | for (int i = 0; i < args.GetNumVisibleColumns(); ++i) |
| | | CellGUI(args.GetCellRect(i), args.item as AssetBundleModel.AssetTreeItem, args.GetColumn(i), ref args); |
| | | } |
| | | |
| | | private void CellGUI(Rect cellRect, AssetBundleModel.AssetTreeItem item, int column, ref RowGUIArgs args) |
| | | { |
| | | Color oldColor = GUI.color; |
| | | CenterRectUsingSingleLineHeight(ref cellRect); |
| | | if(column != 3) |
| | | GUI.color = item.itemColor; |
| | | |
| | | switch (column) |
| | | { |
| | | case 0: |
| | | { |
| | | var iconRect = new Rect(cellRect.x + 1, cellRect.y + 1, cellRect.height - 2, cellRect.height - 2); |
| | | GUI.DrawTexture(iconRect, item.icon, ScaleMode.ScaleToFit); |
| | | DefaultGUI.Label( |
| | | new Rect(cellRect.x + iconRect.xMax + 1, cellRect.y, cellRect.width - iconRect.width, cellRect.height), |
| | | item.displayName, |
| | | args.selected, |
| | | args.focused); |
| | | } |
| | | break; |
| | | case 1: |
| | | DefaultGUI.Label(cellRect, item.asset.bundleName, args.selected, args.focused); |
| | | break; |
| | | case 2: |
| | | DefaultGUI.Label(cellRect, item.asset.GetSizeString(), args.selected, args.focused); |
| | | break; |
| | | case 3: |
| | | var icon = item.MessageIcon(); |
| | | if (icon != null) |
| | | { |
| | | var iconRect = new Rect(cellRect.x, cellRect.y, cellRect.height, cellRect.height); |
| | | GUI.DrawTexture(iconRect, icon, ScaleMode.ScaleToFit); |
| | | } |
| | | break; |
| | | } |
| | | GUI.color = oldColor; |
| | | } |
| | | |
| | | protected override void DoubleClickedItem(int id) |
| | | { |
| | | var assetItem = FindItem(id, rootItem) as AssetBundleModel.AssetTreeItem; |
| | | if (assetItem != null) |
| | | { |
| | | Object o = AssetDatabase.LoadAssetAtPath<Object>(assetItem.asset.fullAssetName); |
| | | EditorGUIUtility.PingObject(o); |
| | | Selection.activeObject = o; |
| | | } |
| | | } |
| | | |
| | | protected override void SelectionChanged(IList<int> selectedIds) |
| | | { |
| | | List<Object> selectedObjects = new List<Object>(); |
| | | List<AssetBundleModel.AssetInfo> selectedAssets = new List<AssetBundleModel.AssetInfo>(); |
| | | foreach (var id in selectedIds) |
| | | { |
| | | var assetItem = FindItem(id, rootItem) as AssetBundleModel.AssetTreeItem; |
| | | if (assetItem != null) |
| | | { |
| | | Object o = AssetDatabase.LoadAssetAtPath<Object>(assetItem.asset.fullAssetName); |
| | | selectedObjects.Add(o); |
| | | Selection.activeObject = o; |
| | | selectedAssets.Add(assetItem.asset); |
| | | } |
| | | } |
| | | m_Controller.SetSelectedItems(selectedAssets); |
| | | Selection.objects = selectedObjects.ToArray(); |
| | | } |
| | | protected override bool CanBeParent(TreeViewItem item) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | protected override bool CanStartDrag(CanStartDragArgs args) |
| | | { |
| | | args.draggedItemIDs = GetSelection(); |
| | | return true; |
| | | } |
| | | |
| | | protected override void SetupDragAndDrop(SetupDragAndDropArgs args) |
| | | { |
| | | DragAndDrop.PrepareStartDrag(); |
| | | DragAndDrop.objectReferences = m_EmptyObjectList.ToArray(); |
| | | List<AssetBundleModel.AssetTreeItem> items = |
| | | new List<AssetBundleModel.AssetTreeItem>(args.draggedItemIDs.Select(id => FindItem(id, rootItem) as AssetBundleModel.AssetTreeItem)); |
| | | DragAndDrop.paths = items.Select(a => a.asset.fullAssetName).ToArray(); |
| | | DragAndDrop.SetGenericData("AssetListTreeSource", this); |
| | | DragAndDrop.StartDrag("AssetListTree"); |
| | | } |
| | | |
| | | protected override DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args) |
| | | { |
| | | if(IsValidDragDrop(args)) |
| | | { |
| | | if (args.performDrop) |
| | | { |
| | | AssetBundleModel.Model.MoveAssetToBundle(DragAndDrop.paths, m_SourceBundles[0].m_Name.bundleName, m_SourceBundles[0].m_Name.variant); |
| | | AssetBundleModel.Model.ExecuteAssetMove(); |
| | | foreach (var bundle in m_SourceBundles) |
| | | { |
| | | bundle.RefreshAssetList(); |
| | | } |
| | | m_Controller.UpdateSelectedBundles(m_SourceBundles); |
| | | } |
| | | return DragAndDropVisualMode.Copy;//Move; |
| | | } |
| | | |
| | | return DragAndDropVisualMode.Rejected; |
| | | } |
| | | protected bool IsValidDragDrop(DragAndDropArgs args) |
| | | { |
| | | //can't do drag & drop if data source is read only |
| | | if (AssetBundles.AssetBundleModel.Model.DataSource.IsReadOnly ()) |
| | | return false; |
| | | |
| | | //can't drag onto none or >1 bundles |
| | | if (m_SourceBundles.Count == 0 || m_SourceBundles.Count > 1) |
| | | return false; |
| | | |
| | | //can't drag nothing |
| | | if (DragAndDrop.paths == null || DragAndDrop.paths.Length == 0) |
| | | return false; |
| | | |
| | | //can't drag into a folder |
| | | var folder = m_SourceBundles[0] as AssetBundleModel.BundleFolderInfo; |
| | | if (folder != null) |
| | | return false; |
| | | |
| | | var data = m_SourceBundles[0] as AssetBundleModel.BundleDataInfo; |
| | | if(data == null) |
| | | return false; // this should never happen. |
| | | |
| | | var thing = DragAndDrop.GetGenericData("AssetListTreeSource") as AssetListTree; |
| | | if (thing != null) |
| | | return false; |
| | | |
| | | if(data.IsEmpty()) |
| | | return true; |
| | | |
| | | |
| | | if (data.isSceneBundle) |
| | | { |
| | | foreach (var assetPath in DragAndDrop.paths) |
| | | { |
| | | if ((AssetDatabase.GetMainAssetTypeAtPath(assetPath) != typeof(SceneAsset)) && |
| | | (!AssetDatabase.IsValidFolder(assetPath))) |
| | | return false; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | foreach (var assetPath in DragAndDrop.paths) |
| | | { |
| | | if (AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(SceneAsset)) |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | |
| | | } |
| | | |
| | | protected override void ContextClickedItem(int id) |
| | | { |
| | | if (AssetBundleModel.Model.DataSource.IsReadOnly ()) { |
| | | return; |
| | | } |
| | | |
| | | List<AssetBundleModel.AssetTreeItem> selectedNodes = new List<AssetBundleModel.AssetTreeItem>(); |
| | | foreach(var nodeID in GetSelection()) |
| | | { |
| | | selectedNodes.Add(FindItem(nodeID, rootItem) as AssetBundleModel.AssetTreeItem); |
| | | } |
| | | |
| | | if(selectedNodes.Count > 0) |
| | | { |
| | | GenericMenu menu = new GenericMenu(); |
| | | menu.AddItem(new GUIContent("Remove asset(s) from bundle."), false, RemoveAssets, selectedNodes); |
| | | menu.ShowAsContext(); |
| | | } |
| | | |
| | | } |
| | | void RemoveAssets(object obj) |
| | | { |
| | | var selectedNodes = obj as List<AssetBundleModel.AssetTreeItem>; |
| | | var assets = new List<AssetBundleModel.AssetInfo>(); |
| | | //var bundles = new List<AssetBundleModel.BundleInfo>(); |
| | | foreach (var node in selectedNodes) |
| | | { |
| | | if (node.asset.bundleName != string.Empty) |
| | | assets.Add(node.asset); |
| | | } |
| | | AssetBundleModel.Model.MoveAssetToBundle(assets, string.Empty, string.Empty); |
| | | AssetBundleModel.Model.ExecuteAssetMove(); |
| | | foreach (var bundle in m_SourceBundles) |
| | | { |
| | | bundle.RefreshAssetList(); |
| | | } |
| | | m_Controller.UpdateSelectedBundles(m_SourceBundles); |
| | | //ReloadAndSelect(new List<int>()); |
| | | } |
| | | |
| | | protected override void KeyEvent() |
| | | { |
| | | if (m_SourceBundles.Count > 0 && Event.current.keyCode == KeyCode.Delete && GetSelection().Count > 0) |
| | | { |
| | | List<AssetBundleModel.AssetTreeItem> selectedNodes = new List<AssetBundleModel.AssetTreeItem>(); |
| | | foreach (var nodeID in GetSelection()) |
| | | { |
| | | selectedNodes.Add(FindItem(nodeID, rootItem) as AssetBundleModel.AssetTreeItem); |
| | | } |
| | | |
| | | RemoveAssets(selectedNodes); |
| | | } |
| | | } |
| | | void OnSortingChanged(MultiColumnHeader multiColumnHeader) |
| | | { |
| | | SortIfNeeded(rootItem, GetRows()); |
| | | } |
| | | void SortIfNeeded(TreeViewItem root, IList<TreeViewItem> rows) |
| | | { |
| | | if (rows.Count <= 1) |
| | | return; |
| | | |
| | | if (multiColumnHeader.sortedColumnIndex == -1) |
| | | return; |
| | | |
| | | SortByColumn(); |
| | | |
| | | rows.Clear(); |
| | | for (int i = 0; i < root.children.Count; i++) |
| | | rows.Add(root.children[i]); |
| | | |
| | | Repaint(); |
| | | } |
| | | void SortByColumn() |
| | | { |
| | | var sortedColumns = multiColumnHeader.state.sortedColumns; |
| | | |
| | | if (sortedColumns.Length == 0) |
| | | return; |
| | | |
| | | List<AssetBundleModel.AssetTreeItem> assetList = new List<AssetBundleModel.AssetTreeItem>(); |
| | | foreach(var item in rootItem.children) |
| | | { |
| | | assetList.Add(item as AssetBundleModel.AssetTreeItem); |
| | | } |
| | | var orderedItems = InitialOrder(assetList, sortedColumns); |
| | | |
| | | rootItem.children = orderedItems.Cast<TreeViewItem>().ToList(); |
| | | } |
| | | |
| | | IOrderedEnumerable<AssetBundleModel.AssetTreeItem> InitialOrder(IEnumerable<AssetBundleModel.AssetTreeItem> myTypes, int[] columnList) |
| | | { |
| | | SortOption sortOption = m_SortOptions[columnList[0]]; |
| | | bool ascending = multiColumnHeader.IsSortedAscending(columnList[0]); |
| | | switch (sortOption) |
| | | { |
| | | case SortOption.Asset: |
| | | return myTypes.Order(l => l.displayName, ascending); |
| | | case SortOption.Size: |
| | | return myTypes.Order(l => l.asset.fileSize, ascending); |
| | | case SortOption.Message: |
| | | return myTypes.Order(l => l.HighestMessageLevel(), ascending); |
| | | case SortOption.Bundle: |
| | | default: |
| | | return myTypes.Order(l => l.asset.bundleName, ascending); |
| | | } |
| | | |
| | | } |
| | | |
| | | private void ReloadAndSelect(IList<int> hashCodes) |
| | | { |
| | | Reload(); |
| | | SetSelection(hashCodes); |
| | | SelectionChanged(hashCodes); |
| | | } |
| | | } |
| | | static class MyExtensionMethods |
| | | { |
| | | public static IOrderedEnumerable<T> Order<T, TKey>(this IEnumerable<T> source, Func<T, TKey> selector, bool ascending) |
| | | { |
| | | if (ascending) |
| | | { |
| | | return source.OrderBy(selector); |
| | | } |
| | | else |
| | | { |
| | | return source.OrderByDescending(selector); |
| | | } |
| | | } |
| | | |
| | | public static IOrderedEnumerable<T> ThenBy<T, TKey>(this IOrderedEnumerable<T> source, Func<T, TKey> selector, bool ascending) |
| | | { |
| | | if (ascending) |
| | | { |
| | | return source.ThenBy(selector); |
| | | } |
| | | else |
| | | { |
| | | return source.ThenByDescending(selector); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 18a3570ba42065e47b3bc4b91c1b6fa7 |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | using UnityEditorInternal; |
| | | using System.Collections.Generic; |
| | | using UnityEditor.IMGUI.Controls; |
| | | using System.Linq; |
| | | using System; |
| | | |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | internal class BundleDetailItem : TreeViewItem |
| | | { |
| | | public BundleDetailItem(int id, int depth, string displayName, MessageType type) : base(id, depth, displayName) |
| | | { |
| | | MessageLevel = type; |
| | | } |
| | | |
| | | public MessageType MessageLevel |
| | | { get; set; } |
| | | } |
| | | internal class BundleDetailList : TreeView |
| | | { |
| | | HashSet<AssetBundleModel.BundleDataInfo> m_Selecteditems; |
| | | Rect m_TotalRect; |
| | | |
| | | const float k_DoubleIndent = 32f; |
| | | const string k_SizeHeader = "Size: "; |
| | | const string k_DependencyHeader = "Dependent On:"; |
| | | const string k_DependencyEmpty = k_DependencyHeader + " - None"; |
| | | const string k_MessageHeader = "Messages:"; |
| | | const string k_MessageEmpty = k_MessageHeader + " - None"; |
| | | |
| | | |
| | | public BundleDetailList(TreeViewState state) : base(state) |
| | | { |
| | | m_Selecteditems = new HashSet<AssetBundleModel.BundleDataInfo>(); |
| | | showBorder = true; |
| | | } |
| | | public void Update() |
| | | { |
| | | bool dirty = false; |
| | | foreach (var bundle in m_Selecteditems) |
| | | { |
| | | dirty |= bundle.dirty; |
| | | } |
| | | if (dirty) |
| | | { |
| | | Reload(); |
| | | ExpandAll(); |
| | | } |
| | | } |
| | | protected override TreeViewItem BuildRoot() |
| | | { |
| | | var root = new TreeViewItem(-1, -1); |
| | | root.children = new List<TreeViewItem>(); |
| | | if (m_Selecteditems != null) |
| | | { |
| | | foreach(var bundle in m_Selecteditems) |
| | | { |
| | | root.AddChild(AppendBundleToTree(bundle)); |
| | | } |
| | | } |
| | | return root; |
| | | } |
| | | |
| | | protected override void RowGUI(RowGUIArgs args) |
| | | { |
| | | if ((args.item as BundleDetailItem) != null) |
| | | { |
| | | EditorGUI.HelpBox( |
| | | new Rect(args.rowRect.x + k_DoubleIndent, args.rowRect.y, args.rowRect.width - k_DoubleIndent, args.rowRect.height), |
| | | args.item.displayName, |
| | | (args.item as BundleDetailItem).MessageLevel); |
| | | } |
| | | else |
| | | { |
| | | Color old = GUI.color; |
| | | if (args.item.depth == 1 && |
| | | (args.item.displayName == k_MessageEmpty || args.item.displayName == k_DependencyEmpty)) |
| | | GUI.color = AssetBundleModel.Model.k_LightGrey; |
| | | base.RowGUI(args); |
| | | GUI.color = old; |
| | | } |
| | | } |
| | | public override void OnGUI(Rect rect) |
| | | { |
| | | m_TotalRect = rect; |
| | | base.OnGUI(rect); |
| | | } |
| | | protected override float GetCustomRowHeight(int row, TreeViewItem item) |
| | | { |
| | | if( (item as BundleDetailItem) != null) |
| | | { |
| | | float height = DefaultStyles.backgroundEven.CalcHeight(new GUIContent(item.displayName), m_TotalRect.width); |
| | | return height + 3f; |
| | | } |
| | | return base.GetCustomRowHeight(row, item); |
| | | } |
| | | |
| | | |
| | | internal TreeViewItem AppendBundleToTree(AssetBundleModel.BundleDataInfo bundle) |
| | | { |
| | | var itemName = bundle.m_Name.fullNativeName; |
| | | var bunRoot = new TreeViewItem(itemName.GetHashCode(), 0, itemName); |
| | | |
| | | var str = itemName + k_SizeHeader; |
| | | var sz = new TreeViewItem(str.GetHashCode(), 1, k_SizeHeader + bundle.TotalSize()); |
| | | |
| | | str = itemName + k_DependencyHeader; |
| | | var dependency = new TreeViewItem(str.GetHashCode(), 1, k_DependencyEmpty); |
| | | var depList = bundle.GetBundleDependencies(); |
| | | if(depList.Count > 0) |
| | | { |
| | | dependency.displayName = k_DependencyHeader; |
| | | foreach (var dep in bundle.GetBundleDependencies()) |
| | | { |
| | | str = itemName + dep; |
| | | dependency.AddChild(new TreeViewItem(str.GetHashCode(), 2, dep)); |
| | | } |
| | | } |
| | | |
| | | str = itemName + k_MessageHeader; |
| | | var msg = new TreeViewItem(str.GetHashCode(), 1, k_MessageEmpty); |
| | | if (bundle.HasMessages()) |
| | | { |
| | | msg.displayName = k_MessageHeader; |
| | | var currMessages = bundle.GetMessages(); |
| | | |
| | | foreach(var currMsg in currMessages) |
| | | { |
| | | str = itemName + currMsg.message; |
| | | msg.AddChild(new BundleDetailItem(str.GetHashCode(), 2, currMsg.message, currMsg.severity)); |
| | | } |
| | | } |
| | | |
| | | |
| | | bunRoot.AddChild(sz); |
| | | bunRoot.AddChild(dependency); |
| | | bunRoot.AddChild(msg); |
| | | |
| | | return bunRoot; |
| | | } |
| | | |
| | | |
| | | |
| | | internal void SetItems(IEnumerable<AssetBundleModel.BundleInfo> items) |
| | | { |
| | | m_Selecteditems.Clear(); |
| | | foreach(var item in items) |
| | | { |
| | | CollectBundles(item); |
| | | } |
| | | SetSelection(new List<int>()); |
| | | Reload(); |
| | | ExpandAll(); |
| | | } |
| | | internal void CollectBundles(AssetBundleModel.BundleInfo bundle) |
| | | { |
| | | var bunData = bundle as AssetBundleModel.BundleDataInfo; |
| | | if (bunData != null) |
| | | m_Selecteditems.Add(bunData); |
| | | else |
| | | { |
| | | var bunFolder = bundle as AssetBundleModel.BundleFolderInfo; |
| | | foreach (var bun in bunFolder.GetChildList()) |
| | | { |
| | | CollectBundles(bun); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 7c62cc7d8f2f5a94290ec50aa5195dee |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 08c232e713e870a4db3d8f89985d8009 |
| | | folderAsset: yes |
| | | timeCreated: 1499908885 |
| | | licenseType: Pro |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: cfb66cdcbb6d96c4ab5bed7d7101cfa2 |
| | | timeCreated: 1499908888 |
| | | licenseType: Pro |
| | | TextureImporter: |
| | | fileIDToRecycleName: {} |
| | | serializedVersion: 4 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 1 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: 1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -1 |
| | | wrapMode: -1 |
| | | nPOTScale: 1 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 0 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spritePixelsToUnits: 100 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 0 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 0 |
| | | textureShape: 1 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | platformSettings: |
| | | - buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | spritePackingTag: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 54684548eedd3744abd8030b861fae40 |
| | | timeCreated: 1499908887 |
| | | licenseType: Pro |
| | | TextureImporter: |
| | | fileIDToRecycleName: {} |
| | | serializedVersion: 4 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 1 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: 1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -1 |
| | | wrapMode: -1 |
| | | nPOTScale: 1 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 0 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spritePixelsToUnits: 100 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 0 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 0 |
| | | textureShape: 1 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | platformSettings: |
| | | - buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | spritePackingTag: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 390759a6bd7b0e64791496f154446dd0 |
| | | folderAsset: yes |
| | | timeCreated: 1499908885 |
| | | licenseType: Pro |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | using UnityEditor.IMGUI.Controls; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Runtime.Serialization.Formatters.Binary; |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | [System.Serializable] |
| | | public class AssetBundleInspectTab |
| | | { |
| | | Rect m_Position; |
| | | [SerializeField] |
| | | private Vector2 m_ScrollPosition; |
| | | |
| | | [SerializeField] |
| | | private InspectTabData m_Data; |
| | | |
| | | |
| | | private List<string> m_BundleList = new List<string>(); |
| | | private InspectBundleTree m_BundleTreeView; |
| | | [SerializeField] |
| | | private TreeViewState m_BundleTreeState; |
| | | |
| | | public Editor m_Editor = null; |
| | | |
| | | //[SerializeField] |
| | | private List<AssetBundle> m_LoadedBundles; |
| | | |
| | | private SingleBundleInspector m_SingleInspector; |
| | | |
| | | |
| | | public AssetBundleInspectTab() |
| | | { |
| | | m_LoadedBundles = new List<AssetBundle>(); |
| | | m_SingleInspector = new SingleBundleInspector(); |
| | | } |
| | | |
| | | public void SaveBundle(AssetBundle b) |
| | | { |
| | | m_LoadedBundles.Add(b); |
| | | } |
| | | |
| | | public void OnEnable(Rect pos, EditorWindow parent) |
| | | { |
| | | m_Position = pos; |
| | | if (m_Data == null) |
| | | m_Data = new InspectTabData(); |
| | | |
| | | //LoadData... |
| | | var dataPath = System.IO.Path.GetFullPath("."); |
| | | dataPath = dataPath.Replace("\\", "/"); |
| | | dataPath += "/Library/AssetBundleBrowserInspect.dat"; |
| | | |
| | | if (File.Exists(dataPath)) |
| | | { |
| | | BinaryFormatter bf = new BinaryFormatter(); |
| | | FileStream file = File.Open(dataPath, FileMode.Open); |
| | | var data = bf.Deserialize(file) as InspectTabData; |
| | | if (data != null) |
| | | m_Data = data; |
| | | file.Close(); |
| | | } |
| | | |
| | | |
| | | if (m_BundleList == null) |
| | | m_BundleList = new List<string>(); |
| | | |
| | | if (m_BundleTreeState == null) |
| | | m_BundleTreeState = new TreeViewState(); |
| | | m_BundleTreeView = new InspectBundleTree(m_BundleTreeState, this); |
| | | m_BundleTreeView.Reload(); |
| | | |
| | | |
| | | RefreshBundles(); |
| | | |
| | | } |
| | | |
| | | public void OnDisable() |
| | | { |
| | | ClearData(); |
| | | |
| | | var dataPath = System.IO.Path.GetFullPath("."); |
| | | dataPath = dataPath.Replace("\\", "/"); |
| | | dataPath += "/Library/AssetBundleBrowserInspect.dat"; |
| | | |
| | | BinaryFormatter bf = new BinaryFormatter(); |
| | | FileStream file = File.Create(dataPath); |
| | | |
| | | bf.Serialize(file, m_Data); |
| | | file.Close(); |
| | | } |
| | | |
| | | public void OnGUI(Rect pos) |
| | | { |
| | | m_Position = pos; |
| | | |
| | | if (Application.isPlaying) |
| | | { |
| | | var style = GUI.skin.label; |
| | | style.alignment = TextAnchor.MiddleCenter; |
| | | style.wordWrap = true; |
| | | GUI.Label( |
| | | new Rect(m_Position.x + 1f, m_Position.y + 1f, m_Position.width - 2f, m_Position.height - 2f), |
| | | new GUIContent("Inspector unavailable while in PLAY mode"), |
| | | style); |
| | | } |
| | | else |
| | | { |
| | | OnGUIEditor(); |
| | | } |
| | | } |
| | | |
| | | private void OnGUIEditor() |
| | | { |
| | | //////input path |
| | | EditorGUILayout.Space(); |
| | | GUILayout.BeginHorizontal(); |
| | | var originalPath = m_Data.m_BundlePath; |
| | | m_Data.m_BundlePath = EditorGUILayout.TextField("Bundle Path", m_Data.m_BundlePath); |
| | | |
| | | if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f))) |
| | | BrowseForFolder(); |
| | | GUILayout.EndHorizontal(); |
| | | EditorGUILayout.Space(); |
| | | |
| | | if (originalPath != m_Data.m_BundlePath) |
| | | { |
| | | RefreshBundles(); |
| | | } |
| | | |
| | | if (m_BundleList.Count > 0) |
| | | { |
| | | m_BundleTreeView.OnGUI(new Rect(m_Position.x, m_Position.y + 30, m_Position.width / 2.0f, m_Position.height - 30)); |
| | | m_SingleInspector.OnGUI(new Rect(m_Position.x + m_Position.width / 2.0f, m_Position.y + 30, m_Position.width / 2.0f, m_Position.height - 30)); |
| | | } |
| | | } |
| | | |
| | | //TODO - this is largely copied from BuildTab, should maybe be shared code. |
| | | private void BrowseForFolder() |
| | | { |
| | | var newPath = EditorUtility.OpenFolderPanel("Bundle Folder", m_Data.m_BundlePath, string.Empty); |
| | | if (!string.IsNullOrEmpty(newPath)) |
| | | { |
| | | var gamePath = System.IO.Path.GetFullPath(".");//TODO - FileUtil.GetProjectRelativePath?? |
| | | gamePath = gamePath.Replace("\\", "/"); |
| | | if (newPath.StartsWith(gamePath)) |
| | | newPath = newPath.Remove(0, gamePath.Length + 1); |
| | | m_Data.m_BundlePath = newPath; |
| | | } |
| | | } |
| | | public void RefreshBundles() |
| | | { |
| | | ClearData(); |
| | | |
| | | //DesignDebug.Log("Did someone say refresh?"); |
| | | //do some loading |
| | | LoadBundles(); |
| | | } |
| | | private void ClearData() |
| | | { |
| | | m_SingleInspector.SetBundle(null); |
| | | |
| | | foreach (var bundle in m_LoadedBundles) |
| | | { |
| | | if (bundle != null) //get into this situation on a rare restart weirdness. |
| | | bundle.Unload(true); |
| | | } |
| | | m_LoadedBundles.Clear(); |
| | | } |
| | | private void AddFilePathToList(string path) |
| | | { |
| | | ////////////////////////////////////// |
| | | /// code to handle appended hash things |
| | | //var files = Directory.GetFiles(path); |
| | | //Array.Sort(files); |
| | | //int size = files.Length; |
| | | //for (int i = 0; i < size; i++) |
| | | //{ |
| | | // ... do something... |
| | | //} |
| | | ////////////////////////////////////// |
| | | |
| | | |
| | | foreach (var file in Directory.GetFiles(path)) |
| | | { |
| | | if (Path.GetExtension(file) == ".manifest") |
| | | { |
| | | var f = file.Substring(0, file.LastIndexOf('.')).Replace('\\', '/'); |
| | | if (File.Exists(f)) |
| | | m_BundleList.Add(f); |
| | | else |
| | | DebugEx.Log("Expected bundle not found: " + f + ". Note: Browser does not yet support inspecting bundles with hash appended."); |
| | | } |
| | | } |
| | | |
| | | foreach (var dir in Directory.GetDirectories(path)) |
| | | { |
| | | AddFilePathToList(dir); |
| | | } |
| | | } |
| | | private void LoadBundles() |
| | | { |
| | | if (m_Data.m_BundlePath == string.Empty) |
| | | return; |
| | | |
| | | //find assets |
| | | if (m_BundleList == null) |
| | | m_BundleList = new List<string>(); |
| | | |
| | | m_BundleList.Clear(); |
| | | if (Directory.Exists(m_Data.m_BundlePath)) |
| | | { |
| | | AddFilePathToList(m_Data.m_BundlePath); |
| | | } |
| | | m_BundleTreeView.Reload(); |
| | | } |
| | | |
| | | public List<string> BundleList |
| | | { get { return m_BundleList; } } |
| | | |
| | | |
| | | public void SetBundleItem(InspectTreeItem selected) |
| | | { |
| | | if (selected == null) |
| | | m_SingleInspector.SetBundle(null); |
| | | else |
| | | m_SingleInspector.SetBundle(selected.bundle, selected.bundlePath); |
| | | } |
| | | |
| | | [System.Serializable] |
| | | public class InspectTabData |
| | | { |
| | | public string m_BundlePath = string.Empty; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 390e28c21cef1024a87a0e52278e0314 |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | using UnityEditor.IMGUI.Controls; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System; |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | class SingleBundleInspector |
| | | { |
| | | public static string currentPath { get; set; } |
| | | |
| | | |
| | | public SingleBundleInspector() { } |
| | | |
| | | private Editor m_Editor = null; |
| | | |
| | | private Rect m_Position; |
| | | |
| | | [SerializeField] |
| | | private Vector2 m_ScrollPosition; |
| | | |
| | | public void SetBundle(AssetBundle bundle, string path = "") |
| | | { |
| | | //static var... |
| | | currentPath = path; |
| | | |
| | | //members |
| | | m_Editor = null; |
| | | if (bundle != null) |
| | | m_Editor = Editor.CreateEditor(bundle); |
| | | } |
| | | |
| | | public void OnGUI(Rect pos) |
| | | { |
| | | if (m_Editor == null) |
| | | return; |
| | | |
| | | m_Position = pos; |
| | | |
| | | DrawBundleData(); |
| | | } |
| | | |
| | | private void DrawBundleData() |
| | | { |
| | | GUILayout.BeginArea(m_Position); |
| | | m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition); |
| | | m_Editor.OnInspectorGUI(); |
| | | EditorGUILayout.EndScrollView(); |
| | | GUILayout.EndArea(); |
| | | } |
| | | } |
| | | |
| | | [CustomEditor(typeof(AssetBundle))] |
| | | public class LevelScriptEditor : Editor |
| | | { |
| | | public override void OnInspectorGUI() |
| | | { |
| | | AssetBundle bundle = target as AssetBundle; |
| | | |
| | | using (new EditorGUI.DisabledScope(true)) |
| | | { |
| | | var leftStyle = GUI.skin.GetStyle("Label"); |
| | | leftStyle.alignment = TextAnchor.UpperLeft; |
| | | GUILayout.Label(new GUIContent("Name: " + bundle.name), leftStyle); |
| | | |
| | | long fileSize = -1; |
| | | if(SingleBundleInspector.currentPath != string.Empty && File.Exists(SingleBundleInspector.currentPath) ) |
| | | { |
| | | System.IO.FileInfo fileInfo = new System.IO.FileInfo(SingleBundleInspector.currentPath); |
| | | fileSize = fileInfo.Length; |
| | | } |
| | | |
| | | if (fileSize < 0) |
| | | GUILayout.Label(new GUIContent("Size: unknown"), leftStyle); |
| | | else |
| | | GUILayout.Label(new GUIContent("Size: " + EditorUtility.FormatBytes(fileSize)), leftStyle); |
| | | |
| | | } |
| | | |
| | | base.OnInspectorGUI(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 32505061201db464096788f93e39fe4d |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | using UnityEditor.IMGUI.Controls; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System; |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | public class InspectTreeItem : TreeViewItem |
| | | { |
| | | private string m_BundlePath; |
| | | public string bundlePath |
| | | { |
| | | get { return m_BundlePath; } |
| | | } |
| | | private AssetBundle m_Bundle; |
| | | |
| | | private AssetBundleInspectTab m_InspectTab; |
| | | //public InspectTreeItem(int id, int depth, string displayName) : base(id, depth, displayName) |
| | | public InspectTreeItem(string path, AssetBundleInspectTab inspectTab) : base(path.GetHashCode(), 0, path) |
| | | { |
| | | m_BundlePath = path; |
| | | m_Bundle = null; |
| | | m_InspectTab = inspectTab; |
| | | } |
| | | public AssetBundle bundle |
| | | { |
| | | get |
| | | { |
| | | if (m_Bundle == null) |
| | | LoadBundle(); |
| | | return m_Bundle; |
| | | } |
| | | } |
| | | public void LoadBundle() |
| | | { |
| | | if (m_Bundle == null) |
| | | { |
| | | m_Bundle = AssetBundle.LoadFromFile(m_BundlePath); |
| | | m_InspectTab.SaveBundle(m_Bundle); |
| | | |
| | | //AssetBundleManifest manifest = m_Bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); |
| | | //if (manifest != null) |
| | | //{ |
| | | // //this is where we could get some overall data. if we wanted it. which we might. someday. |
| | | //} |
| | | |
| | | |
| | | //gotta actually load assets to keep inspector from crashing :( |
| | | var content = m_Bundle.GetAllAssetNames(); |
| | | foreach (var c in content) |
| | | { |
| | | m_Bundle.LoadAsset(c); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | class InspectBundleTree : TreeView |
| | | { |
| | | AssetBundleInspectTab m_InspectTab; |
| | | public InspectBundleTree(TreeViewState s, AssetBundleInspectTab parent) : base(s) |
| | | { |
| | | m_InspectTab = parent; |
| | | showBorder = true; |
| | | } |
| | | |
| | | protected override TreeViewItem BuildRoot() |
| | | { |
| | | var root = new TreeViewItem(-1, -1); |
| | | root.children = new List<TreeViewItem>(); |
| | | if (m_InspectTab == null) |
| | | DebugEx.Log("Unknown problem in AssetBundle Browser Inspect tab. Restart Browser and try again, or file ticket on github."); |
| | | else |
| | | { |
| | | foreach (var b in m_InspectTab.BundleList) |
| | | { |
| | | root.AddChild(new InspectTreeItem(b, m_InspectTab)); |
| | | } |
| | | } |
| | | return root; |
| | | } |
| | | |
| | | public override void OnGUI(Rect rect) |
| | | { |
| | | base.OnGUI(rect); |
| | | if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && rect.Contains(Event.current.mousePosition)) |
| | | { |
| | | SetSelection(new int[0], TreeViewSelectionOptions.FireSelectionChanged); |
| | | } |
| | | } |
| | | |
| | | protected override void SelectionChanged(IList<int> selectedIds) |
| | | { |
| | | base.SelectionChanged(selectedIds); |
| | | |
| | | if (selectedIds.Count > 0) |
| | | { |
| | | m_InspectTab.SetBundleItem(FindItem(selectedIds[0], rootItem) as InspectTreeItem); |
| | | } |
| | | else |
| | | m_InspectTab.SetBundleItem(null); |
| | | } |
| | | |
| | | protected override bool CanMultiSelect(TreeViewItem item) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: adb20806b5333c64aa5e67e4f9343622 |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEditor; |
| | | using UnityEditorInternal; |
| | | using System.Collections.Generic; |
| | | using UnityEditor.IMGUI.Controls; |
| | | using System.Linq; |
| | | using System; |
| | | |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | internal class MessageList |
| | | { |
| | | private Vector2 m_ScrollPosition = Vector2.zero; |
| | | |
| | | private GUIStyle[] m_Style = new GUIStyle[2]; |
| | | |
| | | IEnumerable<AssetBundleModel.AssetInfo> m_Selecteditems; |
| | | List<MessageSystem.Message> m_Messages; |
| | | |
| | | Vector2 m_Dimensions = new Vector2(0, 0); |
| | | const float k_ScrollbarPadding = 16f; |
| | | const float k_BorderSize = 1f; |
| | | |
| | | |
| | | public MessageList() |
| | | { |
| | | Init(); |
| | | } |
| | | private void Init() |
| | | { |
| | | m_Style[0] = "OL EntryBackOdd"; |
| | | m_Style[1] = "OL EntryBackEven"; |
| | | m_Style[0].wordWrap = true; |
| | | m_Style[1].wordWrap = true; |
| | | m_Style[0].padding = new RectOffset(32, 0, 1, 4); |
| | | m_Style[1].padding = new RectOffset(32, 0, 1, 4); |
| | | m_Messages = new List<MessageSystem.Message>(); |
| | | |
| | | } |
| | | public void OnGUI(Rect fullPos) |
| | | { |
| | | DrawOutline(fullPos, 1f); |
| | | |
| | | Rect pos = new Rect(fullPos.x + k_BorderSize, fullPos.y + k_BorderSize, fullPos.width - 2 * k_BorderSize, fullPos.height - 2 * k_BorderSize); |
| | | |
| | | |
| | | if (m_Dimensions.y == 0 || m_Dimensions.x != pos.width - k_ScrollbarPadding) |
| | | { |
| | | //recalculate height. |
| | | m_Dimensions.x = pos.width - k_ScrollbarPadding; |
| | | m_Dimensions.y = 0; |
| | | foreach (var message in m_Messages) |
| | | { |
| | | m_Dimensions.y += m_Style[0].CalcHeight(new GUIContent(message.message), m_Dimensions.x); |
| | | } |
| | | } |
| | | |
| | | m_ScrollPosition = GUI.BeginScrollView(pos, m_ScrollPosition, new Rect(0, 0, m_Dimensions.x, m_Dimensions.y)); |
| | | int counter = 0; |
| | | float runningHeight = 0.0f; |
| | | foreach (var message in m_Messages) |
| | | { |
| | | int index = counter % 2; |
| | | var content = new GUIContent(message.message); |
| | | float height = m_Style[index].CalcHeight(content, m_Dimensions.x); |
| | | |
| | | GUI.Box(new Rect(0, runningHeight, m_Dimensions.x, height), content, m_Style[index]); |
| | | GUI.DrawTexture(new Rect(0, runningHeight, 32f, 32f), message.icon); |
| | | //TODO - cleanup formatting issues and switch to HelpBox |
| | | //EditorGUI.HelpBox(new Rect(0, runningHeight, m_dimensions.x, height), message.message, (MessageType)message.severity); |
| | | |
| | | counter++; |
| | | runningHeight += height; |
| | | } |
| | | GUI.EndScrollView(); |
| | | } |
| | | |
| | | internal void SetItems(IEnumerable<AssetBundleModel.AssetInfo> items) |
| | | { |
| | | m_Selecteditems = items; |
| | | CollectMessages(); |
| | | } |
| | | |
| | | internal void CollectMessages() |
| | | { |
| | | m_Messages.Clear(); |
| | | m_Dimensions.y = 0f; |
| | | if(m_Selecteditems != null) |
| | | { |
| | | foreach (var asset in m_Selecteditems) |
| | | { |
| | | m_Messages.AddRange(asset.GetMessages()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | internal void DrawOutline(Rect rect, float size) |
| | | { |
| | | Color color = new Color(0.6f, 0.6f, 0.6f, 1.333f); |
| | | if(EditorGUIUtility.isProSkin) |
| | | { |
| | | color.r = 0.12f; |
| | | color.g = 0.12f; |
| | | color.b = 0.12f; |
| | | } |
| | | |
| | | if (Event.current.type != EventType.Repaint) |
| | | return; |
| | | |
| | | Color orgColor = GUI.color; |
| | | GUI.color = GUI.color * color; |
| | | GUI.DrawTexture(new Rect(rect.x, rect.y, rect.width, size), EditorGUIUtility.whiteTexture); |
| | | GUI.DrawTexture(new Rect(rect.x, rect.yMax - size, rect.width, size), EditorGUIUtility.whiteTexture); |
| | | GUI.DrawTexture(new Rect(rect.x, rect.y + 1, size, rect.height - 2 * size), EditorGUIUtility.whiteTexture); |
| | | GUI.DrawTexture(new Rect(rect.xMax - size, rect.y + 1, size, rect.height - 2 * size), EditorGUIUtility.whiteTexture); |
| | | |
| | | GUI.color = orgColor; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: e71964deafc80d94489d3315d34b579d |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using UnityEngine; |
| | | using UnityEditor; |
| | | using UnityEngine.Assertions; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using UnityEditor.IMGUI.Controls; |
| | | |
| | | namespace UnityEngine.AssetBundles |
| | | { |
| | | public class MessageSystem |
| | | { |
| | | private static Texture2D m_ErrorIcon = null; |
| | | private static Texture2D m_WarningIcon = null; |
| | | private static Texture2D m_InfoIcon = null; |
| | | private static Dictionary<MessageFlag, Message> m_MessageLookup = null; |
| | | |
| | | [Flags] |
| | | public enum MessageFlag |
| | | { |
| | | None = 0x0, |
| | | |
| | | Info = 0x80, //this flag is only used to check bits, not set. |
| | | EmptyBundle = 0x81, |
| | | EmptyFolder = 0x82, |
| | | |
| | | Warning = 0x8000, //this flag is only used to check bits, not set. |
| | | WarningInChildren = 0x8100, |
| | | AssetsDuplicatedInMultBundles = 0x8200, |
| | | VariantBundleMismatch = 0x8400, |
| | | |
| | | Error = 0x800000, //this flag is only used to check bits, not set. |
| | | ErrorInChildren = 0x810000, |
| | | SceneBundleConflict = 0x820000, |
| | | DependencySceneConflict = 0x840000, |
| | | } |
| | | |
| | | public class MessageState |
| | | { |
| | | //I have an enum and a set of enums to make some logic cleaner. |
| | | // The enum has masks for Error/Warning/Info that won't ever be in the set |
| | | // this allows for easy checking of IsSet for error rather than specific errors. |
| | | private MessageFlag m_MessageFlags; |
| | | private HashSet<MessageFlag> m_MessageSet; |
| | | |
| | | |
| | | public MessageState() |
| | | { |
| | | m_MessageFlags = MessageFlag.None; |
| | | m_MessageSet = new HashSet<MessageFlag>(); |
| | | } |
| | | |
| | | public void Clear() |
| | | { |
| | | m_MessageFlags = MessageFlag.None; |
| | | m_MessageSet.Clear(); |
| | | } |
| | | |
| | | public void SetFlag(MessageFlag flag, bool on) |
| | | { |
| | | if (flag == MessageFlag.Info || flag == MessageFlag.Warning || flag == MessageFlag.Error) |
| | | return; |
| | | |
| | | if (on) |
| | | { |
| | | m_MessageFlags |= flag; |
| | | m_MessageSet.Add(flag); |
| | | } |
| | | else |
| | | { |
| | | m_MessageFlags &= ~flag; |
| | | m_MessageSet.Remove(flag); |
| | | } |
| | | } |
| | | public bool IsSet(MessageFlag flag) |
| | | { |
| | | return (m_MessageFlags & flag) == flag; |
| | | } |
| | | public bool HasMessages() |
| | | { |
| | | return (m_MessageFlags != MessageFlag.None); |
| | | } |
| | | |
| | | public MessageType HighestMessageLevel() |
| | | { |
| | | if (IsSet(MessageFlag.Error)) |
| | | return MessageType.Error; |
| | | if (IsSet(MessageFlag.Warning)) |
| | | return MessageType.Warning; |
| | | if (IsSet(MessageFlag.Info)) |
| | | return MessageType.Info; |
| | | return MessageType.None; |
| | | } |
| | | public MessageFlag HighestMessageFlag() |
| | | { |
| | | MessageFlag high = MessageFlag.None; |
| | | foreach(var f in m_MessageSet) |
| | | { |
| | | if (f > high) |
| | | high = f; |
| | | } |
| | | return high; |
| | | } |
| | | |
| | | public List<Message> GetMessages() |
| | | { |
| | | var msgs = new List<Message>(); |
| | | foreach(var f in m_MessageSet) |
| | | { |
| | | msgs.Add(GetMessage(f)); |
| | | } |
| | | return msgs; |
| | | } |
| | | } |
| | | public static Texture2D GetIcon(MessageType sev) |
| | | { |
| | | if (sev == MessageType.Error) |
| | | return GetErrorIcon(); |
| | | else if (sev == MessageType.Warning) |
| | | return GetWarningIcon(); |
| | | else if (sev == MessageType.Info) |
| | | return GetInfoIcon(); |
| | | else |
| | | return null; |
| | | } |
| | | private static Texture2D GetErrorIcon() |
| | | { |
| | | if (m_ErrorIcon == null) |
| | | FindMessageIcons(); |
| | | return m_ErrorIcon; |
| | | } |
| | | private static Texture2D GetWarningIcon() |
| | | { |
| | | if (m_WarningIcon == null) |
| | | FindMessageIcons(); |
| | | return m_WarningIcon; |
| | | } |
| | | private static Texture2D GetInfoIcon() |
| | | { |
| | | if (m_InfoIcon == null) |
| | | FindMessageIcons(); |
| | | return m_InfoIcon; |
| | | } |
| | | |
| | | private static void FindMessageIcons() |
| | | { |
| | | m_ErrorIcon = EditorGUIUtility.FindTexture("console.errorIcon"); |
| | | m_WarningIcon = EditorGUIUtility.FindTexture("console.warnicon"); |
| | | m_InfoIcon = EditorGUIUtility.FindTexture("console.infoIcon"); |
| | | } |
| | | public class Message |
| | | { |
| | | public Message(string msg, MessageType sev) |
| | | { |
| | | message = msg; |
| | | severity = sev; |
| | | } |
| | | |
| | | public MessageType severity; |
| | | public string message; |
| | | public Texture2D icon |
| | | { |
| | | get |
| | | { |
| | | return GetIcon(severity); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static Message GetMessage(MessageFlag lookup) |
| | | { |
| | | if (m_MessageLookup == null) |
| | | InitMessages(); |
| | | |
| | | Message msg = null; |
| | | m_MessageLookup.TryGetValue(lookup, out msg); |
| | | if (msg == null) |
| | | msg = m_MessageLookup[MessageFlag.None]; |
| | | return msg; |
| | | } |
| | | |
| | | private static void InitMessages() |
| | | { |
| | | m_MessageLookup = new Dictionary<MessageFlag, Message>(); |
| | | |
| | | m_MessageLookup.Add(MessageFlag.None, new Message(string.Empty, MessageType.None)); |
| | | m_MessageLookup.Add(MessageFlag.EmptyBundle, new Message("This bundle is empty. Empty bundles cannot get saved with the scene and will disappear from this list if Unity restarts or if various other bundle rename or move events occur.", MessageType.Info)); |
| | | m_MessageLookup.Add(MessageFlag.EmptyFolder, new Message("This folder is either empty or contains only empty children. Empty bundles cannot get saved with the scene and will disappear from this list if Unity restarts or if various other bundle rename or move events occur.", MessageType.Info)); |
| | | m_MessageLookup.Add(MessageFlag.WarningInChildren, new Message("Warning in child(ren)", MessageType.Warning)); |
| | | m_MessageLookup.Add(MessageFlag.AssetsDuplicatedInMultBundles, new Message("Assets being pulled into this bundle due to dependencies are also being pulled into another bundle. This will cause duplication in memory", MessageType.Warning)); |
| | | m_MessageLookup.Add(MessageFlag.VariantBundleMismatch, new Message("Variants of a given bundle must have exactly the same assets between them based on a Name.Extension (without Path) comparison. These bundle variants fail that check.", MessageType.Warning)); |
| | | m_MessageLookup.Add(MessageFlag.ErrorInChildren, new Message("Error in child(ren)", MessageType.Error)); |
| | | m_MessageLookup.Add(MessageFlag.SceneBundleConflict, new Message("A bundle with one or more scenes must only contain scenes. This bundle has scenes and non-scene assets.", MessageType.Error)); |
| | | m_MessageLookup.Add(MessageFlag.DependencySceneConflict, new Message("The folder added to this bundle has pulled in scenes and non-scene assets. A bundle must only have one type or the other.", MessageType.Error)); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 4082a2bafddd01345ac7078067be0095 |
| | | timeCreated: 1499908886 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | using UnityEditor; |
| | | |
| | | [CustomEditor(typeof(AssetBundleUtility))] |
| | | public class AssetBundleUtilityEditor : Editor { |
| | | |
| | | private string m_LoadAssetBundleName = "ui/texture"; |
| | | private string m_LoadAssetName = "Button_Blue_A"; |
| | | |
| | | private string m_UnloadAssetBundleName = "ui/texture"; |
| | | private bool m_UnloadLoadedObject = false; |
| | | private bool m_IncludeDependenices = false; |
| | | private string m_UnloadAssetName = "Button_Blue_A"; |
| | | |
| | | public override void OnInspectorGUI() { |
| | | |
| | | m_LoadAssetBundleName = EditorGUILayout.TextField("AssetBundle名称", m_LoadAssetBundleName); |
| | | m_LoadAssetName = EditorGUILayout.TextField("Asset名称", m_LoadAssetName); |
| | | |
| | | GUILayout.BeginHorizontal(); |
| | | |
| | | if (GUILayout.Button("同步加载Asset")) { |
| | | AssetBundleUtility.Instance.Sync_LoadAsset(m_LoadAssetBundleName, m_LoadAssetName); |
| | | } |
| | | |
| | | if (GUILayout.Button("异步协程加载Asset")) { |
| | | AssetBundleUtility.Instance.Co_LoadAsset(m_LoadAssetBundleName, m_LoadAssetName); |
| | | } |
| | | |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | GUILayout.Space(10); |
| | | |
| | | m_UnloadAssetBundleName = EditorGUILayout.TextField("AssetBundle名称", m_UnloadAssetBundleName); |
| | | m_UnloadLoadedObject = GUILayout.Toggle(m_UnloadLoadedObject, "同时卸载引用资源"); |
| | | m_IncludeDependenices = GUILayout.Toggle(m_IncludeDependenices, "同时卸载依赖包"); |
| | | |
| | | if (GUILayout.Button("卸载AssetBundle")) { |
| | | AssetBundleUtility.Instance.UnloadAssetBundle(m_UnloadAssetBundleName, m_UnloadLoadedObject, m_IncludeDependenices); |
| | | } |
| | | |
| | | GUILayout.Space(10); |
| | | |
| | | GUILayout.BeginHorizontal(); |
| | | |
| | | m_UnloadAssetName = EditorGUILayout.TextField("Asset名称", m_UnloadAssetName); |
| | | |
| | | if (GUILayout.Button("卸载Asset")) { |
| | | AssetBundleUtility.Instance.UnloadAsset(m_UnloadAssetBundleName, m_UnloadAssetName); |
| | | } |
| | | |
| | | GUILayout.EndHorizontal(); |
| | | |
| | | if (GUILayout.Button("卸载所有AssetBundle")) { |
| | | AssetBundleUtility.Instance.UnloadAll(); |
| | | } |
| | | |
| | | if (GUILayout.Button("调用Resources.UnloadUnUsed()")) { |
| | | Resources.UnloadUnusedAssets(); |
| | | } |
| | | |
| | | if (GUILayout.Button("调用System.GC.Collect()")) { |
| | | System.GC.Collect(); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 3a5db09113674b343b6ffe3166154650 |
| | | timeCreated: 1503232241 |
| | | licenseType: Free |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 15bfde05b66ec4341851ecfdfe2f04e5 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: ac584e55bf0df494694449ee1780d805 |
| | | timeCreated: 1521082299 |
| | | licenseType: Pro |
| | | TextureImporter: |
| | | fileIDToRecycleName: {} |
| | | serializedVersion: 4 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: 1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -1 |
| | | wrapMode: -1 |
| | | nPOTScale: 1 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 0 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spritePixelsToUnits: 100 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 0 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 0 |
| | | textureShape: 1 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | platformSettings: |
| | | - buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | - buildTarget: Standalone |
| | | maxTextureSize: 2048 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | - buildTarget: iPhone |
| | | maxTextureSize: 2048 |
| | | textureFormat: 4 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | - buildTarget: Android |
| | | maxTextureSize: 2048 |
| | | textureFormat: 4 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | spritePackingTag: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 1acb149cfb080764ab981c0d335e05c0 |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: 1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: 1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | - serializedVersion: 3 |
| | | buildTarget: Standalone |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: 4 |
| | | textureCompression: 1 |
| | | compressionQuality: 1 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | - serializedVersion: 3 |
| | | buildTarget: Android |
| | | maxTextureSize: 1024 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: 34 |
| | | textureCompression: 1 |
| | | compressionQuality: 1 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | - serializedVersion: 3 |
| | | buildTarget: iPhone |
| | | maxTextureSize: 1024 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: 32 |
| | | textureCompression: 1 |
| | | compressionQuality: 1 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: def12bc929e317046ac9dbcec54c3598 |
| | | timeCreated: 1555914219 |
| | | licenseType: Free |
| | | TextureImporter: |
| | | fileIDToRecycleName: {} |
| | | serializedVersion: 4 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 1 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: 1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | filterMode: -1 |
| | | aniso: -1 |
| | | mipBias: -1 |
| | | wrapMode: -1 |
| | | nPOTScale: 1 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 0 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spritePixelsToUnits: 100 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 0 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 0 |
| | | textureShape: 1 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | platformSettings: |
| | | - buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | spritePackingTag: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 3b92dd2ea17cdf342bfb6ea448a300e1 |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: 1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: 0 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 0 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | - serializedVersion: 3 |
| | | buildTarget: Standalone |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | - serializedVersion: 3 |
| | | buildTarget: Android |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: 7 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | - serializedVersion: 3 |
| | | buildTarget: iPhone |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: 7 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 3622e3598d53ef44b920180e89f04a41 |
| | | TextureImporter: |
| | | internalIDToNameTable: [] |
| | | externalObjects: {} |
| | | serializedVersion: 11 |
| | | mipmaps: |
| | | mipMapMode: 0 |
| | | enableMipMap: 0 |
| | | sRGBTexture: 1 |
| | | linearTexture: 0 |
| | | fadeOut: 0 |
| | | borderMipMap: 0 |
| | | mipMapsPreserveCoverage: 0 |
| | | alphaTestReferenceValue: 0.5 |
| | | mipMapFadeDistanceStart: 1 |
| | | mipMapFadeDistanceEnd: 3 |
| | | bumpmap: |
| | | convertToNormalMap: 0 |
| | | externalNormalMap: 0 |
| | | heightScale: 0.25 |
| | | normalMapFilter: 0 |
| | | isReadable: 0 |
| | | streamingMipmaps: 0 |
| | | streamingMipmapsPriority: 0 |
| | | grayScaleToAlpha: 0 |
| | | generateCubemap: 6 |
| | | cubemapConvolution: 0 |
| | | seamlessCubemap: 0 |
| | | textureFormat: 1 |
| | | maxTextureSize: 2048 |
| | | textureSettings: |
| | | serializedVersion: 2 |
| | | filterMode: 1 |
| | | aniso: -1 |
| | | mipBias: -100 |
| | | wrapU: 1 |
| | | wrapV: 1 |
| | | wrapW: 1 |
| | | nPOTScale: 0 |
| | | lightmap: 0 |
| | | compressionQuality: 50 |
| | | spriteMode: 1 |
| | | spriteExtrude: 1 |
| | | spriteMeshType: 1 |
| | | alignment: 0 |
| | | spritePivot: {x: 0.5, y: 0.5} |
| | | spritePixelsToUnits: 100 |
| | | spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
| | | spriteGenerateFallbackPhysicsShape: 1 |
| | | alphaUsage: 1 |
| | | alphaIsTransparency: 1 |
| | | spriteTessellationDetail: -1 |
| | | textureType: 8 |
| | | textureShape: 1 |
| | | singleChannelComponent: 0 |
| | | maxTextureSizeSet: 0 |
| | | compressionQualitySet: 0 |
| | | textureFormatSet: 0 |
| | | applyGammaDecoding: 1 |
| | | platformSettings: |
| | | - serializedVersion: 3 |
| | | buildTarget: DefaultTexturePlatform |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: -1 |
| | | textureCompression: 1 |
| | | compressionQuality: 50 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 0 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | - serializedVersion: 3 |
| | | buildTarget: Standalone |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: 4 |
| | | textureCompression: 1 |
| | | compressionQuality: 1 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | - serializedVersion: 3 |
| | | buildTarget: Android |
| | | maxTextureSize: 512 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: 47 |
| | | textureCompression: 1 |
| | | compressionQuality: 1 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | - serializedVersion: 3 |
| | | buildTarget: iPhone |
| | | maxTextureSize: 2048 |
| | | resizeAlgorithm: 0 |
| | | textureFormat: 33 |
| | | textureCompression: 1 |
| | | compressionQuality: 1 |
| | | crunchedCompression: 0 |
| | | allowsAlphaSplitting: 0 |
| | | overridden: 1 |
| | | androidETC2FallbackOverride: 0 |
| | | forceMaximumCompressionQuality_BC6H_BC7: 1 |
| | | spriteSheet: |
| | | serializedVersion: 2 |
| | | sprites: [] |
| | | outline: [] |
| | | physicsShape: [] |
| | | bones: [] |
| | | spriteID: 5e97eb03825dee720800000000000000 |
| | | internalID: 0 |
| | | vertices: [] |
| | | indices: |
| | | edges: [] |
| | | weights: [] |
| | | secondaryTextures: [] |
| | | spritePackingTag: |
| | | pSDRemoveMatte: 0 |
| | | pSDShowRemoveMatteOption: 0 |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | namespace Assets.Editor.Tool |
| | | |
| | | { |
| | | public class AssetBundleBuildTool |
| | | { |
| | | [MenuItem("Tools/AB增量打包(不设置Label)")] |
| | | static void DoIt() |
| | | { |
| | | BuildAssetBundleOptions opt = BuildAssetBundleOptions.ChunkBasedCompression | BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.StrictMode; |
| | | // public class AssetBundleBuildTool |
| | | // { |
| | | // [MenuItem("Tools/AB增量打包(不设置Label)")] |
| | | // static void DoIt() |
| | | // { |
| | | // BuildAssetBundleOptions opt = BuildAssetBundleOptions.ChunkBasedCompression | BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.StrictMode; |
| | | |
| | | string outputPath = StringUtility.Contact(System.Environment.CurrentDirectory, "/AssetBundles/", EditorUserBuildSettings.activeBuildTarget.ToString()); |
| | | string streamingPath = StringUtility.Contact(Application.streamingAssetsPath, Path.AltDirectorySeparatorChar, EditorUserBuildSettings.activeBuildTarget.ToString()); |
| | | // string outputPath = StringUtility.Contact(System.Environment.CurrentDirectory, "/AssetBundles/", EditorUserBuildSettings.activeBuildTarget.ToString()); |
| | | // string streamingPath = StringUtility.Contact(Application.streamingAssetsPath, Path.AltDirectorySeparatorChar, EditorUserBuildSettings.activeBuildTarget.ToString()); |
| | | |
| | | if (!Directory.Exists(outputPath)) |
| | | Directory.CreateDirectory(outputPath); |
| | | // if (!Directory.Exists(outputPath)) |
| | | // Directory.CreateDirectory(outputPath); |
| | | |
| | | AssetBundleBuildExtersion.Build(outputPath, "builtin", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | // AssetBundleBuildExtersion.Build(outputPath, "builtin", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | |
| | | AssetBundleBuildExtersion.Build(outputPath, "audio", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | // AssetBundleBuildExtersion.Build(outputPath, "audio", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | |
| | | AssetBundleBuildExtersion.Build(outputPath, "mobeffectshader", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | // AssetBundleBuildExtersion.Build(outputPath, "mobeffectshader", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | |
| | | AssetBundleBuildExtersion.Build(outputPath, "config", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | TableTool.CopyConfigsToOutPutPath(StringUtility.Contact(outputPath, "/config")); |
| | | // AssetBundleBuildExtersion.Build(outputPath, "config", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | // TableTool.CopyConfigsToOutPutPath(StringUtility.Contact(outputPath, "/config")); |
| | | |
| | | LuaBuildHelper.OnPreBuild(); |
| | | UpdateLuaSetting.SetAllLuaAssetBundleName(); |
| | | AssetBundleBuildExtersion.Build(outputPath, "lua", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | LuaBuildHelper.OnPostBuild(); |
| | | // LuaBuildHelper.OnPreBuild(); |
| | | // UpdateLuaSetting.SetAllLuaAssetBundleName(); |
| | | // AssetBundleBuildExtersion.Build(outputPath, "lua", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | // LuaBuildHelper.OnPostBuild(); |
| | | |
| | | AssetBundleBuildExtersion.Build(outputPath, "maps", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | // AssetBundleBuildExtersion.Build(outputPath, "maps", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | |
| | | AssetBundleBuildExtersion.Build(outputPath, "ui", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | // AssetBundleBuildExtersion.Build(outputPath, "ui", opt, EditorUserBuildSettings.activeBuildTarget, false); |
| | | |
| | | var fileInfos = new List<FileInfo>(); |
| | | FileExtersion.GetAllDirectoryFileInfos(outputPath, fileInfos); |
| | | AssetsVersionMaker.WriteAssetsVersionFile(outputPath, fileInfos); |
| | | // var fileInfos = new List<FileInfo>(); |
| | | // FileExtersion.GetAllDirectoryFileInfos(outputPath, fileInfos); |
| | | // AssetsVersionMaker.WriteAssetsVersionFile(outputPath, fileInfos); |
| | | |
| | | if (Directory.Exists(streamingPath)) |
| | | Directory.Delete(streamingPath, true); |
| | | // if (Directory.Exists(streamingPath)) |
| | | // Directory.Delete(streamingPath, true); |
| | | |
| | | FileExtersion.DirectoryCopy(outputPath, streamingPath); |
| | | // FileExtersion.DirectoryCopy(outputPath, streamingPath); |
| | | |
| | | } |
| | | } |
| | | // } |
| | | // } |
| | | |
| | | } |
| | |
| | | public static void BuildApk(string _sdkPath, string _output, string _publisher, int _buildIndex, bool _development)
|
| | | {
|
| | | PreBuild(_publisher, _buildIndex);
|
| | |
|
| | | var auditTimeFile = StringUtility.Contact(Application.dataPath, Path.DirectorySeparatorChar, "Resources/Config/AuditTime.txt");
|
| | | if (File.Exists(auditTimeFile))
|
| | | {
|
| | |
| | | public class UpdateAllSetting
|
| | | {
|
| | |
|
| | | [MenuItem("程序/设置资源包名/更新全部AssetBundleName")]
|
| | | [MenuItem("程序/设置资源包名/更新全部ABLabel(不包括lua)")]
|
| | | public static void SetAllAssetBundleName()
|
| | | { |
| | | {
|
| | | UpdateSpriteSetting.SetAllSpriteAssetBundleName();
|
| | | UpdateUIWindowSetting.SetAllUIWindowAssetBundleName();
|
| | | UpdateUIPrefabSetting.SetAllUIPrefabAssetBundleName();
|
| | |
| | | UpdateLevelSetting.SetAllLevelAssetBundleName();
|
| | | UpdateAudioSetting.SetAllAudioAssetBundleName();
|
| | | UpdateVideoSetting.SetAllVideoAssetBundleName();
|
| | | UpdateLuaSetting.SetAllLuaAssetBundleName();
|
| | | // UpdateLuaSetting.SetAllLuaAssetBundleName();
|
| | | UpdateBuiltInSetting.SetBuiltinAssetBundleName();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("资源包名全部更新完成!");
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | var importerPath = spriteRelativePath + Path.DirectorySeparatorChar + pathStringArray[pathStringArray.Length - 1] + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "ui/sprite/" + pathStringArray[pathStringArray.Length - 1].ToLower();
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("Sprite资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | |
|
| | | }
|
| | |
| | | var importer = AssetImporter.GetAtPath(path);
|
| | | importer.assetBundleName = "ui/window";
|
| | |
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | guids = AssetDatabase.FindAssets("t:prefab", new string[] { assetRelativePath2 });
|
| | | foreach (var guid in guids)
|
| | | {
|
| | |
| | | var importer = AssetImporter.GetAtPath(path);
|
| | | importer.assetBundleName = StringUtility.Contact("ui/prioritywindow/", Path.GetFileNameWithoutExtension(path).ToLower());
|
| | |
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("Window资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | var importerPath = prefabAssetRelativePath + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "ui/prefab";
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | allFiles = new DirectoryInfo(bossShowRootPath).GetFiles("*.prefab", SearchOption.TopDirectoryOnly);
|
| | |
| | | var importerPath = bossShowAssetRelativePath + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "ui/bossshow";
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | allFiles = new DirectoryInfo(godWeaponRootPath).GetFiles("*.prefab", SearchOption.TopDirectoryOnly);
|
| | |
| | | var importerPath = godWeaponAssetRelativePath + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "ui/godweapon";
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | allFiles = new DirectoryInfo(treasureRootPath).GetFiles("*.prefab", SearchOption.AllDirectories);
|
| | |
| | | var importerPath = treasureAssetRelativePath + Path.DirectorySeparatorChar + pathStringArray[pathStringArray.Length - 1] + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "ui/treasure/" + pathStringArray[pathStringArray.Length - 1].ToLower();
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("Prefab资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | |
|
| | |
|
| | |
| | | var importerPath = assetPath + pathStringArray[pathStringArray.Length - 1] + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "effect/" + pathStringArray[pathStringArray.Length - 1].ToLower();
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("Effect资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | .Replace("Prefab_Hand", "");
|
| | |
|
| | | importer.assetBundleName = StringUtility.Contact("mob/prefab_race", hostfix);
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | allFiles = new DirectoryInfo(createroleRoot).GetFiles("*.prefab", SearchOption.TopDirectoryOnly);
|
| | |
| | | var extersion = Path.GetExtension(file.FullName);
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "mob/createrole";
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | //var zsMaterialFiles = new DirectoryInfo(zsMaterialPath_Origin).GetFiles("*.mat", SearchOption.TopDirectoryOnly);
|
| | |
| | | string _abName = Path.GetFileNameWithoutExtension(_file.Name).Replace("_02", "").Replace("_Dm", "").Replace("_Dm_02", "");
|
| | | _importer.assetBundleName = "mob/prefab_race_" + _abName;
|
| | | }
|
| | | EditorUtility.SetDirty(_importer);
|
| | | // EditorUtility.SetDirty(_importer);
|
| | | }
|
| | |
|
| | | var fsMaterialPathOutFiles = new DirectoryInfo(fsMaterialPath_OutPut).GetFiles("*.mat", SearchOption.TopDirectoryOnly);
|
| | |
| | | string _abName = Path.GetFileNameWithoutExtension(_file.Name).Replace("_02", "").Replace("_Dm", "").Replace("_Dm_02", "");
|
| | | _importer.assetBundleName = "mob/prefab_race_" + _abName;
|
| | | }
|
| | | EditorUtility.SetDirty(_importer);
|
| | | // EditorUtility.SetDirty(_importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | |
|
| | | //foreach (var file in zsMaterialFiles)
|
| | | //{
|
| | |
| | | // importer.assetBundleName = "mob/a_fs_materials";
|
| | | // EditorUtility.SetDirty(importer);
|
| | | //}
|
| | |
|
| | | DebugEx.Log("Mob资源包名更新完成!");
|
| | | //AssetDatabase.SaveAssets();
|
| | | //AssetDatabase.Refresh();
|
| | | }
|
| | |
| | | var importerPath = assetPath + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "graphic/shader";
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("Shader资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | var importerPath = assetPath + relativePath + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "config/scriptableobjects";
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("ScriptableObject资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | var importerPath = assetPath + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "maps/" + Path.GetFileNameWithoutExtension(file.FullName).ToLower();
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | var createRoleAssets = AssetDatabase.FindAssets("t:prefab", new string[] { "Assets/ResourcesOut/Scene/CreateRole" });
|
| | |
| | | {
|
| | | var importer = AssetImporter.GetAtPath(AssetDatabase.GUIDToAssetPath(item));
|
| | | importer.assetBundleName = "maps/createrole";
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | var textures = AssetDatabase.FindAssets("t:Texture2D", new string[] { "Assets/ResourcesOut/Scene/Textures" });
|
| | |
| | | {
|
| | | var importer = AssetImporter.GetAtPath(AssetDatabase.GUIDToAssetPath(item));
|
| | | importer.assetBundleName = "maps/textures";
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("Level资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | |
|
| | | }
|
| | |
| | | var importerPath = assetPath + pathStringArray[pathStringArray.Length - 1] + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "audio/" + pathStringArray[pathStringArray.Length - 1].ToLower();
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("Audio资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | [MenuItem("程序/设置资源包名/更新Video(All) AssetBundleName")]
|
| | | public static void SetAllVideoAssetBundleName()
|
| | | {
|
| | | if (!Directory.Exists(rootPath))
|
| | | return;
|
| | | var allFiles = new DirectoryInfo(rootPath).GetFiles("*.mp4", SearchOption.AllDirectories);
|
| | | foreach (var file in allFiles)
|
| | | {
|
| | | var importerPath = assetPath + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "video/mp4";
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("Video资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | var importerPath = assetPath + relativeDirectory + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "lua/" + relativeDirectory.ToLower();
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("Lua资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | var importerPath = assetPath + relativeDirectory + Path.DirectorySeparatorChar + file.Name;
|
| | | var importer = AssetImporter.GetAtPath(importerPath);
|
| | | importer.assetBundleName = "builtin/" + relativeDirectory.ToLower();
|
| | | EditorUtility.SetDirty(importer);
|
| | | // EditorUtility.SetDirty(importer);
|
| | | }
|
| | |
|
| | | AssetDatabase.SaveAssets();
|
| | | AssetDatabase.Refresh();
|
| | | DebugEx.Log("BuiltIn资源包名更新完成!");
|
| | | // AssetDatabase.SaveAssets();
|
| | | // AssetDatabase.Refresh();
|
| | | }
|
| | | } |
| | |
| | | Id name AppId VersionAuthority m_Version m_ClientPackageFlag m_Branch m_GameId m_AssetAccess m_PartAssetPackage m_ProductName m_BundleIdentifier m_KeystoreFileName m_KeystorePassword m_KeystoreAlias m_KeystoreAliasPassword m_AppleDeveloperTeamID m_DebugVersion m_IsBanShu m_LogoPosition m_BanHao m_SpID m_Recharge m_CreateRolePattern |
| | | 版本标识 版本名称 渠道id 版本权限,0是测试版本,1是发布版本 版本号 客户端标识 分支 游戏项目标识 资源,0NullAsset,1HalfAsset,2FullAsset,3IgnoreDownLoad 是否分包,0不分包,1分包 产品名 产品包名 签名文件名 签名文件密码 签名文件别名 签名文件别名密码 开发者账号密码 是否debug版本,0否1是 是否版署版本,0否1是 登录界面的Logo位置 版号 运营商ID 充值界面风格 创角场景风格 |
| | | 9999 TheSecondWorld test 0 2.0.600 aaa 2 xbqy 1 1 仙宝奇缘 com.secondworld.snxxz thesecondworld thesecondworld2018 thesecondworld thesecondworld2018 0 0 (-32,144) 0 |
| | | 10000 TheSecondWorld test 0 1.100.1 aaa 7 xbqy 1 1 仙宝奇缘 com.secondworld.snxxz thesecondworld thesecondworld2018 thesecondworld thesecondworld2018 0 0 (-32,144) 0 |
| | | 1 xbqy 226114725 1 2.0.600 test 900 xbqy 2 1 仙宝奇缘 com.shandangceshi.snxxz shandangceshi shandangceshi2018 shandangceshi shandangceshi2018 0 0 (-32,144) 226114725 0 |
| | | 15 mgxbqy mgxbqy 1 2.0.600 5001 1 xbqy 1 1 梦灵传说 com.mhtj.mg shandangceshi shandangceshi2018 shandangceshi shandangceshi2018 0 0 (0,80) mggame 0 1 |
| | | 16 mgxbqy mgxbqy 1 2.0.600 5001 2 xbqy 1 1 梦灵传说 com.mhtj.mg shandangceshi shandangceshi2018 shandangceshi shandangceshi2018 0 0 (0,80) mggame 0 1 |
| | | 900 mgxbqy mgxbqy 1 2.0.600 5001 2 xbqy 3 1 梦灵传说 com.mhtj.mg shandangceshi shandangceshi2018 shandangceshi shandangceshi2018 0 0 (0,80) mggame 0 1 |
| | | Id name AppId VersionAuthority m_Version m_ClientPackageFlag m_Branch m_GameId m_AssetAccess m_PartAssetPackage m_ProductName m_BundleIdentifier m_KeystoreFileName m_KeystorePassword m_KeystoreAlias m_KeystoreAliasPassword m_AppleDeveloperTeamID m_DebugVersion m_IsBanShu m_LogoPosition m_BanHao m_SpID m_Recharge m_CreateRolePattern |
| | | 版本标识 版本名称 渠道id 版本权限,0是测试版本,1是发布版本 版本号 客户端标识 分支 游戏项目标识 资源,0NullAsset,1HalfAsset,2FullAsset,3IgnoreDownLoad 是否分包,0不分包,1分包 产品名 产品包名 签名文件名 签名文件密码 签名文件别名 签名文件别名密码 开发者账号密码 是否debug版本,0否1是 是否版署版本,0否1是 登录界面的Logo位置 版号 运营商ID 充值界面风格 创角场景风格 |
| | | 9999 TheSecondWorld test 0 2.0.600 aaa 2 xbqy 1 1 仙宝奇缘 com.secondworld.snxxz thesecondworld thesecondworld2018 thesecondworld thesecondworld2018 0 0 (-32,144) 0 |
| | | 10000 TheSecondWorld test 0 1.100.1 aaa 7 xbqy 1 1 仙宝奇缘 com.secondworld.snxxz thesecondworld thesecondworld2018 thesecondworld thesecondworld2018 0 0 (-32,144) 0 |
| | | 1 xbqy 226114725 1 2.0.600 test 900 xbqy 2 1 仙宝奇缘 com.shandangceshi.snxxz shandangceshi shandangceshi2018 shandangceshi shandangceshi2018 0 0 (-32,144) 226114725 0 |
| | | 15 mgxbqy mgxbqy 1 2.0.600 5001 1 xbqy 1 1 梦灵传说 com.mhtj.mg shandangceshi shandangceshi2018 shandangceshi shandangceshi2018 0 0 (0,80) mggame 0 1 |
| | | 16 mgxbqy mgxbqy 1 2.0.600 5001 2 xbqy 1 1 梦灵传说 com.mhtj.mg shandangceshi shandangceshi2018 shandangceshi shandangceshi2018 0 0 (0,80) mggame 0 1 |
| | | 900 mgxbqy mgxbqy 1 2.0.600 5001 2 xbqy 3 1 梦灵传说 com.mhtj.mg shandangceshi shandangceshi2018 shandangceshi shandangceshi2018 0 0 (0,80) mggame 0 1 |
| | | 9998 xmyjgame xmyjgame 1 1.100.2 aaa 4 xbqy 1 1 仙魔战场 com.xfzc.yj.quick mengxiandao mengxiandao2020 mengxiandao mengxiandao2020 0 0 (-15,64) 出版单位名称:天津电子出版社有限公司 著作权人名称:广州秒乐网络科技有限公司</r>运营单位:广州游路网络科技有限公司 游戏内容类别:移动游戏 批文号:国新出审[2019]1132号 游戏版号:ISBN 978-7-498-06329-8 xmyjgame 0 |
| | | 9527 TheSecondWorld test 0 1.100.1 aaa 2 xbqy 3 1 仙宝奇缘 com.secondworld.snxxz thesecondworld thesecondworld2018 thesecondworld thesecondworld2018 0 0 (-32,144) 0 |
| | | 9528 gtgame gtgame 1 1.0.0 aaa 1 xbqy 3 1 镇魔诀 com.sanxiagame.zmjgp thesecondworld thesecondworld2018 thesecondworld thesecondworld2018 (0,80) gtgame 0 1 |
| | | 9527 TheSecondWorld test 0 1.100.1 aaa 2 xbqy 3 1 仙宝奇缘 com.secondworld.snxxz thesecondworld thesecondworld2018 thesecondworld thesecondworld2018 0 0 (-32,144) 0 |
| | | 9528 gtgame gtgame 1 1.0.0 aaa 1 xbqy 3 1 镇魔诀 com.sanxiagame.zmjgp thesecondworld thesecondworld2018 thesecondworld thesecondworld2018 0 0 (0,80) gtgame 0 1 |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN--> |
| | | <manifest |
| | | xmlns:android="http://schemas.android.com/apk/res/android" |
| | | package="com.unity3d.player" |
| | | xmlns:tools="http://schemas.android.com/tools"> |
| | | <application> |
| | | <activity android:name="com.secondworld.sdk.GameActivity" |
| | | android:theme="@style/UnityThemeSelector"> |
| | | <intent-filter> |
| | | <action android:name="android.intent.action.MAIN" /> |
| | | <category android:name="android.intent.category.LAUNCHER" /> |
| | | </intent-filter> |
| | | <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> |
| | | </activity> |
| | | </application> |
| | | </manifest> |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 44ea7b20ff03e7c479f5a35eac4f2ef4 |
| | | TextScriptImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | // GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN |
| | | |
| | | apply plugin: 'com.android.library' |
| | | //**APPLY_PLUGINS** |
| | | apply from: 'deps.gradle' |
| | | |
| | | dependencies { |
| | | implementation fileTree(dir: 'libs', include: ['*.jar']) |
| | | **DEPS**} |
| | | |
| | | android { |
| | | compileSdkVersion **APIVERSION** |
| | | buildToolsVersion '**BUILDTOOLS**' |
| | | |
| | | compileOptions { |
| | | sourceCompatibility JavaVersion.VERSION_1_8 |
| | | targetCompatibility JavaVersion.VERSION_1_8 |
| | | } |
| | | |
| | | defaultConfig { |
| | | minSdkVersion **MINSDKVERSION** |
| | | targetSdkVersion **TARGETSDKVERSION** |
| | | ndk { |
| | | abiFilters **ABIFILTERS** |
| | | } |
| | | versionCode **VERSIONCODE** |
| | | versionName '**VERSIONNAME**' |
| | | consumerProguardFiles 'proguard-unity.txt'**USER_PROGUARD** |
| | | } |
| | | |
| | | lintOptions { |
| | | abortOnError false |
| | | } |
| | | |
| | | aaptOptions { |
| | | ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~" |
| | | }**PACKAGING_OPTIONS** |
| | | }**REPOSITORIES****SOURCE_BUILD_SETUP** |
| | | **EXTERNAL_SOURCES** |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: b2f2a20fb46444e4fa7af5d82a94bba1 |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | m_Name: VersionConfig |
| | | m_EditorClassIdentifier: |
| | | m_AppId: gtgame |
| | | m_SpID: |
| | | m_SpID: gtgame |
| | | m_VersionAuthority: 1 |
| | | m_Version: 1.0.0 |
| | | m_ClientPackageFlag: aaa |
| | |
| | | m_AppleDeveloperTeamID: |
| | | m_DebugVersion: 0 |
| | | m_IsBanShu: 0 |
| | | m_BuildTime: 20/11/25--15:58 |
| | | m_BuildIndex: 59 |
| | | m_LogoPosition: {x: 0, y: 0} |
| | | m_BuildTime: 20/11/27--17:40 |
| | | m_BuildIndex: 7 |
| | | m_LogoPosition: {x: 0, y: 80} |
| | | m_BanHao: |
| | |
| | | useOnDemandResources: 0 |
| | | accelerometerFrequency: 0 |
| | | companyName: TheSecondWorld |
| | | productName: "\u4ED9\u5B9D\u5947\u7F18" |
| | | productName: "\u9547\u9B54\u8BC0" |
| | | defaultCursor: {fileID: 0} |
| | | cursorHotspot: {x: 0, y: 0} |
| | | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} |
| | |
| | | width: 1 |
| | | height: 1 |
| | | m_SplashScreenLogos: |
| | | - logo: {fileID: 0} |
| | | - logo: {fileID: 21300000, guid: 3b92dd2ea17cdf342bfb6ea448a300e1, type: 3} |
| | | duration: 3 |
| | | m_VirtualRealitySplashScreen: {fileID: 0} |
| | | m_ShowUnitySplashAds: 0 |
| | |
| | | 16:10: 1 |
| | | 16:9: 1 |
| | | Others: 1 |
| | | bundleVersion: 1100001 |
| | | bundleVersion: 1000000 |
| | | preloadedAssets: [] |
| | | metroInputSource: 0 |
| | | wsaTransparentSwapchain: 0 |
| | |
| | | androidSupportedAspectRatio: 1 |
| | | androidMaxAspectRatio: 2.1 |
| | | applicationIdentifier: |
| | | Android: com.secondworld.snxxz |
| | | Android: com.sanxiagame.zmjgp |
| | | Standalone: com.secondworld.snxxz |
| | | iPhone: com.secondworld.snxxz |
| | | buildNumber: {} |
| | |
| | | templateDefaultScene: |
| | | AndroidTargetArchitectures: 3 |
| | | AndroidSplashScreenScale: 2 |
| | | androidSplashScreen: {fileID: 2800000, guid: 179f9801f106906489c8b6bcc9896c8a, type: 3} |
| | | androidSplashScreen: {fileID: 2800000, guid: 3b92dd2ea17cdf342bfb6ea448a300e1, type: 3} |
| | | AndroidKeystoreName: '{inproject}: Assets/Editor/Keystore/thesecondworld.keystore' |
| | | AndroidKeyaliasName: thesecondworld |
| | | AndroidBuildApkPerCpuArchitecture: 0 |
| | |
| | | m_Kind: 1 |
| | | m_SubKind: |
| | | - m_Textures: |
| | | - {fileID: 0} |
| | | - {fileID: 2800000, guid: ac584e55bf0df494694449ee1780d805, type: 3} |
| | | m_Width: 192 |
| | | m_Height: 192 |
| | | m_Kind: 0 |
| | | m_SubKind: |
| | | - m_Textures: |
| | | - {fileID: 0} |
| | | - {fileID: 2800000, guid: ac584e55bf0df494694449ee1780d805, type: 3} |
| | | m_Width: 144 |
| | | m_Height: 144 |
| | | m_Kind: 0 |
| | | m_SubKind: |
| | | - m_Textures: |
| | | - {fileID: 0} |
| | | - {fileID: 2800000, guid: ac584e55bf0df494694449ee1780d805, type: 3} |
| | | m_Width: 96 |
| | | m_Height: 96 |
| | | m_Kind: 0 |
| | | m_SubKind: |
| | | - m_Textures: |
| | | - {fileID: 0} |
| | | - {fileID: 2800000, guid: ac584e55bf0df494694449ee1780d805, type: 3} |
| | | m_Width: 72 |
| | | m_Height: 72 |
| | | m_Kind: 0 |
| | | m_SubKind: |
| | | - m_Textures: |
| | | - {fileID: 0} |
| | | - {fileID: 2800000, guid: ac584e55bf0df494694449ee1780d805, type: 3} |
| | | m_Width: 48 |
| | | m_Height: 48 |
| | | m_Kind: 0 |
| | | m_SubKind: |
| | | - m_Textures: |
| | | - {fileID: 0} |
| | | - {fileID: 2800000, guid: ac584e55bf0df494694449ee1780d805, type: 3} |
| | | m_Width: 36 |
| | | m_Height: 36 |
| | | m_Kind: 0 |