diff --git a/Assets/Asset Cleaner.meta b/Assets/Asset Cleaner.meta new file mode 100644 index 00000000..b7f9a58d --- /dev/null +++ b/Assets/Asset Cleaner.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3b69e6d6a63f3f74e8ea14c2dc3f7812 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/AssetCleaner.asmdef b/Assets/Asset Cleaner/AssetCleaner.asmdef new file mode 100644 index 00000000..89eda969 --- /dev/null +++ b/Assets/Asset Cleaner/AssetCleaner.asmdef @@ -0,0 +1,15 @@ +{ + "name": "AssetCleaner", + "references": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": false, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/AssetCleaner.asmdef.meta b/Assets/Asset Cleaner/AssetCleaner.asmdef.meta new file mode 100644 index 00000000..be999193 --- /dev/null +++ b/Assets/Asset Cleaner/AssetCleaner.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: de141fd48bce7594e9474fe440f5ea10 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/CleanerStyle.asset b/Assets/Asset Cleaner/CleanerStyle.asset new file mode 100644 index 00000000..87178189 --- /dev/null +++ b/Assets/Asset Cleaner/CleanerStyle.asset @@ -0,0 +1,1236 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 16578cbec6a24ac4d951b5f328a970ca, type: 3} + m_Name: CleanerStyle + m_EditorClassIdentifier: Editor.AssetUsageFinder:Asset_Cleaner:WindowStyleAsset + Pro: + RedHighlight: {r: 1, g: 0, b: 0, a: 1} + Lock: + m_Text: + m_Image: {fileID: 2800000, guid: c5fd88366c67daf4585631953fa79779, type: 3} + m_Tooltip: Unlock asset + LockBtn: + m_Name: button + m_Normal: + m_Background: {fileID: 7619082074131061878, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -660027063019260353, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Focused: + m_Background: {fileID: 6868133616650823125, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnNormal: + m_Background: {fileID: -4685157240802103863, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9411765, g: 0.9411765, b: 0.9411765, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 568729325262407274, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnFocused: + m_Background: {fileID: 5631187574603569090, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 32 + m_FixedHeight: 20 + m_StretchWidth: 0 + m_StretchHeight: 0 + SampleBtn: + m_Name: button + m_Normal: + m_Background: {fileID: 7619082074131061878, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -660027063019260353, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Focused: + m_Background: {fileID: 6868133616650823125, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnNormal: + m_Background: {fileID: -4685157240802103863, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9411765, g: 0.9411765, b: 0.9411765, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 568729325262407274, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnFocused: + m_Background: {fileID: 5631187574603569090, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 3 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 20 + m_StretchWidth: 1 + m_StretchHeight: 0 + Unlock: + m_Text: + m_Image: {fileID: 2800000, guid: e755b5ef4cb427f469ba580ae9956237, type: 3} + m_Tooltip: Lock on asset + UnlockBtn: + m_Name: button + m_Normal: + m_Background: {fileID: 7619082074131061878, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -660027063019260353, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Focused: + m_Background: {fileID: 6868133616650823125, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnNormal: + m_Background: {fileID: -4685157240802103863, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9411765, g: 0.9411765, b: 0.9411765, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 568729325262407274, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnFocused: + m_Background: {fileID: 5631187574603569090, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 32 + m_FixedHeight: 20 + m_StretchWidth: 0 + m_StretchHeight: 0 + RemoveFile: + m_Text: + m_Image: {fileID: 2800000, guid: f4b3e5a29ec20194a8ba1d6cf7b1b037, type: 3} + m_Tooltip: Remove unused file(s) + RemoveScene: + m_Text: + m_Image: {fileID: 2800000, guid: 3fec3bf4c4f5e2d48835dbe2f21aa7d0, type: 3} + m_Tooltip: Remove unused scene(s) + RowMainAssetBtn: + m_Name: button + m_Normal: + m_Background: {fileID: 7619082074131061878, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -660027063019260353, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Focused: + m_Background: {fileID: 6868133616650823125, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnNormal: + m_Background: {fileID: -4685157240802103863, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9411765, g: 0.9411765, b: 0.9411765, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 568729325262407274, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnFocused: + m_Background: {fileID: 5631187574603569090, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 3 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 20 + m_StretchWidth: 1 + m_StretchHeight: 1 + RemoveUnusedBtn: + m_Name: button + m_Normal: + m_Background: {fileID: 7619082074131061878, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -660027063019260353, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Focused: + m_Background: {fileID: 6868133616650823125, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnNormal: + m_Background: {fileID: -4685157240802103863, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9411765, g: 0.9411765, b: 0.9411765, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 568729325262407274, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnFocused: + m_Background: {fileID: 5631187574603569090, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 3 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 28.66 + m_FixedHeight: 20 + m_StretchWidth: 0 + m_StretchHeight: 0 + CurrentBtn: + m_Name: button + m_Normal: + m_Background: {fileID: 7619082074131061878, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -660027063019260353, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Focused: + m_Background: {fileID: 6868133616650823125, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnNormal: + m_Background: {fileID: -4685157240802103863, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9411765, g: 0.9411765, b: 0.9411765, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 568729325262407274, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnFocused: + m_Background: {fileID: 5631187574603569090, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 3 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 20 + m_StretchWidth: 1 + m_StretchHeight: 0 + ArrowL: + m_Text: + m_Image: {fileID: 2800000, guid: bfec65de7ee2e114199f83507d375a6f, type: 3} + m_Tooltip: Go back + ArrowR: + m_Text: + m_Image: {fileID: 2800000, guid: 07bb28c80f378c64194dd46c34b2d6c1, type: 3} + m_Tooltip: Go forward + ArrowBtn: + m_Name: button + m_Normal: + m_Background: {fileID: 7619082074131061878, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -660027063019260353, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Focused: + m_Background: {fileID: 6868133616650823125, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnNormal: + m_Background: {fileID: -4685157240802103863, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.9411765, g: 0.9411765, b: 0.9411765, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 568729325262407274, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_OnFocused: + m_Background: {fileID: 5631187574603569090, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.7058824, g: 0.7058824, b: 0.7058824, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 32 + m_FixedHeight: 20 + m_StretchWidth: 0 + m_StretchHeight: 0 + SceneIndent1: 20 + SceneIndent2: 20 + ProjectViewCounterLabel: + m_Name: label + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 0.01960784} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 0.01960784} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 0.01960784} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 2 + m_Bottom: 2 + m_Padding: + m_Left: 2 + m_Right: 4 + m_Top: 1 + m_Bottom: 2 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 3459068928204737762, guid: 0000000000000000d000000000000000, + type: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 5 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 0 + m_ImagePosition: 3 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + MultiSelect: + m_Text: + m_Image: {fileID: 2800000, guid: e0208e3a37267be46ba2d10fad510cef, type: 3} + m_Tooltip: + Personal: + RedHighlight: {r: 1, g: 0, b: 0, a: 0.2} + Lock: + m_Text: + m_Image: {fileID: 2800000, guid: c5fd88366c67daf4585631953fa79779, type: 3} + m_Tooltip: Unlock asset + LockBtn: + m_Name: button + m_Normal: + m_Background: {fileID: -573041650897247223, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -7527060558648309217, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 7832598784815925287, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: -4454209017672384243, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 4047951448802137905, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 8556163245987529883, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 32 + m_FixedHeight: 20 + m_StretchWidth: 0 + m_StretchHeight: 0 + SampleBtn: + m_Name: button + m_Normal: + m_Background: {fileID: -573041650897247223, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -7527060558648309217, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 7832598784815925287, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: -4454209017672384243, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 4047951448802137905, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 8556163245987529883, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 32 + m_FixedHeight: 20 + m_StretchWidth: 0 + m_StretchHeight: 0 + Unlock: + m_Text: + m_Image: {fileID: 2800000, guid: e755b5ef4cb427f469ba580ae9956237, type: 3} + m_Tooltip: Lock on asset + UnlockBtn: + m_Name: button + m_Normal: + m_Background: {fileID: -573041650897247223, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -7527060558648309217, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 7832598784815925287, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: -4454209017672384243, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 4047951448802137905, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 8556163245987529883, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 32 + m_FixedHeight: 20 + m_StretchWidth: 0 + m_StretchHeight: 0 + RemoveFile: + m_Text: + m_Image: {fileID: 2800000, guid: f4b3e5a29ec20194a8ba1d6cf7b1b037, type: 3} + m_Tooltip: Remove unused file(s) + RemoveScene: + m_Text: + m_Image: {fileID: 2800000, guid: 3fec3bf4c4f5e2d48835dbe2f21aa7d0, type: 3} + m_Tooltip: Remove unused scene(s) + RowMainAssetBtn: + m_Name: button + m_Normal: + m_Background: {fileID: -573041650897247223, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: -7527060558648309217, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 7832598784815925287, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: -4454209017672384243, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 4047951448802137905, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 8556163245987529883, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 3 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 20 + m_StretchWidth: 1 + m_StretchHeight: 1 + RemoveUnusedBtn: + m_Name: button + m_Normal: + m_Background: {fileID: -573041650897247223, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -7527060558648309217, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 7832598784815925287, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: -4454209017672384243, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 4047951448802137905, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 8556163245987529883, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 3 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 28.66 + m_FixedHeight: 20 + m_StretchWidth: 0 + m_StretchHeight: 0 + CurrentBtn: + m_Name: button + m_Normal: + m_Background: {fileID: -573041650897247223, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -7527060558648309217, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 7832598784815925287, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: -4454209017672384243, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 4047951448802137905, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 8556163245987529883, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 3 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 20 + m_StretchWidth: 1 + m_StretchHeight: 0 + ArrowL: + m_Text: + m_Image: {fileID: 2800000, guid: bfec65de7ee2e114199f83507d375a6f, type: 3} + m_Tooltip: Go back + ArrowR: + m_Text: + m_Image: {fileID: 2800000, guid: 07bb28c80f378c64194dd46c34b2d6c1, type: 3} + m_Tooltip: Go forward + ArrowBtn: + m_Name: button + m_Normal: + m_Background: {fileID: -573041650897247223, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: -7527060558648309217, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 7832598784815925287, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: -4454209017672384243, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 4047951448802137905, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 8556163245987529883, guid: 0000000000000000d000000000000000, + type: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 3 + m_Bottom: 3 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 2 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 32 + m_FixedHeight: 20 + m_StretchWidth: 0 + m_StretchHeight: 0 + SceneIndent1: 20 + SceneIndent2: 20 + ProjectViewCounterLabel: + m_Name: label + m_Normal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0.203, g: 0.203, b: 0.203, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 0.01960784} + m_OnNormal: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 0.01960784} + m_OnFocused: + m_Background: {fileID: 0} + m_ScaledBackgrounds: [] + m_TextColor: {r: 0, g: 0, b: 0, a: 0.01960784} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 2 + m_Bottom: 2 + m_Padding: + m_Left: 2 + m_Right: 4 + m_Top: 1 + m_Bottom: 2 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 3459068928204737762, guid: 0000000000000000d000000000000000, + type: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 5 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 0 + m_ImagePosition: 3 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + MultiSelect: + m_Text: + m_Image: {fileID: 2800000, guid: e0208e3a37267be46ba2d10fad510cef, type: 3} + m_Tooltip: diff --git a/Assets/Scenes/Main_scene/LightingData.asset.meta b/Assets/Asset Cleaner/CleanerStyle.asset.meta similarity index 63% rename from Assets/Scenes/Main_scene/LightingData.asset.meta rename to Assets/Asset Cleaner/CleanerStyle.asset.meta index 42bab9ed..ef95bba6 100644 --- a/Assets/Scenes/Main_scene/LightingData.asset.meta +++ b/Assets/Asset Cleaner/CleanerStyle.asset.meta @@ -1,8 +1,8 @@ -fileFormatVersion: 2 -guid: 40a73520157b85a4199ff8fa3f867660 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 112000000 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 7f4dfe9d348c0ff4cb525a0b2c48fc34 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Content.meta b/Assets/Asset Cleaner/Content.meta new file mode 100644 index 00000000..932cb5f4 --- /dev/null +++ b/Assets/Asset Cleaner/Content.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f45f9c9770a8371428fce5031e1c7c5c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Content/ac_back1.png b/Assets/Asset Cleaner/Content/ac_back1.png new file mode 100644 index 00000000..651fc4af --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_back1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d20ca2e006bd0c5515039fa3a1d567aac63f307b855bf76202de774574472c1d +size 2206 diff --git a/Assets/Asset Cleaner/Content/ac_back1.png.meta b/Assets/Asset Cleaner/Content/ac_back1.png.meta new file mode 100644 index 00000000..aa3465ba --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_back1.png.meta @@ -0,0 +1,110 @@ +fileFormatVersion: 2 +guid: bfec65de7ee2e114199f83507d375a6f +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + 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: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Content/ac_delete_asset.png b/Assets/Asset Cleaner/Content/ac_delete_asset.png new file mode 100644 index 00000000..30977c5f --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_delete_asset.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d65d95845f9480e84b085132b6085d3ff47e58709c5ff6d646d2fd08364fd9a +size 991 diff --git a/Assets/Scenes/Main_scene/Lightmap-11_comp_light.exr.meta b/Assets/Asset Cleaner/Content/ac_delete_asset.png.meta similarity index 62% rename from Assets/Scenes/Main_scene/Lightmap-11_comp_light.exr.meta rename to Assets/Asset Cleaner/Content/ac_delete_asset.png.meta index 11202a68..59297639 100644 --- a/Assets/Scenes/Main_scene/Lightmap-11_comp_light.exr.meta +++ b/Assets/Asset Cleaner/Content/ac_delete_asset.png.meta @@ -1,96 +1,110 @@ -fileFormatVersion: 2 -guid: 111dd15a59f754d46a87913104dbb489 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: f4b3e5a29ec20194a8ba1d6cf7b1b037 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + 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: 0 + 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: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Content/ac_delete_scene_asset.png b/Assets/Asset Cleaner/Content/ac_delete_scene_asset.png new file mode 100644 index 00000000..65b09fd8 --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_delete_scene_asset.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:433f21715118bb83be7e929e563a95453473a041a78b9bdbaa9f5e2f3d40cad2 +size 4459 diff --git a/Assets/Scenes/Main_scene/Lightmap-12_comp_light.exr.meta b/Assets/Asset Cleaner/Content/ac_delete_scene_asset.png.meta similarity index 62% rename from Assets/Scenes/Main_scene/Lightmap-12_comp_light.exr.meta rename to Assets/Asset Cleaner/Content/ac_delete_scene_asset.png.meta index 1646ab57..72e27d54 100644 --- a/Assets/Scenes/Main_scene/Lightmap-12_comp_light.exr.meta +++ b/Assets/Asset Cleaner/Content/ac_delete_scene_asset.png.meta @@ -1,96 +1,110 @@ -fileFormatVersion: 2 -guid: 6d18636b5c1d2ad49869d53de6329a8a -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 3fec3bf4c4f5e2d48835dbe2f21aa7d0 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + 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: 0 + 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: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Content/ac_forward1.png b/Assets/Asset Cleaner/Content/ac_forward1.png new file mode 100644 index 00000000..891c05ca --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_forward1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:614f69a068f3976f1a0deca1b08906fdfa86943cbde3e67601ec949df2a4d668 +size 5463 diff --git a/Assets/Asset Cleaner/Content/ac_forward1.png.meta b/Assets/Asset Cleaner/Content/ac_forward1.png.meta new file mode 100644 index 00000000..b1cc43d5 --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_forward1.png.meta @@ -0,0 +1,110 @@ +fileFormatVersion: 2 +guid: 07bb28c80f378c64194dd46c34b2d6c1 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + 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: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Content/ac_lock.png b/Assets/Asset Cleaner/Content/ac_lock.png new file mode 100644 index 00000000..6400857a --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_lock.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46eaa0132ef121f2768ff0ac30f80575b27a42bb183db1f8b3667f8b7bcfb1f3 +size 7446 diff --git a/Assets/Scenes/Main_scene/Lightmap-0_comp_light.exr.meta b/Assets/Asset Cleaner/Content/ac_lock.png.meta similarity index 62% rename from Assets/Scenes/Main_scene/Lightmap-0_comp_light.exr.meta rename to Assets/Asset Cleaner/Content/ac_lock.png.meta index accd3112..5c6b4a56 100644 --- a/Assets/Scenes/Main_scene/Lightmap-0_comp_light.exr.meta +++ b/Assets/Asset Cleaner/Content/ac_lock.png.meta @@ -1,96 +1,110 @@ -fileFormatVersion: 2 -guid: a5ade20c3b0640c4aa089c87345bf1b9 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: c5fd88366c67daf4585631953fa79779 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + 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: 0 + 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: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Content/ac_multiselect.png b/Assets/Asset Cleaner/Content/ac_multiselect.png new file mode 100644 index 00000000..4a3b0b19 --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_multiselect.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25d97bc96de612ec3cdc829fb0b0be44c1f3e87248a38430455b3efd7035e0b2 +size 282 diff --git a/Assets/Asset Cleaner/Content/ac_multiselect.png.meta b/Assets/Asset Cleaner/Content/ac_multiselect.png.meta new file mode 100644 index 00000000..6d733d50 --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_multiselect.png.meta @@ -0,0 +1,110 @@ +fileFormatVersion: 2 +guid: e0208e3a37267be46ba2d10fad510cef +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + 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: 0 + 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: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Content/ac_unlock.png b/Assets/Asset Cleaner/Content/ac_unlock.png new file mode 100644 index 00000000..b6880bcb --- /dev/null +++ b/Assets/Asset Cleaner/Content/ac_unlock.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c4821e9ab489350a10eeb792197a700d5074947709528e909a28d310fef28df +size 7623 diff --git a/Assets/Scenes/Main_scene/Lightmap-10_comp_light.exr.meta b/Assets/Asset Cleaner/Content/ac_unlock.png.meta similarity index 62% rename from Assets/Scenes/Main_scene/Lightmap-10_comp_light.exr.meta rename to Assets/Asset Cleaner/Content/ac_unlock.png.meta index 13862aa9..cd74dd58 100644 --- a/Assets/Scenes/Main_scene/Lightmap-10_comp_light.exr.meta +++ b/Assets/Asset Cleaner/Content/ac_unlock.png.meta @@ -1,96 +1,110 @@ -fileFormatVersion: 2 -guid: 7f2cb3f82f1849348bd89908a38ba764 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: e755b5ef4cb427f469ba580ae9956237 +TextureImporter: + fileIDToRecycleName: {} + externalObjects: {} + serializedVersion: 9 + 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: 0 + 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: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Android + maxTextureSize: 32 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + vertices: [] + indices: + edges: [] + weights: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Data.meta b/Assets/Asset Cleaner/Data.meta new file mode 100644 index 00000000..711dd3ac --- /dev/null +++ b/Assets/Asset Cleaner/Data.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4848aa5846cd6264c984dcc6cd9d72af +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Data/AufSerializableData.cs b/Assets/Asset Cleaner/Data/AufSerializableData.cs new file mode 100644 index 00000000..cd459e8d --- /dev/null +++ b/Assets/Asset Cleaner/Data/AufSerializableData.cs @@ -0,0 +1,74 @@ +using System; +using System.Linq; + +namespace Asset_Cleaner { + [Serializable] + class AufSerializableData { + public const int CurrentVersion = 1; + public int Version; + public bool MarkRed; + public int RebuildCacheOnDemand; + public bool ShowInfoBox; + public string IgnorePathContainsCombined; + public bool IgnoreMaterial; + public bool IgnoreScriptable; + + static int BoolToInt(bool val) { + return val ? 2 : 1; + } + + static bool IntToBool(int val, bool defaultVal) { + switch (val) { + case 2: + return true; + case 1: + return false; + default: + return defaultVal; + } + } + + public static AufSerializableData Default() { + return new AufSerializableData { + Version = CurrentVersion, + MarkRed = true, + ShowInfoBox = true, + IgnorePathContainsCombined = "Gizmos;Resources;Editor;Asset Cleaner;Asset Usage Finder;", + IgnoreMaterial = false, + IgnoreScriptable = true, + RebuildCacheOnDemand = 2, + }; + } + + public static void OnSerialize(in Config src, out AufSerializableData result) { + result = new AufSerializableData(); + result.Version = CurrentVersion; + result.MarkRed = src.MarkRed; + result.ShowInfoBox = src.ShowInfoBox; + result.IgnorePathContainsCombined = src.IgnorePathContainsCombined; + result.IgnoreMaterial = src.IgnoreMaterial; + result.IgnoreScriptable = src.IgnoreScriptable; + result.RebuildCacheOnDemand = BoolToInt(src.RebuildCacheOnDemand); + } + + public static void OnDeserialize(in AufSerializableData src, ref Config result) { + var def = Default(); + + result.MarkRed = src.MarkRed; + result.IgnorePathContainsCombined = src.IgnorePathContainsCombined; + result.ShowInfoBox = src.ShowInfoBox; + result.IgnorePathContains = result.IgnorePathContainsCombined + .Split(';') + .Select(s => s.Trim()) + .Where(s => !string.IsNullOrWhiteSpace(s)) + .ToArray(); + result.IgnoreMaterial = src.IgnoreMaterial; + result.IgnoreScriptable = src.IgnoreScriptable; + result.RebuildCacheOnDemand = IntToBool(src.RebuildCacheOnDemand, def.RebuildCacheOnDemand == 2); + } + + public bool Valid() { + return Version == CurrentVersion || IgnorePathContainsCombined == null; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/AufSerializableData.cs.meta b/Assets/Asset Cleaner/Data/AufSerializableData.cs.meta new file mode 100644 index 00000000..08e6ecd6 --- /dev/null +++ b/Assets/Asset Cleaner/Data/AufSerializableData.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 14980ecc573d44c59b5f9323603c7bdf +timeCreated: 1588518687 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/CleanerStyleAsset.cs b/Assets/Asset Cleaner/Data/CleanerStyleAsset.cs new file mode 100644 index 00000000..35cd9a10 --- /dev/null +++ b/Assets/Asset Cleaner/Data/CleanerStyleAsset.cs @@ -0,0 +1,105 @@ +using System; +using System.Linq; +using UnityEditor; +using UnityEngine; +using Object = UnityEngine.Object; + +#pragma warning disable 649 + +namespace Asset_Cleaner { + class CleanerStyleAsset : ScriptableObject { + [Serializable] + public class Style { + public Color RedHighlight = new Color(1, 0, 0, 1f); + + public GUIContent Lock; + public GUIStyle LockBtn = new GUIStyle(); + public GUIStyle SampleBtn = new GUIStyle(); + + public GUIContent Unlock; + public GUIStyle UnlockBtn = new GUIStyle(); + + public GUIContent RemoveFile; + public GUIContent RemoveScene; + + public GUIStyle RowMainAssetBtn = new GUIStyle(); + public GUIStyle RemoveUnusedBtn = new GUIStyle(); + + public GUIStyle CurrentBtn = new GUIStyle(); + + public GUIContent ArrowL; + public GUIContent ArrowR; + public GUIStyle ArrowBtn = new GUIStyle(); + + public float SceneIndent1 = 20f; + public float SceneIndent2 = 20f; + public GUIStyle ProjectViewCounterLabel; + + public GUIContent MultiSelect; + + public static bool TryFindSelf(out Style value) { + const string typeName = nameof(CleanerStyleAsset); + + var guids = AssetDatabase.FindAssets($"t:{typeName}"); + if (!guids.Any()) { + AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); + } + + Asr.IsTrue(guids.Length > 0, $"No '{typeName}' assets found"); + var res = guids.Select(AssetDatabase.GUIDToAssetPath).Select(t => (CleanerStyleAsset) AssetDatabase.LoadAssetAtPath(t, typeof(CleanerStyleAsset))).FirstOrDefault(); + if (res == null) { + value = default; + return false; + } + + value = EditorGUIUtility.isProSkin ? res.Pro : res.Personal; + return value != null; + } + } +#pragma warning disable 0649 + public Style Pro; + public Style Personal; +#pragma warning restore + + [CustomEditor(typeof(CleanerStyleAsset))] + class Editor : UnityEditor.Editor { + public override void OnInspectorGUI() { +#if false + if (GUILayout.Button("Update Btn backgrounds")) { + var targ = (CleanerStyleAsset) target; + Set(targ.Pro); + } +#endif + EditorGUI.BeginChangeCheck(); + base.OnInspectorGUI(); + if (EditorGUI.EndChangeCheck()) + UnityEditorInternal.InternalEditorUtility.RepaintAllViews(); + } + +#if false + static void Set(Style style) { + var st = style; + var sample = st.SampleBtn; + + foreach (var btn in new[] { + st.LockBtn, + st.UnlockBtn, + st.RowMainAssetBtn, + st.RemoveUnusedBtn, + st.CurrentBtn, + st.ArrowBtn, + }) { + btn.normal = sample.normal; + btn.hover = sample.hover; + btn.active = sample.active; + btn.focused = sample.focused; + btn.onNormal = sample.onNormal; + btn.onHover = sample.onHover; + btn.onActive = sample.onActive; + btn.onFocused = sample.onFocused; + } + } +#endif + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/CleanerStyleAsset.cs.meta b/Assets/Asset Cleaner/Data/CleanerStyleAsset.cs.meta new file mode 100644 index 00000000..7e4f59be --- /dev/null +++ b/Assets/Asset Cleaner/Data/CleanerStyleAsset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16578cbec6a24ac4d951b5f328a970ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Data/FindModeEnum.cs b/Assets/Asset Cleaner/Data/FindModeEnum.cs new file mode 100644 index 00000000..76bc4608 --- /dev/null +++ b/Assets/Asset Cleaner/Data/FindModeEnum.cs @@ -0,0 +1,8 @@ +namespace Asset_Cleaner { + enum FindModeEnum { + None = 0, + File = 1, + Scene = 2, + Stage = 3, + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/FindModeEnum.cs.meta b/Assets/Asset Cleaner/Data/FindModeEnum.cs.meta new file mode 100644 index 00000000..1c0aa794 --- /dev/null +++ b/Assets/Asset Cleaner/Data/FindModeEnum.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34e14d6333c649f4fb74ccdb6c86d8b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Data/Globals.meta b/Assets/Asset Cleaner/Data/Globals.meta new file mode 100644 index 00000000..1afd9002 --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f94bcb0962724eeea17b007a6ddfd885 +timeCreated: 1596213773 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/BacklinkStore.cs b/Assets/Asset Cleaner/Data/Globals/BacklinkStore.cs new file mode 100644 index 00000000..2ad42a20 --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/BacklinkStore.cs @@ -0,0 +1,286 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEditorInternal; +using Debug = UnityEngine.Debug; +using Object = UnityEngine.Object; + +namespace Asset_Cleaner { + class BacklinkStore { + public bool Initialized { get; private set; } + + public Dictionary UnusedFiles { get; private set; } + public Dictionary UnusedScenes { get; private set; } + public Dictionary Backward { get; private set; } + public Dictionary FoldersWithQty { get; private set; } + + Dictionary _forward; + List Folders { get; set; } + + + public void Init() { + FoldersWithQty = new Dictionary(); + _forward = new Dictionary(); + Backward = new Dictionary(); + + var defaultAss = typeof(DefaultAsset); + var asmdefAss = typeof(AssemblyDefinitionAsset); + + var paths = AssetDatabase.GetAllAssetPaths() + .Distinct() + .Where(s => s.StartsWith("Assets") || s.StartsWith("ProjectSettings")) + .Where(p => { + var t = AssetDatabase.GetMainAssetTypeAtPath(p); + return !t.IsAssignableFromInverse(defaultAss) && !t.IsAssignableFromInverse(asmdefAss); + }) + .ToArray(); + + + var i = 0f; + var total = (float) paths.Length; + foreach (var path in paths) { + _FillFwAndBacklinks(path); + var percent = i * 100f / total; + if (Math.Abs(percent % 5f) < 0.01f) { + if (EditorUtility.DisplayCancelableProgressBar( + "Please wait...", + "Building the cache...", percent)) + Debug.LogError("Cache build aborted"); + } + + i++; + } + + EditorUtility.ClearProgressBar(); + + // FillFoldersWithQtyByPaths + List foldersAll = new List(); + foreach (var path in paths) { + var folders = GetAllFoldersFromPath(path); + foldersAll.AddRange(folders); + } + + Folders = foldersAll.Distinct().OrderBy(p => p).ToList(); + UpdateUnusedAssets(); + Initialized = true; + } + + void _FillFwAndBacklinks(string path) { + var dependencies = _Dependencies(path); + var hs = new FwMeta {Dependencies = new HashSet(dependencies)}; + _forward.Add(path, hs); + foreach (var backPath in dependencies) { + if (!Backward.TryGetValue(backPath, out var val)) { + val = new BwMeta(); + val.Lookup = new HashSet(); + Backward.Add(backPath, val); + } + + val.Lookup.Add(path); + } + } + + + void UpdateFoldersWithQtyByPath(string path) { + var folders = GetAllFoldersFromPath(path); + foreach (var folder in folders) { + if (!Folders.Exists(p => p == folder)) + Folders.Add(folder); + } + } + + + static List GetAllFoldersFromPath(string p) { + var result = new List(); + var i = p.IndexOf('/', 0); + while (i > 0) { + var item = p.Substring(0, i); + result.Add(item); + i = p.IndexOf('/', i + 1); + } + + return result.Distinct().ToList(); + } + + public void UpdateUnusedAssets() { + var all = new HashSet(_forward.Keys); + var withBacklinks = + new HashSet(Backward.Where(kv => kv.Value.Lookup.Count > 0).Select(kv => kv.Key)); + + all.ExceptWith(withBacklinks); + all.RemoveWhere(SearchUtils.IsFileIgrnoredBySettings); + + var unusedAssets = all; + + var scenes = unusedAssets.Where(s => + AssetDatabase.GetMainAssetTypeAtPath(s).IsAssignableFromInverse(typeof(SceneAsset))).ToArray(); + + unusedAssets.ExceptWith(scenes); + var files = unusedAssets; + UnusedFiles = new Dictionary(); + + foreach (var file in files) UnusedFiles[file] = CommonUtils.Size(file); + + UnusedScenes = new Dictionary(); + foreach (var scene in scenes) UnusedScenes[scene] = CommonUtils.Size(scene); + + // UpdateFoldersWithQty(); + foreach (var folder in Folders) { + var unusedFilesQty = UnusedFiles.Count(p => p.Key.StartsWith(folder)); + var unusedScenesQty = UnusedScenes.Count(p => p.Key.StartsWith(folder)); + long size = 0; + size = UnusedFiles.Where((p => p.Key.StartsWith(folder))).Sum(p => p.Value); + size += UnusedScenes.Where(p => p.Key.StartsWith(folder)).Sum(p => p.Value); + + FoldersWithQty.TryGetValue(folder, out var folderWithQty); + if (folderWithQty == null) { + FoldersWithQty.Add(folder, new UnusedQty(unusedFilesQty, unusedScenesQty, size)); + } + else { + folderWithQty.UnusedFilesQty = unusedFilesQty; + folderWithQty.UnusedScenesQty = unusedScenesQty; + folderWithQty.UnusedSize = size; + } + } + } + + + public void Remove(string path) { + if (!_forward.TryGetValue(path, out var fwMeta)) + return; + + foreach (var dependency in fwMeta.Dependencies) { + if (!Backward.TryGetValue(dependency, out var dep)) continue; + + dep.Lookup.Remove(path); + } + + _forward.Remove(path); + UpdateFoldersWithQtyByPath(path); + } + + public void Replace(string src, string dest) { + _Upd(_forward); + _Upd(Backward); + UpdateFoldersWithQtyByPath(dest); + + void _Upd(Dictionary dic) { + if (!dic.TryGetValue(src, out var refs)) return; + + dic.Remove(src); + dic.Add(dest, refs); + } + } + + public void RebuildFor(string path, bool remove) { + if (!_forward.TryGetValue(path, out var fwMeta)) { + fwMeta = new FwMeta(); + _forward.Add(path, fwMeta); + } + else if (remove) { + foreach (var dependency in fwMeta.Dependencies) { + if (!Backward.TryGetValue(dependency, out var backDep)) continue; + + backDep.Lookup.Remove(path); + } + + fwMeta.Dependencies = null; + } + + var dependencies = _Dependencies(path); + fwMeta.Dependencies = new HashSet(dependencies); + + foreach (var backPath in dependencies) { + if (!Backward.TryGetValue(backPath, out var bwMeta)) { + bwMeta = new BwMeta {Lookup = new HashSet()}; + Backward.Add(backPath, bwMeta); + } + else if (remove) + bwMeta.Lookup.Remove(path); + + bwMeta.Lookup.Add(path); + } + + if (!remove) { + UpdateFoldersWithQtyByPath(path); + } + } + + + static string[] _Dependencies(string s) { + if (s[0] == 'A') + return AssetDatabase.GetDependencies(s, false); + var obj = LoadAllOrMain(s)[0]; + return GetDependenciesManualPaths().ToArray(); + + Object[] LoadAllOrMain(string assetPath) { + // prevents error "Do not use readobjectthreaded on scene objects!" + return typeof(SceneAsset) == AssetDatabase.GetMainAssetTypeAtPath(assetPath) + ? new[] {AssetDatabase.LoadMainAssetAtPath(assetPath)} + : AssetDatabase.LoadAllAssetsAtPath(assetPath); + } + + IEnumerable GetDependenciesManualPaths() { + if (obj is EditorBuildSettings) { + foreach (var scene in EditorBuildSettings.scenes) + yield return scene.path; + } + + using (var so = new SerializedObject(obj)) { + var props = so.GetIterator(); + while (props.Next(true)) { + switch (props.propertyType) { + case SerializedPropertyType.ObjectReference: + var propsObjectReferenceValue = props.objectReferenceValue; + if (!propsObjectReferenceValue) continue; + + var assetPath = AssetDatabase.GetAssetPath(propsObjectReferenceValue); + yield return assetPath; + break; +#if later + case SerializedPropertyType.Generic: + case SerializedPropertyType.ExposedReference: + case SerializedPropertyType.ManagedReference: + break; +#endif + default: + continue; + } + } + } + } + } + + + class FwMeta { + public HashSet Dependencies; + } + + public class BwMeta { + public HashSet Lookup; + } + + public class UnusedQty { + public int UnusedFilesQty; + public int UnusedScenesQty; + + public long UnusedSize; + + public UnusedQty() { + Init(0, 0, 0); + } + + public UnusedQty(int unusedFilesQty, int unusedScenesQty, long unusedSize) { + Init(unusedFilesQty, unusedScenesQty, unusedSize); + } + + private void Init(int unusedFilesQty, int unusedScenesQty, long unusedSize) { + UnusedFilesQty = unusedFilesQty; + UnusedScenesQty = unusedScenesQty; + UnusedSize = unusedSize; + } + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/BacklinkStore.cs.meta b/Assets/Asset Cleaner/Data/Globals/BacklinkStore.cs.meta new file mode 100644 index 00000000..5c78e15b --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/BacklinkStore.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 004e5680782f4e679ae93027d2d40023 +timeCreated: 1577106223 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/Config.cs b/Assets/Asset Cleaner/Data/Globals/Config.cs new file mode 100644 index 00000000..ee149e09 --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/Config.cs @@ -0,0 +1,20 @@ +namespace Asset_Cleaner { + class Config { + // serialized + public bool MarkRed; + public string IgnorePathContainsCombined; + public bool ShowInfoBox; + public bool RebuildCacheOnDemand; + + // todo make type array + public bool IgnoreMaterial; + public bool IgnoreScriptable; + + // serialized only while window is opened + public bool Locked; + + // non-serialized + public string[] IgnorePathContains; + public string InitializationTime; + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/Config.cs.meta b/Assets/Asset Cleaner/Data/Globals/Config.cs.meta new file mode 100644 index 00000000..40c6c816 --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/Config.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a6ff796e4dab4324887a303cba29eed4 +timeCreated: 1577117228 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/PersistentUndoRedoState.cs b/Assets/Asset Cleaner/Data/Globals/PersistentUndoRedoState.cs new file mode 100644 index 00000000..3f5dbcdb --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/PersistentUndoRedoState.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace Asset_Cleaner { + [Serializable] + class PersistentUndoRedoState { + public List History = new List(); + public int Id; + + public void Deconstruct(out List list, out int id) { + id = Id; + list = History; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/PersistentUndoRedoState.cs.meta b/Assets/Asset Cleaner/Data/Globals/PersistentUndoRedoState.cs.meta new file mode 100644 index 00000000..ca3c1561 --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/PersistentUndoRedoState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5414db21dfea4d7eaff8ce4c8f106c8d +timeCreated: 1596213717 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/UndoRedoState.cs b/Assets/Asset Cleaner/Data/Globals/UndoRedoState.cs new file mode 100644 index 00000000..ce1bcd1d --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/UndoRedoState.cs @@ -0,0 +1,6 @@ +namespace Asset_Cleaner { + class UndoRedoState { + public bool UndoEnabled; + public bool RedoEnabled; + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/UndoRedoState.cs.meta b/Assets/Asset Cleaner/Data/Globals/UndoRedoState.cs.meta new file mode 100644 index 00000000..d2a59fb9 --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/UndoRedoState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c3ac9efa32c8491aa8a11749f8020d96 +timeCreated: 1596213776 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/WindowData.cs b/Assets/Asset Cleaner/Data/Globals/WindowData.cs new file mode 100644 index 00000000..0ca85f7a --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/WindowData.cs @@ -0,0 +1,14 @@ +using UnityEngine; + +namespace Asset_Cleaner { + class WindowData { + public bool ExpandFiles; + public bool ExpandScenes; + public Vector2 ScrollPos; + public CleanerStyleAsset.Style Style; + public GUIContent SceneFoldout; + public PrevClick Click; + public AufWindow Window; + public FindModeEnum FindFrom; + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Globals/WindowData.cs.meta b/Assets/Asset Cleaner/Data/Globals/WindowData.cs.meta new file mode 100644 index 00000000..66e64ed9 --- /dev/null +++ b/Assets/Asset Cleaner/Data/Globals/WindowData.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8481f043b2414c08a45957dcd6035fbe +timeCreated: 1575305740 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/InSceneResult.cs b/Assets/Asset Cleaner/Data/InSceneResult.cs new file mode 100644 index 00000000..d2bc28a7 --- /dev/null +++ b/Assets/Asset Cleaner/Data/InSceneResult.cs @@ -0,0 +1,11 @@ +using Leopotam.Ecs; + +namespace Asset_Cleaner { + class InSceneResult : IEcsAutoReset { + public string ScenePath; + + public void Reset() { + ScenePath = default; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/InSceneResult.cs.meta b/Assets/Asset Cleaner/Data/InSceneResult.cs.meta new file mode 100644 index 00000000..11fbb3ae --- /dev/null +++ b/Assets/Asset Cleaner/Data/InSceneResult.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 013577ffef1140109e8367f2a5f75fa6 +timeCreated: 1577269723 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/PrevClick.cs b/Assets/Asset Cleaner/Data/PrevClick.cs new file mode 100644 index 00000000..8b01879f --- /dev/null +++ b/Assets/Asset Cleaner/Data/PrevClick.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +namespace Asset_Cleaner { + public struct PrevClick { + const float DoubleClickTime = 0.5f; + Object _target; + float _timeClicked; + + public PrevClick(Object target) { + _target = target; + _timeClicked = Time.realtimeSinceStartup; + } + + public bool IsDoubleClick(Object o) { + return _target == o && Time.realtimeSinceStartup - _timeClicked < DoubleClickTime; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/PrevClick.cs.meta b/Assets/Asset Cleaner/Data/PrevClick.cs.meta new file mode 100644 index 00000000..a64fb217 --- /dev/null +++ b/Assets/Asset Cleaner/Data/PrevClick.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 31c0f204d1b044caaa02a0726f11a270 +timeCreated: 1576087327 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Result.cs b/Assets/Asset Cleaner/Data/Result.cs new file mode 100644 index 00000000..3394ae24 --- /dev/null +++ b/Assets/Asset Cleaner/Data/Result.cs @@ -0,0 +1,19 @@ +using Leopotam.Ecs; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace Asset_Cleaner { + class Result : IEcsAutoReset { + public string FilePath; + public Object File; + public Object MainFile; + public GameObject RootGo; + + public void Reset() { + FilePath = default; + File = default; + MainFile = default; + RootGo = default; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/Result.cs.meta b/Assets/Asset Cleaner/Data/Result.cs.meta new file mode 100644 index 00000000..2df86cb3 --- /dev/null +++ b/Assets/Asset Cleaner/Data/Result.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 46f4fd24243adc749b377209f744d628 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Data/SceneDetails.cs b/Assets/Asset Cleaner/Data/SceneDetails.cs new file mode 100644 index 00000000..51c52473 --- /dev/null +++ b/Assets/Asset Cleaner/Data/SceneDetails.cs @@ -0,0 +1,20 @@ +using Leopotam.Ecs; +using UnityEngine.SceneManagement; + +namespace Asset_Cleaner { + class SceneDetails : IEcsAutoReset { + public string Path; + public Scene Scene; + public bool SearchRequested; + public bool SearchDone; + public bool WasOpened; + + public void Reset() { + Path = default; + Scene = default; + SearchRequested = default; + SearchDone = default; + WasOpened = default; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SceneDetails.cs.meta b/Assets/Asset Cleaner/Data/SceneDetails.cs.meta new file mode 100644 index 00000000..70d350a9 --- /dev/null +++ b/Assets/Asset Cleaner/Data/SceneDetails.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 14749f86c2c14febb592442508f8c23a +timeCreated: 1577266613 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SceneResult.cs b/Assets/Asset Cleaner/Data/SceneResult.cs new file mode 100644 index 00000000..df6aef6a --- /dev/null +++ b/Assets/Asset Cleaner/Data/SceneResult.cs @@ -0,0 +1,11 @@ +using Leopotam.Ecs; + +namespace Asset_Cleaner { + class SceneResult : IEcsAutoReset { + public string PathNicified; + + public void Reset() { + PathNicified = default; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SceneResult.cs.meta b/Assets/Asset Cleaner/Data/SceneResult.cs.meta new file mode 100644 index 00000000..83dcca84 --- /dev/null +++ b/Assets/Asset Cleaner/Data/SceneResult.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 338e9e86c9274f91808429753a912d4b +timeCreated: 1576083610 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SearchArg.cs b/Assets/Asset Cleaner/Data/SearchArg.cs new file mode 100644 index 00000000..f9c21de1 --- /dev/null +++ b/Assets/Asset Cleaner/Data/SearchArg.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using Leopotam.Ecs; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace Asset_Cleaner { + class SearchArg : IEcsAutoReset { + public Object Target; + public Object Main; + public string FilePath; + public Option SubAssets; + public Scene Scene; + public List UnusedAssetsFiltered; + public List UnusedScenesFiltered; + + public void Reset() { + UnusedAssetsFiltered = default; + UnusedScenesFiltered = default; + Target = default; + Main = default; + SubAssets = default; + Scene = default; + FilePath = default; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SearchArg.cs.meta b/Assets/Asset Cleaner/Data/SearchArg.cs.meta new file mode 100644 index 00000000..34e9784b --- /dev/null +++ b/Assets/Asset Cleaner/Data/SearchArg.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a6b25ca9296c9e41affadc9ccecb1f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Data/SearchResultGui.cs b/Assets/Asset Cleaner/Data/SearchResultGui.cs new file mode 100644 index 00000000..472f84da --- /dev/null +++ b/Assets/Asset Cleaner/Data/SearchResultGui.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using Leopotam.Ecs; +using UnityEditor; +using UnityEngine; + +namespace Asset_Cleaner { + class SearchResultGui : IEcsAutoReset { + public SerializedObject SerializedObject; + public List Properties; + public GUIContent Label; + public string TransformPath; + + public void Reset() { + SerializedObject?.Dispose(); + SerializedObject = default; + + if (Properties != default) + foreach (var propertyData in Properties) { + propertyData.Property.Dispose(); + } + + Properties = default; + Label = default; + TransformPath = default; + } + + public class PropertyData { + public SerializedProperty Property; + public GUIContent Content; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SearchResultGui.cs.meta b/Assets/Asset Cleaner/Data/SearchResultGui.cs.meta new file mode 100644 index 00000000..5cf55aeb --- /dev/null +++ b/Assets/Asset Cleaner/Data/SearchResultGui.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 14f26ff078c04c5685fdbb3ec3f92382 +timeCreated: 1576168925 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SelectionChanged.cs b/Assets/Asset Cleaner/Data/SelectionChanged.cs new file mode 100644 index 00000000..cb355b57 --- /dev/null +++ b/Assets/Asset Cleaner/Data/SelectionChanged.cs @@ -0,0 +1,17 @@ +using Leopotam.Ecs; +using UnityEngine; +using UnityEngine.SceneManagement; + +namespace Asset_Cleaner { + class SelectionChanged : IEcsAutoReset { + public Object Target; + public Scene Scene; + public FindModeEnum From; + + public void Reset() { + Target = default; + Scene = default; + From = default; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SelectionChanged.cs.meta b/Assets/Asset Cleaner/Data/SelectionChanged.cs.meta new file mode 100644 index 00000000..6a19955c --- /dev/null +++ b/Assets/Asset Cleaner/Data/SelectionChanged.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1d0dc4d007bb4ebbbeea6626197d17b9 +timeCreated: 1575365553 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SelectionEntry.cs b/Assets/Asset Cleaner/Data/SelectionEntry.cs new file mode 100644 index 00000000..87e0b117 --- /dev/null +++ b/Assets/Asset Cleaner/Data/SelectionEntry.cs @@ -0,0 +1,31 @@ +using System; +using UnityEditor; +using Object = UnityEngine.Object; + +namespace Asset_Cleaner { + [Serializable] + class SelectionEntry { + public bool IsGuids; + public string[] Guids; + + public Object[] SceneObjects; + + public bool Valid() { + if (IsGuids) { + foreach (var guid in Guids) { + var path = AssetDatabase.GUIDToAssetPath(guid); + if (!string.IsNullOrEmpty(path)) + return true; + } + + return false; + } + + foreach (var sceneObject in SceneObjects) + if (sceneObject) + return true; + + return false; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Data/SelectionEntry.cs.meta b/Assets/Asset Cleaner/Data/SelectionEntry.cs.meta new file mode 100644 index 00000000..427ee7c1 --- /dev/null +++ b/Assets/Asset Cleaner/Data/SelectionEntry.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2b4476be23474ea4b20262c0ee59983c +timeCreated: 1596139978 \ No newline at end of file diff --git a/Assets/Asset Cleaner/IgnoreTypes.cs b/Assets/Asset Cleaner/IgnoreTypes.cs new file mode 100644 index 00000000..0bc09e4f --- /dev/null +++ b/Assets/Asset Cleaner/IgnoreTypes.cs @@ -0,0 +1,34 @@ +using System; +using UnityEditor; +using UnityEditorInternal; +using UnityEngine; + +namespace Asset_Cleaner { + static class IgnoreTypes { + public static bool Check(string path, out Type type) { + type = AssetDatabase.GetMainAssetTypeAtPath(path); + if (type == null) return false; + var conf = Globals.Value; + + if (type.IsAssignableFromInverse(typeof(MonoScript))) return true; + if (type.IsAssignableFromInverse(typeof(DefaultAsset))) return true; + if (conf.IgnoreScriptable && type.IsAssignableFromInverse(typeof(ScriptableObject))) return true; + + if (type.IsAssignableFromInverse(typeof(Shader))) return true; + if (type.IsAssignableFromInverse(typeof(ComputeShader))) return true; + if (type.IsAssignableFromInverse(typeof(ShaderVariantCollection))) return true; +#if UNITY_2019_3_OR_NEWER + if (type.IsAssignableFromInverse(typeof(UnityEngine.Experimental.Rendering.RayTracingShader))) return true; // todo: track of Experimental namespace +#endif + + if (type.IsAssignableFromInverse(typeof(TextAsset))) return true; + if (type.IsAssignableFromInverse(typeof(AssemblyDefinitionAsset))) return true; + + if (type.IsAssignableFromInverse(typeof(UnityEngine.U2D.SpriteAtlas))) return true; + + if (conf.IgnoreMaterial && type.IsAssignableFromInverse(typeof(Material))) return true; + + return false; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/IgnoreTypes.cs.meta b/Assets/Asset Cleaner/IgnoreTypes.cs.meta new file mode 100644 index 00000000..fcc8262b --- /dev/null +++ b/Assets/Asset Cleaner/IgnoreTypes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34f1d98d6e464e5ebee0df9de721af39 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Systems.meta b/Assets/Asset Cleaner/Systems.meta new file mode 100644 index 00000000..1953ca36 --- /dev/null +++ b/Assets/Asset Cleaner/Systems.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4b15d89b453047218955641734d4ec9e +timeCreated: 1596213484 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/External.meta b/Assets/Asset Cleaner/Systems/External.meta new file mode 100644 index 00000000..376f8581 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/External.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cbedea52d931409a8b62256873637225 +timeCreated: 1596214557 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/External/AufWindow.cs b/Assets/Asset Cleaner/Systems/External/AufWindow.cs new file mode 100644 index 00000000..d6ac61b5 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/External/AufWindow.cs @@ -0,0 +1,94 @@ +using System.Diagnostics; +using UnityEditor; +using UnityEngine; +using Debug = UnityEngine.Debug; + +namespace Asset_Cleaner { + class AufWindow : EditorWindow { + [SerializeField] PersistentUndoRedoState _persistentUndo; + + [MenuItem("Window/- Asset Cleaner %L")] + static void OpenActiveWindow() { + GetWindow(); + } + + // restore window state after recompilation + void OnEnable() { + var wd = Globals.Value = new WindowData(); + wd.Window = this; + + var firstTime = _persistentUndo == null; + Globals.Value = _persistentUndo ?? new PersistentUndoRedoState(); + Globals.Value = new BacklinkStore(); + var config = Globals.Value = new Config(); + PersistenceUtils.Load(ref config); + + if (firstTime || !config.RebuildCacheOnDemand) + Globals.Value.Init(); + + EditorApplication.update += Upd; + EditorApplication.projectWindowItemOnGUI += ProjectViewGui.OnProjectWindowItemOnGui; + + AufCtx.TryInitWorld(); + + // need to close window in case of Asset Cleaner uninstalled + if (!CleanerStyleAsset.Style.TryFindSelf(out wd.Style)) + ForceClose(); + } + + void OnGUI() { + var store = Globals.Value; + if (!store.Initialized) { + // prevent further window GUI rendering + if (!GUILayout.Button("Initialize Cache")) return; + var stopwatch = new Stopwatch(); + stopwatch.Start(); + store.Init(); + stopwatch.Stop(); + Globals.Value.InitializationTime = $"Initialized in {stopwatch.Elapsed.TotalSeconds:N} s"; + AufCtx.World.NewEntityWith(out RequestRepaintEvt _); + } + + AufCtx.OnGuiGroup.Run(); + } + + static void Upd() { + if (AufCtx.World == null) { + AufCtx.DestroyWorld(); + return; + } + + if (!Globals.Value.Initialized) return; + AufCtx.UpdateGroup.Run(); + } + + bool _closing; + + void ForceClose() { + if (_closing) return; + _closing = true; + Close(); + EditorWindow.DestroyImmediate(this); + } + + void OnDisable() { + if (AufCtx.Destroyed) return; + _persistentUndo = Globals.Value; + + AufCtx.UpdateGroup.Destroy(); + AufCtx.OnGuiGroup.Destroy(); + AufCtx.DestroyWorld(); + + Globals.Value = default; + Globals.Value = default; + Globals.Value = default; + + EditorApplication.update -= Upd; + EditorApplication.projectWindowItemOnGUI -= ProjectViewGui.OnProjectWindowItemOnGui; + + // need to close window in case of Asset Cleaner uninstalled + if (!CleanerStyleAsset.Style.TryFindSelf(out _)) + ForceClose(); + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/External/AufWindow.cs.meta b/Assets/Asset Cleaner/Systems/External/AufWindow.cs.meta new file mode 100644 index 00000000..56eb22ad --- /dev/null +++ b/Assets/Asset Cleaner/Systems/External/AufWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44ebd7bbb2bb41b4ba0187901e8d583f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Systems/External/ProcessAllAssets.cs b/Assets/Asset Cleaner/Systems/External/ProcessAllAssets.cs new file mode 100644 index 00000000..6a442734 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/External/ProcessAllAssets.cs @@ -0,0 +1,23 @@ +using UnityEditor; + +namespace Asset_Cleaner { + class ProcessAllAssets : AssetPostprocessor { + static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { + if (!AufCtx.InitStarted) return; + if (!Globals.Value.Initialized) return; + + var store = Globals.Value; + var length = movedAssets.Length; + for (var i = 0; i < length; i++) + store.Replace(movedFromAssetPaths[i], movedAssets[i]); + + foreach (var path in deletedAssets) + store.Remove(path); + + foreach (var path in importedAssets) + store.RebuildFor(path, true); + + store.UpdateUnusedAssets(); + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/External/ProcessAllAssets.cs.meta b/Assets/Asset Cleaner/Systems/External/ProcessAllAssets.cs.meta new file mode 100644 index 00000000..4840bbbc --- /dev/null +++ b/Assets/Asset Cleaner/Systems/External/ProcessAllAssets.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17c1f845fa88d38448c4cf65e9745f30 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Systems/External/ProjectViewGui.cs b/Assets/Asset Cleaner/Systems/External/ProjectViewGui.cs new file mode 100644 index 00000000..b769b22e --- /dev/null +++ b/Assets/Asset Cleaner/Systems/External/ProjectViewGui.cs @@ -0,0 +1,47 @@ +using UnityEditor; +using UnityEngine; + +namespace Asset_Cleaner { + static class ProjectViewGui { + static CleanerStyleAsset.Style _style = Globals.Value.Style; + + public static void OnProjectWindowItemOnGui(string guid, Rect rect) { + if (!Globals.Value.MarkRed) return; + + var store = Globals.Value; + if (!store.Initialized) return; + + var path = AssetDatabase.GUIDToAssetPath(guid); + ShowRowQuantity(rect, path, store); + + long size = 0; + var _ = store.UnusedFiles.TryGetValue(path, out size) || store.UnusedScenes.TryGetValue(path, out size); + + if (SearchUtils.IsUnused(path)) { + var buf = GUI.color; + { + GUI.color = _style.RedHighlight; + GUI.Box(rect, string.Empty); + } + GUI.color = buf; + GUI.Label(rect, CommonUtils.BytesToString(size), _style.ProjectViewCounterLabel); + } + } + + + static void ShowRowQuantity(Rect rect, string path, BacklinkStore backlinkStore) { + if (!AssetDatabase.IsValidFolder(path)) + return; + + backlinkStore.FoldersWithQty.TryGetValue(path, out var folderWithQty); + + var cntFiles = folderWithQty?.UnusedFilesQty ?? 0; + var cntScenes = folderWithQty?.UnusedScenesQty ?? 0; + long size = folderWithQty?.UnusedSize ?? 0; + + if (cntFiles == 0 && cntScenes == 0) return; + var countStr = cntFiles + cntScenes > 0 ? $"{cntFiles} | {cntScenes} ({CommonUtils.BytesToString(size)})" : ""; + GUI.Label(rect, countStr, _style.ProjectViewCounterLabel); + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/External/ProjectViewGui.cs.meta b/Assets/Asset Cleaner/Systems/External/ProjectViewGui.cs.meta new file mode 100644 index 00000000..da8d06e0 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/External/ProjectViewGui.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a17718cc645348b0bc4ed6d7e514ab30 +timeCreated: 1589032770 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysProcessSearch.cs b/Assets/Asset Cleaner/Systems/SysProcessSearch.cs new file mode 100644 index 00000000..b49ac618 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysProcessSearch.cs @@ -0,0 +1,56 @@ +using System; +using Leopotam.Ecs; +using UnityEngine; +using static Asset_Cleaner.AufCtx; + +namespace Asset_Cleaner { + class SysProcessSearch : IEcsRunSystem { + EcsFilter _from = null; + + EcsFilter SceneResultRows = null; + EcsFilter ScenePaths = null; + EcsFilter.Exclude SearchArgMain = null; + EcsFilter FileResultRows = null; + + public void Run() { + if (_from.IsEmpty()) + return; + + SearchArgMain.AllDestroy(); + ScenePaths.AllDestroy(); + FileResultRows.AllDestroy(); + SceneResultRows.AllDestroy(); + + var wd = Globals.Value; + if (wd.Window) + wd.Window.Repaint(); + + foreach (var i in _from.Out(out var get1, out _)) { + var t1 = get1[i]; + if (!t1.Target) continue; + wd.FindFrom = t1.From; + + try { + switch (t1.From) { + case FindModeEnum.Scene: + World.NewEntityWith(out SearchArg st); + SearchUtils.Init(st, t1.Target, t1.Scene); + SearchUtils.InScene(st, t1.Scene); + break; + case FindModeEnum.File: + World.NewEntityWith(out SearchArg arg); + SearchUtils.Init(arg, t1.Target); + SearchUtils.FilesThatReference(arg); + SearchUtils.ScenesThatContain(t1.Target); + break; + } + } + catch (Exception e) { + Debug.LogException(e); + } + } + + _from.AllUnset(); + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysProcessSearch.cs.meta b/Assets/Asset Cleaner/Systems/SysProcessSearch.cs.meta new file mode 100644 index 00000000..d898c8fd --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysProcessSearch.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: afd561b0c1384bcc82976f2624afa895 +timeCreated: 1577287503 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysRepaintWindow.cs b/Assets/Asset Cleaner/Systems/SysRepaintWindow.cs new file mode 100644 index 00000000..245d4409 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysRepaintWindow.cs @@ -0,0 +1,30 @@ +using Leopotam.Ecs; +using UnityEditor; +using UnityEditorInternal; +using UnityEngine; + +namespace Asset_Cleaner { + class RequestRepaintEvt { } + + class SysRepaintWindow : IEcsRunSystem, IEcsInitSystem { + EcsFilter Repaint = null; + + public void Init() { + var wd = Globals.Value; + wd.SceneFoldout = new GUIContent(AssetPreview.GetMiniTypeThumbnail(typeof(SceneAsset))); + wd.ExpandScenes = true; + wd.ExpandFiles = true; + wd.ScrollPos = Vector2.zero; + wd.Window.titleContent = new GUIContent("Asset Cleaner v1.0"); + } + + public void Run() { + var wd = Globals.Value; + + if (Repaint.IsEmpty()) return; + wd.Window.Repaint(); + InternalEditorUtility.RepaintAllViews(); + Repaint.AllDestroy(); + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysRepaintWindow.cs.meta b/Assets/Asset Cleaner/Systems/SysRepaintWindow.cs.meta new file mode 100644 index 00000000..bd9541f3 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysRepaintWindow.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 673a2486762b4e3da784f1657b90bb93 +timeCreated: 1577288020 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysSceneCleanup.cs b/Assets/Asset Cleaner/Systems/SysSceneCleanup.cs new file mode 100644 index 00000000..2118e592 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysSceneCleanup.cs @@ -0,0 +1,44 @@ +using Leopotam.Ecs; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine.SceneManagement; + +namespace Asset_Cleaner { + class SceneToClose : IEcsAutoReset { + public Scene Scene; + public int SelectionId; + public bool ForceClose; + + public void Reset() { + ForceClose = default; + Scene = default; + SelectionId = default; + } + } + + class SysSceneCleanup : IEcsRunSystem, IEcsDestroySystem { + EcsFilter ScenesToClose = default; + + public void Run() { + if (ScenesToClose.IsEmpty()) return; + + var selectionId = Globals.Value.Id; + + foreach (var i in ScenesToClose.Out(out var g1, out var entities)) { + var s = g1[i].Scene; + if (g1[i].SelectionId == selectionId && !g1[i].ForceClose) continue; + if (Selection.activeGameObject && Selection.activeGameObject.scene == s) continue; + if (s.isLoaded) EditorSceneManager.CloseScene(s, removeScene: true); + entities[i].Destroy(); + } + } + + // close scenes on window close + public void Destroy() { + foreach (var i in ScenesToClose.Out(out var g1, out _)) { + var s = g1[i].Scene; + if (s.isLoaded) EditorSceneManager.CloseScene(s, removeScene: true); + } + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysSceneCleanup.cs.meta b/Assets/Asset Cleaner/Systems/SysSceneCleanup.cs.meta new file mode 100644 index 00000000..870a16a8 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysSceneCleanup.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d42cae4aa3ff4500948ddd623a270120 +timeCreated: 1596142629 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysUndoRedoSelection.cs b/Assets/Asset Cleaner/Systems/SysUndoRedoSelection.cs new file mode 100644 index 00000000..39c45813 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysUndoRedoSelection.cs @@ -0,0 +1,190 @@ +using System.Linq; +using System.Runtime.InteropServices; +using Leopotam.Ecs; +using UnityEditor; +using UnityEngine; +using static Asset_Cleaner.AufCtx; + +namespace Asset_Cleaner { + class CleanupPrevArg { } + + class UndoEvt { } + + class RedoEvt { } + + class SysUndoRedoSelection : IEcsRunSystem, IEcsInitSystem, IEcsDestroySystem { + EcsFilter UndoEvt = default; + EcsFilter RedoEvt = default; + + bool _preventHistoryInsert; + bool _preventSelectionSet; + + public void Init() { + Undo.undoRedoPerformed += OnUndoRedoPerformed; + Selection.selectionChanged += OnSelectionChanged; + Globals.Value = new UndoRedoState(); + if (Globals.Value.History.Count > 0) + _preventHistoryInsert = true; + OnSelectionChanged(); //init selection + } + + public void Destroy() { + Undo.undoRedoPerformed -= OnUndoRedoPerformed; + Selection.selectionChanged -= OnSelectionChanged; + Globals.Value = default; + } + + public void Run() { + MouseInput(); + + if (UndoEvt.IsEmpty() && RedoEvt.IsEmpty()) return; + Counters(undo: !UndoEvt.IsEmpty(), redo: !RedoEvt.IsEmpty(), false); + _preventHistoryInsert = true; + if (!_preventSelectionSet) { + (var history, var id) = Globals.Value; + SelectionEntry entry = history[id]; + if (entry.Valid()) + Selection.objects = entry.IsGuids + ? entry.Guids.Select(AssetDatabase.GUIDToAssetPath).Select(AssetDatabase.LoadAssetAtPath).Where(obj => obj).ToArray() + : entry.SceneObjects; + } + + _preventSelectionSet = false; + + UndoEvt.AllDestroy(); + RedoEvt.AllDestroy(); + } + + + static void Counters(bool undo, bool redo, bool insertToHistory) { + var state = Globals.Value; + World.NewEntityWith(out RequestRepaintEvt _); + + const int MinId = 0; + if (insertToHistory) { + var entry = new SelectionEntry(); + + var count = state.History.Count - 1 - state.Id; + if (count > 0) + state.History.RemoveRange(state.Id + 1, count); + + state.History.Add(entry); + state.Id = MaxId(); + + if (Selection.assetGUIDs.Length > 0) { + entry.IsGuids = true; + entry.Guids = Selection.assetGUIDs; + } + else { + entry.SceneObjects = Selection.objects; + } + } + + if (undo) { + // loop to skip invalid + while (true) { + state.Id -= 1; + if (state.Id < MinId) break; + if (state.History[state.Id].Valid()) break; + } + } + + if (redo) { + // loop to skip invalid + while (true) { + state.Id += 1; + if (state.Id > MaxId()) break; + if (state.History[state.Id].Valid()) break; + } + } + + state.Id = Mathf.Clamp(state.Id, MinId, MaxId()); + + var undoRedoState = Globals.Value; + undoRedoState.UndoEnabled = state.Id != MinId; + undoRedoState.RedoEnabled = state.Id != MaxId(); + + int MaxId() => Mathf.Max(0, state.History.Count - 1); + } + + void OnSelectionChanged() { + World.NewEntityWith(out RequestRepaintEvt _); + if (Globals.Value.Locked) return; + Counters(undo: false, redo: false, insertToHistory: !_preventHistoryInsert); + _preventHistoryInsert = false; + + World.NewEntityWith(out SelectionChanged comp); + World.NewEntityWith(out CleanupPrevArg _); + var go = Selection.activeGameObject; + if (go && go.scene.IsValid()) { + comp.From = FindModeEnum.Scene; + comp.Target = go; + comp.Scene = go.scene; + } + else { + var guids = Selection.assetGUIDs; + // comp.Guids = Selection.assetGUIDs; + bool any = guids != null && guids.Length > 0; + if (any) { + comp.From = FindModeEnum.File; + var path = AssetDatabase.GUIDToAssetPath(guids[0]); + comp.Target = AssetDatabase.LoadAssetAtPath(path); + } + else { + comp.From = FindModeEnum.None; + comp.Target = null; + } + } + } + + // prevents selection history flooding + void OnUndoRedoPerformed() { + // below is a hackish way to catch Undo/Redo from editor + if (!Undo.GetCurrentGroupName().Equals("Selection Change")) return; + var evt = Event.current; + if (evt == null) return; + if (evt.rawType != EventType.KeyDown) return; + + switch (evt.keyCode) { + case KeyCode.Z: + World.NewEntityWith(out UndoEvt _); + _preventSelectionSet = true; // prevent manual Selection set + break; + case KeyCode.Y: + World.NewEntityWith(out RedoEvt _); + _preventSelectionSet = true; + break; + } + } + + void MouseInput() { + if (_nextClick > EditorApplication.timeSinceStartup) return; + + var any = false; + if (Pressed(0x5)) { + World.NewEntityWith(out UndoEvt _); + any = true; + } + + if (Pressed(0x6)) { + World.NewEntityWith(out RedoEvt _); + any = true; + } + + if (any) + _nextClick = EditorApplication.timeSinceStartup + 0.25; + } + +#if UNITY_EDITOR_WIN + [DllImport("USER32.dll")] + static extern short GetKeyState(int keycode); +#else + static short GetKeyState(int keycode) => 0; +#endif + + double _nextClick; + + // 5 back, 6 fw + static bool Pressed(int keyCode) => (GetKeyState(keyCode) & 0x100) != 0; + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysUndoRedoSelection.cs.meta b/Assets/Asset Cleaner/Systems/SysUndoRedoSelection.cs.meta new file mode 100644 index 00000000..c9e3cf08 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysUndoRedoSelection.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6e6a2f49ce174cabbc560ea8e3e9975c +timeCreated: 1596008857 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysWindowGui.cs b/Assets/Asset Cleaner/Systems/SysWindowGui.cs new file mode 100644 index 00000000..c25ea7f0 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysWindowGui.cs @@ -0,0 +1,970 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using Leopotam.Ecs; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.SceneManagement; +using Object = UnityEngine.Object; + +namespace Asset_Cleaner { + class FileResultTag { } + + enum TargetTypeEnum { + File = 0, + Directory = 1, + Scene = 2, + ObjectInScene = 3, + ObjectInStage = 4 + } + + class SysWindowGui : IEcsRunSystem, IEcsInitSystem { + EcsFilter SceneResultRows = null; + EcsFilter ScenePaths = null; + EcsFilter.Exclude SearchArgMain = null; + EcsFilter FileResultRows = null; + + public void Init() { + BacklinkStoreDirty(true); + VisualSettingDirty(true); + } + + public void Run() { + var windowData = Globals.Value; + + _toolbarSelection = GUILayout.Toolbar(_toolbarSelection, _toolbarStrings, GUILayout.ExpandWidth(false)); + var conf = Globals.Value; + switch (_toolbarSelection) { + case 0: { + ShowTabMain(conf, windowData); + break; + } + case 1: { + ShowTabSettings(conf); + break; + } + } + } + + string[] _toolbarStrings = {"Main", "Settings"}; + + const int _progressBarShowFromLevel = 10; + int _toolbarSelection = 0; + + int _settingIgnoredPathsHash1; + + bool BacklinkStoreDirty(bool set) { + var res = Hash() != _settingIgnoredPathsHash1; + if (set) _settingIgnoredPathsHash1 = Hash(); + return res; + + int Hash() { + var conf = Globals.Value; + return DirtyUtils.HashCode(conf.IgnorePathContainsCombined, + conf.IgnoreMaterial, + conf.IgnoreScriptable); + } + } + + int _settingCodeHash1; + + bool VisualSettingDirty(bool set) { + var res = Hash() != _settingCodeHash1; + if (set) _settingCodeHash1 = Hash(); + return res; + + int Hash() { + var conf = Globals.Value; + return DirtyUtils.HashCode( + conf.MarkRed, + conf.ShowInfoBox, + conf.RebuildCacheOnDemand); + } + } + + void ShowTabSettings(Config conf) { + using (new EditorGUILayout.VerticalScope()) { + EditorGUILayout.Space(); + + var enabled = GUI.enabled; + GUI.enabled = true; + + + using (new EditorGUILayout.VerticalScope()) { + conf.MarkRed = GUILayout.Toggle(conf.MarkRed, "Display counters and red overlay in Project View"); + conf.ShowInfoBox = GUILayout.Toggle(conf.ShowInfoBox, "Help suggestions"); + conf.RebuildCacheOnDemand = GUILayout.Toggle(conf.RebuildCacheOnDemand, "Rebuild cache on demand (when scripts are updated often)"); + EditorGUILayout.Space(); + conf.IgnoreMaterial = GUILayout.Toggle(conf.IgnoreMaterial, "Ignore Materials"); + conf.IgnoreScriptable = GUILayout.Toggle(conf.IgnoreScriptable, "Ignore ScriptableObjects"); + } + + EditorGUILayout.Space(); + + GUI.enabled = enabled; + + EditorGUILayout.LabelField("Ignore Path(s) contains:"); + + conf.IgnorePathContainsCombined = GUILayout.TextArea(conf.IgnorePathContainsCombined); + + using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false))) { + EditorGUILayout.Space(); + + var previous = GUI.enabled; + + GUI.enabled = BacklinkStoreDirty(false) || VisualSettingDirty(false); + if (GUILayout.Button("Apply")) { + conf.IgnorePathContains = conf.IgnorePathContainsCombined.Split(';') + .Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); + Apply(); + } + + GUI.enabled = previous; + + var selectedGuids = Selection.assetGUIDs; + var assetPaths = new List(); + if (selectedGuids.Length > 0) { + foreach (var guid in selectedGuids) { + var realAssetPath = AssetDatabase.GUIDToAssetPath(guid); + var obj = AssetDatabase.LoadAssetAtPath(realAssetPath); + var assetPath = realAssetPath.Replace("Assets/", string.Empty); + if (obj is DefaultAsset && + !conf.IgnorePathContains.Any(p => (StringComparer.Ordinal.Equals(p, assetPath)))) { + assetPaths.Add(assetPath); + } + } + } + + GUI.enabled = (assetPaths.Count > 0); + var foldersList = string.Join(", ", assetPaths); + if (GUILayout.Button("Add Selected Path")) { + var choice = EditorUtility.DisplayDialog( + title: "Asset Cleaner", + message: + $"Do you really want to add these folder(s) to ignored list: \"{foldersList}\"?", + ok: "Ignore", + cancel: "Cancel"); + if (choice) { + conf.IgnorePathContainsCombined += $"{foldersList};"; + conf.IgnorePathContains = conf.IgnorePathContainsCombined.Split(';') + .Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); + Apply(); + } + } + + GUI.enabled = true; + if (GUILayout.Button("Reset")) { + var choice = EditorUtility.DisplayDialog( + title: "Asset Cleaner", + message: + $"Do you really want to reset to the factory settings?", + ok: "Reset", + cancel: "Cancel"); + if (choice) { + var serializable = AufSerializableData.Default(); + AufSerializableData.OnDeserialize(in serializable, ref conf); + Apply(); + } + } + + GUI.enabled = previous; + } + + EditorGUILayout.Space(); + EditorGUILayout.LabelField(conf.InitializationTime); + + var buf = GUI.enabled; + GUI.enabled = Selection.objects.Length > 0; + if (GUILayout.Button("Reserialize selected assets", GUILayout.ExpandWidth(false))) { + var paths = Selection.objects.Select(AssetDatabase.GetAssetPath); + AssetDatabase.ForceReserializeAssets(paths); + EditorApplication.ExecuteMenuItem("File/Save Project"); + AssetDatabase.Refresh(); + } + + GUI.enabled = buf; + + EditorGUILayout.Space(); + } + + void Apply() { + var rebuild = BacklinkStoreDirty(true); + VisualSettingDirty(true); + PersistenceUtils.Save(in conf); + AufCtx.World.NewEntityWith(out RequestRepaintEvt _); + if (rebuild) + Globals.Value.UpdateUnusedAssets(); + InternalEditorUtility.RepaintAllViews(); + } + } + + void ShowTabMain(Config conf, WindowData windowData) { + var store = Globals.Value; + EditorGUIUtility.labelWidth = windowData.Window.position.width * .7f; + + int Hash() => DirtyUtils.HashCode(conf.Locked); + var active = SearchArgMain.Get1[0]; + if (conf.Locked && (windowData.FindFrom == FindModeEnum.File && + (active == null || active.Main == null || !AssetDatabase.Contains(active.Main)))) { + conf.Locked = false; + AufCtx.World.NewEntityWith(out RequestRepaintEvt _); + } + + var style = windowData.Style; + var hash = Hash(); + if (hash != Hash()) { + PersistenceUtils.Save(in conf); + AufCtx.World.NewEntityWith(out RequestRepaintEvt _); + } + + // if (Globals.Get() == null) return; + EditorGUILayout.Space(); + + SearchArg arg = default; + foreach (var i in SearchArgMain) { + arg = SearchArgMain.Get1[i]; + if (arg != null && arg.Main != null) { + break; + } + } + + if (arg == default) + return; + + var targetTypeEnum = GetTargetType(windowData, arg?.Main); + BacklinkStore.UnusedQty unusedQty = new BacklinkStore.UnusedQty(0, 0, 0); + + using (new EditorGUILayout.HorizontalScope()) { + var enabledBuf = GUI.enabled; + var selectedGuids = Selection.assetGUIDs; + + var undoRedoState = Globals.Value; + + GUI.enabled = selectedGuids != null && !conf.Locked && undoRedoState.UndoEnabled; + if (GUILayout.Button(style.ArrowL, style.ArrowBtn)) { + AufCtx.World.NewEntityWith(out UndoEvt _); + } + + GUI.enabled = selectedGuids != null && !conf.Locked && undoRedoState.RedoEnabled; + if (GUILayout.Button(style.ArrowR, style.ArrowBtn)) { + AufCtx.World.NewEntityWith(out RedoEvt _); + } + + GUI.enabled = enabledBuf; + + if (conf.Locked) { + if (GUILayout.Button(style.Lock, style.LockBtn)) { + AufCtx.World.NewEntityWith(out SelectionChanged selectionChanged); + conf.Locked = false; + if (Selection.activeObject != arg.Target) { + selectionChanged.From = FindModeEnum.Scene; + selectionChanged.Scene = SceneManager.GetActiveScene(); + selectionChanged.Target = Selection.activeObject; + } + else if (Selection.assetGUIDs is string[] guids) { + // todo show info box multiple selection is unsupported + if (guids.Length > 0) { + var path = AssetDatabase.GUIDToAssetPath(guids[0]); + selectionChanged.Target = AssetDatabase.LoadAssetAtPath(path); + switch (Selection.selectionChanged.Target) { + case DefaultAsset _: + selectionChanged.From = FindModeEnum.File; + break; + case GameObject go when go.scene.isLoaded: + selectionChanged.From = FindModeEnum.Scene; + selectionChanged.Scene = SceneManager.GetActiveScene(); + break; + default: + selectionChanged.From = FindModeEnum.File; + break; + } + } + else if (Selection.activeObject is GameObject go && go.scene.isLoaded) { + selectionChanged.From = FindModeEnum.Scene; + selectionChanged.Target = Selection.activeObject; + selectionChanged.Scene = SceneManager.GetActiveScene(); + } + } + } + } + else { + var enabled = GUI.enabled; + GUI.enabled = selectedGuids != null && selectedGuids.Length == 1; + if (GUILayout.Button(style.Unlock, style.UnlockBtn)) { + conf.Locked = true; + } + + GUI.enabled = enabled; + } + + unusedQty = ShowObjectName(store, windowData, targetTypeEnum, arg, selectedGuids); + } + + bool isMultiSelect = Selection.assetGUIDs != null && Selection.assetGUIDs.Length > 1; + + if (conf.ShowInfoBox) { + if (isMultiSelect && (unusedQty.UnusedFilesQty + unusedQty.UnusedScenesQty > 0)) { + var msgUnusedFiles = (unusedQty.UnusedFilesQty > 0) + ? $"unused files ({unusedQty.UnusedFilesQty})," + : ""; + var msgUnusedScenes = (unusedQty.UnusedScenesQty > 0) + ? $"unused scenes ({unusedQty.UnusedScenesQty})," + : ""; + var msgMultiSelect = $"This multi-selection contains: " + + msgUnusedFiles + msgUnusedScenes + + $"\nYou could delete them pressing corresponding button to the right."; + EditorGUILayout.HelpBox(msgMultiSelect, MessageType.Info); + } + else if (TryGetHelpInfo(arg, out var msg, out var msgType)) { + EditorGUILayout.HelpBox(msg, msgType); + } + } + + if (targetTypeEnum != TargetTypeEnum.Directory && !isMultiSelect) { + var windowData2 = Globals.Value; + + EditorGUILayout.BeginVertical(); + { + windowData2.ScrollPos = EditorGUILayout.BeginScrollView(windowData2.ScrollPos); + { + RenderRows(windowData2); //TODO? + EditorGUILayout.Space(); + } + EditorGUILayout.EndScrollView(); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.Space(); + } + } + + + static bool TryGetHelpInfo(SearchArg arg, out string msg, out MessageType msgType) { + msgType = MessageType.Info; + if (arg == null) { + msg = default; + return false; + } + + var path = arg.FilePath; + if (string.IsNullOrEmpty(path)) { + msg = default; + return false; + } + + if (SearchUtils.IgnoredPaths(path, out var subPath)) { + msg = $"Paths containing '{subPath}' are ignored. You could add or remove it in Settings tab"; + return true; + } + + if (SearchUtils.IgnoredNonAssets(path) && !path.Eq("Assets")) { + msg = $"Asset is outside of Assets folder"; + return true; + } + + if (IgnoreTypes.Check(path, out var type)) { + if (AssetDatabase.IsValidFolder(path)) { + var scenes = arg.UnusedScenesFiltered?.Count; + var files = arg.UnusedAssetsFiltered?.Count; + if (scenes == 0 && files == 0) { + msg = default; + return false; + } + + var b = new StringBuilder(); + b.Append("This directory contains: "); + var any = false; + + if (files > 0) { + any = true; + + b.Append($"unused files ({files})"); + } + + if (scenes > 0) { + if (any) + b.Append(", "); + b.Append($"unused scenes ({scenes})"); + } + + b.Append( + ".\nYou could delete them pressing corresponding button to the right.\nIf you don't want it to be inspected, please add it to Ignore list in the Settings tab"); + msg = b.ToString(); + return true; + } + + msg = $"Assets of type '{type.Name}' are ignored. Please contact support if you need to change it"; + return true; + } + + // if (Filters.ScenePaths.GetEntitiesCount() == 0 && Filters.FileResultRows.GetEntitiesCount() == 0) { + if (SearchUtils.IsUnused(path)) { + type = AssetDatabase.GetMainAssetTypeAtPath(path); + var name = type.IsAssignableFromInverse(typeof(SceneAsset)) ? "scene" : "file"; + msg = + $"This {name} has no explicit serialized usages and potentially could be removed. If you don't want it to be inspected, please add the containing folder to ignore list"; + return true; + } + + msgType = default; + msg = default; + return false; + } + + static TargetTypeEnum GetTargetType(WindowData windowData1, Object obj) { + if (obj == null) return TargetTypeEnum.File; + var targetTypeEnum = TargetTypeEnum.Directory; + var path = AssetDatabase.GetAssetPath(obj); + switch (windowData1.FindFrom) { + case FindModeEnum.File when obj is DefaultAsset: + targetTypeEnum = TargetTypeEnum.Directory; + break; + case FindModeEnum.File when path.LastIndexOf(".unity", StringComparison.Ordinal) != -1: + targetTypeEnum = TargetTypeEnum.Scene; + break; + case FindModeEnum.File: + targetTypeEnum = TargetTypeEnum.File; + break; + case FindModeEnum.Scene: + targetTypeEnum = TargetTypeEnum.ObjectInScene; + break; + case FindModeEnum.Stage: + targetTypeEnum = TargetTypeEnum.ObjectInStage; + break; + } + + return targetTypeEnum; + } + + GUIContent _contentBuf = new GUIContent(); + GUIContent _buf2 = new GUIContent(); + + BacklinkStore.UnusedQty ShowObjectName(BacklinkStore store, WindowData windowData, TargetTypeEnum targetTypeEnum, SearchArg arg, string[] selectedGuids) { + float TextWidth() { + _buf2.text = _contentBuf.text; + return 20f + GUI.skin.button.CalcSize(_buf2).x; + } + + if (arg == null || arg.Main == null) return new BacklinkStore.UnusedQty(); + + bool isMultiSelect = selectedGuids != null && selectedGuids.Length > 1; + + if (_contentBuf == null) { + _contentBuf = new GUIContent {tooltip = $"Click to ping"}; + } + + _contentBuf.image = isMultiSelect + ? windowData.Style.MultiSelect.image + : AssetPreview.GetMiniThumbnail(arg.Target); + _contentBuf.text = string.Empty; + _contentBuf.tooltip = string.Empty; + + if (!isMultiSelect) { + switch (targetTypeEnum) { + case TargetTypeEnum.Directory: + if (!SearchArgMain.IsEmpty()) { + _contentBuf.text = $"{arg.Main.name} (Folder)"; + if (GUILayout.Button(_contentBuf, windowData.Style.CurrentBtn, + GUILayout.MinWidth(TextWidth()))) { + EditorGUIUtility.PingObject(arg.Main); + } + + if (AskDeleteUnusedFiles(arg, arg.UnusedAssetsFiltered, windowData)) + return new BacklinkStore.UnusedQty(); + + if (AskDeleteUnusedScenes(arg, arg.UnusedScenesFiltered, windowData)) + return new BacklinkStore.UnusedQty(); + } + + break; + case TargetTypeEnum.File: + _contentBuf.text = $"{arg.Main.name} (File Asset)"; + if (GUILayout.Button(_contentBuf, windowData.Style.CurrentBtn, + GUILayout.MinWidth(TextWidth()))) { + EditorGUIUtility.PingObject(arg.Main); + } + + bool hasUnusedFile = SearchUtils.IsUnused(arg.FilePath); + var previous = GUI.enabled; + GUI.enabled = hasUnusedFile; + + if (GUILayout.Button(windowData.Style.RemoveFile, + windowData.Style.RemoveUnusedBtn)) { + var choice = EditorUtility.DisplayDialog( + title: "Asset Cleaner", + message: + $"Do you really want to remove file: \"{arg.Main.name}\"?", + ok: "Remove", + cancel: "Cancel"); + if (choice) { + EditorApplication.ExecuteMenuItem("File/Save Project"); + DeleteWithMeta(arg.FilePath); + AssetDatabase.Refresh(); + SearchUtils.Upd(arg); + } + } + + GUI.enabled = previous; + + break; + case TargetTypeEnum.Scene: + _contentBuf.text = $"{arg.Main.name} (Scene)"; + if (GUILayout.Button(_contentBuf, windowData.Style.CurrentBtn, + GUILayout.MinWidth(TextWidth()))) { + EditorGUIUtility.PingObject(arg.Main); + } + + bool hasUnusedScene = SearchUtils.IsUnused(arg.FilePath); + previous = GUI.enabled; + GUI.enabled = hasUnusedScene; + + if (GUILayout.Button(windowData.Style.RemoveScene, + windowData.Style.RemoveUnusedBtn)) { + var choice = EditorUtility.DisplayDialog( + title: "Asset Cleaner", + message: + $"Do you really want to remove scene: {arg.Main.name}?", + ok: "Remove", + cancel: "Cancel"); + if (choice) { + EditorApplication.ExecuteMenuItem("File/Save Project"); + DeleteWithMeta(arg.FilePath); + AssetDatabase.Refresh(); + SearchUtils.Upd(arg); + } + } + + GUI.enabled = previous; + break; + case TargetTypeEnum.ObjectInScene: + _contentBuf.text = $"{arg.Main.name} (Object in Scene)"; + + if (GUILayout.Button(_contentBuf, windowData.Style.CurrentBtn, + GUILayout.MinWidth(TextWidth()))) { + EditorGUIUtility.PingObject(arg.Main); + } + + break; + case TargetTypeEnum.ObjectInStage: + _contentBuf.image = AssetPreview.GetMiniThumbnail(arg.Target); + _contentBuf.text = $"{arg.Main.name} (Object in Staging)"; + + if (GUILayout.Button(_contentBuf, + windowData.Style.RemoveUnusedBtn)) { + EditorGUIUtility.PingObject(arg.Main); + } + + break; + default: + if (GUILayout.Button($"{arg.Main.name} (Unknown Object Type)", + windowData.Style.RemoveUnusedBtn)) { + EditorGUIUtility.PingObject(arg.Main); + } + + break; + } + } + else { + var unusedAssets = new List(); + var unusedScenes = new List(); + + foreach (var guid in selectedGuids) { + var path = AssetDatabase.GUIDToAssetPath(guid); + + if (store.UnusedFiles.TryGetValue(path, out _)) + unusedAssets.Add(path); + + else if (store.UnusedScenes.TryGetValue(path, out _)) + unusedScenes.Add(path); + + if (store.FoldersWithQty.TryGetValue(path, out _)) { + SearchArg searchArg = new SearchArg() { + FilePath = path, + Target = AssetDatabase.LoadAssetAtPath(path), + Main = AssetDatabase.LoadAssetAtPath(path) + }; + SearchUtils.Upd(searchArg); + + foreach (var unusedAssetPath in searchArg.UnusedAssetsFiltered) + if (store.UnusedFiles.TryGetValue(unusedAssetPath, out _)) + unusedAssets.Add(unusedAssetPath); + + foreach (var unusedScenePath in searchArg.UnusedScenesFiltered) + if (store.UnusedScenes.TryGetValue(unusedScenePath, out _)) + unusedScenes.Add(unusedScenePath); + } + } + + unusedAssets = unusedAssets.Distinct().ToList(); + unusedScenes = unusedScenes.Distinct().ToList(); + + var assetSize = unusedAssets.Sum(CommonUtils.Size); + var sceneSize = unusedScenes.Sum(CommonUtils.Size); + + _contentBuf.text = + $"Assets: {unusedAssets.Count} ({CommonUtils.BytesToString(assetSize)}), Scenes: {unusedScenes.Count} ({CommonUtils.BytesToString(sceneSize)})"; + ; + + GUILayout.Button(_contentBuf, windowData.Style.CurrentBtn, GUILayout.MinWidth(TextWidth())); + + if (AskDeleteUnusedFiles(arg, unusedAssets, windowData)) + return new BacklinkStore.UnusedQty(); + + if (AskDeleteUnusedScenes(arg, unusedScenes, windowData)) + return new BacklinkStore.UnusedQty(); + + return new BacklinkStore.UnusedQty(unusedAssets.Count, unusedScenes.Count, assetSize + sceneSize); + } + + return new BacklinkStore.UnusedQty(); + } + + static bool AskDeleteUnusedFiles(SearchArg arg, List unusedAssets, WindowData windowData) { + if (arg == null || unusedAssets == null) return false; + var hasUnusedAssets = unusedAssets.Count > 0; + var previous = GUI.enabled; + GUI.enabled = hasUnusedAssets; + + var guiContentRemoveAssets = windowData.Style.RemoveFile; + + if (GUILayout.Button(guiContentRemoveAssets, + windowData.Style.RemoveUnusedBtn)) { + var choice = EditorUtility.DisplayDialog( + title: "Asset Cleaner", + message: + $"Do you really want to remove {unusedAssets.Count} asset(s)?", + ok: "Remove", + cancel: "Cancel"); + if (choice) { + EditorApplication.ExecuteMenuItem("File/Save Project"); + + var i = 0f; + var total = (float) unusedAssets.Count; + + foreach (var f in unusedAssets) { + var path = Application.dataPath.Replace("Assets", f); + DeleteWithMeta(path); + + var percent = i * 100 / total; + if (total >= _progressBarShowFromLevel) { + if (Math.Abs(percent % 5f) < 0.01f) { + if (EditorUtility.DisplayCancelableProgressBar( + "Please wait...", + "Deleting assets...", percent)) + throw new Exception("Deleting aborted"); + } + + i++; + } + } + + if (total >= _progressBarShowFromLevel) { + EditorUtility.ClearProgressBar(); + } + + AssetDatabase.Refresh(); + SearchUtils.Upd(arg); + } + + GUI.enabled = previous; + return true; + } + + GUI.enabled = previous; + + return false; + } + + static void DeleteWithMeta(string path) { + FileUtil.DeleteFileOrDirectory(path); + var metaPath = AssetDatabase.GetTextMetaFilePathFromAssetPath(path); + if (!string.IsNullOrEmpty(metaPath)) + FileUtil.DeleteFileOrDirectory(metaPath); + } + + static bool AskDeleteUnusedScenes(SearchArg arg, List unusedScenes, WindowData windowData) { + if (arg == null || unusedScenes == null) return false; + var hasUnusedScenes = unusedScenes.Count > 0; + var previous = GUI.enabled; + GUI.enabled = hasUnusedScenes; + + var guiContentRemoveScenes = windowData.Style.RemoveScene; + + if (GUILayout.Button(guiContentRemoveScenes, + windowData.Style.RemoveUnusedBtn)) { + var choice = EditorUtility.DisplayDialog( + title: "Asset Cleaner", + message: + $"Do you really want to remove {unusedScenes.Count} scene(s)?", + ok: "Remove", + cancel: "Cancel"); + if (choice) { + EditorApplication.ExecuteMenuItem("File/Save Project"); + + var i = 0f; + var total = (float) unusedScenes.Count; + + foreach (var scene in unusedScenes) { + var path = Application.dataPath.Replace("Assets", scene); + DeleteWithMeta(path); + + if (total >= _progressBarShowFromLevel) { + var percent = i * 100 / total; + if (Math.Abs(percent % 5f) < 0.01f) { + if (EditorUtility.DisplayCancelableProgressBar( + "Please wait...", + "Deleting scenes...", percent)) + throw new Exception("Deleting aborted"); + } + + i++; + } + } + + if (total >= _progressBarShowFromLevel) { + EditorUtility.ClearProgressBar(); + } + + AssetDatabase.Refresh(); + SearchUtils.Upd(arg); + } + + GUI.enabled = previous; + + return true; + } + + GUI.enabled = previous; + + return false; + } + + + void RenderRows(WindowData windowData) { + // todo show spinner until scene is loaded, + + if (FileResultRows.GetEntitiesCount() > 0) { + windowData.ExpandFiles = + EditorGUILayout.Foldout(windowData.ExpandFiles, + $"Usages in Project: {FileResultRows.GetEntitiesCount()}"); + } + + if (SearchArgMain.IsEmpty()) + return; + + if (windowData.ExpandFiles && windowData.FindFrom == FindModeEnum.File) + foreach (var i in FileResultRows.Out(out var get1, out var get2, out _, out _)) + DrawRowFile(get1[i], get2[i], windowData); + + + var sceneMessage = $"Usages in Scenes: {ScenePaths.GetEntitiesCount()}"; + if (ScenePaths.GetEntitiesCount() > 0) { + windowData.ExpandScenes = + EditorGUILayout.Foldout(windowData.ExpandScenes, sceneMessage); + } + + + if (!windowData.ExpandScenes) return; + + if (windowData.ExpandScenes && windowData.FindFrom == FindModeEnum.Scene) { + foreach (var (grp, indices) in SceneResultRows.Out(out _, out var get2, out _, out _) + .GroupBy1(ResultComp.Instance)) { + using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { + var count = 0; + foreach (var i in indices) { + if (count++ == 0) + if (GUILayout.Button(get2[i].Label, windowData.Style.RowMainAssetBtn)) { + if (windowData.Click.IsDoubleClick(grp.RootGo)) { + // _selectionChangedByArrows = false; + Selection.activeObject = grp.RootGo; + } + else + EditorGUIUtility.PingObject(grp.RootGo); + + windowData.Click = new PrevClick(grp.RootGo); + } + + DrawRowScene(get2[i]); + } + } + } + } + + using (new GUILayout.HorizontalScope()) { + GUILayout.Space(windowData.Style.SceneIndent1); + using (new EditorGUILayout.VerticalScope()) { + foreach (var i1 in ScenePaths.Out(out var get1, out var get2, out _)) { + windowData.SceneFoldout.text = get1[i1].PathNicified; + var details = get2[i1]; + + details.SearchRequested = details.Scene.isLoaded; + details.SearchRequested = EditorGUILayout.Foldout(details.SearchRequested, + windowData.SceneFoldout, EditorStyles.foldout); + if (details.SearchRequested && details.Scene.isLoaded && !details.SearchDone) { + var mainArg = SearchArgMain.GetSingle(); + + mainArg.Scene = SceneManager.GetSceneByPath(details.Scene.path); + + SearchUtils.InScene(mainArg, details.Scene); + details.SearchDone = true; + } + + if (!details.SearchRequested) { + if (!details.Scene.isLoaded) continue; + if (!details.WasOpened) { + // to clean up on selection change + AufCtx.World.NewEntityWith(out SceneToClose comp); + comp.Scene = details.Scene; + comp.ForceClose = true; + } + + foreach (var row in SceneResultRows.Out(out _, out _, out var get3, out var entities)) { + if (!get3[row].ScenePath.Eq(details.Path)) + continue; + + entities[row].Destroy(); + } + + details.SearchDone = false; + } + else { + if (!details.Scene.isLoaded) { + details.Scene = EditorSceneManager.OpenScene(details.Path, OpenSceneMode.Additive); + + // to clean up on selection change + AufCtx.World.NewEntityWith(out SceneToClose comp); + comp.Scene = details.Scene; + comp.SelectionId = Globals.Value.Id; + + +#if UNITY_2019_1_OR_NEWER + EditorSceneManager.SetSceneCullingMask(details.Scene, 0); +#endif + details.SearchRequested = true; + // todo Scope component +#if later + if (details.Scene.isLoaded) + EditorSceneManager.CloseScene(details.Scene, false); +#endif + } + else if (SceneResultRows.IsEmpty()) + EditorGUILayout.LabelField("No in-scene dependencies found."); + else + using (new GUILayout.HorizontalScope()) { + GUILayout.Space(windowData.Style.SceneIndent2); + using (new EditorGUILayout.VerticalScope()) + foreach (var (grp, indices) in SceneResultRows + .Out(out var g1, out var g2, out var g3, out _) + .GroupBy1(ResultComp.Instance)) { + var any = false; + foreach (var i3 in indices) { + if (!g3[i3].ScenePath.Eq(details.Path)) + continue; + any = true; + break; + } + + if (!any) + continue; + + using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { + var count = 0; + foreach (var i2 in indices) { + if (!g3[i2].ScenePath.Eq(details.Path)) + continue; + + if (count++ == 0) { + Result comp = g1[i2]; + if (GUILayout.Button(g2[i2].Label, + windowData.Style.RowMainAssetBtn)) { + if (windowData.Click.IsDoubleClick(grp.RootGo)) { + // _selectionChangedByArrows = false; + Selection.activeObject = comp.RootGo; + } + else + EditorGUIUtility.PingObject(comp.RootGo); + + windowData.Click = new PrevClick(comp.RootGo); + } + } + + DrawRowScene(g2[i2]); + } + } + } + } + } + } + } + } + } + + class ResultComp : IEqualityComparer { + public static ResultComp Instance { get; } = new ResultComp(); + public bool Equals(Result x, Result y) => GetHashCode(x) == GetHashCode(y); + public int GetHashCode(Result obj) => obj.RootGo.GetInstanceID(); + } + + static void DrawRowScene(SearchResultGui gui) { + EditorGUI.BeginChangeCheck(); + // if (data.TargetGo || data.TargetComponent) + foreach (var prop in gui.Properties) { + { + var locked = prop.Property.objectReferenceValue is MonoScript; + var f = GUI.enabled; + + if (locked) GUI.enabled = false; + + EditorGUILayout.PropertyField(prop.Property, prop.Content, false); + + if (locked) GUI.enabled = f; + } + } + + if (EditorGUI.EndChangeCheck()) + gui.SerializedObject.ApplyModifiedProperties(); + } + + + static void DrawRowFile(Result data, SearchResultGui gui, WindowData windowData) { + using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { + var buf = GUI.color; + var pingGo = data.MainFile == null ? data.RootGo : data.MainFile; + if (GUILayout.Button(gui.Label, windowData.Style.RowMainAssetBtn)) { + if (windowData.Click.IsDoubleClick(pingGo)) { + // _selectionChangedByArrows = false; + Selection.activeObject = pingGo; + } + else { + EditorGUIUtility.PingObject(pingGo); + } + + windowData.Click = new PrevClick(pingGo); + } + + GUI.color = buf; + + EditorGUI.BeginChangeCheck(); + if (data.File) { + foreach (var prop in gui.Properties) { + using (new EditorGUILayout.HorizontalScope()) { + var locked = prop.Property.objectReferenceValue is MonoScript; + var f = GUI.enabled; + if (locked) GUI.enabled = false; + EditorGUILayout.PropertyField(prop.Property, prop.Content, false); + if (locked) GUI.enabled = f; + } + } + } + + if (EditorGUI.EndChangeCheck()) { + gui.SerializedObject.ApplyModifiedProperties(); + // dependency.SerializedObject.Update(); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Systems/SysWindowGui.cs.meta b/Assets/Asset Cleaner/Systems/SysWindowGui.cs.meta new file mode 100644 index 00000000..ab926b13 --- /dev/null +++ b/Assets/Asset Cleaner/Systems/SysWindowGui.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 87ac41283aa347c4aece096c90076c7f +timeCreated: 1596213420 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils.meta b/Assets/Asset Cleaner/Utils.meta new file mode 100644 index 00000000..993c397a --- /dev/null +++ b/Assets/Asset Cleaner/Utils.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8f9623ba76cbf214994b7b865c65f362 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Utils/Asr.cs b/Assets/Asset Cleaner/Utils/Asr.cs new file mode 100644 index 00000000..51f89a55 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Asr.cs @@ -0,0 +1,34 @@ +using System.Diagnostics; +using UnityEngine.Assertions; + +namespace Asset_Cleaner { + static class FLAGS { + // cleanup in release + public const string DEBUG = "DEBUG1"; + public const string M_DISABLE_POOLING = "M_DISABLE_POOLING"; + } + + static class Asr { +#line hidden + [Conditional(FLAGS.DEBUG)] + public static void AreEqual(int a, int b) { + Assert.AreEqual(a, b); + } + + [Conditional(FLAGS.DEBUG)] + public static void IsTrue(bool b, string format = null) { + Assert.IsTrue(b, format); + } + + [Conditional(FLAGS.DEBUG)] + public static void IsFalse(bool b, string format = null) { + Assert.IsFalse(b, format); + } + + [Conditional(FLAGS.DEBUG)] + public static void IsNotNull(object target, string format = null) { + Assert.IsNotNull(target, format); + } +#line default + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/Asr.cs.meta b/Assets/Asset Cleaner/Utils/Asr.cs.meta new file mode 100644 index 00000000..ed257fdc --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Asr.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 53c5eeeb89d541a5b26f906f93ffe650 +timeCreated: 1581424097 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/AufCtx.cs b/Assets/Asset Cleaner/Utils/AufCtx.cs new file mode 100644 index 00000000..1a02655e --- /dev/null +++ b/Assets/Asset Cleaner/Utils/AufCtx.cs @@ -0,0 +1,37 @@ +using Leopotam.Ecs; + +namespace Asset_Cleaner { + static class AufCtx { + public static EcsWorld World; + + public static EcsSystems UpdateGroup; + public static EcsSystems OnGuiGroup; + + internal static bool InitStarted { get; private set; } + internal static bool Destroyed { get; private set; } + + internal static void TryInitWorld() { + if (InitStarted) return; + InitStarted = true; + + World = new EcsWorld(); + + (OnGuiGroup = new EcsSystems(World) + .Add(new SysWindowGui())).Init(); + + (UpdateGroup = new EcsSystems(World) + .Add(new SysRepaintWindow()) + .Add(new SysUndoRedoSelection()) + .Add(new SysProcessSearch()) + .Add(new SysSceneCleanup()) + ).Init(); + } + + internal static void DestroyWorld() { + if (!InitStarted) return; + InitStarted = false; + Destroyed = true; + Asr.IsFalse(__GlobalsCounter.HasAnyValue()); + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/AufCtx.cs.meta b/Assets/Asset Cleaner/Utils/AufCtx.cs.meta new file mode 100644 index 00000000..b3ae0721 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/AufCtx.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 999cc1329c8dd5743b39fe17eb02a7aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Utils/CommonUtils.cs b/Assets/Asset Cleaner/Utils/CommonUtils.cs new file mode 100644 index 00000000..8fc77f4e --- /dev/null +++ b/Assets/Asset Cleaner/Utils/CommonUtils.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; + +namespace Asset_Cleaner { + static class CommonUtils { + static string[] _suffix = {"B", "KB", "MB", "GB", "TB"}; + + public static string BytesToString(long byteCount) { + if (byteCount == 0) + return $"0 {_suffix[0]}"; + + var bytes = Math.Abs(byteCount); + var place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024))); + double num; + if (place == 0 || place == 1) { // display B, KB in MB + num = Math.Round(bytes / Math.Pow(1024, 2), 4); + return $"{Math.Sign(byteCount) * num:N} {_suffix[2]}"; + } + + num = Math.Round(bytes / Math.Pow(1024, place), 1); + return $"{Math.Sign(byteCount) * num:F0} {_suffix[place]}"; + } + + // todo + public static long Size(string path) { + return TryGetSize(path, out var res) ? res : 0L; + } + + public static bool TryGetSize(string path, out long result) { + if (!File.Exists(path)) { + result = default; + return false; + } + + var fi = new FileInfo(path); + result = fi.Length; + return true; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/CommonUtils.cs.meta b/Assets/Asset Cleaner/Utils/CommonUtils.cs.meta new file mode 100644 index 00000000..824c3bff --- /dev/null +++ b/Assets/Asset Cleaner/Utils/CommonUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4a0fa79cb05e495a8dc80a251a33970c +timeCreated: 1595072385 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/DirtyUtils.cs b/Assets/Asset Cleaner/Utils/DirtyUtils.cs new file mode 100644 index 00000000..1147e36b --- /dev/null +++ b/Assets/Asset Cleaner/Utils/DirtyUtils.cs @@ -0,0 +1,46 @@ +using System.Runtime.CompilerServices; + +namespace Asset_Cleaner { + static class DirtyUtils { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int HashCode(in T1 v1) { + var hash = v1.GetHashCode(); + hash = (hash * 397); + return hash; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int HashCode(in T1 v1, in T2 v2) { + var hash = v1.GetHashCode(); + hash = (hash * 397) ^ v2.GetHashCode(); + return hash; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int HashCode(in T1 v1, in T2 v2, in T3 v3) { + var hash = v1.GetHashCode(); + hash = (hash * 397) ^ v2.GetHashCode(); + hash = (hash * 397) ^ v3.GetHashCode(); + return hash; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int HashCode(in T1 v1, in T2 v2, in T3 v3, in T4 v4) { + var hash = v1.GetHashCode(); + hash = (hash * 397) ^ v2.GetHashCode(); + hash = (hash * 397) ^ v3.GetHashCode(); + hash = (hash * 397) ^ v4.GetHashCode(); + return hash; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int HashCode(in T1 v1, in T2 v2, in T3 v3, in T4 v4, in T5 v5) { + var hash = v1.GetHashCode(); + hash = (hash * 397) ^ v2.GetHashCode(); + hash = (hash * 397) ^ v3.GetHashCode(); + hash = (hash * 397) ^ v4.GetHashCode(); + hash = (hash * 397) ^ v5.GetHashCode(); + return hash; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/DirtyUtils.cs.meta b/Assets/Asset Cleaner/Utils/DirtyUtils.cs.meta new file mode 100644 index 00000000..f27e68f0 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/DirtyUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3fd8e20db38143e3a3c51ea733bd0bab +timeCreated: 1577270369 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/EcsUtils.cs b/Assets/Asset Cleaner/Utils/EcsUtils.cs new file mode 100644 index 00000000..fa1d2c8b --- /dev/null +++ b/Assets/Asset Cleaner/Utils/EcsUtils.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using System.Linq; +using Leopotam.Ecs; + +namespace Asset_Cleaner { + static class EcsUtils { + public static IEnumerable<(T Group, IEnumerable Indices)> GroupBy1(this EcsFilter f, IEqualityComparer comp) + where T : class + where T1 : class + where T2 : class { + foreach (var group in Inner().GroupBy(tuple => tuple.Group, comp)) + yield return (group.Key, group.Select(g => g.EcsIndex)); + + IEnumerable<(T Group, int EcsIndex)> Inner() { + var get1 = f.Get1; + foreach (var i in f) yield return (get1[i], i); + } + } + + public static EcsFilter Out(this EcsFilter filter, out T[] get1, out EcsEntity[] entities) where T : class { + get1 = filter.Get1; + entities = filter.Entities; + return filter; + } + + public static EcsFilter Out(this EcsFilter filter, out T1[] get1, out T2[] get2, out EcsEntity[] entities) + where T1 : class where T2 : class { + get1 = filter.Get1; + get2 = filter.Get2; + entities = filter.Entities; + return filter; + } + + public static EcsFilter Out(this EcsFilter filter, out T1[] get1, out T2[] get2, out T3[] get3, out EcsEntity[] entities) + where T1 : class where T2 : class where T3 : class { + get1 = filter.Get1; + get2 = filter.Get2; + get3 = filter.Get3; + entities = filter.Entities; + return filter; + } + + public static void AllDestroy(this EcsFilter f) { + var ecsEntities = f.Entities; + foreach (var i in f) + ecsEntities[i].Destroy(); + } + + public static void AllUnset(this EcsFilter f) where T : class { + var e = f.Entities; + foreach (var i in f) + e[i].Unset(); + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/EcsUtils.cs.meta b/Assets/Asset Cleaner/Utils/EcsUtils.cs.meta new file mode 100644 index 00000000..8542f2b3 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/EcsUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d81e9bb0744bc4448ddb9bbd93bffd3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Utils/Ext.cs b/Assets/Asset Cleaner/Utils/Ext.cs new file mode 100644 index 00000000..2168c011 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Ext.cs @@ -0,0 +1,17 @@ +using System.Runtime.CompilerServices; +using Leopotam.Ecs; + +namespace Asset_Cleaner { + static class Ext { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool Eq(this string s1, string s2) => (s1 == s2); + // public static bool Eq(this string s1, string s2) => StringComparer.Ordinal.Equals(s1, s2); + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T GetSingle(this EcsFilter f) where T : class { + Asr.AreEqual(f.GetEntitiesCount(), 1); + return f.Get1[0]; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/Ext.cs.meta b/Assets/Asset Cleaner/Utils/Ext.cs.meta new file mode 100644 index 00000000..81d110ca --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Ext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 66f6b6922016ea04797deac8d082bc80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/Utils/Globals.cs b/Assets/Asset Cleaner/Utils/Globals.cs new file mode 100644 index 00000000..a25ac58c --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Globals.cs @@ -0,0 +1,29 @@ +namespace Asset_Cleaner { + static class Globals where T : class { + static T _instance; + + public static T Value { + get { + Asr.IsFalse(_instance == null); + return _instance; + } + set { + var was = HasValue(); + _instance = value; + + // keep counter to check during deinitialization if all Globals are cleared + if (was && !HasValue()) + __GlobalsCounter.Counter -= 1; + if (!was && HasValue()) + __GlobalsCounter.Counter += 1; + + bool HasValue() => _instance != null; + } + } + } + + static class __GlobalsCounter { + internal static int Counter; + public static bool HasAnyValue() => Counter > 0; + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/Globals.cs.meta b/Assets/Asset Cleaner/Utils/Globals.cs.meta new file mode 100644 index 00000000..1b2f26b1 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Globals.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dd0464bfdb1b4253ba131c7140510c81 +timeCreated: 1596137163 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/Option.cs b/Assets/Asset Cleaner/Utils/Option.cs new file mode 100644 index 00000000..de165ef9 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Option.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Asset_Cleaner { + readonly struct Option : IEquatable>, IComparable> { + // ReSharper disable once StaticMemberInGenericType + static readonly bool IsValueType; + + public bool HasValue { get; } + + T Value { get; } + + public static implicit operator Option(T arg) { + if (!IsValueType) return ReferenceEquals(arg, null) ? new Option() : new Option(arg, true); +#if M_WARN + if (arg.Equals(default(T))) + Warn.Warning($"{arg} has default value"); +#endif + return new Option(arg, true); + } + + static Option() { + IsValueType = typeof(T).IsValueType; + } + + public void GetOrFail(out T value) { + if (!TryGet(out value)) + Fail($"Option<{typeof(T).Name}> has no value"); + } + + public T GetOrFail() { + if (!TryGet(out var value)) + Fail($"Option<{typeof(T).Name}> has no value"); + return value; + } + + [Conditional("DEBUG1")] + static void Fail(string format = null) { + throw new Exception(format); + } + + public bool TryGet(out T value) { + if (!HasValue) { + value = default(T); + return false; + } + + value = Value; + return true; + } + + internal Option(T value, bool hasValue) { + Value = value; + HasValue = hasValue; + } + + public T ValueOr(T alternative) { + return HasValue ? Value : alternative; + } + + // for debug purposes + public override string ToString() { + if (!HasValue) return "None"; + + return Value == null ? "Some(null)" : $"Some({Value})"; + } + + #region eq comparers boilerplate + + public bool Equals(Option other) { + if (!HasValue && !other.HasValue) + return true; + + if (HasValue && other.HasValue) + return EqualityComparer.Default.Equals(Value, other.Value); + + return false; + } + + public override bool Equals(object obj) { + return obj is Option && Equals((Option) obj); + } + + public static bool operator ==(Option left, Option right) { + return left.Equals(right); + } + + public static bool operator !=(Option left, Option right) { + return !left.Equals(right); + } + + public override int GetHashCode() { + if (!HasValue) return 0; + + return IsValueType || Value != null ? Value.GetHashCode() : 1; + } + + public int CompareTo(Option other) { + if (HasValue && !other.HasValue) return 1; + if (!HasValue && other.HasValue) return -1; + + return Comparer.Default.Compare(Value, other.Value); + } + + public static bool operator <(Option left, Option right) { + return left.CompareTo(right) < 0; + } + + public static bool operator <=(Option left, Option right) { + return left.CompareTo(right) <= 0; + } + + public static bool operator >(Option left, Option right) { + return left.CompareTo(right) > 0; + } + + public static bool operator >=(Option left, Option right) { + return left.CompareTo(right) >= 0; + } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/Option.cs.meta b/Assets/Asset Cleaner/Utils/Option.cs.meta new file mode 100644 index 00000000..0456f505 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Option.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 098c45ccebe14f5caa28635386021c94 +timeCreated: 1591801098 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/PersistenceUtils.cs b/Assets/Asset Cleaner/Utils/PersistenceUtils.cs new file mode 100644 index 00000000..58b47460 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/PersistenceUtils.cs @@ -0,0 +1,57 @@ +using System.IO; +using UnityEngine; + +namespace Asset_Cleaner { + static class PersistenceUtils { + public static void Load(ref Config result) { + var serializable = Deserialize(); + AufSerializableData.OnDeserialize(in serializable, ref result); + } + + public static void Save(in Config src) { + AufSerializableData.OnSerialize(in src, out var serializable); + var json = JsonUtility.ToJson(serializable); + File.WriteAllText(Path, json); + } + + static AufSerializableData Deserialize() { + AufSerializableData serializableData; + string json; + + if (!File.Exists(Path)) { + // not exists - write new + serializableData = AufSerializableData.Default(); + json = JsonUtility.ToJson(serializableData); + File.WriteAllText(Path, json); + } + else { + // exists + json = File.ReadAllText(Path); + + if (string.IsNullOrEmpty(json)) { + // but corrupted - overwrite with new + serializableData = AufSerializableData.Default(); + json = JsonUtility.ToJson(serializableData); + File.WriteAllText(Path, json); + } + + serializableData = JsonUtility.FromJson(json); + if (serializableData.Valid()) + return serializableData; + + serializableData = AufSerializableData.Default(); + json = JsonUtility.ToJson(serializableData); + File.WriteAllText(Path, json); + } + + return serializableData; + } + + static string Path => $"{Application.temporaryCachePath}/AssetCleaner_{AufSerializableData.CurrentVersion}.json"; + + // [MenuItem("Tools/LogPath")] + static void Log() { + Debug.Log(Application.temporaryCachePath); + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/PersistenceUtils.cs.meta b/Assets/Asset Cleaner/Utils/PersistenceUtils.cs.meta new file mode 100644 index 00000000..742850fe --- /dev/null +++ b/Assets/Asset Cleaner/Utils/PersistenceUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 764a6ef52ca2456eb7c276bbcd0929f0 +timeCreated: 1589466213 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/Pool.cs b/Assets/Asset Cleaner/Utils/Pool.cs new file mode 100644 index 00000000..04f5755b --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Pool.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; + +namespace Asset_Cleaner { + class Pool : IDisposable where T : class { + Func _ctor; + readonly Stack _stack; + + // todo place asserts on app quit + Action _reset; + Action _destroy; + + static Action Empty = _ => { }; + + public Pool(Func ctor, Action reset, Action destroy = null) { + _ctor = ctor; +#if !M_DISABLE_POOLING + _destroy = destroy ?? Empty; + _reset = reset; + _stack = new Stack(); +#endif + } + + public T Get() { +#if M_DISABLE_POOLING + return _ctor.Invoke(); +#else + T element; + if (_stack.Count == 0) { + element = _ctor(); + } + else { + element = _stack.Pop(); + } + + return element; +#endif + } + + public void Release(ref T element) { +#if !M_DISABLE_POOLING + Asr.IsFalse(_stack.Count > 0 && ReferenceEquals(_stack.Peek(), element), + "Internal error. Trying to release object that is already released to pool. "); + + _reset.Invoke(element); + _stack.Push(element); +#endif + + element = null; + } + + + public void Dispose() { +#if !M_DISABLE_POOLING + while (_stack.Count > 0) { + var t = _stack.Pop(); + _destroy.Invoke(t); + } +#endif + } + + public _Scope GetScoped(out T tmp) { + tmp = Get(); + return new _Scope(this, ref tmp); + } + + public struct _Scope : IDisposable { + Pool _pool; + T _val; + + internal _Scope(Pool pool, ref T val) { + _pool = pool; + _val = val; + } + + public void Dispose() { + _pool.Release(ref _val); + } + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/Pool.cs.meta b/Assets/Asset Cleaner/Utils/Pool.cs.meta new file mode 100644 index 00000000..137d5370 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/Pool.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b5a618b193c34a5cba77e7cc0df122f1 +timeCreated: 1591254176 \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/SearchUtils.cs b/Assets/Asset Cleaner/Utils/SearchUtils.cs new file mode 100644 index 00000000..9623e9b4 --- /dev/null +++ b/Assets/Asset Cleaner/Utils/SearchUtils.cs @@ -0,0 +1,458 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using Leopotam.Ecs; +using UnityEditor; +using UnityEditor.Animations; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.SceneManagement; +using static Asset_Cleaner.AufCtx; +using Object = UnityEngine.Object; + +namespace Asset_Cleaner { + static class SearchUtils { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsAssignableFromInverse(this Type lhs, Type rhs) { + if (lhs == null || rhs == null) + return false; + + return rhs.IsAssignableFrom(lhs); + } + + static Queue _tmp = new Queue(); + + public static void Upd(SearchArg arg) { + if (arg.Target is DefaultAsset folder) { + var path = AssetDatabase.GetAssetPath(folder); + var store = Globals.Value; + arg.UnusedAssetsFiltered = store.UnusedFiles.Where(p => p.Key.StartsWith(path)).Select(p => p.Key).ToList(); + arg.UnusedScenesFiltered = store.UnusedScenes.Where(p => p.Key.StartsWith(path)).Select(p => p.Key).ToList(); + } + } + + public static void Init(SearchArg arg, Object target, Scene scene = default) { + Asr.IsNotNull(target, "Asset you're trying to search is corrupted"); + + arg.Target = target; + + arg.FilePath = AssetDatabase.GetAssetPath(arg.Target); + if (!scene.IsValid()) { + Upd(arg); + + arg.Main = AssetDatabase.LoadMainAssetAtPath(arg.FilePath); + if (AssetDatabase.IsSubAsset(arg.Target)) { } + else { + switch (target) { + case SceneAsset _: + // todo support cross-scene references? + // nested = all assets + break; + default: + // AssetDatabase.IsMainAssetAtPathLoaded() + var subAssets = AssetDatabase.LoadAllAssetsAtPath(arg.FilePath).Where(Predicate).ToArray(); + arg.SubAssets = subAssets.Length == 0 ? default(Option) : subAssets; + + bool Predicate(Object s) { + if (!s) + return false; + return s.GetInstanceID() != arg.Target.GetInstanceID(); + } + + break; + } + } + } + else { + switch (arg.Target) { + case GameObject gg: + arg.Main = gg; + arg.Scene = scene; + arg.SubAssets = gg.GetComponents().OfType().ToArray(); + break; + case Component component: { + // treat like subAsset + arg.Main = component.gameObject; + arg.Scene = scene; + break; + } + default: + // project asset such as Material + arg.Main = arg.Target; + arg.Scene = scene; + break; + } + } + } + + static bool SearchInChildProperties(SearchArg arg, Object suspect, bool scene, out EcsEntity entity) { + if (IsTargetOrNested(arg, suspect)) { + entity = default; + return false; + } + + if (!suspect) { + entity = default; + return false; + } + + var so = new SerializedObject(suspect); + _tmp.Clear(); + var queue = _tmp; + var propIterator = so.GetIterator(); + + var prefabInstance = false; + + if (scene && !string.IsNullOrEmpty(arg.FilePath) && PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(suspect) == arg.FilePath) { + prefabInstance = true; + while (propIterator.NextVisible(true)) { + if (propIterator.propertyType != SerializedPropertyType.ObjectReference) + continue; + if (!IsTargetOrNested(arg, propIterator.objectReferenceValue)) + continue; + + queue.Enqueue(propIterator.Copy()); + } + } + else { + while (propIterator.Next(true)) { + if (propIterator.propertyType != SerializedPropertyType.ObjectReference) + continue; + if (!IsTargetOrNested(arg, propIterator.objectReferenceValue)) + continue; + + queue.Enqueue(propIterator.Copy()); + } + } + + if (queue.Count == 0 && !prefabInstance) { + entity = default; + return false; + } + + entity = World.NewEntityWith(out Result data); + + var gui = entity.Set(); + gui.Properties = new List(); + gui.SerializedObject = so; + gui.Label = new GUIContent(); + + // init header + Texture2D miniTypeThumbnail = null; + if (scene) { + switch (suspect) { + case Component component: + data.RootGo = component.gameObject; + gui.TransformPath = AnimationUtility.CalculateTransformPath(component.transform, null); + gui.Label.image = AssetPreview.GetMiniThumbnail(data.RootGo); + gui.Label.text = gui.TransformPath; + break; + case GameObject go: + data.RootGo = go; + gui.Label.image = AssetPreview.GetMiniThumbnail(data.RootGo); + gui.TransformPath = AnimationUtility.CalculateTransformPath(go.transform, null); + gui.Label.text = gui.TransformPath; + break; + default: + throw new NotImplementedException(); + } + + miniTypeThumbnail = data.RootGo.GetInstanceID() == suspect.GetInstanceID() + ? null + : AssetPreview.GetMiniThumbnail(suspect); + } + else { + data.File = suspect; + data.FilePath = AssetDatabase.GetAssetPath(data.File); + data.MainFile = AssetDatabase.LoadMainAssetAtPath(data.FilePath); + + // todo + var prefabInstanceStatus = PrefabUtility.GetPrefabInstanceStatus(data.MainFile); + switch (prefabInstanceStatus) { + case PrefabInstanceStatus.Connected: + case PrefabInstanceStatus.Disconnected: + switch (data.File) { + case Component comp: + // transformPath = $"{AnimationUtility.CalculateTransformPath(comp.transform, null)}/".Replace("/", "/\n"); + gui.TransformPath = + $"{AnimationUtility.CalculateTransformPath(comp.transform, null)}"; + break; + case GameObject go: + // transformPath = $"{AnimationUtility.CalculateTransformPath(go.transform, null)}/".Replace("/", "/\n"); + gui.TransformPath = + $"{AnimationUtility.CalculateTransformPath(go.transform, null)}"; + break; + default: + // Assert.Fail("Not a component"); //todo + break; + } + + break; + case PrefabInstanceStatus.NotAPrefab: + case PrefabInstanceStatus.MissingAsset: + if (!AssetDatabase.IsMainAsset(data.File)) { + // {row.Main.name} + gui.TransformPath = $"/{data.File.name}"; + } + + break; + } + + gui.Label.text = data.FilePath.Replace(AssetsRootPath, string.Empty); + gui.Label.image = AssetDatabase.GetCachedIcon(data.FilePath); + } + + gui.Label.tooltip = gui.TransformPath; + + + // init properties (footer) + while (queue.Count > 0) { + var prop = queue.Dequeue(); + var targetObject = prop.serializedObject.targetObject; + var item = new SearchResultGui.PropertyData { + Property = prop, + Content = new GUIContent() + }; + item.Content.image = miniTypeThumbnail; + item.Content.text = Nicify(prop, targetObject, gui.TransformPath); + item.Content.tooltip = gui.TransformPath; + var typeName = targetObject.GetType().Name; + if (StringComparer.Ordinal.Equals(typeName, targetObject.name)) + item.Content.tooltip = $"{gui.TransformPath}.{prop.propertyPath}"; + else + item.Content.tooltip = $"{gui.TransformPath}({typeName}).{prop.propertyPath}"; + gui.Properties.Add(item: item); + } + + return true; + } + + public static bool IsFileIgrnoredBySettings(string path) { + if (IgnoreTypes.Check(path, out _)) return true; + if (IgnoredNonAssets(path)) return true; + if (IgnoredPaths(path, out _)) return true; + + return false; + } + + public static bool IgnoredPaths(string path, out string str) { + var conf = Globals.Value; + foreach (var substr in conf.IgnorePathContains) { + Asr.IsNotNull(path); + Asr.IsNotNull(substr); + if (!path.Contains(substr)) continue; + str = substr; + return true; + } + + str = default; + return false; + } + + public static bool IgnoredNonAssets(string path) { + return !path.Contains("Assets/"); + } + + #region Project + + public static bool IsUnused(string path) { + if (IsFileIgrnoredBySettings(path)) + return false; + return !AnyDependencies(path); + } + + static bool AnyDependencies(string path) { + var store = Globals.Value; + if (store.UnusedFiles.Select(p => p.Key).Contains(path)) + return false; + if (store.UnusedScenes.Select(p => p.Key).Contains(path)) + return false; + return true; + } + + public static void FilesThatReference(SearchArg arg) { + var store = Globals.Value; + var path1 = AssetDatabase.GetAssetPath(arg.Target); + + if (!store.Backward.TryGetValue(path1, out var dep)) + return; + + foreach (var path in dep.Lookup) { + var mainAsset = AssetDatabase.GetMainAssetTypeAtPath(path); + if (mainAsset.IsAssignableFromInverse(typeof(SceneAsset))) + continue; + + var any = false; + if (mainAsset.IsAssignableFromInverse(typeof(GameObject))) { } + else { + var allAssetsAtPath = AssetDatabase.LoadAllAssetsAtPath(path); + foreach (var suspect in allAssetsAtPath) { + if (suspect is DefaultAsset || suspect is Transform || !suspect) continue; + + if (!SearchInChildProperties(arg, suspect, false, out var entity)) + continue; + + entity.Set(); + any = true; + } + } + + if (any) continue; + + // failed to find any property - just show main asset + var e = World.NewEntity(); + var gui = e.Set(); + gui.Properties = new List(); + var main = AssetDatabase.LoadMainAssetAtPath(path); + gui.Label = new GUIContent() { + image = AssetPreview.GetMiniThumbnail(main), + text = path.Replace(AssetsRootPath, string.Empty) + }; + var res = e.Set(); + res.MainFile = main; + e.Set(); + } + } + + public static void ScenesThatContain(Object activeObject) { + var store = Globals.Value; + var path1 = AssetDatabase.GetAssetPath(activeObject); + if (!store.Backward.TryGetValue(path1, out var dep)) + return; + + foreach (var path in dep.Lookup) { + if (!AssetDatabase.GetMainAssetTypeAtPath(path).IsAssignableFromInverse(typeof(SceneAsset))) + continue; + + World.NewEntityWith(out SceneResult sp, out SceneDetails sceneDetails); + sp.PathNicified = path.Replace("Assets/", string.Empty); + + // heavy + sceneDetails.Path = path; + var alreadyOpened = false; + for (var i = 0; i < EditorSceneManager.loadedSceneCount; i++) { + var cur = SceneManager.GetSceneAt(i); + if (!cur.path.Eq(sceneDetails.Path)) continue; + alreadyOpened = true; + sceneDetails.Scene = cur; + } + + sceneDetails.WasOpened = alreadyOpened; + } + } + + #endregion + + #region Scene + + static Pool> ComponentListPool = new Pool>(() => new List(), list => list.Clear()); + + // todo provide explicit scene arg + public static void InScene(SearchArg arg, Scene currentScene) { + var rootGameObjects = currentScene.GetRootGameObjects(); + + foreach (var suspect in Traverse(rootGameObjects)) { + if (!SearchInChildProperties(arg, suspect, scene: true, out var entity)) + continue; + var s = entity.Set(); + s.ScenePath = arg.Scene.path; + } + + IEnumerable Traverse(GameObject[] roots) { + foreach (var rootGo in roots) + foreach (var comp in GoAndChildComps(rootGo)) { + yield return comp; + } + } + + IEnumerable GoAndChildComps(GameObject rr) { + using (ComponentListPool.GetScoped(out var pooled)) { + rr.GetComponents(pooled); + foreach (var component in pooled) { + if (component is Transform) + continue; + yield return component; + } + } + + var transform = rr.transform; + var childCount = transform.childCount; + for (int i = 0; i < childCount; i++) { + var g = transform.GetChild(i).gameObject; + foreach (var res in GoAndChildComps(g)) + yield return res; + } + } + } +#if backup + static void InScene(SearchArg arg, Scene currentScene) { + var allObjects = currentScene + .GetRootGameObjects() + .SelectMany(g => g.GetComponentsInChildren(true) + .Where(c => c && !(c is Transform)) + .Union(Enumerable.Repeat(g as Object, 1)) + ) + .ToArray(); + + var total = allObjects.Length; + for (var i = 0; i < total; i++) { + var suspect = allObjects[i]; + + if (SearchInChildProperties(arg, suspect, true, out var entity)) { + var s = entity.Set(); + s.ScenePath = arg.Scene.path; + } + } + } +#endif + + static bool IsTargetOrNested(SearchArg target, Object suspect) { + if (!suspect) + return false; + + if (target.Target.GetInstanceID() == suspect.GetInstanceID() || target.Main.GetInstanceID() == (suspect).GetInstanceID()) + return true; + + if (target.SubAssets.TryGet(out var subassets)) + foreach (var asset in subassets) { + if (asset.GetInstanceID() == (suspect).GetInstanceID()) + return true; + } + + return false; + } + + static string Nicify(SerializedProperty sp, Object o, string transformPath) { + // return sp.propertyPath; + + string nice; + switch (o) { + case AnimatorState animatorState: + return animatorState.name; + case Material material: + nice = material.name; + break; + default: { + nice = sp.propertyPath.Replace(".Array.data", string.Empty); + if (nice.IndexOf(".m_PersistentCalls.m_Calls", StringComparison.Ordinal) > 0) { + nice = nice.Replace(".m_PersistentCalls.m_Calls", string.Empty) + .Replace(".m_Target", string.Empty); + } + + nice = nice.Split('.').Select(t => ObjectNames.NicifyVariableName(t).Replace(" ", string.Empty)) + .Aggregate((a, b) => a + "." + b); + break; + } + } + + // nice = $"{transformPath}({o.GetType().Name}).{nice}"; + nice = $"({o.GetType().Name}).{nice}"; + return nice; + } + + const string AssetsRootPath = "Assets/"; + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/Utils/SearchUtils.cs.meta b/Assets/Asset Cleaner/Utils/SearchUtils.cs.meta new file mode 100644 index 00000000..09a49d8c --- /dev/null +++ b/Assets/Asset Cleaner/Utils/SearchUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 66f3f357bedc44e2907d7e5f48de45d3 +timeCreated: 1576134438 \ No newline at end of file diff --git a/Assets/Asset Cleaner/com.leopotam.ecs.meta b/Assets/Asset Cleaner/com.leopotam.ecs.meta new file mode 100644 index 00000000..d0f99659 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf3dfe88eca681d449c3f24f79d64b4c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/README.md b/Assets/Asset Cleaner/com.leopotam.ecs/README.md new file mode 100644 index 00000000..ec3f8599 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/README.md @@ -0,0 +1,408 @@ +[![discord](https://img.shields.io/discord/404358247621853185.svg?label=discord)](https://discord.gg/5GZVde6) +[![license](https://img.shields.io/github/license/Leopotam/ecs.svg)](https://github.com/Leopotam/ecs/blob/develop/LICENSE) +# LeoECS - Simple lightweight C# Entity Component System framework +Performance, zero/small memory allocations/footprint, no dependencies on any game engine - main goals of this project. + +> C#7.3 or above required for this framework. + +> Tested on unity 2019.1 (not dependent on it) and contains assembly definition for compiling to separate assembly file for performance reason. + +> **Important!** Dont forget to use `DEBUG` builds for development and `RELEASE` builds in production: all internal error checks / exception throwing works only in `DEBUG` builds and eleminated for performance reasons in `RELEASE`. + + +# Installation + +## As unity module +This repository can be installed as unity module directly from git url. In this way new line should be added to `Packages/manifest.json`: +``` +"com.leopotam.ecs": "https://github.com/Leopotam/ecs.git", +``` +By default last released version will be used. If you need trunk / developing version then `develop` name of branch should be added after hash: +``` +"com.leopotam.ecs": "https://github.com/Leopotam/ecs.git#develop", +``` + +## As unity module from npm registry (Experimental) +This repository can be installed as unity module from external npm registry with support of different versions. In this way new block should be added to `Packages/manifest.json` right after opening `{` bracket: +``` + "scopedRegistries": [ + { + "name": "Leopotam", + "url": "https://npm.leopotam.com", + "scopes": [ + "com.leopotam" + ] + } + ], +``` +After this operation registry can be installed from list of packages from standard unity module manager. +> **Important!** Url can be changed later, check actual url at `README`. + +## As source +If you can't / don't want to use unity modules, code can be downloaded as sources archive of required release from [Releases page](`https://github.com/Leopotam/ecs/releases`). + + +# Main parts of ecs + +## Component +Container for user data without / with small logic inside. Can be used any user class without any additional inheritance: +```csharp +class WeaponComponent { + public int Ammo; + public string GunName; +} +``` + +> **Important!** Dont forget to manually init all fields of new added component. Default value initializers will not work due all components can be reused automatically multiple times through builtin pooling mechanism (no destroying / creating new instance for each request for performance reason). + +> **Important!** Dont forget to cleanup reference links to instances of any classes before removing components from entity, otherwise it can lead to memory leaks. +> +> By default all `marshal-by-reference` typed fields of component (classes in common case) will be checked for null on removing attempt in `DEBUG`-mode. If you know that you have object instance that should be not null (preinited collections for example) - `[EcsIgnoreNullCheck]` attribute can be used for disabling these checks. + +## Entity +Сontainer for components. Implemented as `EcsEntity` for wrapping internal identifiers: +```csharp +EcsEntity entity = _world.NewEntity (); +Component1 c1 = entity.Set (); +Component2 c2 = entity.Set (); +``` +There are some helpers to simplify creation of entity with multiple components: +```csharp +EcsEntity entity = _world.NewEntityWith (out Component1 c1, out Component2 c2); +``` + +> **Important!** Entities without components on them will be automatically removed on last `EcsEntity.Unset()` call. + +## System +Сontainer for logic for processing filtered entities. User class should implements `IEcsInitSystem`, `IEcsDestroySystem`, `IEcsRunSystem` (or other supported) interfaces: +```csharp +class WeaponSystem : IEcsPreInitSystem, IEcsInitSystem, IEcsDestroySystem, IEcsPreDestroySystem { + public void PreInit () { + // Will be called once during EcsSystems.Init() call and before IEcsInitSystem.Init. + } + + public void Init () { + // Will be called once during EcsSystems.Init() call. + } + + public void Destroy () { + // Will be called once during EcsSystems.Destroy() call. + } + + public void AfterDestroy () { + // Will be called once during EcsSystems.Destroy() call and after IEcsDestroySystem.Destroy. + } +} +``` + +```csharp +class HealthSystem : IEcsRunSystem { + public void Run () { + // Will be called on each EcsSystems.Run() call. + } +} +``` + +# Data injection +All compatible `EcsWorld` and `EcsFilter` fields of ecs-system will be auto-initialized (auto-injected): +```csharp +class HealthSystem : IEcsSystem { + // auto-injected fields. + EcsWorld _world = null; + EcsFilter _weaponFilter = null; +} +``` +Instance of any custom type can be injected to all systems through `EcsSystems.Inject()` method: +```csharp +var systems = new EcsSystems (world) + .Add (new TestSystem1 ()) + .Add (new TestSystem2 ()) + .Add (new TestSystem3 ()) + .Inject (a) + .Inject (b) + .Inject (c) + .Inject (d); +systems.Init (); +``` +Each system will be scanned for compatible fields (can contains all of them or no one) with proper initialization. + +> **Important!** Data injection for any user type can be used for sharing external data between systems. + +## Data Injection with multiple EcsSystems + +If you want to use multiple `EcsSystems` you can find strange behaviour with DI: + +```csharp +class Component1 { } + +class System1 : IEcsInitSystem { + EcsWorld _world = null; + + public void Init () { + _world.NewEntity ().Set (); + } +} + +class System2 : IEcsInitSystem { + EcsFilter _filter = null; + + public void Init () { + Debug.Log (_filter.GetEntitiesCount ()); + } +} + +var systems1 = new EcsSystems (world); +var systems2 = new EcsSystems (world); +systems1.Add (new System1 ()); +systems2.Add (new System2 ()); +systems1.Init (); +systems2.Init (); +``` +You will get "0" at console. Problem is that DI starts at `Init` method inside each `EcsSystems`. It means that any new `EcsFilter` instance (with lazy initialization) will be correctly injected only at current `EcsSystems`. + +To fix this behaviour startup code should be modified in this way: + +```csharp +var systems1 = new EcsSystems (world); +var systems2 = new EcsSystems (world); +systems1.Add (new System1 ()); +systems2.Add (new System2 ()); +systems1.ProcessInjects (); +systems2.ProcessInjects (); +systems1.Init (); +systems2.Init (); +``` +You should get "1" at console after fix. + +# Special classes + +## EcsFilter +Container for keeping filtered entities with specified component list: +```csharp +class WeaponSystem : IEcsInitSystem, IEcsRunSystem { + // auto-injected fields: EcsWorld instance and EcsFilter. + EcsWorld _world = null; + // We wants to get entities with "WeaponComponent" and without "HealthComponent". + EcsFilter.Exclude _filter = null; + + public void Init () { + // new C# syntax can be used if component instance not required right now. + _world.NewEntityWith (out _); + } + + public void Run () { + foreach (var i in _filter) { + // entity that contains WeaponComponent. + // Performance hint: use 'ref' prefixes for disable copying entity structure. + // Important: dont use `ref` on filter data outside of foreach-loop over this filter. + ref var entity = ref _filter.Entities[i]; + + // Get1 will return link to attached "WeaponComponent". + var weapon = _filter.Get1[i]; + weapon.Ammo = System.Math.Max (0, weapon.Ammo - 1); + } + } +} +``` +> **Important!** You should not use `ref` modifier for any filter data outside of foreach-loop over this filter if you want to destroy part of this data (entity or component) - it will break memory integrity. + +All components from filter `Include` constraint can be fast accessed through `filter.Get1()`, `filter.Get2()`, etc - in same order as they were used in filter type declaration. + +If fast access not required (for example, for flag-based components without data), component can implements `IEcsIgnoreInFilter` interface for decrease memory usage and increase performance: +```csharp +class Component1 { } + +class Component2 : IEcsIgnoreInFilter { } + +class TestSystem : IEcsRunSystem { + EcsFilter _filter = null; + + public void Run () { + foreach (var i in _filter) { + // its valid code. + var component1 = _filter.Get1[i]; + + // its invalid code due to cache for _filter.Get2[] is null for memory / performance reasons. + var component2 = _filter.Get2[i]; + } + } +} +``` + +> Important: Any filter supports up to 4 component types as "include" constraints and up to 2 component types as "exclude" constraints. Shorter constraints - better performance. + +> Important: If you will try to use 2 filters with same components but in different order - you will get exception with detailed info about conflicted types, but only in `DEBUG` mode. In `RELEASE` mode all checks will be skipped. + +## EcsWorld +Root level container for all entities / components, works like isolated environment. + +> Important: Do not forget to call `EcsWorld.Destroy()` method when instance will not be used anymore. + +## EcsSystems +Group of systems to process `EcsWorld` instance: +```csharp +class Startup : MonoBehaviour { + EcsWorld _world; + EcsSystems _systems; + + void Start () { + // create ecs environment. + _world = new EcsWorld (); + _systems = new EcsSystems (_world) + .Add (new WeaponSystem ()); + _systems.Init (); + } + + void Update () { + // process all dependent systems. + _systems.Run (); + _world.EndFrame (); + } + + void OnDestroy () { + // destroy systems logical group. + _systems.Destroy (); + // destroy world. + _world.Destroy (); + } +} +``` +> Important: Do not forget to call `EcsWorld.EndFrame()` method when all `EcsSystems` completed. + +`EcsSystems` instance can be used as nested system (any types of `IEcsInitSystem`, `IEcsRunSystem`, ecs behaviours are supported): +```csharp +// initialization. +var nestedSystems = new EcsSystems (_world).Add (new NestedSystem ()); +// dont call nestedSystems.Init() here, rootSystems will do it automatically. + +var rootSystems = new EcsSystems (_world).Add (nestedSystems); +rootSystems.Init (); + +// update loop. +// dont call nestedSystems.Run() here, rootSystems will do it automatically. +rootSystems.Run (); + +// destroying. +// dont call nestedSystems.Destroy() here, rootSystems will do it automatically. +rootSystems.Destroy (); +``` + +Any `IEcsRunSystem` or `EcsSystems` instance can be enabled or disabled from processing in runtime: +```csharp +class TestSystem : IEcsRunSystem { + public void Run () { } +} +var systems = new EcsSystems (_world); +systems.Add (new TestSystem (), "my special system"); +systems.Init (); +var idx = systems.GetNamedRunSystem ("my special system"); + +// state will be true here, all systems are active by default. +var state = systems.GetRunSystemState (idx); + +// disable system from execution. +systems.SetRunSystemState (idx, false); +``` + +# Examples +##With sources: +* [Snake game](https://github.com/Leopotam/ecs-snake) +* [Pacman game](https://github.com/SH42913/pacmanecs) +* [GTA5 custom wounds mod](https://github.com/SH42913/gunshotwound3) +* [Ecs Hybrid Unity integration](https://github.com/SH42913/leoecshybrid) + +##Without sources: +* [Hattori2 game](https://www.instagram.com/hattorigame/) +* [Natives game](https://alex-kpojb.itch.io/natives-ecs) +* [PrincessRun android game](https://play.google.com/store/apps/details?id=ru.zlodey.princessrun) +* [TowerRunner Revenge android game](https://play.google.com/store/apps/details?id=ru.zlodey.towerrunner20) +* [HypnoTap android game](https://play.google.com/store/apps/details?id=com.ZlodeyStudios.HypnoTap) +* [Elves-vs-Dwarfs game](https://globalgamejam.org/2019/games/elves-vs-dwarfs) + +# Extensions +* [Unity editor integration](https://github.com/Leopotam/ecs-unityintegration) +* [Unity uGui events support](https://github.com/Leopotam/ecs-ui) +* [Multi-threading support](https://github.com/Leopotam/ecs-threads) +* [Reactive systems](https://github.com/Leopotam/ecs-reactive) +* [Engine independent types](https://github.com/Leopotam/ecs-types) + +# License +The software released under the terms of the [MIT license](./LICENSE.md). Enjoy. + +# Donate +Its free opensource software, but you can buy me a coffee: + +Buy Me A Coffee + +# FAQ + +### I want to process one system at MonoBehaviour.Update() and another - at MonoBehaviour.FixedUpdate(). How I can do it? + +For splitting systems by `MonoBehaviour`-method multiple `EcsSystems` logical groups should be used: +```csharp +EcsSystems _update; +EcsSystems _fixedUpdate; + +void Start () { + var world = new EcsWorld (); + _update = new EcsSystems (world).Add (new UpdateSystem ()); + _update.Init (); + _fixedUpdate = new EcsSystems (world).Add (new FixedUpdateSystem ()); + _fixedUpdate.Init (); +} + +void Update () { + _update.Run (); +} + +void FixedUpdate () { + _fixedUpdate.Run (); +} +``` + +### I like how dependency injection works, but i want to skip some fields from initialization. How I can do it? + +You can use `[EcsIgnoreInject]` attribute on any field of system: +```csharp +... +// will be injected. +EcsFilter _filter1 = null; + +// will be skipped. +[EcsIgnoreInject] +EcsFilter _filter2 = null; +``` + +### I do not like foreach-loops, I know that for-loops are faster. How I can use it? + +Current implementation of foreach-loop fast enough (custom enumerator, no memory allocation), small performance differences can be found on 10k items and more. Current version doesnt support for-loop iterations anymore. + +### I copy&paste my reset components code again and again. How I can do it in other manner? + +If you want to simplify your code and keep reset-code in one place, you can use `IEcsAutoReset` interface for components: +```csharp +class MyComponent : IEcsAutoReset { + public object LinkToAnotherComponent; + + public void Reset() { + // Cleanup all marshal-by-reference fields here. + LinkToAnotherComponent = null; + } +} +``` +This method will be automatically called after component removing from entity and before recycling to component pool. + + +### I use components as events that works only one frame, then remove it at last system in execution sequence. It's boring, how I can automate it? + +If you want to remove one-frame components without additional custom code, you can implement `IEcsOneFrame` interface: +```csharp +class MyComponent : IEcsOneFrame { } +``` +> Important: Do not forget to call `EcsWorld.EndFrame()` method once after all `EcsSystems.Run` calls. + +> Important: Do not forget that if one-frame component contains `marshal-by-reference` typed fields - this component should implements `IEcsAutoReset` interface. + +### I need more than 4 components in filter, how i can do it? + +Check `EcsFilter` type source, copy&paste it to your project and add additional components support in same manner. \ No newline at end of file diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/README.md.meta b/Assets/Asset Cleaner/com.leopotam.ecs/README.md.meta new file mode 100644 index 00000000..6e3de5ae --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 484480c77292d814397c3ea54478c998 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src.meta b/Assets/Asset Cleaner/com.leopotam.ecs/src.meta new file mode 100644 index 00000000..ea34f2bc --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1d7681912a9edcc4d9b3629e4f487604 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsComponent.cs b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsComponent.cs new file mode 100644 index 00000000..8b3442a9 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsComponent.cs @@ -0,0 +1,184 @@ +// ---------------------------------------------------------------------------- +// The MIT License +// Simple Entity Component System framework https://github.com/Leopotam/ecs +// Copyright (c) 2017-2020 Leopotam +// ---------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Threading; + +// ReSharper disable ClassNeverInstantiated.Global + +namespace Leopotam.Ecs { + /// + /// Marks component type to be not auto-filled as GetX in filter. + /// + public interface IEcsIgnoreInFilter { } + + /// + /// Marks component type as resettable with custom logic. + /// + public interface IEcsAutoReset { + void Reset (); + } + + /// + /// Marks field of IEcsSystem class to be ignored during dependency injection. + /// + public sealed class EcsIgnoreInjectAttribute : Attribute { } + + /// + /// Marks field of component to be not checked for null on component removing. + /// Works only in DEBUG mode! + /// + [System.Diagnostics.Conditional ("DEBUG")] + [AttributeUsage (AttributeTargets.Field)] + public sealed class EcsIgnoreNullCheckAttribute : Attribute { } + + /// + /// Global descriptor of used component type. + /// + /// Component type. + public static class EcsComponentType where T : class { + // ReSharper disable StaticMemberInGenericType + public static readonly int TypeIndex; + public static readonly Type Type; + public static readonly bool IsAutoReset; + public static readonly bool IsIgnoreInFilter; + // ReSharper restore StaticMemberInGenericType + + static EcsComponentType () { + TypeIndex = Interlocked.Increment (ref EcsComponentPool.ComponentTypesCount); + Type = typeof (T); + IsAutoReset = typeof (IEcsAutoReset).IsAssignableFrom (Type); + IsIgnoreInFilter = typeof (IEcsIgnoreInFilter).IsAssignableFrom (Type); + } + } + +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + public sealed class EcsComponentPool { + /// + /// Global component type counter. + /// First component will be "1" for correct filters updating (add component on positive and remove on negative). + /// + internal static int ComponentTypesCount; + +#if DEBUG + readonly List _nullableFields = new List (8); +#endif + + public object[] Items = new Object[128]; + + Func _customCtor; + readonly Type _type; + readonly bool _isAutoReset; + + int[] _reservedItems = new int[128]; + int _itemsCount; + int _reservedItemsCount; + + internal EcsComponentPool (Type cType, bool isAutoReset) { + _type = cType; + _isAutoReset = isAutoReset; +#if DEBUG + // collect all marshal-by-reference fields. + var fields = _type.GetFields (); + for (var i = 0; i < fields.Length; i++) { + var field = fields[i]; + if (!Attribute.IsDefined (field, typeof (EcsIgnoreNullCheckAttribute))) { + var type = field.FieldType; + var underlyingType = Nullable.GetUnderlyingType (type); + if (!type.IsValueType || (underlyingType != null && !underlyingType.IsValueType)) { + if (type != typeof (string)) { + _nullableFields.Add (field); + } + } + if (type == typeof (EcsEntity)) { + _nullableFields.Add (field); + } + } + } +#endif + } + + /// + /// Sets custom constructor for component instances. + /// + /// + public void SetCustomCtor (Func ctor) { +#if DEBUG + // ReSharper disable once JoinNullCheckWithUsage + if (ctor == null) { throw new Exception ("Ctor is null."); } +#endif + _customCtor = ctor; + } + + /// + /// Sets new capacity (if more than current amount). + /// + /// New value. + public void SetCapacity (int capacity) { + if (capacity > Items.Length) { + Array.Resize (ref Items, capacity); + } + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public int New () { + int id; + if (_reservedItemsCount > 0) { + id = _reservedItems[--_reservedItemsCount]; + } else { + id = _itemsCount; + if (_itemsCount == Items.Length) { + Array.Resize (ref Items, _itemsCount << 1); + } + var instance = _customCtor != null ? _customCtor () : Activator.CreateInstance (_type); + // reset brand new instance if component implements IEcsAutoReset. + if (_isAutoReset) { + ((IEcsAutoReset) instance).Reset (); + } + Items[_itemsCount++] = instance; + } + return id; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public object GetItem (int idx) { + return Items[idx]; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public void Recycle (int idx) { + if (_isAutoReset) { + ((IEcsAutoReset) Items[idx]).Reset (); + } +#if DEBUG + // check all marshal-by-reference typed fields for nulls. + var obj = Items[idx]; + for (int i = 0, iMax = _nullableFields.Count; i < iMax; i++) { + if (_nullableFields[i].FieldType.IsValueType) { + if (_nullableFields[i].FieldType == typeof (EcsEntity) && ((EcsEntity) _nullableFields[i].GetValue (obj)).Owner != null) { + throw new Exception ( + $"Memory leak for \"{_type.Name}\" component: \"{_nullableFields[i].Name}\" field not null-ed with EcsEntity.Null. If you are sure that it's not - mark field with [EcsIgnoreNullCheck] attribute."); + } + } else { + if (_nullableFields[i].GetValue (obj) != null) { + throw new Exception ( + $"Memory leak for \"{_type.Name}\" component: \"{_nullableFields[i].Name}\" field not null-ed. If you are sure that it's not - mark field with [EcsIgnoreNullCheck] attribute."); + } + } + } +#endif + if (_reservedItemsCount == _reservedItems.Length) { + Array.Resize (ref _reservedItems, _reservedItemsCount << 1); + } + _reservedItems[_reservedItemsCount++] = idx; + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsComponent.cs.meta b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsComponent.cs.meta new file mode 100644 index 00000000..0fde1658 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15b66a8957ba23c418ec0f6922d999e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsEntity.cs b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsEntity.cs new file mode 100644 index 00000000..7127faa1 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsEntity.cs @@ -0,0 +1,301 @@ +// ---------------------------------------------------------------------------- +// The MIT License +// Simple Entity Component System framework https://github.com/Leopotam/ecs +// Copyright (c) 2017-2020 Leopotam +// ---------------------------------------------------------------------------- + +using System; +using System.Runtime.CompilerServices; + +namespace Leopotam.Ecs { + /// + /// Entity descriptor. + /// + public struct EcsEntity { + internal int Id; + internal ushort Gen; + internal EcsWorld Owner; + + public static readonly EcsEntity Null = new EcsEntity (); + + /// + /// Attaches or finds already attached component to entity. + /// + /// Type of component. +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public T Set () where T : class { + ref var entityData = ref Owner.GetEntityData (this); +#if DEBUG + if (entityData.Gen != Gen) { throw new Exception ("Cant add component to destroyed entity."); } +#endif + var typeIdx = EcsComponentType.TypeIndex; + // check already attached components. + for (int i = 0, iiMax = entityData.ComponentsCountX2; i < iiMax; i += 2) { + if (entityData.Components[i] == typeIdx) { + return (T) Owner.ComponentPools[typeIdx].Items[entityData.Components[i + 1]]; + } + } + // attach new component. + if (entityData.Components.Length == entityData.ComponentsCountX2) { + Array.Resize (ref entityData.Components, entityData.ComponentsCountX2 << 1); + } + entityData.Components[entityData.ComponentsCountX2++] = typeIdx; + + var pool = Owner.GetPool (); + + var idx = pool.New (); + entityData.Components[entityData.ComponentsCountX2++] = idx; +#if DEBUG + for (var ii = 0; ii < Owner.DebugListeners.Count; ii++) { + Owner.DebugListeners[ii].OnComponentListChanged (this); + } +#endif + Owner.UpdateFilters (typeIdx, this, entityData); + return (T) pool.Items[idx]; + } + + /// + /// Gets component attached to entity or null. + /// + /// Type of component. +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public T Get () where T : class { + ref var entityData = ref Owner.GetEntityData (this); +#if DEBUG + if (entityData.Gen != Gen) { throw new Exception ("Cant check component on destroyed entity."); } +#endif + var typeIdx = EcsComponentType.TypeIndex; + for (int i = 0, iMax = entityData.ComponentsCountX2; i < iMax; i += 2) { + if (entityData.Components[i] == typeIdx) { + return (T) Owner.ComponentPools[typeIdx].Items[entityData.Components[i + 1]]; + } + } + return null; + } + + /// + /// Removes component from entity. + /// + /// Type of component. +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public void Unset () where T : class { + Unset (EcsComponentType.TypeIndex); + } + + /// + /// Removes component from entity. + /// +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + internal void Unset (int typeIndex) { + ref var entityData = ref Owner.GetEntityData (this); + // save copy to local var for protect from cleanup fields outside. + var owner = Owner; +#if DEBUG + if (entityData.Gen != Gen) { throw new Exception ("Cant touch destroyed entity."); } +#endif + for (int i = 0, iMax = entityData.ComponentsCountX2; i < iMax; i += 2) { + if (entityData.Components[i] == typeIndex) { + owner.UpdateFilters (-typeIndex, this, entityData); + owner.ComponentPools[typeIndex].Recycle (entityData.Components[i + 1]); + // remove current item and move last component to this gap. + entityData.ComponentsCountX2 -= 2; + if (i < entityData.ComponentsCountX2) { + entityData.Components[i] = entityData.Components[entityData.ComponentsCountX2]; + entityData.Components[i + 1] = entityData.Components[entityData.ComponentsCountX2 + 1]; + } +#if DEBUG + for (var ii = 0; ii < Owner.DebugListeners.Count; ii++) { + Owner.DebugListeners[ii].OnComponentListChanged (this); + } +#endif + break; + } + } + // unrolled and inlined Destroy() call. + if (entityData.ComponentsCountX2 == 0) { + owner.RecycleEntityData (Id, ref entityData); +#if DEBUG + for (var ii = 0; ii < Owner.DebugListeners.Count; ii++) { + owner.DebugListeners[ii].OnEntityDestroyed (this); + } +#endif + } + } + + /// + /// Gets component index at component pool. + /// If component doesn't exists "-1" will be returned. + /// + /// Type of component. +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public int GetComponentIndexInPool () where T : class { + ref var entityData = ref Owner.GetEntityData (this); +#if DEBUG + if (entityData.Gen != Gen) { throw new Exception ("Cant check component on destroyed entity."); } +#endif + var typeIdx = EcsComponentType.TypeIndex; + for (int i = 0, iMax = entityData.ComponentsCountX2; i < iMax; i += 2) { + if (entityData.Components[i] == typeIdx) { + return entityData.Components[i + 1]; + } + } + return -1; + } + + /// + /// Gets internal identifier. + /// + public int GetInternalId () { + return Id; + } + + /// + /// Removes components from entity and destroys it. + /// +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public void Destroy () { + ref var entityData = ref Owner.GetEntityData (this); + // save copy to local var for protect from cleanup fields outside. + EcsEntity savedEntity; + savedEntity.Id = Id; + savedEntity.Gen = Gen; + savedEntity.Owner = Owner; +#if DEBUG + if (entityData.Gen != Gen) { throw new Exception ("Cant touch destroyed entity."); } +#endif + // remove components first. + for (var i = entityData.ComponentsCountX2 - 2; i >= 0; i -= 2) { + savedEntity.Owner.UpdateFilters (-entityData.Components[i], savedEntity, entityData); + savedEntity.Owner.ComponentPools[entityData.Components[i]].Recycle (entityData.Components[i + 1]); + entityData.ComponentsCountX2 -= 2; +#if DEBUG + for (var ii = 0; ii < savedEntity.Owner.DebugListeners.Count; ii++) { + savedEntity.Owner.DebugListeners[ii].OnComponentListChanged (savedEntity); + } +#endif + } + entityData.ComponentsCountX2 = 0; + savedEntity.Owner.RecycleEntityData (savedEntity.Id, ref entityData); +#if DEBUG + for (var ii = 0; ii < savedEntity.Owner.DebugListeners.Count; ii++) { + savedEntity.Owner.DebugListeners[ii].OnEntityDestroyed (savedEntity); + } +#endif + } + + /// + /// Is entity null-ed. + /// + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public bool IsNull () { + return Id == 0 && Gen == 0; + } + + /// + /// Is entity alive. + /// +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public bool IsAlive () { + if (Owner == null) { return false; } + ref var entityData = ref Owner.GetEntityData (this); + return entityData.Gen == Gen && entityData.ComponentsCountX2 >= 0; + } + + /// + /// Gets components count on entity. + /// +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public int GetComponentsCount () { + ref var entityData = ref Owner.GetEntityData (this); +#if DEBUG + if (entityData.Gen != Gen) { throw new Exception ("Cant touch destroyed entity."); } +#endif + return entityData.ComponentsCountX2 <= 0 ? 0 : (entityData.ComponentsCountX2 >> 1); + } + + /// + /// Gets all components on entity. + /// + /// List to put results in it. if null - will be created. + /// Amount of components in list. + public int GetComponents (ref object[] list) { + ref var entityData = ref Owner.GetEntityData (this); +#if DEBUG + if (entityData.Gen != Gen) { throw new Exception ("Cant touch destroyed entity."); } +#endif + var itemsCount = entityData.ComponentsCountX2 >> 1; + if (list == null || list.Length < itemsCount) { + list = new object[itemsCount]; + } + for (int i = 0, j = 0, iMax = entityData.ComponentsCountX2; i < iMax; i += 2, j++) { + list[j] = Owner.ComponentPools[entityData.Components[i]].GetItem (entityData.Components[i + 1]); + } + return itemsCount; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public static bool operator == (in EcsEntity lhs, in EcsEntity rhs) { + return lhs.Id == rhs.Id && lhs.Gen == rhs.Gen; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public static bool operator != (in EcsEntity lhs, in EcsEntity rhs) { + return lhs.Id != rhs.Id || lhs.Gen != rhs.Gen; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override int GetHashCode () { + // ReSharper disable NonReadonlyMemberInGetHashCode + // not readonly for performance reason - no ctor calls for EcsEntity struct. + return Id.GetHashCode () ^ (Gen.GetHashCode () << 2); + // ReSharper restore NonReadonlyMemberInGetHashCode + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override bool Equals (object other) { + if (!(other is EcsEntity)) { + return false; + } + var rhs = (EcsEntity) other; + return Id == rhs.Id && Gen == rhs.Gen; + } + +#if DEBUG + public override string ToString () { + return IsNull () ? "Entity-Null" : $"Entity-{Id}:{Gen}"; + } +#endif + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsEntity.cs.meta b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsEntity.cs.meta new file mode 100644 index 00000000..4d79b595 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsEntity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2813e6db660119c42933cad837cdc77a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsFilter.cs b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsFilter.cs new file mode 100644 index 00000000..aa00fe81 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsFilter.cs @@ -0,0 +1,696 @@ +// ---------------------------------------------------------------------------- +// The MIT License +// Simple Entity Component System framework https://github.com/Leopotam/ecs +// Copyright (c) 2017-2020 Leopotam +// ---------------------------------------------------------------------------- + +using System; +using System.Runtime.CompilerServices; + +// ReSharper disable InconsistentNaming +// ReSharper disable ClassNeverInstantiated.Global + +namespace Leopotam.Ecs { + /// + /// Common interface for all filter listeners. + /// + public interface IEcsFilterListener { + void OnEntityAdded (in EcsEntity entity); + void OnEntityRemoved (in EcsEntity entity); + } + + /// + /// Container for filtered entities based on specified constraints. + /// +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif +#if UNITY_2019_1_OR_NEWER + [UnityEngine.Scripting.Preserve] +#endif + public abstract class EcsFilter { + public EcsEntity[] Entities = new EcsEntity[EcsHelpers.FilterEntitiesSize]; + protected int EntitiesCount; + + int _lockCount; + + DelayedOp[] _delayedOps = new DelayedOp[EcsHelpers.FilterEntitiesSize]; + int _delayedOpsCount; + + // ReSharper disable MemberCanBePrivate.Global + protected IEcsFilterListener[] Listeners = new IEcsFilterListener[4]; + protected int ListenersCount; + // ReSharper restore MemberCanBePrivate.Global + + protected internal int[] IncludedTypeIndices; + protected internal int[] ExcludedTypeIndices; + + public Type[] IncludedTypes; + public Type[] ExcludedTypes; + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public Enumerator GetEnumerator () { + return new Enumerator (this); + } + + /// + /// Gets entities count. + /// + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public int GetEntitiesCount () { + return EntitiesCount; + } + + /// + /// Is filter not contains entities. + /// + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public bool IsEmpty () { + return EntitiesCount == 0; + } + + /// + /// Subscribes listener to filter events. + /// + /// Listener. + public void AddListener (IEcsFilterListener listener) { +#if DEBUG + for (int i = 0, iMax = ListenersCount; i < iMax; i++) { + if (Listeners[i] == listener) { + throw new Exception ("Listener already subscribed."); + } + } +#endif + if (Listeners.Length == ListenersCount) { + Array.Resize (ref Listeners, ListenersCount << 1); + } + Listeners[ListenersCount++] = listener; + } + + // ReSharper disable once CommentTypo + /// + /// Unsubscribes listener from filter events. + /// + /// Listener. + public void RemoveListener (IEcsFilterListener listener) { + for (int i = 0, iMax = ListenersCount; i < iMax; i++) { + if (Listeners[i] == listener) { + ListenersCount--; + // cant fill gap with last element due listeners order is important. + Array.Copy (Listeners, i + 1, Listeners, i, ListenersCount - i); + break; + } + } + } + + /// + /// Is filter compatible with components on entity with optional added / removed component. + /// + /// Entity data. + /// Optional added (greater 0) or removed (less 0) component. Will be ignored if zero. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + internal bool IsCompatible (in EcsWorld.EcsEntityData entityData, int addedRemovedTypeIndex) { + var incIdx = IncludedTypeIndices.Length - 1; + for (; incIdx >= 0; incIdx--) { + var typeIdx = IncludedTypeIndices[incIdx]; + var idx = entityData.ComponentsCountX2 - 2; + for (; idx >= 0; idx -= 2) { + var typeIdx2 = entityData.Components[idx]; + if (typeIdx2 == -addedRemovedTypeIndex) { + continue; + } + if (typeIdx2 == addedRemovedTypeIndex || typeIdx2 == typeIdx) { + break; + } + } + // not found. + if (idx == -2) { + break; + } + } + // one of required component not found. + if (incIdx != -1) { + return false; + } + // check for excluded components. + if (ExcludedTypeIndices != null) { + for (var excIdx = 0; excIdx < ExcludedTypeIndices.Length; excIdx++) { + var typeIdx = ExcludedTypeIndices[excIdx]; + for (var idx = entityData.ComponentsCountX2 - 2; idx >= 0; idx -= 2) { + var typeIdx2 = entityData.Components[idx]; + if (typeIdx2 == -addedRemovedTypeIndex) { + continue; + } + if (typeIdx2 == addedRemovedTypeIndex || typeIdx2 == typeIdx) { + return false; + } + } + } + } + return true; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + protected bool AddDelayedOp (bool isAdd, in EcsEntity entity) { + if (_lockCount <= 0) { + return false; + } + if (_delayedOps.Length == _delayedOpsCount) { + Array.Resize (ref _delayedOps, _delayedOpsCount << 1); + } + ref var op = ref _delayedOps[_delayedOpsCount++]; + op.IsAdd = isAdd; + op.Entity = entity; + return true; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + protected void ProcessListeners (bool isAdd, in EcsEntity entity) { + if (isAdd) { + for (int i = 0, iMax = ListenersCount; i < iMax; i++) { + Listeners[i].OnEntityAdded (entity); + } + } else { + for (int i = 0, iMax = ListenersCount; i < iMax; i++) { + Listeners[i].OnEntityRemoved (entity); + } + } + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + void Lock () { + _lockCount++; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + void Unlock () { +#if DEBUG + if (_lockCount <= 0) { + throw new Exception ($"Invalid lock-unlock balance for \"{GetType ().Name}\"."); + } +#endif + _lockCount--; + if (_lockCount == 0 && _delayedOpsCount > 0) { + // process delayed operations. + for (int i = 0, iMax = _delayedOpsCount; i < iMax; i++) { + ref var op = ref _delayedOps[i]; + if (op.IsAdd) { + OnAddEntity (op.Entity); + } else { + OnRemoveEntity (op.Entity); + } + } + _delayedOpsCount = 0; + } + } + +#if DEBUG + /// + /// For debug purposes. Check filters equality by included / excluded components. + /// + /// Filter to compare. + internal bool AreComponentsSame (EcsFilter filter) { + if (IncludedTypeIndices.Length != filter.IncludedTypeIndices.Length) { + return false; + } + for (var i = 0; i < IncludedTypeIndices.Length; i++) { + if (Array.IndexOf (filter.IncludedTypeIndices, IncludedTypeIndices[i]) == -1) { + return false; + } + } + if ((ExcludedTypeIndices == null && filter.ExcludedTypeIndices != null) || + (ExcludedTypeIndices != null && filter.ExcludedTypeIndices == null)) { + return false; + } + if (ExcludedTypeIndices != null) { + if (filter.ExcludedTypeIndices == null || ExcludedTypeIndices.Length != filter.ExcludedTypeIndices.Length) { + return false; + } + for (var i = 0; i < ExcludedTypeIndices.Length; i++) { + if (Array.IndexOf (filter.ExcludedTypeIndices, ExcludedTypeIndices[i]) == -1) { + return false; + } + } + } + return true; + } +#endif + + /// + /// Event for adding compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + public abstract void OnAddEntity (in EcsEntity entity); + + /// + /// Event for removing non-compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + public abstract void OnRemoveEntity (in EcsEntity entity); + + public struct Enumerator : IDisposable { + readonly EcsFilter _filter; + readonly int _count; + int _idx; + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + internal Enumerator (EcsFilter filter) { + _filter = filter; + _count = _filter.GetEntitiesCount (); + _idx = -1; + _filter.Lock (); + } + + public int Current { + [MethodImpl (MethodImplOptions.AggressiveInlining)] + get => _idx; + } + +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public void Dispose () { + _filter.Unlock (); + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public bool MoveNext () { + return ++_idx < _count; + } + } + + struct DelayedOp { + public bool IsAdd; + public EcsEntity Entity; + } + } + +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif +#if UNITY_2019_1_OR_NEWER + [UnityEngine.Scripting.Preserve] +#endif + public class EcsFilter : EcsFilter where Inc1 : class { + public Inc1[] Get1; + readonly bool _allow1; + + protected EcsFilter () { + _allow1 = !EcsComponentType.IsIgnoreInFilter; + Get1 = _allow1 ? new Inc1[EcsHelpers.FilterEntitiesSize] : null; + IncludedTypeIndices = new[] { EcsComponentType.TypeIndex }; + IncludedTypes = new[] { EcsComponentType.Type }; + } + + /// + /// Event for adding compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override void OnAddEntity (in EcsEntity entity) { + if (AddDelayedOp (true, entity)) { return; } + if (Entities.Length == EntitiesCount) { + Array.Resize (ref Entities, EntitiesCount << 1); + if (_allow1) { Array.Resize (ref Get1, EntitiesCount << 1); } + } + // inlined and optimized World.GetComponent() call. + ref var entityData = ref entity.Owner.GetEntityData (entity); + var allow1 = _allow1; + for (int i = 0, iMax = entityData.ComponentsCountX2; i < iMax; i += 2) { + var typeIdx = entityData.Components[i]; + var itemIdx = entityData.Components[i + 1]; + if (allow1 && typeIdx == EcsComponentType.TypeIndex) { + Get1[EntitiesCount] = (Inc1) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow1 = false; + } + } + Entities[EntitiesCount++] = entity; + ProcessListeners (true, entity); + } + + /// + /// Event for removing non-compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override void OnRemoveEntity (in EcsEntity entity) { + if (AddDelayedOp (false, entity)) { return; } + for (int i = 0, iMax = EntitiesCount; i < iMax; i++) { + if (Entities[i] == entity) { + EntitiesCount--; + if (i < EntitiesCount) { + Entities[i] = Entities[EntitiesCount]; + if (_allow1) { Get1[i] = Get1[EntitiesCount]; } + } + ProcessListeners (false, entity); + break; + } + } + } + + public class Exclude : EcsFilter where Exc1 : class { + protected Exclude () { + ExcludedTypeIndices = new[] { EcsComponentType.TypeIndex }; + ExcludedTypes = new[] { EcsComponentType.Type }; + } + } + + public class Exclude : EcsFilter where Exc1 : class where Exc2 : class { + protected Exclude () { + ExcludedTypeIndices = new[] { EcsComponentType.TypeIndex, EcsComponentType.TypeIndex }; + ExcludedTypes = new[] { EcsComponentType.Type, EcsComponentType.Type }; + } + } + } + +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif +#if UNITY_2019_1_OR_NEWER + [UnityEngine.Scripting.Preserve] +#endif + public class EcsFilter : EcsFilter where Inc1 : class where Inc2 : class { + public Inc1[] Get1; + public Inc2[] Get2; + readonly bool _allow1; + readonly bool _allow2; + + protected EcsFilter () { + _allow1 = !EcsComponentType.IsIgnoreInFilter; + _allow2 = !EcsComponentType.IsIgnoreInFilter; + Get1 = _allow1 ? new Inc1[EcsHelpers.FilterEntitiesSize] : null; + Get2 = _allow2 ? new Inc2[EcsHelpers.FilterEntitiesSize] : null; + IncludedTypeIndices = new[] { EcsComponentType.TypeIndex, EcsComponentType.TypeIndex }; + IncludedTypes = new[] { EcsComponentType.Type, EcsComponentType.Type }; + } + + /// + /// Event for adding compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override void OnAddEntity (in EcsEntity entity) { + if (AddDelayedOp (true, entity)) { return; } + if (Entities.Length == EntitiesCount) { + Array.Resize (ref Entities, EntitiesCount << 1); + if (_allow1) { Array.Resize (ref Get1, EntitiesCount << 1); } + if (_allow2) { Array.Resize (ref Get2, EntitiesCount << 1); } + } + // inlined and optimized World.GetComponent() call. + ref var entityData = ref entity.Owner.GetEntityData (entity); + var allow1 = _allow1; + var allow2 = _allow2; + for (int i = 0, iMax = entityData.ComponentsCountX2; i < iMax; i += 2) { + var typeIdx = entityData.Components[i]; + var itemIdx = entityData.Components[i + 1]; + if (allow1 && typeIdx == EcsComponentType.TypeIndex) { + Get1[EntitiesCount] = (Inc1) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow1 = false; + } + if (allow2 && typeIdx == EcsComponentType.TypeIndex) { + Get2[EntitiesCount] = (Inc2) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow2 = false; + } + } + Entities[EntitiesCount++] = entity; + ProcessListeners (true, entity); + } + + /// + /// Event for removing non-compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override void OnRemoveEntity (in EcsEntity entity) { + if (AddDelayedOp (false, entity)) { return; } + for (int i = 0, iMax = EntitiesCount; i < iMax; i++) { + if (Entities[i] == entity) { + EntitiesCount--; + if (i < EntitiesCount) { + Entities[i] = Entities[EntitiesCount]; + if (_allow1) { Get1[i] = Get1[EntitiesCount]; } + if (_allow2) { Get2[i] = Get2[EntitiesCount]; } + } + ProcessListeners (false, entity); + break; + } + } + } + + public class Exclude : EcsFilter where Exc1 : class { + protected Exclude () { + ExcludedTypeIndices = new[] { EcsComponentType.TypeIndex }; + ExcludedTypes = new[] { EcsComponentType.Type }; + } + } + + public class Exclude : EcsFilter where Exc1 : class where Exc2 : class { + protected Exclude () { + ExcludedTypeIndices = new[] { EcsComponentType.TypeIndex, EcsComponentType.TypeIndex }; + ExcludedTypes = new[] { EcsComponentType.Type, EcsComponentType.Type }; + } + } + } + +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif +#if UNITY_2019_1_OR_NEWER + [UnityEngine.Scripting.Preserve] +#endif + public class EcsFilter : EcsFilter where Inc1 : class where Inc2 : class where Inc3 : class { + // ReSharper disable MemberCanBePrivate.Global + public Inc1[] Get1; + public Inc2[] Get2; + public Inc3[] Get3; + // ReSharper restore MemberCanBePrivate.Global + readonly bool _allow1; + readonly bool _allow2; + readonly bool _allow3; + + protected EcsFilter () { + _allow1 = !EcsComponentType.IsIgnoreInFilter; + _allow2 = !EcsComponentType.IsIgnoreInFilter; + _allow3 = !EcsComponentType.IsIgnoreInFilter; + Get1 = _allow1 ? new Inc1[EcsHelpers.FilterEntitiesSize] : null; + Get2 = _allow2 ? new Inc2[EcsHelpers.FilterEntitiesSize] : null; + Get3 = _allow3 ? new Inc3[EcsHelpers.FilterEntitiesSize] : null; + IncludedTypeIndices = new[] { EcsComponentType.TypeIndex, EcsComponentType.TypeIndex, EcsComponentType.TypeIndex }; + IncludedTypes = new[] { EcsComponentType.Type, EcsComponentType.Type, EcsComponentType.Type }; + } + + /// + /// Event for adding compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override void OnAddEntity (in EcsEntity entity) { + if (AddDelayedOp (true, entity)) { return; } + if (Entities.Length == EntitiesCount) { + Array.Resize (ref Entities, EntitiesCount << 1); + if (_allow1) { Array.Resize (ref Get1, EntitiesCount << 1); } + if (_allow2) { Array.Resize (ref Get2, EntitiesCount << 1); } + if (_allow3) { Array.Resize (ref Get3, EntitiesCount << 1); } + } + // inlined and optimized World.GetComponent() call. + ref var entityData = ref entity.Owner.GetEntityData (entity); + var allow1 = _allow1; + var allow2 = _allow2; + var allow3 = _allow3; + for (int i = 0, iMax = entityData.ComponentsCountX2; i < iMax; i += 2) { + var typeIdx = entityData.Components[i]; + var itemIdx = entityData.Components[i + 1]; + if (allow1 && typeIdx == EcsComponentType.TypeIndex) { + Get1[EntitiesCount] = (Inc1) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow1 = false; + } + if (allow2 && typeIdx == EcsComponentType.TypeIndex) { + Get2[EntitiesCount] = (Inc2) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow2 = false; + } + if (allow3 && typeIdx == EcsComponentType.TypeIndex) { + Get3[EntitiesCount] = (Inc3) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow3 = false; + } + } + Entities[EntitiesCount++] = entity; + ProcessListeners (true, entity); + } + + /// + /// Event for removing non-compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override void OnRemoveEntity (in EcsEntity entity) { + if (AddDelayedOp (false, entity)) { return; } + for (int i = 0, iMax = EntitiesCount; i < iMax; i++) { + if (Entities[i] == entity) { + EntitiesCount--; + if (i < EntitiesCount) { + Entities[i] = Entities[EntitiesCount]; + if (_allow1) { Get1[i] = Get1[EntitiesCount]; } + if (_allow2) { Get2[i] = Get2[EntitiesCount]; } + if (_allow3) { Get3[i] = Get3[EntitiesCount]; } + } + ProcessListeners (false, entity); + break; + } + } + } + + public class Exclude : EcsFilter where Exc1 : class { + protected Exclude () { + ExcludedTypeIndices = new[] { EcsComponentType.TypeIndex }; + ExcludedTypes = new[] { EcsComponentType.Type }; + } + } + + public class Exclude : EcsFilter where Exc1 : class where Exc2 : class { + protected Exclude () { + ExcludedTypeIndices = new[] { EcsComponentType.TypeIndex, EcsComponentType.TypeIndex }; + ExcludedTypes = new[] { EcsComponentType.Type, EcsComponentType.Type }; + } + } + } + +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif +#if UNITY_2019_1_OR_NEWER + [UnityEngine.Scripting.Preserve] +#endif + public class EcsFilter : EcsFilter where Inc1 : class where Inc2 : class where Inc3 : class where Inc4 : class { + // ReSharper disable MemberCanBePrivate.Global + public Inc1[] Get1; + public Inc2[] Get2; + public Inc3[] Get3; + public Inc4[] Get4; + // ReSharper restore MemberCanBePrivate.Global + readonly bool _allow1; + readonly bool _allow2; + readonly bool _allow3; + readonly bool _allow4; + + protected EcsFilter () { + _allow1 = !EcsComponentType.IsIgnoreInFilter; + _allow2 = !EcsComponentType.IsIgnoreInFilter; + _allow3 = !EcsComponentType.IsIgnoreInFilter; + _allow4 = !EcsComponentType.IsIgnoreInFilter; + Get1 = _allow1 ? new Inc1[EcsHelpers.FilterEntitiesSize] : null; + Get2 = _allow2 ? new Inc2[EcsHelpers.FilterEntitiesSize] : null; + Get3 = _allow3 ? new Inc3[EcsHelpers.FilterEntitiesSize] : null; + Get4 = _allow4 ? new Inc4[EcsHelpers.FilterEntitiesSize] : null; + IncludedTypeIndices = new[] { + EcsComponentType.TypeIndex, + EcsComponentType.TypeIndex, + EcsComponentType.TypeIndex, + EcsComponentType.TypeIndex + }; + IncludedTypes = new[] { + EcsComponentType.Type, + EcsComponentType.Type, + EcsComponentType.Type, + EcsComponentType.Type + }; + } + + /// + /// Event for adding compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override void OnAddEntity (in EcsEntity entity) { + if (AddDelayedOp (true, entity)) { return; } + if (Entities.Length == EntitiesCount) { + Array.Resize (ref Entities, EntitiesCount << 1); + if (_allow1) { Array.Resize (ref Get1, EntitiesCount << 1); } + if (_allow2) { Array.Resize (ref Get2, EntitiesCount << 1); } + if (_allow3) { Array.Resize (ref Get3, EntitiesCount << 1); } + if (_allow4) { Array.Resize (ref Get4, EntitiesCount << 1); } + } + // inlined and optimized World.GetComponent() call. + ref var entityData = ref entity.Owner.GetEntityData (entity); + var allow1 = _allow1; + var allow2 = _allow2; + var allow3 = _allow3; + var allow4 = _allow4; + for (int i = 0, iMax = entityData.ComponentsCountX2; i < iMax; i += 2) { + var typeIdx = entityData.Components[i]; + var itemIdx = entityData.Components[i + 1]; + if (allow1 && typeIdx == EcsComponentType.TypeIndex) { + Get1[EntitiesCount] = (Inc1) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow1 = false; + } + if (allow2 && typeIdx == EcsComponentType.TypeIndex) { + Get2[EntitiesCount] = (Inc2) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow2 = false; + } + if (allow3 && typeIdx == EcsComponentType.TypeIndex) { + Get3[EntitiesCount] = (Inc3) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow3 = false; + } + if (allow4 && typeIdx == EcsComponentType.TypeIndex) { + Get4[EntitiesCount] = (Inc4) entity.Owner.ComponentPools[typeIdx].Items[itemIdx]; + allow4 = false; + } + } + Entities[EntitiesCount++] = entity; + ProcessListeners (true, entity); + } + + /// + /// Event for removing non-compatible entity to filter. + /// Warning: Don't call manually! + /// + /// Entity. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public override void OnRemoveEntity (in EcsEntity entity) { + if (AddDelayedOp (false, entity)) { return; } + for (int i = 0, iMax = EntitiesCount; i < iMax; i++) { + if (Entities[i] == entity) { + EntitiesCount--; + if (i < EntitiesCount) { + Entities[i] = Entities[EntitiesCount]; + if (_allow1) { Get1[i] = Get1[EntitiesCount]; } + if (_allow2) { Get2[i] = Get2[EntitiesCount]; } + if (_allow3) { Get3[i] = Get3[EntitiesCount]; } + if (_allow4) { Get4[i] = Get4[EntitiesCount]; } + } + ProcessListeners (false, entity); + break; + } + } + } + + public class Exclude : EcsFilter where Exc1 : class { + protected Exclude () { + ExcludedTypeIndices = new[] { EcsComponentType.TypeIndex }; + ExcludedTypes = new[] { EcsComponentType.Type }; + } + } + + public class Exclude : EcsFilter where Exc1 : class where Exc2 : class { + protected Exclude () { + ExcludedTypeIndices = new[] { EcsComponentType.TypeIndex, EcsComponentType.TypeIndex }; + ExcludedTypes = new[] { EcsComponentType.Type, EcsComponentType.Type }; + } + } + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsFilter.cs.meta b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsFilter.cs.meta new file mode 100644 index 00000000..6ac9892a --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsFilter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b90027f88e50ab84091856e4c71b9710 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsHelpers.cs b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsHelpers.cs new file mode 100644 index 00000000..321bcf49 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsHelpers.cs @@ -0,0 +1,68 @@ +// ---------------------------------------------------------------------------- +// The MIT License +// Simple Entity Component System framework https://github.com/Leopotam/ecs +// Copyright (c) 2017-2019 Leopotam +// ---------------------------------------------------------------------------- + +using System; +using System.Runtime.CompilerServices; + +namespace Leopotam.Ecs { + static class EcsHelpers { + const int EntityComponentsCount = 8; + public const int FilterEntitiesSize = 256; + public const int EntityComponentsCountX2 = EntityComponentsCount * 2; + } + + /// + /// Fast List replacement for growing only collections. + /// + /// Type of item. + public class EcsGrowList { + public T[] Items; + public int Count; + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public EcsGrowList (int capacity) { + Items = new T[capacity]; + Count = 0; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public void Add (T item) { + if (Items.Length == Count) { + Array.Resize (ref Items, Items.Length << 1); + } + Items[Count++] = item; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public void EnsureCapacity (int count) { + if (Items.Length < count) { + var len = Items.Length << 1; + while (len <= count) { + len <<= 1; + } + Array.Resize (ref Items, len); + } + } + } +} + +#if ENABLE_IL2CPP +// Unity IL2CPP performance optimization attribute. +namespace Unity.IL2CPP.CompilerServices { + enum Option { + NullChecks = 1, + ArrayBoundsChecks = 2 + } + + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] + class Il2CppSetOptionAttribute : Attribute { + public Option Option { get; private set; } + public object Value { get; private set; } + + public Il2CppSetOptionAttribute (Option option, object value) { Option = option; Value = value; } + } +} +#endif \ No newline at end of file diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsHelpers.cs.meta b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsHelpers.cs.meta new file mode 100644 index 00000000..45a2e0b2 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsHelpers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 93f7c1225241e624693cdb11c7f16e19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsSystem.cs b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsSystem.cs new file mode 100644 index 00000000..a40aa53c --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsSystem.cs @@ -0,0 +1,373 @@ +// ---------------------------------------------------------------------------- +// The MIT License +// Simple Entity Component System framework https://github.com/Leopotam/ecs +// Copyright (c) 2017-2020 Leopotam +// ---------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Leopotam.Ecs { + /// + /// Base interface for all systems. + /// + public interface IEcsSystem { } + + /// + /// Interface for PreInit systems. PreInit() will be called before Init(). + /// + public interface IEcsPreInitSystem : IEcsSystem { + void PreInit (); + } + + /// + /// Interface for Init systems. Init() will be called before Run(). + /// + public interface IEcsInitSystem : IEcsSystem { + void Init (); + } + + /// + /// Interface for AfterDestroy systems. AfterDestroy() will be called after Destroy(). + /// + public interface IEcsAfterDestroySystem : IEcsSystem { + void AfterDestroy (); + } + + /// + /// Interface for Destroy systems. Destroy() will be called last in system lifetime cycle. + /// + public interface IEcsDestroySystem : IEcsSystem { + void Destroy (); + } + + /// + /// Interface for Run systems. + /// + public interface IEcsRunSystem : IEcsSystem { + void Run (); + } + +#if DEBUG + /// + /// Debug interface for systems events processing. + /// + public interface IEcsSystemsDebugListener { + void OnSystemsDestroyed (); + } +#endif + + /// + /// Logical group of systems. + /// +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + public sealed class EcsSystems : IEcsInitSystem, IEcsDestroySystem, IEcsRunSystem { + public readonly string Name; + public readonly EcsWorld World; + readonly EcsGrowList _allSystems = new EcsGrowList (64); + readonly EcsGrowList _runSystems = new EcsGrowList (64); + readonly Dictionary _namedRunSystems = new Dictionary (64); + readonly Dictionary _injections = new Dictionary (32); + bool _injected; +#if DEBUG + bool _inited; + bool _destroyed; + readonly List _debugListeners = new List (4); + + /// + /// Adds external event listener. + /// + /// Event listener. + public void AddDebugListener (IEcsSystemsDebugListener listener) { + if (listener == null) { throw new Exception ("listener is null"); } + _debugListeners.Add (listener); + } + + /// + /// Removes external event listener. + /// + /// Event listener. + public void RemoveDebugListener (IEcsSystemsDebugListener listener) { + if (listener == null) { throw new Exception ("listener is null"); } + _debugListeners.Remove (listener); + } +#endif + + /// + /// Creates new instance of EcsSystems group. + /// + /// EcsWorld instance. + /// Custom name for this group. + public EcsSystems (EcsWorld world, string name = null) { + World = world; + Name = name; + } + + /// + /// Adds new system to processing. + /// + /// System instance. + /// Optional name of system. + public EcsSystems Add (IEcsSystem system, string namedRunSystem = null) { +#if DEBUG + if (system == null) { throw new Exception ("System is null."); } + if (_inited) { throw new Exception ("Cant add system after initialization."); } + if (_destroyed) { throw new Exception ("Cant touch after destroy."); } + if (!string.IsNullOrEmpty (namedRunSystem) && !(system is IEcsRunSystem)) { throw new Exception ("Cant name non-IEcsRunSystem."); } +#endif + _allSystems.Add (system); + if (system is IEcsRunSystem) { + if (namedRunSystem != null) { + _namedRunSystems[namedRunSystem.GetHashCode ()] = _runSystems.Count; + } + _runSystems.Add (new EcsSystemsRunItem () { Active = true, System = (IEcsRunSystem) system }); + } + return this; + } + + public int GetNamedRunSystem (string name) { + return _namedRunSystems.TryGetValue (name.GetHashCode (), out var idx) ? idx : -1; + } + + /// + /// Sets IEcsRunSystem active state. + /// + /// Index of system. + /// New state of system. + public void SetRunSystemState (int idx, bool state) { +#if DEBUG + if (idx < 0 || idx >= _runSystems.Count) { throw new Exception ("Invalid index"); } +#endif + _runSystems.Items[idx].Active = state; + } + + /// + /// Gets IEcsRunSystem active state. + /// + /// Index of system. + public bool GetRunSystemState (int idx) { +#if DEBUG + if (idx < 0 || idx >= _runSystems.Count) { throw new Exception ("Invalid index"); } +#endif + return _runSystems.Items[idx].Active; + } + + /// + /// Get all systems. Important: Don't change collection! + /// + public EcsGrowList GetAllSystems () { + return _allSystems; + } + + /// + /// Gets all run systems. Important: Don't change collection! + /// + public EcsGrowList GetRunSystems () { + return _runSystems; + } + + /// + /// Injects instance of object type to all compatible fields of added systems. + /// + /// Instance. + public EcsSystems Inject (T obj) { +#if DEBUG + if (_inited) { throw new Exception ("Cant inject after initialization."); } +#endif + _injections[typeof (T)] = obj; + return this; + } + + /// + /// Processes injections immediately. + /// Can be used to DI before Init() call. + /// + public EcsSystems ProcessInjects () { +#if DEBUG + if (_inited) { throw new Exception ("Cant inject after initialization."); } + if (_destroyed) { throw new Exception ("Cant touch after destroy."); } +#endif + if (!_injected) { + _injected = true; + for (int i = 0, iMax = _allSystems.Count; i < iMax; i++) { + var nestedSystems = _allSystems.Items[i] as EcsSystems; + if (nestedSystems != null) { + foreach (var pair in _injections) { + nestedSystems._injections[pair.Key] = pair.Value; + } + nestedSystems.ProcessInjects (); + } else { + InjectDataToSystem (_allSystems.Items[i], World, _injections); + } + } + } + return this; + } + + /// + /// Registers component type as one-frame for auto-removing at end of Run() call. + /// + public EcsSystems OneFrame () where T : class { + Add (new RemoveOneFrame ()); + return this; + } + + /// + /// Closes registration for new systems, initialize all registered. + /// + public void Init () { +#if DEBUG + if (_inited) { throw new Exception ("Already inited."); } + if (_destroyed) { throw new Exception ("Cant touch after destroy."); } +#endif + ProcessInjects (); + // IEcsPreInitSystem processing. + for (int i = 0, iMax = _allSystems.Count; i < iMax; i++) { + var system = _allSystems.Items[i]; + if (system is IEcsPreInitSystem) { + ((IEcsPreInitSystem) system).PreInit (); +#if DEBUG + World.CheckForLeakedEntities ($"{system.GetType ().Name}.PreInit()"); +#endif + } + } + // IEcsInitSystem processing. + for (int i = 0, iMax = _allSystems.Count; i < iMax; i++) { + var system = _allSystems.Items[i]; + if (system is IEcsInitSystem) { + ((IEcsInitSystem) system).Init (); +#if DEBUG + World.CheckForLeakedEntities ($"{system.GetType ().Name}.Init()"); +#endif + } + } +#if DEBUG + _inited = true; +#endif + } + + /// + /// Processes all IEcsRunSystem systems. + /// + public void Run () { +#if DEBUG + if (!_inited) { throw new Exception ($"[{Name ?? "NONAME"}] EcsSystems should be initialized before."); } + if (_destroyed) { throw new Exception ("Cant touch after destroy."); } +#endif + for (int i = 0, iMax = _runSystems.Count; i < iMax; i++) { + var runItem = _runSystems.Items[i]; + if (runItem.Active) { + runItem.System.Run (); + } +#if DEBUG + if (World.CheckForLeakedEntities (null)) { + throw new Exception ($"Empty entity detected, possible memory leak in {_runSystems.Items[i].GetType ().Name}.Run ()"); + } +#endif + } + } + + /// + /// Destroys registered data. + /// + public void Destroy () { +#if DEBUG + if (_destroyed) { throw new Exception ("Already destroyed."); } + _destroyed = true; +#endif + // IEcsDestroySystem processing. + for (var i = _allSystems.Count - 1; i >= 0; i--) { + var system = _allSystems.Items[i]; + if (system is IEcsDestroySystem) { + ((IEcsDestroySystem) system).Destroy (); +#if DEBUG + World.CheckForLeakedEntities ($"{system.GetType ().Name}.Destroy ()"); +#endif + } + } + // IEcsAfterDestroySystem processing. + for (var i = _allSystems.Count - 1; i >= 0; i--) { + var system = _allSystems.Items[i]; + if (system is IEcsAfterDestroySystem) { + ((IEcsAfterDestroySystem) system).AfterDestroy (); +#if DEBUG + World.CheckForLeakedEntities ($"{system.GetType ().Name}.AfterDestroy ()"); +#endif + } + } +#if DEBUG + for (int i = 0, iMax = _debugListeners.Count; i < iMax; i++) { + _debugListeners[i].OnSystemsDestroyed (); + } +#endif + } + + /// + /// Injects custom data to fields of ISystem instance. + /// + /// ISystem instance. + /// EcsWorld instance. + /// Additional instances for injection. + public static void InjectDataToSystem (IEcsSystem system, EcsWorld world, Dictionary injections) { + var systemType = system.GetType (); + var worldType = world.GetType (); + var filterType = typeof (EcsFilter); + var ignoreType = typeof (EcsIgnoreInjectAttribute); + + foreach (var f in systemType.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { + // skip statics or fields with [EcsIgnoreInject] attribute. + if (f.IsStatic || Attribute.IsDefined (f, ignoreType)) { + continue; + } + // EcsWorld + if (f.FieldType.IsAssignableFrom (worldType)) { + f.SetValue (system, world); + continue; + } + // EcsFilter +#if DEBUG + if (f.FieldType == filterType) { + throw new Exception ($"Cant use EcsFilter type at \"{system}\" system for dependency injection, use generic version instead"); + } +#endif + if (f.FieldType.IsSubclassOf (filterType)) { + f.SetValue (system, world.GetFilter (f.FieldType)); + continue; + } + // Other injections. + foreach (var pair in injections) { + if (f.FieldType.IsAssignableFrom (pair.Key)) { + f.SetValue (system, pair.Value); + break; + } + } + } + } + } + + /// + /// System for removing OneFrame component. + /// + /// OneFrame component type. + sealed class RemoveOneFrame : IEcsRunSystem where T : class { + readonly EcsFilter _oneFrames = null; + + void IEcsRunSystem.Run () { + foreach (var idx in _oneFrames) { + _oneFrames.Entities[idx].Unset (); + } + } + } + + /// + /// IEcsRunSystem instance with active state. + /// + public sealed class EcsSystemsRunItem { + public bool Active; + public IEcsRunSystem System; + } +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsSystem.cs.meta b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsSystem.cs.meta new file mode 100644 index 00000000..b995c34f --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 622f9ce2b229d5849b5a8f60a1486ddd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsWorld.cs b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsWorld.cs new file mode 100644 index 00000000..eb9bd67e --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsWorld.cs @@ -0,0 +1,463 @@ +// ---------------------------------------------------------------------------- +// The MIT License +// Simple Entity Component System framework https://github.com/Leopotam/ecs +// Copyright (c) 2017-2020 Leopotam +// ---------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Leopotam.Ecs { + /// + /// Ecs data context. + /// +#if ENABLE_IL2CPP + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.NullChecks, false)] + [Unity.IL2CPP.CompilerServices.Il2CppSetOption (Unity.IL2CPP.CompilerServices.Option.ArrayBoundsChecks, false)] +#endif + // ReSharper disable once ClassWithVirtualMembersNeverInherited.Global + public class EcsWorld { + // ReSharper disable MemberCanBePrivate.Global + protected EcsEntityData[] Entities = new EcsEntityData[1024]; + protected int EntitiesCount; + protected readonly EcsGrowList FreeEntities = new EcsGrowList (1024); + protected readonly EcsGrowList Filters = new EcsGrowList (128); + protected readonly Dictionary> FilterByIncludedComponents = new Dictionary> (64); + protected readonly Dictionary> FilterByExcludedComponents = new Dictionary> (64); + int _usedComponentsCount; + + /// + /// Component pools cache. + /// + // ReSharper restore MemberCanBePrivate.Global + public EcsComponentPool[] ComponentPools = new EcsComponentPool[512]; +#if DEBUG + internal readonly List DebugListeners = new List (4); + readonly EcsGrowList _leakedEntities = new EcsGrowList (256); + bool _isDestroyed; + bool _inDestroying; + + /// + /// Adds external event listener. + /// + /// Event listener. + public void AddDebugListener (IEcsWorldDebugListener listener) { + if (listener == null) { throw new Exception ("Listener is null."); } + DebugListeners.Add (listener); + } + + /// + /// Removes external event listener. + /// + /// Event listener. + public void RemoveDebugListener (IEcsWorldDebugListener listener) { + if (listener == null) { throw new Exception ("Listener is null."); } + DebugListeners.Remove (listener); + } +#endif + + /// + /// Destroys world and exist entities. + /// + public virtual void Destroy () { +#if DEBUG + if (_isDestroyed || _inDestroying) { throw new Exception ("EcsWorld already destroyed."); } + _inDestroying = true; + CheckForLeakedEntities ("Destroy"); +#endif + EcsEntity entity; + entity.Owner = this; + for (var i = EntitiesCount - 1; i >= 0; i--) { + ref var entityData = ref Entities[i]; + if (entityData.ComponentsCountX2 > 0) { + entity.Id = i; + entity.Gen = entityData.Gen; + entity.Destroy (); + } + } +#if DEBUG + _isDestroyed = true; + for (var i = DebugListeners.Count - 1; i >= 0; i--) { + DebugListeners[i].OnWorldDestroyed (); + } +#endif + } + + /// + /// Creates new entity. + /// + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public EcsEntity NewEntity () { +#if DEBUG + if (_isDestroyed) { throw new Exception ("EcsWorld already destroyed."); } +#endif + EcsEntity entity; + entity.Owner = this; + // try to reuse entity from pool. + if (FreeEntities.Count > 0) { + entity.Id = FreeEntities.Items[--FreeEntities.Count]; + ref var entityData = ref Entities[entity.Id]; + entity.Gen = entityData.Gen; + entityData.ComponentsCountX2 = 0; + } else { + // create new entity. + if (EntitiesCount == Entities.Length) { + Array.Resize (ref Entities, EntitiesCount << 1); + } + entity.Id = EntitiesCount++; + ref var entityData = ref Entities[entity.Id]; + entityData.Components = new int[EcsHelpers.EntityComponentsCountX2]; + entityData.Gen = 1; + entity.Gen = entityData.Gen; + entityData.ComponentsCountX2 = 0; + } +#if DEBUG + _leakedEntities.Add (entity); + for (var ii = 0; ii < DebugListeners.Count; ii++) { + DebugListeners[ii].OnEntityCreated (entity); + } +#endif + return entity; + } + + /// + /// Creates entity and attaches component. + /// + /// Type of component1. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public EcsEntity NewEntityWith (out T1 c1) where T1 : class { + var entity = NewEntity (); + c1 = entity.Set (); + return entity; + } + + /// + /// Creates entity and attaches components. + /// + /// Type of component1. + /// Type of component2. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public EcsEntity NewEntityWith (out T1 c1, out T2 c2) where T1 : class where T2 : class { + var entity = NewEntity (); + c1 = entity.Set (); + c2 = entity.Set (); + return entity; + } + + /// + /// Creates entity and attaches components. + /// + /// Type of component1. + /// Type of component2. + /// Type of component3. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public EcsEntity NewEntityWith (out T1 c1, out T2 c2, out T3 c3) where T1 : class where T2 : class where T3 : class { + var entity = NewEntity (); + c1 = entity.Set (); + c2 = entity.Set (); + c3 = entity.Set (); + return entity; + } + + /// + /// Creates entity and attaches components. + /// + /// Type of component1. + /// Type of component2. + /// Type of component3. + /// Type of component4. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public EcsEntity NewEntityWith (out T1 c1, out T2 c2, out T3 c3, out T4 c4) where T1 : class where T2 : class where T3 : class where T4 : class { + var entity = NewEntity (); + c1 = entity.Set (); + c2 = entity.Set (); + c3 = entity.Set (); + c4 = entity.Set (); + return entity; + } + + /// + /// Restores EcsEntity from internal id. For internal use only! + /// + /// Internal id. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public EcsEntity RestoreEntityFromInternalId (int id) { + EcsEntity entity; + entity.Owner = this; + entity.Id = id; + entity.Gen = 0; + ref var entityData = ref GetEntityData (entity); + entity.Gen = entityData.Gen; + return entity; + } + + /// + /// Request exist filter or create new one. For internal use only! + /// + /// Filter type. + public EcsFilter GetFilter (Type filterType) { +#if DEBUG + if (filterType == null) { throw new Exception ("FilterType is null."); } + if (!filterType.IsSubclassOf (typeof (EcsFilter))) { throw new Exception ($"Invalid filter type: {filterType}."); } + if (_isDestroyed) { throw new Exception ("EcsWorld already destroyed."); } +#endif + // check already exist filters. + for (int i = 0, iMax = Filters.Count; i < iMax; i++) { + if (Filters.Items[i].GetType () == filterType) { + return Filters.Items[i]; + } + } + // create new filter. + var filter = (EcsFilter) Activator.CreateInstance (filterType, true); +#if DEBUG + for (var filterIdx = 0; filterIdx < Filters.Count; filterIdx++) { + if (filter.AreComponentsSame (Filters.Items[filterIdx])) { + throw new Exception ( + $"Invalid filter \"{filter.GetType ()}\": Another filter \"{Filters.Items[filterIdx].GetType ()}\" already has same components, but in different order."); + } + } +#endif + Filters.Add (filter); + // add to component dictionaries for fast compatibility scan. + for (int i = 0, iMax = filter.IncludedTypeIndices.Length; i < iMax; i++) { + if (!FilterByIncludedComponents.TryGetValue (filter.IncludedTypeIndices[i], out var filtersList)) { + filtersList = new EcsGrowList (8); + FilterByIncludedComponents[filter.IncludedTypeIndices[i]] = filtersList; + } + filtersList.Add (filter); + } + if (filter.ExcludedTypeIndices != null) { + for (int i = 0, iMax = filter.ExcludedTypeIndices.Length; i < iMax; i++) { + if (!FilterByExcludedComponents.TryGetValue (filter.ExcludedTypeIndices[i], out var filtersList)) { + filtersList = new EcsGrowList (8); + FilterByExcludedComponents[filter.ExcludedTypeIndices[i]] = filtersList; + } + filtersList.Add (filter); + } + } +#if DEBUG + for (var ii = 0; ii < DebugListeners.Count; ii++) { + DebugListeners[ii].OnFilterCreated (filter); + } +#endif + return filter; + } + + /// + /// Gets stats of internal data. + /// + public EcsWorldStats GetStats () { + var stats = new EcsWorldStats () { + ActiveEntities = EntitiesCount - FreeEntities.Count, + ReservedEntities = FreeEntities.Count, + Filters = Filters.Count, + Components = _usedComponentsCount + }; + return stats; + } + + /// + /// Recycles internal entity data to pool. + /// + /// Entity id. + /// Entity internal data. + protected internal void RecycleEntityData (int id, ref EcsEntityData entityData) { +#if DEBUG + if (entityData.ComponentsCountX2 != 0) { throw new Exception ("Cant recycle invalid entity."); } +#endif + entityData.ComponentsCountX2 = -2; + entityData.Gen = (ushort) ((entityData.Gen + 1) % ushort.MaxValue); + FreeEntities.Add (id); + } + +#if DEBUG + /// + /// Checks exist entities but without components. + /// + /// Prefix for error message. + public bool CheckForLeakedEntities (string errorMsg) { + if (_leakedEntities.Count > 0) { + for (int i = 0, iMax = _leakedEntities.Count; i < iMax; i++) { + if (GetEntityData (_leakedEntities.Items[i]).ComponentsCountX2 == 0) { + if (errorMsg != null) { + throw new Exception ($"{errorMsg}: Empty entity detected, possible memory leak."); + } + return true; + } + } + _leakedEntities.Count = 0; + } + return false; + } +#endif + + /// + /// Updates filters. + /// + /// Component type index.abstract Positive for add operation, negative for remove operation. + /// Target entity. + /// Target entity data. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + protected internal void UpdateFilters (int typeIdx, in EcsEntity entity, in EcsEntityData entityData) { +#if DEBUG + if (_isDestroyed) { throw new Exception ("EcsWorld already destroyed."); } +#endif + EcsGrowList filters; + if (typeIdx < 0) { + // remove component. + if (FilterByIncludedComponents.TryGetValue (-typeIdx, out filters)) { + for (int i = 0, iMax = filters.Count; i < iMax; i++) { + if (filters.Items[i].IsCompatible (entityData, 0)) { +#if DEBUG + var isValid = false; + foreach (var idx in filters.Items[i]) { + if (filters.Items[i].Entities[idx].Id == entity.Id) { + isValid = true; + break; + } + } + if (!isValid) { throw new Exception ($"{filters.Items[i]}Entity not in filter."); } +#endif + filters.Items[i].OnRemoveEntity (entity); + } + } + } + if (FilterByExcludedComponents.TryGetValue (-typeIdx, out filters)) { + for (int i = 0, iMax = filters.Count; i < iMax; i++) { + if (filters.Items[i].IsCompatible (entityData, typeIdx)) { +#if DEBUG + var isValid = true; + foreach (var idx in filters.Items[i]) { + if (filters.Items[i].Entities[idx].Id == entity.Id) { + isValid = false; + break; + } + } + if (!isValid) { throw new Exception ($"{filters.Items[i]}Entity already in filter."); } +#endif + filters.Items[i].OnAddEntity (entity); + } + } + } + } else { + // add component. + if (FilterByIncludedComponents.TryGetValue (typeIdx, out filters)) { + for (int i = 0, iMax = filters.Count; i < iMax; i++) { + if (filters.Items[i].IsCompatible (entityData, 0)) { +#if DEBUG + var isValid = true; + foreach (var idx in filters.Items[i]) { + if (filters.Items[i].Entities[idx].Id == entity.Id) { + isValid = false; + break; + } + } + if (!isValid) { throw new Exception ($"{filters.Items[i]}Entity already in filter."); } +#endif + filters.Items[i].OnAddEntity (entity); + } + } + } + if (FilterByExcludedComponents.TryGetValue (typeIdx, out filters)) { + for (int i = 0, iMax = filters.Count; i < iMax; i++) { + if (filters.Items[i].IsCompatible (entityData, -typeIdx)) { +#if DEBUG + var isValid = false; + foreach (var idx in filters.Items[i]) { + if (filters.Items[i].Entities[idx].Id == entity.Id) { + isValid = true; + break; + } + } + if (!isValid) { throw new Exception ($"{filters.Items[i]}Entity not in filter."); } +#endif + filters.Items[i].OnRemoveEntity (entity); + } + } + } + } + } + + /// + /// Returns internal state of entity. For internal use! + /// + /// Entity. + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public ref EcsEntityData GetEntityData (in EcsEntity entity) { +#if DEBUG + if (_isDestroyed) { throw new Exception ("EcsWorld already destroyed."); } + if (entity.Id < 0 || entity.Id > EntitiesCount) { throw new Exception ($"Invalid entity {entity.Id}"); } +#endif + return ref Entities[entity.Id]; + } + + /// + /// Internal state of entity. + /// + [StructLayout (LayoutKind.Sequential, Pack = 2)] + public struct EcsEntityData { + public ushort Gen; + public short ComponentsCountX2; + public int[] Components; + } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public EcsComponentPool GetPool () where T : class { + var typeIdx = EcsComponentType.TypeIndex; + if (ComponentPools.Length < typeIdx) { + var len = ComponentPools.Length << 1; + while (len <= typeIdx) { + len <<= 1; + } + Array.Resize (ref ComponentPools, len); + } + var pool = ComponentPools[typeIdx]; + if (pool == null) { + pool = new EcsComponentPool (EcsComponentType.Type, EcsComponentType.IsAutoReset); + ComponentPools[typeIdx] = pool; + _usedComponentsCount++; + } + return pool; + } + } + + /// + /// Stats of EcsWorld instance. + /// + public struct EcsWorldStats { + /// + /// Amount of active entities. + /// + public int ActiveEntities; + + /// + /// Amount of cached (not in use) entities. + /// + public int ReservedEntities; + + /// + /// Amount of registered filters. + /// + public int Filters; + + /// + /// Amount of registered component types. + /// + public int Components; + } + +#if DEBUG + /// + /// Debug interface for world events processing. + /// + public interface IEcsWorldDebugListener { + void OnEntityCreated (EcsEntity entity); + void OnEntityDestroyed (EcsEntity entity); + void OnFilterCreated (EcsFilter filter); + void OnComponentListChanged (EcsEntity entity); + void OnWorldDestroyed (); + } +#endif +} \ No newline at end of file diff --git a/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsWorld.cs.meta b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsWorld.cs.meta new file mode 100644 index 00000000..c745be95 --- /dev/null +++ b/Assets/Asset Cleaner/com.leopotam.ecs/src/EcsWorld.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d506ff5dff038d547959e91aad707a8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Asset Cleaner/readme.txt b/Assets/Asset Cleaner/readme.txt new file mode 100644 index 00000000..0e9f6e42 --- /dev/null +++ b/Assets/Asset Cleaner/readme.txt @@ -0,0 +1,35 @@ +Asset Cleaner PRO - Clean | Find References + +Importing new version of an asset: +1) Delete an old version of the product - Assets/Asset Cleaner folder +2) Import from Asset Store to Assets folder + +IMPORTANT NOTICE: +We highly recomment you using repository at all times and have a repo backup before you do cleaning of your projects (general rule, not specific to this particular cleaner asset) + +How to launch Asset Cleaner? +1) Click on Window in top menu -> choose "- Asset Cleaner" +2) CTRL + L Unity (version 2019+) + +Tips & tricks to help master Asset Cleaner: +- Tooltips with explanation available for each button +- You can turn on infoboxes in Settings tab in Asset to increase the learning curve for the asset +- Videos available on the product page in Asset Store https://assetstore.unity.com/packages/tools/utilities/asset-cleaner-pro-clean-find-references-167990 + +Feature 1 - Project Cleaner: +- Project View is enhanced with counters for unused files on Folders and unused files marked RED. Size of unused assets/scenes is shown both on Folders and the files themselves +- Select Folder in Project View. Asset Cleaner will show the buttons to clean the folder from all unused Scenes and Assets if there are any +- Select File in Project View. Asset Cleaner will show the buttons to remove the Asset/Scene if it's unused +- *NEW* Multiselect in Project View (support for both Folders and Files) +- Use ignore path option in Settings tab +- *NEW* Customize your color for the highlighting of unused assets/scenes (works for both Personal and Dark themes): + 1) Open "Asset Cleaner" folder + 2) Open "Cleaner Style" asset located in the folder in Inspector + 3) Unfold "Pro" or "Personal" depending on the Unity skin you're using + 4) Click on the color near field "Red Highlight" + 5) Choose the color that fits you (RGBA values supported). Enjoy! + +Feature 2 - Find Reference +- Select the file that isn't unused/isn't marked RED in Project view and see the references to it in Project and in Scenes +- The usages are shown immediately in Asset Cleaner after switching the target in Project View +- Use Back/Forward (*NEW* also works for Ctrl+Z/Ctrl+Y and most mice Back/Forward buttons) and Lock buttons to navigate easily \ No newline at end of file diff --git a/Assets/Asset Cleaner/readme.txt.meta b/Assets/Asset Cleaner/readme.txt.meta new file mode 100644 index 00000000..48726698 --- /dev/null +++ b/Assets/Asset Cleaner/readme.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 91b865f19ed9ae24c8eabf86917841de +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Objects (Prefabs)/Furniture_Inside/M-11_Pro.prefab b/Assets/Objects (Prefabs)/Furniture_Inside/M-11_Pro.prefab index d6205803..4e29da3a 100644 --- a/Assets/Objects (Prefabs)/Furniture_Inside/M-11_Pro.prefab +++ b/Assets/Objects (Prefabs)/Furniture_Inside/M-11_Pro.prefab @@ -16,7 +16,7 @@ GameObject: m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 - m_StaticEditorFlags: 87 + m_StaticEditorFlags: 4294967295 m_IsActive: 1 --- !u!4 &7754365941339491261 Transform: @@ -25,14 +25,14 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6757179987670563246} - m_LocalRotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071067} + m_LocalRotation: {x: -0.7069834, y: 0, z: 0, w: 0.7072302} m_LocalPosition: {x: -22.124903, y: -0.00000035762787, z: 6.250992} - m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalScale: {x: -1, y: 1, z: 1} m_Children: - {fileID: 7754365941196070952} m_Father: {fileID: 0} m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_LocalEulerAnglesHint: {x: -89.98, y: 0, z: 0} --- !u!33 &1641012317642731915 MeshFilter: m_ObjectHideFlags: 0 @@ -98,7 +98,7 @@ GameObject: m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 - m_StaticEditorFlags: 87 + m_StaticEditorFlags: 4294967295 m_IsActive: 1 --- !u!4 &7754365941196070952 Transform: @@ -108,7 +108,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6757179987812930107} m_LocalRotation: {x: 0.000000029802322, y: 0.000000059604645, z: -0.7071072, w: 0.70710635} - m_LocalPosition: {x: -0.5208969, y: -0.23570822, z: 0} + m_LocalPosition: {x: -0.521, y: -0.236, z: -0.006} m_LocalScale: {x: 0.7884001, y: 0.70300007, z: 1} m_Children: [] m_Father: {fileID: 7754365941339491261} diff --git a/Assets/Other/Delta (Toomas) v0.blend b/Assets/Other/Delta (Toomas) v0.blend index 6be818c9..516af400 100644 --- a/Assets/Other/Delta (Toomas) v0.blend +++ b/Assets/Other/Delta (Toomas) v0.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8db2e51d34a4d5d09dd09981d0462ac8fb4c7f9f7c90dc5a166d6a1171ab65e2 -size 10745204 +oid sha256:d5ff9d115b102ecc6af8b2fb458be199b5b72760ab6c5c150789f743391b9841 +size 10728444 diff --git a/Assets/Other/Delta (Toomas) v0.blend1 b/Assets/Other/Delta (Toomas) v0.blend1 index 269f875f..c678b266 100644 Binary files a/Assets/Other/Delta (Toomas) v0.blend1 and b/Assets/Other/Delta (Toomas) v0.blend1 differ diff --git a/Assets/Scenes/Main_scene/LightingData.asset b/Assets/Scenes/Main_scene/LightingData.asset deleted file mode 100644 index 351952eb..00000000 Binary files a/Assets/Scenes/Main_scene/LightingData.asset and /dev/null differ diff --git a/Assets/Scenes/Main_scene/Lightmap-13_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-13_comp_light.exr.meta deleted file mode 100644 index 2d3e5798..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-13_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: 971c8c38756ec5f48bb29660fa550866 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-14_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-14_comp_light.exr.meta deleted file mode 100644 index 1b7df17a..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-14_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: bcc684f70f580c04f9f1d2d8d16c27eb -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-15_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-15_comp_light.exr.meta deleted file mode 100644 index e99c4b29..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-15_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: 776acd35e9548974381fbddc56e28f71 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-16_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-16_comp_light.exr.meta deleted file mode 100644 index 6281b674..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-16_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: 70c28ac1c5aebd2468748ec4fd08c166 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-17_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-17_comp_light.exr.meta deleted file mode 100644 index 27eb3bd9..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-17_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: f9fef71a97c63374499fe4428dac8a2d -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-1_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-1_comp_light.exr.meta deleted file mode 100644 index 18d9447e..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-1_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: 4c35c1c7d0c602044ba3e89b2d0a4158 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-2_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-2_comp_light.exr.meta deleted file mode 100644 index a845ca78..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-2_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: acaf357a7cd47114c92a6690f3902b0b -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-3_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-3_comp_light.exr.meta deleted file mode 100644 index 38253d53..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-3_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: c5349706b61c91547b6e16bc770d4142 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-4_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-4_comp_light.exr.meta deleted file mode 100644 index 94610342..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-4_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: 2b44b9855cc7ec34eb9ff81be987e68c -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-5_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-5_comp_light.exr.meta deleted file mode 100644 index 843cd991..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-5_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: 566ce0e907d521746a2de1248138edd2 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-6_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-6_comp_light.exr.meta deleted file mode 100644 index cc7286fd..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-6_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: b1292c9ea297c8d4e98031c71251bab5 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-7_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-7_comp_light.exr.meta deleted file mode 100644 index 8b46167e..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-7_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: 9687f137d55c41b439978b421f117b97 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-8_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-8_comp_light.exr.meta deleted file mode 100644 index 8b63cf6e..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-8_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: f1743df96fa2b7445b1c79b0565cbb45 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/Lightmap-9_comp_light.exr.meta b/Assets/Scenes/Main_scene/Lightmap-9_comp_light.exr.meta deleted file mode 100644 index 88c2da57..00000000 --- a/Assets/Scenes/Main_scene/Lightmap-9_comp_light.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: 12d79653ad558bc4e852382b43747af9 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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: 1 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 3 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 6 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 2 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/ReflectionProbe-0.exr.meta b/Assets/Scenes/Main_scene/ReflectionProbe-0.exr.meta deleted file mode 100644 index feb65055..00000000 --- a/Assets/Scenes/Main_scene/ReflectionProbe-0.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: bb05da44c0633ff488a504d1bf42adba -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 1 - seamlessCubemap: 1 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 2 - aniso: 0 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 2 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 100 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/ReflectionProbe-1.exr.meta b/Assets/Scenes/Main_scene/ReflectionProbe-1.exr.meta deleted file mode 100644 index 219e2221..00000000 --- a/Assets/Scenes/Main_scene/ReflectionProbe-1.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: 146e48e4ef9f1fd4a91aa13a422da3a3 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 1 - seamlessCubemap: 1 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 2 - aniso: 0 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 2 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 100 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scenes/Main_scene/ReflectionProbe-2.exr.meta b/Assets/Scenes/Main_scene/ReflectionProbe-2.exr.meta deleted file mode 100644 index d9eeba21..00000000 --- a/Assets/Scenes/Main_scene/ReflectionProbe-2.exr.meta +++ /dev/null @@ -1,96 +0,0 @@ -fileFormatVersion: 2 -guid: bf9e7c70e4622e24792a9448ed4a5460 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - 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 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 1 - seamlessCubemap: 1 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 2 - aniso: 0 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - 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: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 2 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 100 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 706abfe9..2b742061 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -198,7 +198,7 @@ "depth": 1, "source": "registry", "dependencies": { - "com.unity.subsystemregistration": "1.0.6" + "com.unity.subsystemregistration": "1.0.5" }, "url": "https://packages.unity.com" },