- Home /
Custom MaterialPropertyDrawer with argument
I am working on a group of shaders. And I want to add some custom shader property GUI. By driving from MaterialPropertyDrawer class. A simple test code looks like this
using UnityEngine;
using System.Collections;
using UnityEditor;
public class TestMatPropDrawer : MaterialPropertyDrawer {
public TestMatPropDrawer(int i)
{
}
public override void OnGUI (Rect position, MaterialProperty prop, string label, MaterialEditor editor)
{
//Debug.Log ("Drawing");
if(GUILayout.Button("Show Label"))
{
Debug.Log(label);
EditorUtility.SetDirty(prop.targets[0]);
}
base.OnGUI (position, prop, label, editor);
}
public override void Apply (MaterialProperty prop)
{
Debug.Log ("Applying");
base.Apply (prop);
}
public override float GetPropertyHeight (MaterialProperty prop, string label, MaterialEditor editor)
{
//Debug.Log ("Getting height");
return base.GetPropertyHeight (prop, label, editor);
}
}
And with a shader like this
Shader "Custom/TestShader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
[TestMatProp]
_testProp ("TestProp", Float) = 1
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
CustomEditor "TestCustomMatProp"
}
This drawer works find as long as I keep [TestMatProp] without arguments
What I am trying to do is to add some arguments like [KeywordEnum(None, Add, Multiply)] when I try to add some simple argument like[TestMatProp(1)] Unity is giving me a
Failed to create material drawer TestMatProp with arguments '1'
But as I look through the doc there no clear reference about how to implement a argumented version of MaterialPropertyDrawer.
Any one have any idea?
Answer by Lex-DRL · Jun 17, 2015 at 06:27 AM
Just faced the same issue.
Man, you just need to add several overloaded constructors. I.e.:
your custom GUI script:
public class TestMatPropDrawer : MaterialPropertyDrawer {
protected bool isArgumentGiven;
protected int argValue;
public TestMatPropDrawer()
{
isArgumentGiven = false;
argValue = 0; // <- some default value
}
public TestMatPropDrawer(int i)
{
isArgumentGiven = true;
argValue = i;
}
public override void OnGUI (Rect position, MaterialProperty prop, string label, MaterialEditor editor)
{
if(isArgumentGiven)
{
// perform some "default" stuff if user didn't pass an argument
}
else
{
// some other stuff if the argument is manually specified
}
}
}
But keep in mind that if your argument is string (not int) and you want to pass "BlaBlaBla" as an argument, you need to write it like this in your shader:
[TestMatProp(BlaBlaBla)]
_testProp ("TestProp", Float) = 1
i.e., without quotes. That's really disappointing since that's why we're stuck with a LongCamelCaseStrings and can't pass a "real string" (with spaces, special characters etc).
Answer by jmgek · Dec 30, 2014 at 08:32 PM
I think this is what you are asking, .cs
float TestProp = //Anything here;
renderer.material.SetFloat("_TestProp ", TestProp );