#pragma warning disable 0219 using System; using System.Collections.Generic; using UnityEditor.AssetImporters; using UnityEditor.U2D.Aseprite.Common; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; namespace UnityEditor.U2D.Aseprite { [CustomEditor(typeof(AsepriteImporter))] [CanEditMultipleObjects] internal class AsepriteImporterEditor : ScriptedImporterEditor, ITexturePlatformSettingsDataProvider { const string k_BaseFieldAlignedUssClass = "unity-base-field__aligned"; const string k_HiddenElementUssClass = "HiddenElement"; const string k_PaddingElementUssClass = "PaddingElement"; const string k_SubElementUssClass = "SubElement"; SerializedProperty m_TextureType; SerializedProperty m_TextureShape; SerializedProperty m_SpriteMode; SerializedProperty m_SpritePixelsToUnits; SerializedProperty m_SpriteMeshType; SerializedProperty m_SpriteExtrude; SerializedProperty m_Alignment; SerializedProperty m_SpritePivot; SerializedProperty m_NPOTScale; SerializedProperty m_IsReadable; SerializedProperty m_sRGBTexture; SerializedProperty m_AlphaSource; #if ENABLE_TEXTURE_STREAMING SerializedProperty m_StreamingMipmaps; SerializedProperty m_StreamingMipmapsPriority; #endif SerializedProperty m_MipMapMode; SerializedProperty m_EnableMipMap; SerializedProperty m_FadeOut; SerializedProperty m_BorderMipMap; SerializedProperty m_MipMapsPreserveCoverage; SerializedProperty m_AlphaTestReferenceValue; SerializedProperty m_MipMapFadeDistanceStart; SerializedProperty m_MipMapFadeDistanceEnd; SerializedProperty m_AlphaIsTransparency; SerializedProperty m_FilterMode; SerializedProperty m_Aniso; SerializedProperty m_WrapU; SerializedProperty m_WrapV; SerializedProperty m_WrapW; SerializedProperty m_ConvertToNormalMap; SerializedProperty m_PlatformSettingsArrProp; SerializedProperty m_FileImportMode; SerializedProperty m_ImportHiddenLayers; SerializedProperty m_LayerImportMode; SerializedProperty m_DefaultPivotSpace; SerializedProperty m_DefaultPivotAlignment; SerializedProperty m_CustomPivotPosition; SerializedProperty m_SpritePadding; SerializedProperty m_GenerateModelPrefab; SerializedProperty m_AddSortingGroup; SerializedProperty m_AddShadowCasters; SerializedProperty m_GenerateAnimationClips; SerializedProperty m_PrevGenerateAnimationClips; VisualElement m_RootVisualElement; VisualElement m_InspectorSettingsView; readonly Dictionary m_AdvancedInspectorGUI = new(); bool m_IsPowerOfTwo = false; readonly AsepriteImporterEditorFoldOutState m_EditorFoldOutState = new(); bool m_ShowPerAxisWrapModes = false; readonly int[] m_FilterModeOptions = (int[])(Enum.GetValues(typeof(FilterMode))); TexturePlatformSettingsHelper m_TexturePlatformSettingsHelper; VisualElement[] m_InspectorUI; int m_ActiveEditorIndex = 0; bool ITexturePlatformSettingsDataProvider.textureTypeHasMultipleDifferentValues => m_TextureType.hasMultipleDifferentValues; TextureImporterType ITexturePlatformSettingsDataProvider.textureType => (TextureImporterType)m_TextureType.intValue; SpriteImportMode ITexturePlatformSettingsDataProvider.spriteImportMode => spriteImportMode; FileImportModes fileImportMode => (FileImportModes) m_FileImportMode.intValue; SpriteImportMode spriteImportMode => (SpriteImportMode)m_SpriteMode.intValue; AnimationClip m_DefaultClip; ModelPreviewer m_ModelPreviewer; AsepriteImporter[] m_ImporterTargets; string[] m_AssetPaths; /// /// The SerializedProperty of an array of TextureImporterPlatformSettings. /// public SerializedProperty platformSettingsArray => m_PlatformSettingsArrProp; public override bool showImportedObject => false; public override bool UseDefaultMargins() => false; /// /// Implementation of AssetImporterEditor.OnEnable /// public override void OnEnable() { base.OnEnable(); CacheImporterData(); CacheSerializedProperties(); SetupInspectorUI(); InitPreview(); } void CacheImporterData() { m_ImporterTargets = new AsepriteImporter[targets.Length]; m_AssetPaths = new string[targets.Length]; for (var i = 0; i < targets.Length; ++i) { var importer = (AsepriteImporter)targets[i]; m_ImporterTargets[i] = importer; m_AssetPaths[i] = importer.assetPath; m_IsPowerOfTwo &= importer.isNPOT; } } void CacheSerializedProperties() { var textureImporterSettingsSP = serializedObject.FindProperty("m_TextureImporterSettings"); m_TextureType = textureImporterSettingsSP.FindPropertyRelative("m_TextureType"); m_TextureShape = textureImporterSettingsSP.FindPropertyRelative("m_TextureShape"); m_ConvertToNormalMap = textureImporterSettingsSP.FindPropertyRelative("m_ConvertToNormalMap"); m_SpriteMode = textureImporterSettingsSP.FindPropertyRelative("m_SpriteMode"); m_SpritePixelsToUnits = textureImporterSettingsSP.FindPropertyRelative("m_SpritePixelsToUnits"); m_SpriteMeshType = textureImporterSettingsSP.FindPropertyRelative("m_SpriteMeshType"); m_SpriteExtrude = textureImporterSettingsSP.FindPropertyRelative("m_SpriteExtrude"); m_Alignment = textureImporterSettingsSP.FindPropertyRelative("m_Alignment"); m_SpritePivot = textureImporterSettingsSP.FindPropertyRelative("m_SpritePivot"); m_NPOTScale = textureImporterSettingsSP.FindPropertyRelative("m_NPOTScale"); m_IsReadable = textureImporterSettingsSP.FindPropertyRelative("m_IsReadable"); m_sRGBTexture = textureImporterSettingsSP.FindPropertyRelative("m_sRGBTexture"); m_AlphaSource = textureImporterSettingsSP.FindPropertyRelative("m_AlphaSource"); #if ENABLE_TEXTURE_STREAMING m_StreamingMipmaps = textureImporterSettingsSP.FindPropertyRelative("m_StreamingMipmaps"); m_StreamingMipmapsPriority = textureImporterSettingsSP.FindPropertyRelative("m_StreamingMipmapsPriority"); #endif m_MipMapMode = textureImporterSettingsSP.FindPropertyRelative("m_MipMapMode"); m_EnableMipMap = textureImporterSettingsSP.FindPropertyRelative("m_EnableMipMap"); m_FadeOut = textureImporterSettingsSP.FindPropertyRelative("m_FadeOut"); m_BorderMipMap = textureImporterSettingsSP.FindPropertyRelative("m_BorderMipMap"); m_MipMapsPreserveCoverage = textureImporterSettingsSP.FindPropertyRelative("m_MipMapsPreserveCoverage"); m_AlphaTestReferenceValue = textureImporterSettingsSP.FindPropertyRelative("m_AlphaTestReferenceValue"); m_MipMapFadeDistanceStart = textureImporterSettingsSP.FindPropertyRelative("m_MipMapFadeDistanceStart"); m_MipMapFadeDistanceEnd = textureImporterSettingsSP.FindPropertyRelative("m_MipMapFadeDistanceEnd"); m_AlphaIsTransparency = textureImporterSettingsSP.FindPropertyRelative("m_AlphaIsTransparency"); m_FilterMode = textureImporterSettingsSP.FindPropertyRelative("m_FilterMode"); m_Aniso = textureImporterSettingsSP.FindPropertyRelative("m_Aniso"); m_WrapU = textureImporterSettingsSP.FindPropertyRelative("m_WrapU"); m_WrapV = textureImporterSettingsSP.FindPropertyRelative("m_WrapV"); m_WrapW = textureImporterSettingsSP.FindPropertyRelative("m_WrapW"); m_PlatformSettingsArrProp = extraDataSerializedObject.FindProperty("platformSettings"); var asepriteImporterSettings = serializedObject.FindProperty("m_AsepriteImporterSettings"); m_FileImportMode = asepriteImporterSettings.FindPropertyRelative("m_FileImportMode"); m_ImportHiddenLayers = asepriteImporterSettings.FindPropertyRelative("m_ImportHiddenLayers"); m_LayerImportMode = asepriteImporterSettings.FindPropertyRelative("m_LayerImportMode"); m_DefaultPivotSpace = asepriteImporterSettings.FindPropertyRelative("m_DefaultPivotSpace"); m_DefaultPivotAlignment = asepriteImporterSettings.FindPropertyRelative("m_DefaultPivotAlignment"); m_CustomPivotPosition = asepriteImporterSettings.FindPropertyRelative("m_CustomPivotPosition"); m_SpritePadding = asepriteImporterSettings.FindPropertyRelative("m_SpritePadding"); m_GenerateModelPrefab = asepriteImporterSettings.FindPropertyRelative("m_GenerateModelPrefab"); m_AddSortingGroup = asepriteImporterSettings.FindPropertyRelative("m_AddSortingGroup"); m_AddShadowCasters = asepriteImporterSettings.FindPropertyRelative("m_AddShadowCasters"); m_GenerateAnimationClips = asepriteImporterSettings.FindPropertyRelative("m_GenerateAnimationClips"); var prevAsepriteImporterSettings = serializedObject.FindProperty("m_PreviousAsepriteImporterSettings"); m_PrevGenerateAnimationClips = prevAsepriteImporterSettings.FindPropertyRelative("m_GenerateAnimationClips"); m_TexturePlatformSettingsHelper = new TexturePlatformSettingsHelper(this); } void SetupInspectorUI() { var advancedGUIAction = new Action[] { ColorSpaceGUI, AlphaHandlingGUI, POTScaleGUI, ReadableGUI, MipMapGUI }; m_AdvancedInspectorGUI.Add(TextureImporterType.Sprite, advancedGUIAction); advancedGUIAction = new Action[] { POTScaleGUI, ReadableGUI, MipMapGUI }; m_AdvancedInspectorGUI.Add(TextureImporterType.Default, advancedGUIAction); m_InspectorUI = new [] { SetupSpriteActorContainer() }; m_ActiveEditorIndex = Mathf.Max(EditorPrefs.GetInt(this.GetType().Name + "ActiveEditorIndex", 0), 0); m_ActiveEditorIndex %= m_InspectorUI.Length; } VisualElement SetupSpriteActorContainer() { var spriteActorContainer = new VisualElement() { name = "SpriteActorContainer" }; SetupGeneralContainer(spriteActorContainer); SetupLayerImportContainer(spriteActorContainer); SetupGenerateAssetContainer(spriteActorContainer); SetupCommonTextureSettingsContainer(spriteActorContainer); SetupPlatformSettingsContainer(spriteActorContainer); SetupAdvancedContainer(spriteActorContainer); var applyRevertContainer = new IMGUIContainer(ApplyRevertGUI); spriteActorContainer.Add(applyRevertContainer); return spriteActorContainer; } void SetupGeneralContainer(VisualElement root) { var foldOut = new Foldout() { text = styles.generalHeaderText.text, tooltip = styles.generalHeaderText.tooltip, value = m_EditorFoldOutState.generalFoldout }; ImporterEditorUtils.AddSkinUssClass(foldOut.Q()); foldOut.RegisterValueChangedCallback(_ => { m_EditorFoldOutState.generalFoldout = foldOut.value; }); root.Add(foldOut); var importModeField = new PropertyField(m_FileImportMode, styles.fileImportMode.text) { tooltip = styles.fileImportMode.tooltip }; importModeField.Bind(serializedObject); foldOut.Add(importModeField); var ppuField = new PropertyField(m_SpritePixelsToUnits, styles.spritePixelsPerUnit.text) { tooltip = styles.spritePixelsPerUnit.tooltip }; ppuField.Bind(serializedObject); ppuField.RegisterValueChangeCallback(x => { m_SpritePixelsToUnits.floatValue = Mathf.Max(m_SpritePixelsToUnits.floatValue, 1f); serializedObject.ApplyModifiedProperties(); }); foldOut.Add(ppuField); var meshField = new PopupField(styles.spriteMeshTypeOptions, m_SpriteMeshType.intValue) { label = styles.spriteMeshType.text, tooltip = styles.spriteMeshType.tooltip }; meshField.AddToClassList(k_BaseFieldAlignedUssClass); meshField.RegisterValueChangedCallback(x => { m_SpriteMeshType.intValue = meshField.index; serializedObject.ApplyModifiedProperties(); }); foldOut.Add(meshField); SetupSpriteEditorButton(foldOut); var paddingElement = new VisualElement() { name = "PaddingElement" }; paddingElement.AddToClassList(k_PaddingElementUssClass); foldOut.Add(paddingElement); } void SetupSpriteEditorButton(VisualElement root) { var spriteEditorBtn = new Button() { text = styles.spriteEditorButtonLabel.text }; root.Add(spriteEditorBtn); spriteEditorBtn.SetEnabled(m_ImporterTargets.Length == 1); spriteEditorBtn.clicked += () => { if (HasModified()) { // To ensure Sprite Editor Window to have the latest texture import setting, // We must applied those modified values first. var dialogText = string.Format(s_Styles.unappliedSettingsDialogContent.text, ((AssetImporter)target).assetPath); if (EditorUtility.DisplayDialog(s_Styles.unappliedSettingsDialogTitle.text, dialogText, s_Styles.applyButtonLabel.text, s_Styles.cancelButtonLabel.text)) { SaveChanges(); InternalEditorBridge.ShowSpriteEditorWindow(this.assetTarget); // We re-imported the asset which destroyed the editor, so we can't keep running the UI here. GUIUtility.ExitGUI(); } } else { InternalEditorBridge.ShowSpriteEditorWindow(this.assetTarget); } }; } void SetupLayerImportContainer(VisualElement root) { var foldOut = new Foldout() { text = styles.layerImportHeaderText.text, tooltip = styles.layerImportHeaderText.tooltip, value = m_EditorFoldOutState.layerImportFoldout }; ImporterEditorUtils.AddSkinUssClass(foldOut.Q()); foldOut.RegisterValueChangedCallback(_ => { m_EditorFoldOutState.layerImportFoldout = foldOut.value; }); root.Add(foldOut); var hiddenLayersField = new PropertyField(m_ImportHiddenLayers, styles.importHiddenLayer.text) { tooltip = styles.importHiddenLayer.tooltip }; hiddenLayersField.Bind(serializedObject); foldOut.Add(hiddenLayersField); var layerModePopup = new PopupField(s_Styles.layerImportOptions, m_LayerImportMode.intValue) { label = s_Styles.layerImportMode.text, tooltip = s_Styles.layerImportMode.tooltip }; layerModePopup.RegisterValueChangedCallback(_ => { m_LayerImportMode.intValue = layerModePopup.index; serializedObject.ApplyModifiedProperties(); }); layerModePopup.AddToClassList(k_BaseFieldAlignedUssClass); foldOut.Add(layerModePopup); var pivotSpaceField = new PropertyField(m_DefaultPivotSpace, styles.defaultPivotSpace.text) { tooltip = styles.defaultPivotSpace.tooltip }; pivotSpaceField.Bind(serializedObject); pivotSpaceField.schedule.Execute(() => { var shouldShow = fileImportMode == FileImportModes.AnimatedSprite; if (pivotSpaceField.visible != shouldShow) { pivotSpaceField.visible = shouldShow; pivotSpaceField.EnableInClassList(k_HiddenElementUssClass, !shouldShow); } }).Every(100); foldOut.Add(pivotSpaceField); var pivotAlignmentPopup = new PopupField(s_Styles.spriteAlignmentOptions, m_DefaultPivotAlignment.intValue) { label = s_Styles.defaultPivotAlignment.text, tooltip = s_Styles.defaultPivotAlignment.tooltip }; pivotAlignmentPopup.RegisterValueChangedCallback(x => { m_DefaultPivotAlignment.intValue = pivotAlignmentPopup.index; serializedObject.ApplyModifiedProperties(); }); pivotAlignmentPopup.AddToClassList(k_BaseFieldAlignedUssClass); pivotAlignmentPopup.schedule.Execute(() => { var shouldShow = fileImportMode == FileImportModes.AnimatedSprite; if (pivotAlignmentPopup.visible != shouldShow) { pivotAlignmentPopup.visible = shouldShow; pivotAlignmentPopup.EnableInClassList(k_HiddenElementUssClass, !shouldShow); } }).Every(100); foldOut.Add(pivotAlignmentPopup); var shouldShow = (SpriteAlignment)pivotAlignmentPopup.index == SpriteAlignment.Custom; var customPivotField = new PropertyField(m_CustomPivotPosition, styles.customPivotPosition.text) { tooltip = styles.customPivotPosition.tooltip, visible = shouldShow }; customPivotField.Bind(serializedObject); customPivotField.EnableInClassList(k_HiddenElementUssClass, !shouldShow); customPivotField.schedule.Execute(x => { var shouldShow = (SpriteAlignment)pivotAlignmentPopup.index == SpriteAlignment.Custom; if (customPivotField.visible != shouldShow) { customPivotField.visible = shouldShow; customPivotField.EnableInClassList(k_HiddenElementUssClass, !shouldShow); } }).Every(100); foldOut.Add(customPivotField); var spritePaddingField = new PropertyField(m_SpritePadding, styles.spritePadding.text) { tooltip = styles.spritePadding.tooltip }; spritePaddingField.Bind(serializedObject); spritePaddingField.schedule.Execute(() => { var shouldShow = fileImportMode == FileImportModes.AnimatedSprite; if (spritePaddingField.visible != shouldShow) { spritePaddingField.visible = shouldShow; spritePaddingField.EnableInClassList(k_HiddenElementUssClass, !shouldShow); } }).Every(100); foldOut.Add(spritePaddingField); var paddingElement = new VisualElement() { name = "PaddingElement" }; paddingElement.AddToClassList(k_PaddingElementUssClass); foldOut.Add(paddingElement); } void SetupGenerateAssetContainer(VisualElement root) { #if ENABLE_URP var isUrpEnabled = true; #else var isUrpEnabled = false; #endif var foldOut = new Foldout() { text = styles.generateAssetsHeaderText.text, tooltip = styles.generateAssetsHeaderText.tooltip, value = m_EditorFoldOutState.generateAssetFoldout }; ImporterEditorUtils.AddSkinUssClass(foldOut.Q()); foldOut.RegisterValueChangedCallback(_ => { m_EditorFoldOutState.generateAssetFoldout = foldOut.value; }); foldOut.schedule.Execute(() => { var shouldShow = fileImportMode == FileImportModes.AnimatedSprite; if (foldOut.visible != shouldShow) { foldOut.visible = shouldShow; foldOut.EnableInClassList(k_HiddenElementUssClass, !shouldShow); } }).Every(100); root.Add(foldOut); var generateModelField = new PropertyField(m_GenerateModelPrefab, styles.generateModelPrefab.text) { tooltip = styles.generateModelPrefab.tooltip }; generateModelField.Bind(serializedObject); foldOut.Add(generateModelField); var isSortingEnabled = m_GenerateModelPrefab.boolValue; var sortingGroupField = new PropertyField(m_AddSortingGroup, styles.addSortingGroup.text) { tooltip = styles.addSortingGroup.tooltip }; sortingGroupField.Bind(serializedObject); sortingGroupField.AddToClassList(k_SubElementUssClass); sortingGroupField.SetEnabled(isSortingEnabled); sortingGroupField.schedule.Execute(() => { isSortingEnabled = m_GenerateModelPrefab.boolValue; if (sortingGroupField.enabledSelf != isSortingEnabled) sortingGroupField.SetEnabled(isSortingEnabled); }).Every(100); foldOut.Add(sortingGroupField); #if UNITY_2023_1_OR_NEWER var areShadowsEnabled = isUrpEnabled && m_GenerateModelPrefab.boolValue; var shadowCasterField = new PropertyField(m_AddShadowCasters, styles.addShadowCasters.text) { tooltip = styles.addShadowCasters.tooltip }; shadowCasterField.Bind(serializedObject); shadowCasterField.AddToClassList(k_SubElementUssClass); shadowCasterField.SetEnabled(areShadowsEnabled); shadowCasterField.schedule.Execute(() => { areShadowsEnabled = isUrpEnabled && m_GenerateModelPrefab.boolValue; if (shadowCasterField.enabledSelf != areShadowsEnabled) shadowCasterField.SetEnabled(areShadowsEnabled); }).Every(100); foldOut.Add(shadowCasterField); #endif var generateClipsField = new PropertyField(m_GenerateAnimationClips, styles.generateAnimationClips.text) { tooltip = styles.generateAnimationClips.tooltip }; generateClipsField.Bind(serializedObject); foldOut.Add(generateClipsField); SetupAnimationAssetsButton(foldOut); var paddingElement = new VisualElement() { name = "PaddingElement" }; paddingElement.AddToClassList(k_PaddingElementUssClass); foldOut.Add(paddingElement); } void SetupAnimationAssetsButton(VisualElement root) { var isEnabled = m_ImporterTargets.Length == 1 && m_DefaultClip != null && m_GenerateAnimationClips.boolValue; var assetsBtn = new Button() { text = styles.exportAnimationAssetsText.text }; assetsBtn.SetEnabled(isEnabled); assetsBtn.schedule.Execute(() => { isEnabled = m_ImporterTargets.Length == 1 && m_DefaultClip != null && m_GenerateAnimationClips.boolValue; if (assetsBtn.enabledSelf != isEnabled) assetsBtn.SetEnabled(isEnabled); }).Every(100); assetsBtn.clicked += () => { var window = EditorWindow.GetWindow(); window.ShowExportPopup(this, m_ImporterTargets); }; root.Add(assetsBtn); var helpBox = new HelpBox(styles.exportAnimationInfoText.text, HelpBoxMessageType.Info); helpBox.visible = m_GenerateAnimationClips.boolValue && !m_PrevGenerateAnimationClips.boolValue; helpBox.EnableInClassList(k_HiddenElementUssClass, !helpBox.visible); helpBox.schedule.Execute(() => { // If the Generate Animation Clips checkbox has been checked, but not yet applied. var isVisible = m_GenerateAnimationClips.boolValue && !m_PrevGenerateAnimationClips.boolValue; if (helpBox.visible != isVisible) { helpBox.visible = isVisible; helpBox.EnableInClassList(k_HiddenElementUssClass, !isVisible); } }).Every(100); root.Add(helpBox); } void SetupCommonTextureSettingsContainer(VisualElement root) { var foldOut = new Foldout() { text = styles.textureHeaderText.text, tooltip = styles.textureHeaderText.tooltip, value = m_EditorFoldOutState.textureFoldout }; ImporterEditorUtils.AddSkinUssClass(foldOut.Q()); foldOut.RegisterValueChangedCallback(_ => { m_EditorFoldOutState.textureFoldout = foldOut.value; }); root.Add(foldOut); var imguiContainer = new IMGUIContainer(() => { serializedObject.Update(); extraDataSerializedObject.Update(); EditorGUI.BeginChangeCheck(); // Wrap mode var isVolume = false; WrapModePopup(m_WrapU, m_WrapV, m_WrapW, isVolume, ref m_ShowPerAxisWrapModes); // Display warning about repeat wrap mode on restricted npot emulation if (m_NPOTScale.intValue == (int)TextureImporterNPOTScale.None && (m_WrapU.intValue == (int)TextureWrapMode.Repeat || m_WrapV.intValue == (int)TextureWrapMode.Repeat) && !InternalEditorBridge.DoesHardwareSupportsFullNPOT()) { var displayWarning = false; foreach (var importer in m_ImporterTargets) { var w = importer.textureActualWidth; var h = importer.textureActualHeight; if (!Mathf.IsPowerOfTwo(w) || !Mathf.IsPowerOfTwo(h)) { displayWarning = true; break; } } if (displayWarning) { EditorGUILayout.HelpBox(styles.warpNotSupportWarning.text, MessageType.Warning, true); } } // Filter mode EditorGUI.showMixedValue = m_FilterMode.hasMultipleDifferentValues; var filter = (FilterMode)m_FilterMode.intValue; if ((int)filter == -1) { if (m_FadeOut.intValue > 0 || m_ConvertToNormalMap.intValue > 0) filter = FilterMode.Trilinear; else filter = FilterMode.Bilinear; } filter = (FilterMode)EditorGUILayout.IntPopup(styles.filterMode, (int)filter, styles.filterModeOptions, m_FilterModeOptions); EditorGUI.showMixedValue = false; if (EditorGUI.EndChangeCheck()) m_FilterMode.intValue = (int)filter; // Aniso var showAniso = (FilterMode)m_FilterMode.intValue != FilterMode.Point && m_EnableMipMap.intValue > 0 && (TextureImporterShape)m_TextureShape.intValue != TextureImporterShape.TextureCube; using (new EditorGUI.DisabledScope(!showAniso)) { EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = m_Aniso.hasMultipleDifferentValues; int aniso = m_Aniso.intValue; if (aniso == -1) aniso = 1; aniso = EditorGUILayout.IntSlider(styles.anisoLevelLabel, aniso, 0, 16); EditorGUI.showMixedValue = false; if (EditorGUI.EndChangeCheck()) m_Aniso.intValue = aniso; if (aniso > 1) { if (QualitySettings.anisotropicFiltering == AnisotropicFiltering.Disable) EditorGUILayout.HelpBox(styles.anisotropicDisableInfo.text, MessageType.Info); else if (QualitySettings.anisotropicFiltering == AnisotropicFiltering.ForceEnable) EditorGUILayout.HelpBox(styles.anisotropicForceEnableInfo.text, MessageType.Info); } } GUILayout.Space(5); serializedObject.ApplyModifiedProperties(); extraDataSerializedObject.ApplyModifiedProperties(); }); foldOut.Add(imguiContainer); } void SetupPlatformSettingsContainer(VisualElement root) { var foldOut = new Foldout() { text = styles.platformSettingsHeaderText.text, tooltip = styles.platformSettingsHeaderText.tooltip, value = m_EditorFoldOutState.platformSettingsFoldout }; ImporterEditorUtils.AddSkinUssClass(foldOut.Q()); foldOut.RegisterValueChangedCallback(_ => { m_EditorFoldOutState.platformSettingsFoldout = foldOut.value; }); root.Add(foldOut); var imguiContainer = new IMGUIContainer(() => { serializedObject.Update(); extraDataSerializedObject.Update(); GUILayout.Space(5); m_TexturePlatformSettingsHelper.ShowPlatformSpecificSettings(); GUILayout.Space(5); serializedObject.ApplyModifiedProperties(); extraDataSerializedObject.ApplyModifiedProperties(); }); foldOut.Add(imguiContainer); } void SetupAdvancedContainer(VisualElement root) { if (m_TextureType.hasMultipleDifferentValues) return; if (!m_AdvancedInspectorGUI.ContainsKey((TextureImporterType) m_TextureType.intValue)) return; var foldOut = new Foldout() { text = styles.advancedHeaderText.text, tooltip = styles.advancedHeaderText.tooltip, value = m_EditorFoldOutState.advancedFoldout }; ImporterEditorUtils.AddSkinUssClass(foldOut.Q()); foldOut.RegisterValueChangedCallback(_ => { m_EditorFoldOutState.advancedFoldout = foldOut.value; }); root.Add(foldOut); var imguiContainer = new IMGUIContainer(() => { serializedObject.Update(); extraDataSerializedObject.Update(); foreach (var action in m_AdvancedInspectorGUI[(TextureImporterType) m_TextureType.intValue]) { action(); } serializedObject.ApplyModifiedProperties(); extraDataSerializedObject.ApplyModifiedProperties(); }); foldOut.Add(imguiContainer); } void InitPreview() { if (m_ImporterTargets.Length > 1) return; var importerPath = m_AssetPaths[0]; var gameObject = AssetDatabase.LoadAssetAtPath(importerPath); if (m_ModelPreviewer != null) { m_ModelPreviewer.Dispose(); m_ModelPreviewer = null; } if (gameObject != null) { var clips = GetAllAnimationClips(importerPath); m_ModelPreviewer = new ModelPreviewer(gameObject, clips); m_DefaultClip = clips != null && clips.Length > 0 ? clips[0] : null; } } void DisposePreview() { if (m_ModelPreviewer == null) return; m_ModelPreviewer.Dispose(); m_ModelPreviewer = null; } static AnimationClip[] GetAllAnimationClips(string assetPath) { var assets = AssetDatabase.LoadAllAssetsAtPath(assetPath); var clips = new List(); for (var i = 0; i < assets.Length; ++i) { if (assets[i] is AnimationClip clip) clips.Add(clip); } return clips.ToArray(); } /// /// Override for AssetImporter.extraDataType /// protected override Type extraDataType => typeof(AsepriteImporterEditorExternalData); /// /// Override for AssetImporter.InitializeExtraDataInstance /// /// Target object /// Target index protected override void InitializeExtraDataInstance(UnityEngine.Object extraTarget, int targetIndex) { var importer = targets[targetIndex] as AsepriteImporter; var extraData = extraTarget as AsepriteImporterEditorExternalData; var platformSettingsNeeded = TexturePlatformSettingsHelper.PlatformSettingsNeeded(this); if (importer != null) { extraData.Init(importer, platformSettingsNeeded); } } /// /// Implementation of virtual method CreateInspectorGUI. /// /// VisualElement container for Inspector visual. public override VisualElement CreateInspectorGUI() { m_RootVisualElement = new VisualElement() { name = "Root" }; var styleSheet = EditorGUIUtility.Load("packages/com.unity.2d.aseprite/Editor/Assets/UI/AsepriteImporterStyleSheet.uss") as StyleSheet; m_RootVisualElement.styleSheets.Add(styleSheet); m_InspectorSettingsView = new VisualElement() { name = "InspectorSettings" }; m_RootVisualElement.Add(m_InspectorSettingsView); ShowInspectorTab(m_ActiveEditorIndex); return m_RootVisualElement; } /// /// Implementation of AssetImporterEditor.OnDisable /// public override void OnDisable() { base.OnDisable(); DisposePreview(); if(m_RootVisualElement != null) m_RootVisualElement.Clear(); } #if UNITY_2023_2_OR_NEWER /// /// Implementation of AssetImporterEditor.DiscardChanges. /// public override void DiscardChanges() { base.DiscardChanges(); m_TexturePlatformSettingsHelper = new TexturePlatformSettingsHelper(this); } #else /// /// Implementation of AssetImporterEditor.ResetValues. /// protected override void ResetValues() { base.ResetValues(); m_TexturePlatformSettingsHelper = new TexturePlatformSettingsHelper(this); } #endif void ShowInspectorTab(int tab) { m_InspectorSettingsView.Clear(); m_InspectorSettingsView.Add(m_InspectorUI[tab]); } #if UNITY_2022_2_OR_NEWER /// /// Implementation of AssetImporterEditor.SaveChanges. /// public override void SaveChanges() { ApplyTexturePlatformSettings(); serializedObject.ApplyModifiedProperties(); extraDataSerializedObject.ApplyModifiedProperties(); base.SaveChanges(); } #else internal void SaveChanges() { ApplyTexturePlatformSettings(); ApplyAndImport(); } #endif // showPerAxisWrapModes is state of whether "Per-Axis" mode should be active in the main dropdown. // It is set automatically if wrap modes in UVW are different, or if user explicitly picks "Per-Axis" option -- when that one is picked, // then it should stay true even if UVW wrap modes will initially be the same. // // Note: W wrapping mode is only shown when isVolumeTexture is true. static void WrapModePopup(SerializedProperty wrapU, SerializedProperty wrapV, SerializedProperty wrapW, bool isVolumeTexture, ref bool showPerAxisWrapModes) { // In texture importer settings, serialized properties for things like wrap modes can contain -1; // that seems to indicate "use defaults, user has not changed them to anything" but not totally sure. // Show them as Repeat wrap modes in the popups. var wu = (TextureWrapMode)Mathf.Max(wrapU.intValue, 0); var wv = (TextureWrapMode)Mathf.Max(wrapV.intValue, 0); var ww = (TextureWrapMode)Mathf.Max(wrapW.intValue, 0); // automatically go into per-axis mode if values are already different if (wu != wv) showPerAxisWrapModes = true; if (isVolumeTexture) { if (wu != ww || wv != ww) showPerAxisWrapModes = true; } // It's not possible to determine whether any single texture in the whole selection is using per-axis wrap modes // just from SerializedProperty values. They can only tell if "some values in whole selection are different" (e.g. // wrap value on U axis is not the same among all textures), and can return value of "some" object in the selection // (typically based on object loading order). So in order for more intuitive behavior with multi-selection, // we go over the actual objects when there's >1 object selected and some wrap modes are different. if (!showPerAxisWrapModes) { if (wrapU.hasMultipleDifferentValues || wrapV.hasMultipleDifferentValues || (isVolumeTexture && wrapW.hasMultipleDifferentValues)) { if (IsAnyTextureObjectUsingPerAxisWrapMode(wrapU.serializedObject.targetObjects, isVolumeTexture)) { showPerAxisWrapModes = true; } } } int value = showPerAxisWrapModes ? -1 : (int)wu; // main wrap mode popup EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = !showPerAxisWrapModes && (wrapU.hasMultipleDifferentValues || wrapV.hasMultipleDifferentValues || (isVolumeTexture && wrapW.hasMultipleDifferentValues)); value = EditorGUILayout.IntPopup(styles.wrapModeLabel, value, styles.wrapModeContents, styles.wrapModeValues); if (EditorGUI.EndChangeCheck() && value != -1) { // assign the same wrap mode to all axes, and hide per-axis popups wrapU.intValue = value; wrapV.intValue = value; wrapW.intValue = value; showPerAxisWrapModes = false; } // show per-axis popups if needed if (value == -1) { showPerAxisWrapModes = true; EditorGUI.indentLevel++; WrapModeAxisPopup(styles.wrapU, wrapU); WrapModeAxisPopup(styles.wrapV, wrapV); if (isVolumeTexture) { WrapModeAxisPopup(styles.wrapW, wrapW); } EditorGUI.indentLevel--; } EditorGUI.showMixedValue = false; } static void WrapModeAxisPopup(GUIContent label, SerializedProperty wrapProperty) { // In texture importer settings, serialized properties for wrap modes can contain -1, which means "use default". var wrap = (TextureWrapMode)Mathf.Max(wrapProperty.intValue, 0); Rect rect = EditorGUILayout.GetControlRect(); EditorGUI.BeginChangeCheck(); EditorGUI.BeginProperty(rect, label, wrapProperty); wrap = (TextureWrapMode)EditorGUI.EnumPopup(rect, label, wrap); EditorGUI.EndProperty(); if (EditorGUI.EndChangeCheck()) { wrapProperty.intValue = (int)wrap; } } static bool IsAnyTextureObjectUsingPerAxisWrapMode(UnityEngine.Object[] objects, bool isVolumeTexture) { foreach (var o in objects) { int u = 0, v = 0, w = 0; // the objects can be Textures themselves, or texture-related importers if (o is Texture) { var ti = (Texture)o; u = (int)ti.wrapModeU; v = (int)ti.wrapModeV; w = (int)ti.wrapModeW; } if (o is TextureImporter) { var ti = (TextureImporter)o; u = (int)ti.wrapModeU; v = (int)ti.wrapModeV; w = (int)ti.wrapModeW; } if (o is IHVImageFormatImporter) { var ti = (IHVImageFormatImporter)o; u = (int)ti.wrapModeU; v = (int)ti.wrapModeV; w = (int)ti.wrapModeW; } u = Mathf.Max(0, u); v = Mathf.Max(0, v); w = Mathf.Max(0, w); if (u != v) { return true; } if (isVolumeTexture) { if (u != w || v != w) { return true; } } } return false; } void ColorSpaceGUI() { ToggleFromInt(m_sRGBTexture, styles.sRGBTexture); } void AlphaHandlingGUI() { EditorGUI.showMixedValue = m_AlphaSource.hasMultipleDifferentValues; EditorGUI.BeginChangeCheck(); int newAlphaUsage = EditorGUILayout.IntPopup(styles.alphaSource, m_AlphaSource.intValue, styles.alphaSourceOptions, styles.alphaSourceValues); EditorGUI.showMixedValue = false; if (EditorGUI.EndChangeCheck()) { m_AlphaSource.intValue = newAlphaUsage; } bool showAlphaIsTransparency = (TextureImporterAlphaSource)m_AlphaSource.intValue != TextureImporterAlphaSource.None; using (new EditorGUI.DisabledScope(!showAlphaIsTransparency)) { ToggleFromInt(m_AlphaIsTransparency, styles.alphaIsTransparency); } } void POTScaleGUI() { using (new EditorGUI.DisabledScope(m_IsPowerOfTwo || m_TextureType.intValue == (int)TextureImporterType.Sprite)) { EnumPopup(m_NPOTScale, typeof(TextureImporterNPOTScale), styles.npot); } } void ReadableGUI() { ToggleFromInt(m_IsReadable, styles.readWrite); } void MipMapGUI() { ToggleFromInt(m_EnableMipMap, styles.generateMipMaps); if (m_EnableMipMap.boolValue && !m_EnableMipMap.hasMultipleDifferentValues) { EditorGUI.indentLevel++; ToggleFromInt(m_BorderMipMap, styles.borderMipMaps); #if ENABLE_TEXTURE_STREAMING ToggleFromInt(m_StreamingMipmaps, styles.streamingMipMaps); if (m_StreamingMipmaps.boolValue && !m_StreamingMipmaps.hasMultipleDifferentValues) { EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_StreamingMipmapsPriority, styles.streamingMipmapsPriority); if (EditorGUI.EndChangeCheck()) { m_StreamingMipmapsPriority.intValue = Mathf.Clamp(m_StreamingMipmapsPriority.intValue, -128, 127); } EditorGUI.indentLevel--; } #endif m_MipMapMode.intValue = EditorGUILayout.Popup(styles.mipMapFilter, m_MipMapMode.intValue, styles.mipMapFilterOptions); ToggleFromInt(m_MipMapsPreserveCoverage, styles.mipMapsPreserveCoverage); if (m_MipMapsPreserveCoverage.intValue != 0 && !m_MipMapsPreserveCoverage.hasMultipleDifferentValues) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(m_AlphaTestReferenceValue, styles.alphaTestReferenceValue); EditorGUI.indentLevel--; } // Mipmap fadeout ToggleFromInt(m_FadeOut, styles.mipmapFadeOutToggle); if (m_FadeOut.intValue > 0) { EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); float min = m_MipMapFadeDistanceStart.intValue; float max = m_MipMapFadeDistanceEnd.intValue; EditorGUILayout.MinMaxSlider(styles.mipmapFadeOut, ref min, ref max, 0, 10); if (EditorGUI.EndChangeCheck()) { m_MipMapFadeDistanceStart.intValue = Mathf.RoundToInt(min); m_MipMapFadeDistanceEnd.intValue = Mathf.RoundToInt(max); } EditorGUI.indentLevel--; } EditorGUI.indentLevel--; } } /// /// Implementation of AssetImporterEditor.Apply /// protected override void Apply() { m_TexturePlatformSettingsHelper.Apply(); ApplyTexturePlatformSettings(); InternalEditorBridge.ApplySpriteEditorWindow(); base.Apply(); if (m_ModelPreviewer != null) { m_ModelPreviewer.Dispose(); m_ModelPreviewer = null; } } void ApplyTexturePlatformSettings() { for(var i = 0; i < targets.Length && i < extraDataTargets.Length; ++i) { var asepriteImporter = (AsepriteImporter)targets[i]; var externalData = (AsepriteImporterEditorExternalData)extraDataTargets[i]; foreach (var ps in externalData.platformSettings) { asepriteImporter.SetImporterPlatformSettings(ps); asepriteImporter.Apply(); } } } /// /// Override of AssetImporterEditor.HasModified. /// /// Returns True if has modified data. False otherwise. public override bool HasModified() { if (base.HasModified()) return true; return m_TexturePlatformSettingsHelper.HasModified(); } /// /// Implementation of ITexturePlatformSettingsDataProvider.GetTargetCount. /// /// Returns the number of selected targets. int ITexturePlatformSettingsDataProvider.GetTargetCount() => targets.Length; /// /// ITexturePlatformSettingsDataProvider.GetPlatformTextureSettings. /// /// Selected target index. /// Name of the platform. /// TextureImporterPlatformSettings for the given platform name and selected target index. TextureImporterPlatformSettings ITexturePlatformSettingsDataProvider.GetPlatformTextureSettings(int i, string name) { var externalData = extraDataSerializedObject.targetObjects[i] as AsepriteImporterEditorExternalData; if (externalData != null) { foreach (var ps in externalData.platformSettings) { if (ps.name == name) return ps; } } return new TextureImporterPlatformSettings() { name = name, overridden = false }; } /// /// Implementation of ITexturePlatformSettingsDataProvider.ShowPresetSettings. /// /// True if valid asset is selected, false otherwise. bool ITexturePlatformSettingsDataProvider.ShowPresetSettings() { return assetTarget == null; } /// /// Implementation of ITexturePlatformSettingsDataProvider.DoesSourceTextureHaveAlpha. /// /// Index to selected target. /// Always returns true since importer deals with source file that has alpha. bool ITexturePlatformSettingsDataProvider.DoesSourceTextureHaveAlpha(int i) { return true; } /// /// Implementation of ITexturePlatformSettingsDataProvider.IsSourceTextureHDR. /// /// Index to selected target. /// Always returns false since importer does not handle HDR textures. bool ITexturePlatformSettingsDataProvider.IsSourceTextureHDR(int i) { return false; } /// /// Implementation of ITexturePlatformSettingsDataProvider.SetPlatformTextureSettings. /// /// Selected target index. /// TextureImporterPlatformSettings to apply to target. void ITexturePlatformSettingsDataProvider.SetPlatformTextureSettings(int i, TextureImporterPlatformSettings platformSettings) { var importer = (AsepriteImporter)targets[i]; var sp = new SerializedObject(importer); sp.FindProperty("m_PlatformSettingsDirtyTick").longValue = System.DateTime.Now.Ticks; sp.ApplyModifiedProperties(); } /// /// Implementation of ITexturePlatformSettingsDataProvider.GetImporterSettings. /// /// Selected target index. /// TextureImporterPlatformSettings reference for data retrieval. void ITexturePlatformSettingsDataProvider.GetImporterSettings(int i, TextureImporterSettings settings) { ((AsepriteImporter)targets[i]).ReadTextureSettings(settings); // Get settings that have been changed in the inspector GetSerializedPropertySettings(settings); } /// /// Get the name property of TextureImporterPlatformSettings from a SerializedProperty. /// /// The SerializedProperty to retrive data. /// The name value in string. public string GetBuildTargetName(SerializedProperty sp) { return sp.FindPropertyRelative("m_Name").stringValue; } TextureImporterSettings GetSerializedPropertySettings(TextureImporterSettings settings) { if (!m_AlphaSource.hasMultipleDifferentValues) settings.alphaSource = (TextureImporterAlphaSource)m_AlphaSource.intValue; if (!m_ConvertToNormalMap.hasMultipleDifferentValues) settings.convertToNormalMap = m_ConvertToNormalMap.intValue > 0; if (!m_BorderMipMap.hasMultipleDifferentValues) settings.borderMipmap = m_BorderMipMap.intValue > 0; #if ENABLE_TEXTURE_STREAMING if (!m_StreamingMipmaps.hasMultipleDifferentValues) settings.streamingMipmaps = m_StreamingMipmaps.intValue > 0; if (!m_StreamingMipmapsPriority.hasMultipleDifferentValues) settings.streamingMipmapsPriority = m_StreamingMipmapsPriority.intValue; #endif if (!m_MipMapsPreserveCoverage.hasMultipleDifferentValues) settings.mipMapsPreserveCoverage = m_MipMapsPreserveCoverage.intValue > 0; if (!m_AlphaTestReferenceValue.hasMultipleDifferentValues) settings.alphaTestReferenceValue = m_AlphaTestReferenceValue.floatValue; if (!m_NPOTScale.hasMultipleDifferentValues) settings.npotScale = (TextureImporterNPOTScale)m_NPOTScale.intValue; if (!m_IsReadable.hasMultipleDifferentValues) settings.readable = m_IsReadable.intValue > 0; if (!m_sRGBTexture.hasMultipleDifferentValues) settings.sRGBTexture = m_sRGBTexture.intValue > 0; if (!m_EnableMipMap.hasMultipleDifferentValues) settings.mipmapEnabled = m_EnableMipMap.intValue > 0; if (!m_MipMapMode.hasMultipleDifferentValues) settings.mipmapFilter = (TextureImporterMipFilter)m_MipMapMode.intValue; if (!m_FadeOut.hasMultipleDifferentValues) settings.fadeOut = m_FadeOut.intValue > 0; if (!m_MipMapFadeDistanceStart.hasMultipleDifferentValues) settings.mipmapFadeDistanceStart = m_MipMapFadeDistanceStart.intValue; if (!m_MipMapFadeDistanceEnd.hasMultipleDifferentValues) settings.mipmapFadeDistanceEnd = m_MipMapFadeDistanceEnd.intValue; if (!m_SpriteMode.hasMultipleDifferentValues) settings.spriteMode = m_SpriteMode.intValue; if (!m_SpritePixelsToUnits.hasMultipleDifferentValues) settings.spritePixelsPerUnit = m_SpritePixelsToUnits.floatValue; if (!m_SpriteExtrude.hasMultipleDifferentValues) settings.spriteExtrude = (uint)m_SpriteExtrude.intValue; if (!m_SpriteMeshType.hasMultipleDifferentValues) settings.spriteMeshType = (SpriteMeshType)m_SpriteMeshType.intValue; if (!m_Alignment.hasMultipleDifferentValues) settings.spriteAlignment = m_Alignment.intValue; if (!m_SpritePivot.hasMultipleDifferentValues) settings.spritePivot = m_SpritePivot.vector2Value; if (!m_WrapU.hasMultipleDifferentValues) settings.wrapModeU = (TextureWrapMode)m_WrapU.intValue; if (!m_WrapV.hasMultipleDifferentValues) settings.wrapModeU = (TextureWrapMode)m_WrapV.intValue; if (!m_WrapW.hasMultipleDifferentValues) settings.wrapModeU = (TextureWrapMode)m_WrapW.intValue; if (!m_FilterMode.hasMultipleDifferentValues) settings.filterMode = (FilterMode)m_FilterMode.intValue; if (!m_Aniso.hasMultipleDifferentValues) settings.aniso = m_Aniso.intValue; if (!m_AlphaIsTransparency.hasMultipleDifferentValues) settings.alphaIsTransparency = m_AlphaIsTransparency.intValue > 0; if (!m_TextureType.hasMultipleDifferentValues) settings.textureType = (TextureImporterType)m_TextureType.intValue; if (!m_TextureShape.hasMultipleDifferentValues) settings.textureShape = (TextureImporterShape)m_TextureShape.intValue; return settings; } static void ToggleFromInt(SerializedProperty property, GUIContent label) { EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = property.hasMultipleDifferentValues; var value = EditorGUILayout.Toggle(label, property.intValue > 0) ? 1 : 0; EditorGUI.showMixedValue = false; if (EditorGUI.EndChangeCheck()) property.intValue = value; } static void EnumPopup(SerializedProperty property, System.Type type, GUIContent label) { EditorGUILayout.IntPopup(label.text, property.intValue, System.Enum.GetNames(type), System.Enum.GetValues(type) as int[]); } /// /// Override from AssetImporterEditor to show custom preview. /// /// Preview Rect. public override void DrawPreview(Rect r) { if (HasRenamedAssets()) ReloadPreviewData(); if (m_ModelPreviewer == null) InitPreview(); if (m_ModelPreviewer != null) m_ModelPreviewer.DrawPreview(r, "PreBackgroundSolid"); else base.DrawPreview(r); } void ReloadPreviewData() { DisposePreview(); CacheImporterData(); InitPreview(); Apply(); } bool HasRenamedAssets() { for (var i = 0; i < m_AssetPaths.Length; ++i) { if (m_AssetPaths[i] != (targets[i] as AsepriteImporter).assetPath) return true; } return false; } class Styles { readonly GUIContent textureShape2D = new ("2D, Texture is 2D."); readonly GUIContent textureShapeCube = new ("Cube", "Texture is a Cubemap."); public readonly Dictionary textureShapeOptionsDictionnary = new (); public readonly Dictionary textureShapeValuesDictionnary = new (); public readonly GUIContent filterMode = new ("Filter Mode"); public readonly GUIContent[] filterModeOptions = { new ("Point (no filter)"), new ("Bilinear"), new ("Trilinear") }; public readonly GUIContent mipmapFadeOutToggle = new ("Fadeout Mip Maps"); public readonly GUIContent mipmapFadeOut = new ("Fade Range"); public readonly GUIContent readWrite = new ("Read/Write Enabled", "Enable to be able to access the raw pixel data from code."); public readonly GUIContent alphaSource = new ("Alpha Source", "How is the alpha generated for the imported texture."); public readonly GUIContent[] alphaSourceOptions = { new ("None", "No Alpha will be used."), new ("Input Texture Alpha", "Use Alpha from the input texture if one is provided."), new ("From Gray Scale", "Generate Alpha from image gray scale."), }; public readonly int[] alphaSourceValues = { (int)TextureImporterAlphaSource.None, (int)TextureImporterAlphaSource.FromInput, (int)TextureImporterAlphaSource.FromGrayScale, }; public readonly GUIContent generateMipMaps = new ("Generate Mip Maps"); public readonly GUIContent sRGBTexture = new ("sRGB (Color Texture)", "Texture content is stored in gamma space. Non-HDR color textures should enable this flag (except if used for IMGUI)."); public readonly GUIContent borderMipMaps = new ("Border Mip Maps"); #if ENABLE_TEXTURE_STREAMING public readonly GUIContent streamingMipMaps = EditorGUIUtility.TrTextContent("Mip Streaming", "Only load larger mipmaps as needed to render the current game cameras. Requires texture streaming to be enabled in quality settings."); public readonly GUIContent streamingMipmapsPriority = EditorGUIUtility.TrTextContent("Priority", "Mipmap streaming priority when there's contention for resources. Positive numbers represent higher priority. Valid range is -128 to 127."); #endif public readonly GUIContent mipMapsPreserveCoverage = new ("Mip Maps Preserve Coverage", "The alpha channel of generated Mip Maps will preserve coverage during the alpha test."); public readonly GUIContent alphaTestReferenceValue = new ("Alpha Cutoff Value", "The reference value used during the alpha test. Controls Mip Map coverage."); public readonly GUIContent mipMapFilter = new ("Mip Map Filtering"); public readonly GUIContent[] mipMapFilterOptions = { new ("Box"), new ("Kaiser"), }; public readonly GUIContent npot = new ("Non Power of 2", "How non-power-of-two textures are scaled on import."); public readonly List spriteMeshTypeOptions = new() { L10n.Tr("Full Rect"), L10n.Tr("Tight"), }; public readonly GUIContent fileImportMode = new ("Import Mode", "How the file should be imported."); public readonly GUIContent spritePixelsPerUnit = new ("Pixels Per Unit", "How many pixels in the sprite correspond to one unit in the world."); public readonly GUIContent spriteMeshType = new ("Mesh Type", "Type of sprite mesh to generate."); public readonly GUIContent warpNotSupportWarning = new ("Graphics device doesn't support Repeat wrap mode on NPOT textures. Falling back to Clamp."); public readonly GUIContent anisoLevelLabel = new ("Aniso Level"); public readonly GUIContent anisotropicDisableInfo = new ("Anisotropic filtering is disabled for all textures in Quality Settings."); public readonly GUIContent anisotropicForceEnableInfo = new ("Anisotropic filtering is enabled for all textures in Quality Settings."); public readonly GUIContent unappliedSettingsDialogTitle = new ("Unapplied import settings"); public readonly GUIContent unappliedSettingsDialogContent = new ("Unapplied import settings for \'{0}\'.\nApply and continue to sprite editor or cancel."); public readonly GUIContent applyButtonLabel = new ("Apply"); public readonly GUIContent cancelButtonLabel = new ("Cancel"); public readonly GUIContent spriteEditorButtonLabel = new ("Open Sprite Editor"); public readonly GUIContent alphaIsTransparency = new ("Alpha Is Transparency", "If the provided alpha channel is transparency, enable this to pre-filter the color to avoid texture filtering artifacts. This is not supported for HDR textures."); public readonly GUIContent advancedHeaderText = new ("Advanced", "Show advanced settings."); public readonly GUIContent platformSettingsHeaderText = new GUIContent("Platform Settings"); public readonly GUIContent[] platformSettingsSelection; public readonly GUIContent wrapModeLabel = new ("Wrap Mode"); public readonly GUIContent wrapU = new ("U axis"); public readonly GUIContent wrapV = new ("V axis"); public readonly GUIContent wrapW = new ("W axis"); public readonly GUIContent[] wrapModeContents = { new ("Repeat"), new ("Clamp"), new ("Mirror"), new ("Mirror Once"), new ("Per-axis") }; public readonly int[] wrapModeValues = { (int)TextureWrapMode.Repeat, (int)TextureWrapMode.Clamp, (int)TextureWrapMode.Mirror, (int)TextureWrapMode.MirrorOnce, -1 }; public readonly GUIContent importHiddenLayer = EditorGUIUtility.TrTextContent("Include Hidden Layers", "Settings to determine when hidden layers should be imported."); public readonly GUIContent defaultPivotSpace = EditorGUIUtility.TrTextContent("Pivot Space", "Select which space the pivot should be calculated in."); public readonly GUIContent defaultPivotAlignment = EditorGUIUtility.TrTextContent("Pivot Alignment", "Select where the pivot should be located based on the Pivot Space."); public readonly GUIContent customPivotPosition = EditorGUIUtility.TrTextContent("Custom Pivot Position", "Input the normalized position of the Sprite pivots. The position will be calculated based on the Pivot Space."); public readonly GUIContent spritePadding = EditorGUIUtility.TrTextContent("Sprite Padding", "Internal padding within each SpriteRect generated from the Aseprite file."); public readonly List spriteAlignmentOptions = new() { L10n.Tr("Center"), L10n.Tr("Top Left"), L10n.Tr("Top"), L10n.Tr("Top Right"), L10n.Tr("Left"), L10n.Tr("Right"), L10n.Tr("Bottom Left"), L10n.Tr("Bottom"), L10n.Tr("Bottom Right"), L10n.Tr("Custom"), }; public readonly GUIContent layerImportMode = EditorGUIUtility.TrTextContent("Import Mode", "Choose between generating one Sprite per layer, or merge all layers in a frame into a single Sprite."); public readonly List layerImportOptions = new() { L10n.Tr("Individual Layers"), L10n.Tr("Merge Frame") }; public readonly GUIContent generateModelPrefab = EditorGUIUtility.TrTextContent("Model Prefab", "Generate a Model Prefab laid out the same way as inside Aseprite."); public readonly GUIContent addSortingGroup = EditorGUIUtility.TrTextContent("Sorting Group", "Add a Sorting Group component to the root of the generated model prefab if it has more than one Sprite Renderer."); public readonly GUIContent addShadowCasters = EditorGUIUtility.TrTextContent("Shadow Casters", "Add Shadow Casters on all GameObjects with SpriteRenderer. Note: The Universal Rendering Pipeline package has to be installed."); public readonly GUIContent generateAnimationClips = EditorGUIUtility.TrTextContent("Animation Clips", "Generate Animation Clips based on the frame and tag data from the Aseprite file."); public readonly GUIContent generalHeaderText = EditorGUIUtility.TrTextContent("General", "General settings."); public readonly GUIContent layerImportHeaderText = EditorGUIUtility.TrTextContent("Layer Import","Layer Import settings."); public readonly GUIContent generateAssetsHeaderText = EditorGUIUtility.TrTextContent("Generate Assets","Generated assets settings."); public readonly GUIContent textureHeaderText = EditorGUIUtility.TrTextContent("Texture","Texture settings."); public readonly GUIContent exportAnimationAssetsText = EditorGUIUtility.TrTextContent("Export Animation Assets"); public readonly GUIContent exportAnimationInfoText = EditorGUIUtility.TrTextContent("To enable the Export Animation Assets button, make sure to first Apply the changes."); public Styles() { // This is far from ideal, but it's better than having tons of logic in the GUI code itself. // The combination should not grow too much anyway since only Texture3D will be added later. GUIContent[] s2D_Options = { textureShape2D }; GUIContent[] sCube_Options = { textureShapeCube }; GUIContent[] s2D_Cube_Options = { textureShape2D, textureShapeCube }; textureShapeOptionsDictionnary.Add(TextureImporterShape.Texture2D, s2D_Options); textureShapeOptionsDictionnary.Add(TextureImporterShape.TextureCube, sCube_Options); textureShapeOptionsDictionnary.Add(TextureImporterShape.Texture2D | TextureImporterShape.TextureCube, s2D_Cube_Options); int[] s2D_Values = { (int)TextureImporterShape.Texture2D }; int[] sCube_Values = { (int)TextureImporterShape.TextureCube }; int[] s2D_Cube_Values = { (int)TextureImporterShape.Texture2D, (int)TextureImporterShape.TextureCube }; textureShapeValuesDictionnary.Add(TextureImporterShape.Texture2D, s2D_Values); textureShapeValuesDictionnary.Add(TextureImporterShape.TextureCube, sCube_Values); textureShapeValuesDictionnary.Add(TextureImporterShape.Texture2D | TextureImporterShape.TextureCube, s2D_Cube_Values); platformSettingsSelection = new GUIContent[TexturePlatformSettingsModal.validBuildPlatform.Length]; for (var i = 0; i < TexturePlatformSettingsModal.validBuildPlatform.Length; ++i) { platformSettingsSelection[i] = new GUIContent(TexturePlatformSettingsModal.validBuildPlatform[i].buildTargetName); } } } static Styles s_Styles; static Styles styles { get { if (s_Styles == null) s_Styles = new Styles(); return s_Styles; } } class AsepriteImporterEditorFoldOutState { readonly SavedBool m_GeneralFoldout; readonly SavedBool m_LayerImportFoldout; readonly SavedBool m_GenerateAssetFoldout; readonly SavedBool m_AdvancedFoldout; readonly SavedBool m_TextureFoldout; readonly SavedBool m_PlatformSettingsFoldout; public bool generalFoldout { get => m_GeneralFoldout.value; set => m_GeneralFoldout.value = value; } public bool layerImportFoldout { get => m_LayerImportFoldout.value; set => m_LayerImportFoldout.value = value; } public bool generateAssetFoldout { get => m_GenerateAssetFoldout.value; set => m_GenerateAssetFoldout.value = value; } public bool advancedFoldout { get => m_AdvancedFoldout.value; set => m_AdvancedFoldout.value = value; } public bool textureFoldout { get => m_TextureFoldout.value; set => m_TextureFoldout.value = value; } public bool platformSettingsFoldout { get => m_PlatformSettingsFoldout.value; set => m_PlatformSettingsFoldout.value = value; } public AsepriteImporterEditorFoldOutState() { m_GeneralFoldout = new SavedBool("AsepriteImporterEditor.m_GeneralFoldout", true); m_LayerImportFoldout = new SavedBool("AsepriteImporterEditor.m_LayerImportFoldout", true); m_GenerateAssetFoldout = new SavedBool("AsepriteImporterEditor.m_ExportAssetFoldout", true); m_AdvancedFoldout = new SavedBool("AsepriteImporterEditor.m_AdvancedFoldout", false); m_TextureFoldout = new SavedBool("AsepriteImporterEditor.m_TextureFoldout", false); m_PlatformSettingsFoldout = new SavedBool("AsepriteImporterEditor.m_PlatformSettingsFoldout", false); } class SavedBool { readonly string m_Name; bool m_Value; bool m_Loaded; public SavedBool(string name, bool value) { m_Name = name; m_Loaded = false; m_Value = value; } void Load() { if (m_Loaded) return; m_Loaded = true; m_Value = EditorPrefs.GetBool(m_Name, m_Value); } public bool value { get { Load(); return m_Value; } set { Load(); if (m_Value == value) return; m_Value = value; EditorPrefs.SetBool(m_Name, value); } } public static implicit operator bool(SavedBool s) { return s.value; } } } } }