using System; using System.Collections.Generic; using System.Text.RegularExpressions; using ABI.CCK.Components; using ABI.CCK.Scripts.Editor; using UnityEditor; using UnityEditorInternal; using UnityEngine; using UnityEngine.Rendering; namespace ABI.CCK.Scripts.Editor { [CustomEditor(typeof(ABI.CCK.Components.CVRMaterialDriver))] public class CVRMaterialDriverEditor : UnityEditor.Editor { private CVRMaterialDriver _driver; private ReorderableList reorderableList; private CVRMaterialDriverTask entity; private void InitializeList() { reorderableList = new ReorderableList(_driver.tasks, typeof(CVRMaterialDriverTask), true, true, true, true); reorderableList.drawHeaderCallback = OnDrawHeader; reorderableList.drawElementCallback = OnDrawElement; reorderableList.elementHeightCallback = OnHeightElement; reorderableList.onAddCallback = OnAdd; reorderableList.onChangedCallback = OnChanged; } private void OnChanged(ReorderableList list) { //EditorUtility.SetDirty(target); } private void OnAdd(ReorderableList list) { if (_driver.tasks.Count >= 16) return; _driver.tasks.Add(new CVRMaterialDriverTask()); Repaint(); } private float OnHeightElement(int index) { return EditorGUIUtility.singleLineHeight * 3 * 1.25f; } private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused) { if (index > _driver.tasks.Count) return; entity = _driver.tasks[index]; rect.y += 2; rect.x += 12; rect.width -= 12; Rect _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(_rect, "Renderer"); _rect.x += 100; _rect.width = rect.width - 100; entity.Renderer = (Renderer) EditorGUI.ObjectField(_rect, entity.Renderer, typeof(Renderer), true); rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); var materialList = new Dictionary(); if (entity.Renderer != null) { for (var i = 0; i < entity.Renderer.sharedMaterials.Length; i++) { if (entity.Renderer.sharedMaterials[i] != null) { materialList.Add(i, entity.Renderer.sharedMaterials[i].name + "[" + i + "]"); } else { materialList.Add(i, "None[" + i + "]"); } } } var materialNames = new string[materialList.Count]; materialList.Values.CopyTo(materialNames, 0); var materialIndeces = new int[materialList.Count]; materialList.Keys.CopyTo(materialIndeces, 0); EditorGUI.LabelField(_rect, "Material"); _rect.x += 100; _rect.width = rect.width - 100; entity.Index = EditorGUI.Popup(_rect, entity.Index, materialNames); rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); var propertyList = new Dictionary(); if (entity.Renderer != null) { int i = entity.Index; var material = entity.Renderer.sharedMaterials[i]; if (material != null) { var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if ((shader.GetPropertyType(j) == ShaderPropertyType.Float || shader.GetPropertyType(j) == ShaderPropertyType.Range || shader.GetPropertyType(j) == ShaderPropertyType.Vector || shader.GetPropertyType(j) == ShaderPropertyType.Color)) { var propertyKey = material.name + "[" + i + "]: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add( propertyKey, "REN[" + i + "]:" + shader.GetPropertyName(j) ); } } } } } var propertyNames = new string[propertyList.Count]; propertyList.Values.CopyTo(propertyNames, 0); var propertyDescriptions = new string[propertyList.Count]; propertyList.Keys.CopyTo(propertyDescriptions, 0); EditorGUI.LabelField(_rect, "Property"); _rect.x += 100; _rect.width = rect.width - 100; var propertyIndex = EditorGUI.Popup(_rect, Array.IndexOf(propertyNames, entity.RendererType + "["+ entity.Index +"]:" + entity.PropertyName), propertyDescriptions); if (propertyIndex >= 0) { Regex rx = new Regex(@"^([A-Z]{3})\[(\d+)\]\:(.+)$"); var match = rx.Match(propertyNames[propertyIndex]); entity.RendererType = match.Groups[1].Value; entity.Index = Convert.ToInt32(match.Groups[2].Value); entity.PropertyName = match.Groups[3].Value; var shader = entity.Renderer.sharedMaterials[entity.Index].shader; switch (shader.GetPropertyType(shader.FindPropertyIndex(entity.PropertyName))) { case ShaderPropertyType.Float: case ShaderPropertyType.Range: entity.PropertyType = CVRMaterialDriverTask.Type.Float; break; case ShaderPropertyType.Vector: entity.PropertyType = CVRMaterialDriverTask.Type.Vector4; break; case ShaderPropertyType.Color: entity.PropertyType = CVRMaterialDriverTask.Type.Color; break; } } } private void OnDrawHeader(Rect rect) { Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight); GUI.Label(_rect, "Materials"); EditorGUIExtensions.UtilityMenu(_rect, reorderableList); } public override void OnInspectorGUI() { if (_driver == null) _driver = (CVRMaterialDriver) target; base.OnInspectorGUI(); EditorGUILayout.Space(); if (reorderableList == null) InitializeList(); reorderableList.DoLayoutList(); } } }