From a634d3976564f584e5a4350034b1dd46c7d1810c Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Wed, 13 Apr 2016 18:56:32 +0200 Subject: [PATCH] Improved material overrides (#536) * per-material material overrides, separate MonoBehaviour for setting overrides from inspector * clean-up and fix SkeletonRendererMaterialOverride * SkeletonRendererCustomMaterials: initialize SkeletonRenderer to ensure skeletonRenderer.skeleton != null * rename SkeletonRendererCustomMaterials folder for consistency --- .../spine-unity/Modules/CustomMaterials.meta | 7 + .../Modules/CustomMaterials/Editor.meta | 7 + ...keletonRendererCustomMaterialsInspector.cs | 27 +++ ...onRendererCustomMaterialsInspector.cs.meta | 10 ++ .../SkeletonRendererCustomMaterials.cs | 161 ++++++++++++++++++ .../SkeletonRendererCustomMaterials.cs.meta | 10 ++ 6 files changed, 222 insertions(+) create mode 100644 spine-unity/Assets/spine-unity/Modules/CustomMaterials.meta create mode 100644 spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor.meta create mode 100644 spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs create mode 100644 spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs.meta create mode 100644 spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs create mode 100644 spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs.meta diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials.meta b/spine-unity/Assets/spine-unity/Modules/CustomMaterials.meta new file mode 100644 index 000000000..16b542c7f --- /dev/null +++ b/spine-unity/Assets/spine-unity/Modules/CustomMaterials.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a7236dbdc6a4e5a4989483dac97aee0b +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor.meta b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor.meta new file mode 100644 index 000000000..6b6e2f6d3 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 99abd7478ddde384cbf86f2ecd396900 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs new file mode 100644 index 000000000..1a2379021 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs @@ -0,0 +1,27 @@ +/***************************************************************************** + * SkeletonRendererCustomMaterialsInspector created by Lost Polygon + * Full irrevocable rights and permissions granted to Esoteric Software +*****************************************************************************/ + +using UnityEditor; + +namespace Spine.Unity.Editor { + [CustomEditor(typeof(SkeletonRendererCustomMaterials))] + public class SkeletonRendererCustomMaterialsInspector : UnityEditor.Editor { + public override void OnInspectorGUI() { + SkeletonRendererCustomMaterials obj = (SkeletonRendererCustomMaterials) target; + + // Just draw the default inspector and reapply overrides on any change + EditorGUI.BeginChangeCheck(); + { + DrawDefaultInspector(); + } + if (EditorGUI.EndChangeCheck()) { + obj.RemoveCustomMaterialOverrides(); + obj.RemoveCustomSlotMaterials(); + obj.SetCustomMaterialOverrides(); + obj.SetCustomSlotMaterials(); + } + } + } +} \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs.meta b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs.meta new file mode 100644 index 000000000..1e37a56ac --- /dev/null +++ b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/Editor/SkeletonRendererCustomMaterialsInspector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e70f7f2a241d6d34aafd6a4a52a368d0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs new file mode 100644 index 000000000..6eece8f92 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs @@ -0,0 +1,161 @@ +/***************************************************************************** + * SkeletonRendererCustomMaterials created by Lost Polygon + * Full irrevocable rights and permissions granted to Esoteric Software +*****************************************************************************/ + +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Spine.Unity { + [ExecuteInEditMode] + public class SkeletonRendererCustomMaterials : MonoBehaviour { + public SkeletonRenderer skeletonRenderer; + + [SerializeField] + private List customSlotMaterials = new List(); + + [SerializeField] + private List customMaterialOverrides = new List(); + + public List CustomSlotMaterials { + get { return customSlotMaterials; } + } + + public List CustomMaterialOverrides { + get { return customMaterialOverrides; } + } + + public void SetCustomSlotMaterials() { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + for (int i = 0; i < customSlotMaterials.Count; i++) { + SlotMaterialOverride slotMaterialOverride = customSlotMaterials[i]; + if (slotMaterialOverride.overrideDisabled || string.IsNullOrEmpty(slotMaterialOverride.slotName)) + continue; + + Slot slotObject = skeletonRenderer.skeleton.FindSlot(slotMaterialOverride.slotName); + skeletonRenderer.CustomSlotMaterials[slotObject] = slotMaterialOverride.material; + } + } + + public void RemoveCustomSlotMaterials() { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + for (int i = 0; i < customSlotMaterials.Count; i++) { + SlotMaterialOverride slotMaterialOverride = customSlotMaterials[i]; + if (string.IsNullOrEmpty(slotMaterialOverride.slotName)) + continue; + + Slot slotObject = skeletonRenderer.skeleton.FindSlot(slotMaterialOverride.slotName); + + Material currentMaterial; + if (!skeletonRenderer.CustomSlotMaterials.TryGetValue(slotObject, out currentMaterial)) + continue; + + // Do not revert the material if it was changed by something else + if (currentMaterial != slotMaterialOverride.material) + continue; + + skeletonRenderer.CustomSlotMaterials.Remove(slotObject); + } + } + + public void SetCustomMaterialOverrides() { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + for (int i = 0; i < customMaterialOverrides.Count; i++) { + AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i]; + if (atlasMaterialOverride.overrideDisabled) + continue; + + skeletonRenderer.CustomMaterialOverride[atlasMaterialOverride.originalMaterial] = atlasMaterialOverride.replacementMaterial; + } + } + + public void RemoveCustomMaterialOverrides() { + if (skeletonRenderer == null) { + Debug.LogError("skeletonRenderer == null"); + return; + } + + for (int i = 0; i < customMaterialOverrides.Count; i++) { + AtlasMaterialOverride atlasMaterialOverride = customMaterialOverrides[i]; + Material currentMaterial; + if (!skeletonRenderer.CustomMaterialOverride.TryGetValue(atlasMaterialOverride.originalMaterial, out currentMaterial)) + continue; + + // Do not revert the material if it was changed by something else + if (currentMaterial != atlasMaterialOverride.replacementMaterial) + continue; + + skeletonRenderer.CustomMaterialOverride.Remove(atlasMaterialOverride.originalMaterial); + } + } + + private void OnEnable() { + if (skeletonRenderer == null) { + skeletonRenderer = GetComponent(); + } + + skeletonRenderer.Initialize(false); + SetCustomMaterialOverrides(); + SetCustomSlotMaterials(); + } + + private void OnDisable() { + RemoveCustomMaterialOverrides(); + RemoveCustomSlotMaterials(); + } + + private void Reset() { + skeletonRenderer = GetComponent(); + + // Populate atlas list + if (skeletonRenderer != null && skeletonRenderer.skeletonDataAsset != null) { + AtlasAsset[] atlasAssets = skeletonRenderer.skeletonDataAsset.atlasAssets; + + List initialAtlasMaterialOverrides = new List(); + foreach (AtlasAsset atlasAsset in atlasAssets) { + foreach (Material atlasMaterial in atlasAsset.materials) { + AtlasMaterialOverride atlasMaterialOverride = new AtlasMaterialOverride(); + atlasMaterialOverride.overrideDisabled = true; + atlasMaterialOverride.originalMaterial = atlasMaterial; + + initialAtlasMaterialOverrides.Add(atlasMaterialOverride); + } + } + + customMaterialOverrides = initialAtlasMaterialOverrides; + } + } + + [Serializable] + public class MaterialOverride { + public bool overrideDisabled; + } + + [Serializable] + public class SlotMaterialOverride : MaterialOverride { + [SpineSlot] + public string slotName; + + public Material material; + } + + [Serializable] + public class AtlasMaterialOverride : MaterialOverride { + public Material originalMaterial; + public Material replacementMaterial; + } + } +} \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs.meta b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs.meta new file mode 100644 index 000000000..eb50faf21 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Modules/CustomMaterials/SkeletonRendererCustomMaterials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 26947ae098a8447408d80c0c86e35b48 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: