holopy3/Assets/Klak/Spout/Editor/MaterialPropertySelector.cs
2020-12-10 15:25:12 +01:00

90 lines
2.8 KiB
C#

// KlakSpout - Spout video frame sharing plugin for Unity
// https://github.com/keijiro/KlakSpout
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
namespace Klak.Spout
{
static class MaterialPropertySelector
{
#region Public method
// Material property drop-down list
public static void DropdownList(
SerializedProperty rendererProperty,
SerializedProperty materialProperty
)
{
// Try retrieving the target shader.
var shader = RetrieveTargetShader(rendererProperty);
// Abandon the current value if it failed to get a shader.
if (shader == null)
{
materialProperty.stringValue = "";
return;
}
// Cache property names found in the target shader.
CachePropertyNames(shader);
// Abandon the current value if there is no property candidate.
if (_propertyNames.Length == 0)
{
materialProperty.stringValue = "";
return;
}
// Show the dropdown list.
var index = Array.IndexOf(_propertyNames, materialProperty.stringValue);
var newIndex = EditorGUILayout.Popup("Property", index, _propertyNames);
// Update the serialized property if the selection was changed.
if (index != newIndex) materialProperty.stringValue = _propertyNames[newIndex];
}
#endregion
#region Private members
static string[] _propertyNames; // Property name list
static Shader _cachedShader; // Shader used to cache the name list
// Retrieve a shader from a given renderer.
static Shader RetrieveTargetShader(SerializedProperty rendererProperty)
{
var renderer = rendererProperty.objectReferenceValue as Renderer;
if (renderer == null) return null;
var material = renderer.sharedMaterial;
if (material == null) return null;
return material.shader;
}
// Cache property names provided within a specified shader.
static void CachePropertyNames(Shader shader)
{
// Exit early when the shader is same to the cached one.
if (shader == _cachedShader) return;
var temp = new List<string>();
var count = ShaderUtil.GetPropertyCount(shader);
for (var i = 0; i < count; i++)
{
var propType = ShaderUtil.GetPropertyType(shader, i);
if (propType == ShaderUtil.ShaderPropertyType.TexEnv)
temp.Add(ShaderUtil.GetPropertyName(shader, i));
}
_propertyNames = temp.ToArray();
_cachedShader = shader;
}
#endregion
}
}