123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598 |
- 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 Universal RP 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;
- // UniversalRP 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 Universal RP 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.SrcAlpha);
- 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
- }
- }
|