#if UNITY_EDITOR using UnityEngine; using UnityEditor; [CustomEditor(typeof(MaterialIndexController))] public class MaterialIndexControllerEditor : Editor { public override void OnInspectorGUI() { MaterialIndexController controller = (MaterialIndexController)target; Renderer rend = controller.GetComponent(); if (rend == null) { EditorGUILayout.HelpBox("No Renderer found!", MessageType.Error); return; } Material[] materials = rend.sharedMaterials; int materialsWithIndex = 0; // Count materials with _GradientIndex for (int i = 0; i < materials.Length; i++) { if (materials[i] != null && materials[i].HasProperty("_GradientIndex")) { materialsWithIndex++; } } EditorGUILayout.Space(5); EditorGUILayout.LabelField("Material Index Controller", EditorStyles.boldLabel); string infoMessage = ""; if (materialsWithIndex == 1) { infoMessage = "This component is OPTIONAL for single material.\n\n" + "Provides a convenient slider for _GradientIndex.\n" + "You can also animate directly: Renderer > Material > _GradientIndex"; } else if (materialsWithIndex >= 2) { infoMessage = "This component is REQUIRED for multiple materials.\n\n" + "Without it, animating _GradientIndex will affect all materials together.\n" + "This controller allows independent animation per material slot."; } else { infoMessage = "No materials with _GradientIndex detected."; } EditorGUILayout.HelpBox(infoMessage, materialsWithIndex >= 2 ? MessageType.Warning : MessageType.Info); EditorGUILayout.Space(5); // Check if using instances bool usingInstances = false; for (int i = 0; i < materials.Length; i++) { if (materials[i] != null && materials[i].name.Contains("(Instance)")) { usingInstances = true; break; } } if (!usingInstances && materialsWithIndex > 0) { EditorGUILayout.HelpBox( "⚠️ Material instances not detected!\n\n" + "For Timeline animation to work:\n" + "1. Find 'PotionTextureSetup' component\n" + "2. Click 'Prepare for Timeline'", MessageType.Warning ); EditorGUILayout.Space(5); } EditorGUILayout.LabelField($"Detected: {materialsWithIndex} material(s) with _GradientIndex", EditorStyles.miniLabel); EditorGUILayout.Space(10); EditorGUILayout.LabelField("Individual Material Indices", EditorStyles.boldLabel); // Show only the sliders for materials that exist and have _GradientIndex SerializedProperty indexProp0 = serializedObject.FindProperty("indexMaterial0"); SerializedProperty indexProp1 = serializedObject.FindProperty("indexMaterial1"); SerializedProperty indexProp2 = serializedObject.FindProperty("indexMaterial2"); SerializedProperty indexProp3 = serializedObject.FindProperty("indexMaterial3"); for (int i = 0; i < materials.Length && i < 4; i++) { if (materials[i] == null) continue; if (!materials[i].HasProperty("_GradientIndex")) continue; EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.LabelField($"Material {i}: {materials[i].name}", EditorStyles.miniLabel); SerializedProperty prop = null; switch (i) { case 0: prop = indexProp0; break; case 1: prop = indexProp1; break; case 2: prop = indexProp2; break; case 3: prop = indexProp3; break; } if (prop != null) { EditorGUILayout.PropertyField(prop, new GUIContent($"Index Material {i}")); } EditorGUILayout.EndVertical(); EditorGUILayout.Space(3); } serializedObject.ApplyModifiedProperties(); EditorGUILayout.Space(10); // Timeline instructions if (materialsWithIndex >= 2) { EditorGUILayout.HelpBox( "Timeline Animation (Multiple Materials):\n" + "1. Add Animation Track\n" + "2. Drag this GameObject to track\n" + "3. Add properties: 'Index Material 0', 'Index Material 1', etc.\n" + "4. Each material animates independently!", MessageType.None ); } else if (materialsWithIndex == 1) { EditorGUILayout.HelpBox( "Timeline Animation (Single Material):\n" + "1. Add Animation Track\n" + "2. Drag this GameObject to track\n" + "3. Add property: 'Index Material 0'\n" + " (Or animate directly via Renderer > Material > _GradientIndex)", MessageType.None ); } } } #endif