86 lines
2.2 KiB
C#

using UnityEngine;
using UnityEditor;
using System.Linq;
namespace Klak.Spout.Editor {
static class MaterialPropertySelector
{
#region Public method
// Material property dropdown list
public static void DropdownList
(SerializedProperty rendererProperty,
SerializedProperty materialProperty)
{
var shader = GetShaderFromRenderer(rendererProperty);
// Abandon the current value if there is no shader assignment.
if (shader == null)
{
materialProperty.stringValue = "";
return;
}
var names = CachePropertyNames(shader);
// Abandon the current value if there is no option.
if (names.Length == 0)
{
materialProperty.stringValue = "";
return;
}
// Dropdown GUI
var index = System.Array.IndexOf(names, materialProperty.stringValue);
var newIndex = EditorGUILayout.Popup("Property", index, names);
if (index != newIndex) materialProperty.stringValue = names[newIndex];
}
#endregion
#region Utility function
// Shader retrieval function
static Shader GetShaderFromRenderer(SerializedProperty property)
{
var renderer = property.objectReferenceValue as Renderer;
if (renderer == null) return null;
var material = renderer.sharedMaterial;
if (material == null) return null;
return material.shader;
}
#endregion
#region Property name cache
static Shader _cachedShader;
static string[] _cachedPropertyNames;
static bool IsPropertyTexture(Shader shader, int index)
=> ShaderUtil.GetPropertyType(shader, index) ==
ShaderUtil.ShaderPropertyType.TexEnv;
static string[] CachePropertyNames(Shader shader)
{
if (shader == _cachedShader) return _cachedPropertyNames;
var names =
Enumerable.Range(0, ShaderUtil.GetPropertyCount(shader))
.Where(i => IsPropertyTexture(shader, i))
.Select(i => ShaderUtil.GetPropertyName(shader, i));
_cachedShader = shader;
_cachedPropertyNames = names.ToArray();
return _cachedPropertyNames;
}
#endregion
}
} // namespace Klak.Spout.Editor