90 lines
2.8 KiB
C#
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
|
|
}
|
|
}
|