您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
598 行
26 KiB
598 行
26 KiB
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
using UnityEditor.Rendering.Universal;
|
|
|
|
namespace UnityEditor
|
|
{
|
|
public abstract class BaseShaderGUI : ShaderGUI
|
|
{
|
|
#region EnumsAndClasses
|
|
|
|
public enum SurfaceType
|
|
{
|
|
Opaque,
|
|
Transparent
|
|
}
|
|
|
|
public enum BlendMode
|
|
{
|
|
Alpha, // Old school alpha-blending mode, fresnel does not affect amount of transparency
|
|
Premultiply, // Physically plausible transparency mode, implemented as alpha pre-multiply
|
|
Additive,
|
|
Multiply
|
|
}
|
|
|
|
public enum SmoothnessSource
|
|
{
|
|
BaseAlpha,
|
|
SpecularAlpha
|
|
}
|
|
|
|
public enum RenderFace
|
|
{
|
|
Front = 2,
|
|
Back = 1,
|
|
Both = 0
|
|
}
|
|
|
|
protected class Styles
|
|
{
|
|
// Catergories
|
|
public static readonly GUIContent SurfaceOptions =
|
|
new GUIContent("Surface Options", "Controls how LWRP renders the Material on a screen.");
|
|
|
|
public static readonly GUIContent SurfaceInputs = new GUIContent("Surface Inputs",
|
|
"These settings describe the look and feel of the surface itself.");
|
|
|
|
public static readonly GUIContent AdvancedLabel = new GUIContent("Advanced",
|
|
"These settings affect behind-the-scenes rendering and underlying calculations.");
|
|
|
|
public static readonly GUIContent surfaceType = new GUIContent("Surface Type",
|
|
"Select a surface type for your texture. Choose between Opaque or Transparent.");
|
|
|
|
public static readonly GUIContent blendingMode = new GUIContent("Blending Mode",
|
|
"Controls how the color of the Transparent surface blends with the Material color in the background.");
|
|
|
|
public static readonly GUIContent cullingText = new GUIContent("Render Face",
|
|
"Specifies which faces to cull from your geometry. Front culls front faces. Back culls backfaces. None means that both sides are rendered.");
|
|
|
|
public static readonly GUIContent alphaClipText = new GUIContent("Alpha Clipping",
|
|
"Makes your Material act like a Cutout shader. Use this to create a transparent effect with hard edges between opaque and transparent areas.");
|
|
|
|
public static readonly GUIContent alphaClipThresholdText = new GUIContent("Threshold",
|
|
"Sets where the Alpha Clipping starts. The higher the value is, the brighter the effect is when clipping starts.");
|
|
|
|
public static readonly GUIContent receiveShadowText = new GUIContent("Receive Shadows",
|
|
"When enabled, other GameObjects can cast shadows onto this GameObject.");
|
|
|
|
public static readonly GUIContent baseMap = new GUIContent("Base Map",
|
|
"Specifies the base Material and/or Color of the surface. If you’ve selected Transparent or Alpha Clipping under Surface Options, your Material uses the Texture’s alpha channel or color.");
|
|
|
|
public static readonly GUIContent emissionMap = new GUIContent("Emission Map",
|
|
"Sets a Texture map to use for emission. You can also select a color with the color picker. Colors are multiplied over the Texture.");
|
|
|
|
public static readonly GUIContent normalMapText =
|
|
new GUIContent("Normal Map", "Assigns a tangent-space normal map.");
|
|
|
|
public static readonly GUIContent bumpScaleNotSupported =
|
|
new GUIContent("Bump scale is not supported on mobile platforms");
|
|
|
|
public static readonly GUIContent fixNormalNow = new GUIContent("Fix now",
|
|
"Converts the assigned texture to be a normal map format.");
|
|
|
|
public static readonly GUIContent queueSlider = new GUIContent("Priority",
|
|
"Determines the chronological rendering order for a Material. High values are rendered first.");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Variables
|
|
|
|
protected MaterialEditor materialEditor { get; set; }
|
|
|
|
protected MaterialProperty surfaceTypeProp { get; set; }
|
|
|
|
protected MaterialProperty blendModeProp { get; set; }
|
|
|
|
protected MaterialProperty cullingProp { get; set; }
|
|
|
|
protected MaterialProperty alphaClipProp { get; set; }
|
|
|
|
protected MaterialProperty alphaCutoffProp { get; set; }
|
|
|
|
protected MaterialProperty receiveShadowsProp { get; set; }
|
|
|
|
// Common Surface Input properties
|
|
|
|
protected MaterialProperty baseMapProp { get; set; }
|
|
|
|
protected MaterialProperty baseColorProp { get; set; }
|
|
|
|
protected MaterialProperty emissionMapProp { get; set; }
|
|
|
|
protected MaterialProperty emissionColorProp { get; set; }
|
|
|
|
protected MaterialProperty queueOffsetProp { get; set; }
|
|
|
|
public bool m_FirstTimeApply = true;
|
|
|
|
private const string k_KeyPrefix = "UniversalRP:Material:UI_State:";
|
|
|
|
private string m_HeaderStateKey = null;
|
|
|
|
// Header foldout states
|
|
|
|
SavedBool m_SurfaceOptionsFoldout;
|
|
|
|
SavedBool m_SurfaceInputsFoldout;
|
|
|
|
SavedBool m_AdvancedFoldout;
|
|
|
|
#endregion
|
|
|
|
private const int queueOffsetRange = 50;
|
|
////////////////////////////////////
|
|
// General Functions //
|
|
////////////////////////////////////
|
|
#region GeneralFunctions
|
|
|
|
public abstract void MaterialChanged(Material material);
|
|
|
|
public virtual void FindProperties(MaterialProperty[] properties)
|
|
{
|
|
surfaceTypeProp = FindProperty("_Surface", properties);
|
|
blendModeProp = FindProperty("_Blend", properties);
|
|
cullingProp = FindProperty("_Cull", properties);
|
|
alphaClipProp = FindProperty("_AlphaClip", properties);
|
|
alphaCutoffProp = FindProperty("_Cutoff", properties);
|
|
receiveShadowsProp = FindProperty("_ReceiveShadows", properties, false);
|
|
baseMapProp = FindProperty("_BaseMap", properties, false);
|
|
baseColorProp = FindProperty("_BaseColor", properties, false);
|
|
emissionMapProp = FindProperty("_EmissionMap", properties, false);
|
|
emissionColorProp = FindProperty("_EmissionColor", properties, false);
|
|
queueOffsetProp = FindProperty("_QueueOffset", properties, false);
|
|
}
|
|
|
|
public override void OnGUI(MaterialEditor materialEditorIn, MaterialProperty[] properties)
|
|
{
|
|
if (materialEditorIn == null)
|
|
throw new ArgumentNullException("materialEditorIn");
|
|
|
|
FindProperties(properties); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
|
|
materialEditor = materialEditorIn;
|
|
Material material = materialEditor.target as Material;
|
|
|
|
// Make sure that needed setup (ie keywords/renderqueue) are set up if we're switching some existing
|
|
// material to a universal shader.
|
|
if (m_FirstTimeApply)
|
|
{
|
|
OnOpenGUI(material, materialEditorIn);
|
|
m_FirstTimeApply = false;
|
|
}
|
|
|
|
ShaderPropertiesGUI(material);
|
|
}
|
|
|
|
public virtual void OnOpenGUI(Material material, MaterialEditor materialEditor)
|
|
{
|
|
// Foldout states
|
|
m_HeaderStateKey = k_KeyPrefix + material.shader.name; // Create key string for editor prefs
|
|
m_SurfaceOptionsFoldout = new SavedBool($"{m_HeaderStateKey}.SurfaceOptionsFoldout", true);
|
|
m_SurfaceInputsFoldout = new SavedBool($"{m_HeaderStateKey}.SurfaceInputsFoldout", true);
|
|
m_AdvancedFoldout = new SavedBool($"{m_HeaderStateKey}.AdvancedFoldout", false);
|
|
|
|
foreach (var obj in materialEditor.targets)
|
|
MaterialChanged((Material)obj);
|
|
}
|
|
|
|
public void ShaderPropertiesGUI(Material material)
|
|
{
|
|
if (material == null)
|
|
throw new ArgumentNullException("material");
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
m_SurfaceOptionsFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SurfaceOptionsFoldout.value, Styles.SurfaceOptions);
|
|
if(m_SurfaceOptionsFoldout.value){
|
|
DrawSurfaceOptions(material);
|
|
EditorGUILayout.Space();
|
|
}
|
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
|
|
m_SurfaceInputsFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SurfaceInputsFoldout.value, Styles.SurfaceInputs);
|
|
if (m_SurfaceInputsFoldout.value)
|
|
{
|
|
DrawSurfaceInputs(material);
|
|
EditorGUILayout.Space();
|
|
}
|
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
|
|
m_AdvancedFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_AdvancedFoldout.value, Styles.AdvancedLabel);
|
|
if (m_AdvancedFoldout.value)
|
|
{
|
|
DrawAdvancedOptions(material);
|
|
EditorGUILayout.Space();
|
|
}
|
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
|
|
DrawAdditionalFoldouts(material);
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
foreach (var obj in materialEditor.targets)
|
|
MaterialChanged((Material)obj);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
////////////////////////////////////
|
|
// Drawing Functions //
|
|
////////////////////////////////////
|
|
#region DrawingFunctions
|
|
|
|
public virtual void DrawSurfaceOptions(Material material)
|
|
{
|
|
DoPopup(Styles.surfaceType, surfaceTypeProp, Enum.GetNames(typeof(SurfaceType)));
|
|
if ((SurfaceType)material.GetFloat("_Surface") == SurfaceType.Transparent)
|
|
DoPopup(Styles.blendingMode, blendModeProp, Enum.GetNames(typeof(BlendMode)));
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUI.showMixedValue = cullingProp.hasMixedValue;
|
|
var culling = (RenderFace)cullingProp.floatValue;
|
|
culling = (RenderFace)EditorGUILayout.EnumPopup(Styles.cullingText, culling);
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
materialEditor.RegisterPropertyChangeUndo(Styles.cullingText.text);
|
|
cullingProp.floatValue = (float)culling;
|
|
material.doubleSidedGI = (RenderFace)cullingProp.floatValue != RenderFace.Front;
|
|
}
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUI.showMixedValue = alphaClipProp.hasMixedValue;
|
|
var alphaClipEnabled = EditorGUILayout.Toggle(Styles.alphaClipText, alphaClipProp.floatValue == 1);
|
|
if (EditorGUI.EndChangeCheck())
|
|
alphaClipProp.floatValue = alphaClipEnabled ? 1 : 0;
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
if (alphaClipProp.floatValue == 1)
|
|
materialEditor.ShaderProperty(alphaCutoffProp, Styles.alphaClipThresholdText, 1);
|
|
|
|
if (receiveShadowsProp != null)
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUI.showMixedValue = receiveShadowsProp.hasMixedValue;
|
|
var receiveShadows =
|
|
EditorGUILayout.Toggle(Styles.receiveShadowText, receiveShadowsProp.floatValue == 1.0f);
|
|
if (EditorGUI.EndChangeCheck())
|
|
receiveShadowsProp.floatValue = receiveShadows ? 1.0f : 0.0f;
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
}
|
|
|
|
public virtual void DrawSurfaceInputs(Material material)
|
|
{
|
|
DrawBaseProperties(material);
|
|
}
|
|
|
|
public virtual void DrawAdvancedOptions(Material material)
|
|
{
|
|
materialEditor.EnableInstancingField();
|
|
|
|
if (queueOffsetProp != null)
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUI.showMixedValue = queueOffsetProp.hasMixedValue;
|
|
var queue = EditorGUILayout.IntSlider(Styles.queueSlider, (int)queueOffsetProp.floatValue, -queueOffsetRange, queueOffsetRange);
|
|
if (EditorGUI.EndChangeCheck())
|
|
queueOffsetProp.floatValue = queue;
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
}
|
|
|
|
public virtual void DrawAdditionalFoldouts(Material material){}
|
|
|
|
public virtual void DrawBaseProperties(Material material)
|
|
{
|
|
if (baseMapProp != null && baseColorProp != null) // Draw the baseMap, most shader will have at least a baseMap
|
|
{
|
|
materialEditor.TexturePropertySingleLine(Styles.baseMap, baseMapProp, baseColorProp);
|
|
// TODO Temporary fix for lightmapping, to be replaced with attribute tag.
|
|
if (material.HasProperty("_MainTex"))
|
|
{
|
|
material.SetTexture("_MainTex", baseMapProp.textureValue);
|
|
var baseMapTiling = baseMapProp.textureScaleAndOffset;
|
|
material.SetTextureScale("_MainTex", new Vector2(baseMapTiling.x, baseMapTiling.y));
|
|
material.SetTextureOffset("_MainTex", new Vector2(baseMapTiling.z, baseMapTiling.w));
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void DrawEmissionProperties(Material material, bool keyword)
|
|
{
|
|
var emissive = true;
|
|
var hadEmissionTexture = emissionMapProp.textureValue != null;
|
|
|
|
if (!keyword)
|
|
{
|
|
materialEditor.TexturePropertyWithHDRColor(Styles.emissionMap, emissionMapProp, emissionColorProp,
|
|
false);
|
|
}
|
|
else
|
|
{
|
|
// Emission for GI?
|
|
emissive = materialEditor.EmissionEnabledProperty();
|
|
|
|
EditorGUI.BeginDisabledGroup(!emissive);
|
|
{
|
|
// Texture and HDR color controls
|
|
materialEditor.TexturePropertyWithHDRColor(Styles.emissionMap, emissionMapProp,
|
|
emissionColorProp,
|
|
false);
|
|
}
|
|
EditorGUI.EndDisabledGroup();
|
|
}
|
|
|
|
// If texture was assigned and color was black set color to white
|
|
var brightness = emissionColorProp.colorValue.maxColorComponent;
|
|
if (emissionMapProp.textureValue != null && !hadEmissionTexture && brightness <= 0f)
|
|
emissionColorProp.colorValue = Color.white;
|
|
|
|
// LW does not support RealtimeEmissive. We set it to bake emissive and handle the emissive is black right.
|
|
if (emissive)
|
|
{
|
|
material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive;
|
|
if (brightness <= 0f)
|
|
material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
|
}
|
|
}
|
|
|
|
public static void DrawNormalArea(MaterialEditor materialEditor, MaterialProperty bumpMap, MaterialProperty bumpMapScale = null)
|
|
{
|
|
if (bumpMapScale != null)
|
|
{
|
|
materialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap,
|
|
bumpMap.textureValue != null ? bumpMapScale : null);
|
|
if (bumpMapScale.floatValue != 1 &&
|
|
UnityEditorInternal.InternalEditorUtility.IsMobilePlatform(
|
|
EditorUserBuildSettings.activeBuildTarget))
|
|
if (materialEditor.HelpBoxWithButton(Styles.bumpScaleNotSupported, Styles.fixNormalNow))
|
|
bumpMapScale.floatValue = 1;
|
|
}
|
|
else
|
|
{
|
|
materialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap);
|
|
}
|
|
}
|
|
|
|
protected static void DrawTileOffset(MaterialEditor materialEditor, MaterialProperty textureProp)
|
|
{
|
|
materialEditor.TextureScaleOffsetProperty(textureProp);
|
|
}
|
|
|
|
#endregion
|
|
////////////////////////////////////
|
|
// Material Data Functions //
|
|
////////////////////////////////////
|
|
#region MaterialDataFunctions
|
|
|
|
public static void SetMaterialKeywords(Material material, Action<Material> shadingModelFunc = null, Action<Material> shaderFunc = null)
|
|
{
|
|
// Clear all keywords for fresh start
|
|
material.shaderKeywords = null;
|
|
// Setup blending - consistent across all LWRP shaders
|
|
SetupMaterialBlendMode(material);
|
|
// Receive Shadows
|
|
if(material.HasProperty("_ReceiveShadows"))
|
|
CoreUtils.SetKeyword(material, "_RECEIVE_SHADOWS_OFF", material.GetFloat("_ReceiveShadows") == 0.0f);
|
|
// Emission
|
|
if (material.HasProperty("_EmissionColor"))
|
|
MaterialEditor.FixupEmissiveFlag(material);
|
|
bool shouldEmissionBeEnabled =
|
|
(material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0;
|
|
if (material.HasProperty("_EmissionEnabled") && !shouldEmissionBeEnabled)
|
|
shouldEmissionBeEnabled = material.GetFloat("_EmissionEnabled") >= 0.5f;
|
|
CoreUtils.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled);
|
|
// Normal Map
|
|
if(material.HasProperty("_BumpMap"))
|
|
CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap"));
|
|
// Shader specific keyword functions
|
|
shadingModelFunc?.Invoke(material);
|
|
shaderFunc?.Invoke(material);
|
|
}
|
|
|
|
public static void SetupMaterialBlendMode(Material material)
|
|
{
|
|
if (material == null)
|
|
throw new ArgumentNullException("material");
|
|
|
|
bool alphaClip = material.GetFloat("_AlphaClip") == 1;
|
|
if (alphaClip)
|
|
{
|
|
material.EnableKeyword("_ALPHATEST_ON");
|
|
}
|
|
else
|
|
{
|
|
material.DisableKeyword("_ALPHATEST_ON");
|
|
}
|
|
|
|
var queueOffset = 0; // queueOffsetRange;
|
|
if(material.HasProperty("_QueueOffset"))
|
|
queueOffset = queueOffsetRange - (int) material.GetFloat("_QueueOffset");
|
|
|
|
SurfaceType surfaceType = (SurfaceType)material.GetFloat("_Surface");
|
|
if (surfaceType == SurfaceType.Opaque)
|
|
{
|
|
if (alphaClip)
|
|
{
|
|
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
|
|
material.SetOverrideTag("RenderType", "TransparentCutout");
|
|
}
|
|
else
|
|
{
|
|
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
|
|
material.SetOverrideTag("RenderType", "Opaque");
|
|
}
|
|
material.renderQueue += queueOffset;
|
|
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
|
|
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
|
|
material.SetInt("_ZWrite", 1);
|
|
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
material.SetShaderPassEnabled("ShadowCaster", true);
|
|
}
|
|
else
|
|
{
|
|
BlendMode blendMode = (BlendMode)material.GetFloat("_Blend");
|
|
var queue = (int) UnityEngine.Rendering.RenderQueue.Transparent;
|
|
|
|
// Specific Transparent Mode Settings
|
|
switch (blendMode)
|
|
{
|
|
case BlendMode.Alpha:
|
|
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
|
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
|
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
break;
|
|
case BlendMode.Premultiply:
|
|
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
|
|
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
|
material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
break;
|
|
case BlendMode.Additive:
|
|
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
|
|
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
|
|
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
break;
|
|
case BlendMode.Multiply:
|
|
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
|
|
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
|
|
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
material.EnableKeyword("_ALPHAMODULATE_ON");
|
|
break;
|
|
}
|
|
// General Transparent Material Settings
|
|
material.SetOverrideTag("RenderType", "Transparent");
|
|
material.SetInt("_ZWrite", 0);
|
|
material.renderQueue = queue + queueOffset;
|
|
material.SetShaderPassEnabled("ShadowCaster", false);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
////////////////////////////////////
|
|
// Helper Functions //
|
|
////////////////////////////////////
|
|
#region HelperFunctions
|
|
|
|
public static void TwoFloatSingleLine(GUIContent title, MaterialProperty prop1, GUIContent prop1Label,
|
|
MaterialProperty prop2, GUIContent prop2Label, MaterialEditor materialEditor, float labelWidth = 30f)
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUI.showMixedValue = prop1.hasMixedValue || prop2.hasMixedValue;
|
|
Rect rect = EditorGUILayout.GetControlRect();
|
|
EditorGUI.PrefixLabel(rect, title);
|
|
var indent = EditorGUI.indentLevel;
|
|
var preLabelWidth = EditorGUIUtility.labelWidth;
|
|
EditorGUI.indentLevel = 0;
|
|
EditorGUIUtility.labelWidth = labelWidth;
|
|
Rect propRect1 = new Rect(rect.x + preLabelWidth, rect.y,
|
|
(rect.width - preLabelWidth) * 0.5f, EditorGUIUtility.singleLineHeight);
|
|
var prop1val = EditorGUI.FloatField(propRect1, prop1Label, prop1.floatValue);
|
|
|
|
Rect propRect2 = new Rect(propRect1.x + propRect1.width, rect.y,
|
|
propRect1.width, EditorGUIUtility.singleLineHeight);
|
|
var prop2val = EditorGUI.FloatField(propRect2, prop2Label, prop2.floatValue);
|
|
|
|
EditorGUI.indentLevel = indent;
|
|
EditorGUIUtility.labelWidth = preLabelWidth;
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
materialEditor.RegisterPropertyChangeUndo(title.text);
|
|
prop1.floatValue = prop1val;
|
|
prop2.floatValue = prop2val;
|
|
}
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
|
|
public void DoPopup(GUIContent label, MaterialProperty property, string[] options)
|
|
{
|
|
DoPopup(label, property, options, materialEditor);
|
|
}
|
|
|
|
public static void DoPopup(GUIContent label, MaterialProperty property, string[] options, MaterialEditor materialEditor)
|
|
{
|
|
if (property == null)
|
|
throw new ArgumentNullException("property");
|
|
|
|
EditorGUI.showMixedValue = property.hasMixedValue;
|
|
|
|
var mode = property.floatValue;
|
|
EditorGUI.BeginChangeCheck();
|
|
mode = EditorGUILayout.Popup(label, (int)mode, options);
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
materialEditor.RegisterPropertyChangeUndo(label.text);
|
|
property.floatValue = mode;
|
|
}
|
|
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
|
|
// Helper to show texture and color properties
|
|
public static Rect TextureColorProps(MaterialEditor materialEditor, GUIContent label, MaterialProperty textureProp, MaterialProperty colorProp, bool hdr = false)
|
|
{
|
|
Rect rect = EditorGUILayout.GetControlRect();
|
|
EditorGUI.showMixedValue = textureProp.hasMixedValue;
|
|
materialEditor.TexturePropertyMiniThumbnail(rect, textureProp, label.text, label.tooltip);
|
|
EditorGUI.showMixedValue = false;
|
|
|
|
if (colorProp != null)
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUI.showMixedValue = colorProp.hasMixedValue;
|
|
int indentLevel = EditorGUI.indentLevel;
|
|
EditorGUI.indentLevel = 0;
|
|
Rect rectAfterLabel = new Rect(rect.x + EditorGUIUtility.labelWidth, rect.y,
|
|
EditorGUIUtility.fieldWidth, EditorGUIUtility.singleLineHeight);
|
|
var col = EditorGUI.ColorField(rectAfterLabel, GUIContent.none, colorProp.colorValue, true,
|
|
false, hdr);
|
|
EditorGUI.indentLevel = indentLevel;
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
materialEditor.RegisterPropertyChangeUndo(colorProp.displayName);
|
|
colorProp.colorValue = col;
|
|
}
|
|
EditorGUI.showMixedValue = false;
|
|
}
|
|
|
|
return rect;
|
|
}
|
|
|
|
// Copied from shaderGUI as it is a protected function in an abstract class, unavailable to others
|
|
|
|
public new static MaterialProperty FindProperty(string propertyName, MaterialProperty[] properties)
|
|
{
|
|
return FindProperty(propertyName, properties, true);
|
|
}
|
|
|
|
// Copied from shaderGUI as it is a protected function in an abstract class, unavailable to others
|
|
|
|
public new static MaterialProperty FindProperty(string propertyName, MaterialProperty[] properties, bool propertyIsMandatory)
|
|
{
|
|
for (int index = 0; index < properties.Length; ++index)
|
|
{
|
|
if (properties[index] != null && properties[index].name == propertyName)
|
|
return properties[index];
|
|
}
|
|
if (propertyIsMandatory)
|
|
throw new ArgumentException("Could not find MaterialProperty: '" + propertyName + "', Num properties: " + (object) properties.Length);
|
|
return null;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|