// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif namespace Microsoft.MixedReality.GraphicsTools { /// /// Utility class to help restore materials which are assets (normally shared materials) to their original state when modified. /// public static class MaterialRestorer { #if UNITY_EDITOR private class MaterialSnapshot { public Material Snapshot = null; public int RefCount = 0; public MaterialSnapshot(Material material) { Snapshot = material; RefCount = 1; } } private static Dictionary materialsToRestore = new Dictionary(); #endif /// /// Call this method to save a snapshot of a materials current state in time. /// This only works with material assets. /// public static void Capture(Material material) { #if UNITY_EDITOR if (material != null) { // Ensure this material represents an asset. if (AssetDatabase.Contains(material)) { if (!materialsToRestore.ContainsKey(material)) { materialsToRestore.Add(material, new MaterialSnapshot(new Material(material))); } else { ++materialsToRestore[material].RefCount; } } } #endif } /// /// Call this method to restore a material to the state in time it was called with AddMaterialSnapshot. /// This only works with material assets. /// public static void Restore(Material material) { #if UNITY_EDITOR if (material != null) { MaterialSnapshot materialRef; if (materialsToRestore.TryGetValue(material, out materialRef)) { --materialRef.RefCount; if (materialRef.RefCount == 0) { if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(material.GetInstanceID(), out string guid, out long _) && !new GUID(guid).Empty()) { // Restore to the original material snapshot. material.CopyPropertiesFromMaterial(materialRef.Snapshot); // SaveAssetIfDirty does not exist in 2021.1.10f1. #if UNITY_2021_2_OR_NEWER AssetDatabase.SaveAssetIfDirty(material); #else AssetDatabase.SaveAssets(); #endif } else { Debug.LogError($"Failed to restore material \"{material.name}\" because the material is no longer in the asset database."); } materialsToRestore.Remove(material); } } } #endif } } }