Change value of a shader propertie using a Slider

Hi I’ve looked at other answers similar to what I’m asking but i still need clarity on it.

How would you use a GUI slider to control say specular amount of a shader in game.

using UnityEngine;
using System.Collections;

public class ClickObject : MonoBehaviour {

Rect windowRect = new Rect(10, 20, 500,300 );
public bool canClick;
public GameObject cont;

//Toggle Booleans
bool toggleWindow;
bool toggleWindowTwo;
bool toggleWindowThree;
bool toggleWindowFour;
bool toggleWindowFive;

// Use this for initialization
void Start () {
	canClick = false;

	toggleWindow = false;
	toggleWindowTwo = false;
}

void OnGUI ()
{
	if(canClick)
	{

		ToggleWindows();

		if(Input.GetMouseButtonUp(0))
		{
			Ray ray = camera.ScreenPointToRay(Input.mousePosition);
			RaycastHit hit;

			if(Physics.Raycast(ray,out hit) && hit.transform.tag == "Object")
			{
				Debug.Log("Open Lambert Shader Window");
				toggleWindow = true;
			}
			else if(Physics.Raycast(ray,out hit) && hit.transform.tag == "Object2")
			{
				Debug.Log("Open Blinn Shader Window");
				toggleWindowTwo = true;
			}

		}

	}
	else
	{
		toggleWindow = false;
		toggleWindowTwo = false;
	}

	if(Input.GetKeyUp(KeyCode.Escape))
	{
		toggleWindow = false;
		toggleWindowTwo = false;
	}
}

void ToggleWindows ()
{
	if(toggleWindow)
	{
		GUI.Window(0, windowRect, DoMyWindow, "My Window");
		toggleWindowTwo = false;
	}
	else if(toggleWindowTwo)
	{
		GUI.Window(1, windowRect, DoMyWindowTwo, "My Window 2");
		toggleWindow = false;
	}
}

void DoMyWindow(int windowID) 
{
	float hSliderValue;
	float hSliderValue2=1.0f;
	float hSliderValue3=1.0f;
	float hSliderValue4=1.0f;
	float hSliderValue5=1.0f;
	float hSliderValue6=1.0f;
	float hSliderValue7=1.0f;
	float hSliderValue8=1.0f;
	float hSliderValue9=1.0f;
	float hSliderValue10=1.0f;
	float hSliderValue11=1.0f;




	//gets the shader
	

		// Animate the blend value

hSliderValue =	cont.renderer.material.SetFloat( "_BaseColour", hSliderValue );
		
		if (GUI.Button(new Rect(350, 30, 100, 20), "Shader 1"))
	{
		print("Tweak Values");

	}

	hSliderValue = GUI.HorizontalSlider (new Rect (25, 40, 100, 30), hSliderValue, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 35, 100, 30), "Base Colour");
	hSliderValue2 = GUI.HorizontalSlider (new Rect (25, 60, 100, 30), hSliderValue2, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 55, 100, 30), "Subsurface");
	hSliderValue3 = GUI.HorizontalSlider (new Rect (25, 80, 100, 30), hSliderValue3, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 75, 100, 30), "Metallic");
	hSliderValue4 = GUI.HorizontalSlider (new Rect (25, 100, 100, 30), hSliderValue4, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 95, 100, 30), "Specular");
	hSliderValue5 = GUI.HorizontalSlider (new Rect (25, 120, 100, 30), hSliderValue5, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 115, 100, 30), "Specular Tint");
	hSliderValue6 = GUI.HorizontalSlider (new Rect (25, 140, 100, 30), hSliderValue6, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 135, 100, 30), "Roughness");
	hSliderValue7 = GUI.HorizontalSlider (new Rect (25, 160, 100, 30), hSliderValue7, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 155, 100, 30), "Anisotropic");
	hSliderValue8 = GUI.HorizontalSlider (new Rect (25, 180, 100, 30), hSliderValue8, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 175, 100, 30), "Sheen");
	hSliderValue9 = GUI.HorizontalSlider (new Rect (25, 200, 100, 30), hSliderValue9, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 195, 100, 30), "Sheen Tint");
	hSliderValue10 = GUI.HorizontalSlider (new Rect (25, 220, 100, 30), hSliderValue10, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 215, 100, 30), "Clearcoat");
	hSliderValue11 = GUI.HorizontalSlider (new Rect (25, 240, 100, 30), hSliderValue11, 0.0f, 1.0f);
	GUI.Label (new Rect (150, 235, 100, 30), "Clearcoat Gloss");

}

void DoMyWindowTwo(int windowID) 
{
	if (GUI.Button(new Rect(10, 20, 100, 20), "Shader 2")){
		print("Tweak Values");
	}
}

}

1 Answer

1

See here for the GUI Slider (horizontal one anyway):

The value returned by the call (hSliderValue in the link above) can be stored in a variable. In the Update method, you can use this value to drive the shader (kind of like this):

float value;
float prevValue;

public GameObject shadedObject;

void  OnGUI() {
  value = GUI.HorizontalSlider(new Rect(25, 25, 100, 30), value, 0.0F, 10.0F);
}

void Update() {
  if (prevValue != value) {
    prevValue = value;
    shadedObject.renderer.sharedMaterial.SetFloat("myShaderSpec", value);
  }
}

Using sharedMaterial will modify every object in the scene that uses it. Use renderer.material if you just want to change a single object.

Unity Ref:

Oh okay sweet ill try this out .Does this principle still apply if i wanted to change the value eg//specular of a shader thats attached to another gameobject in the scene. Is the referencing any different

Hmm i still can't figure it out i'm going in regards to what i'm doing. I want to be able to use the GUIslider to control a value of i made in a shader which is exposed in the property eg// control _Specular with a GUI slider. Like how you see in some demos of people who have GUI sliders that control the shader in the game rather than just outside. Ill update my question with the code

You're on the right path. What part isn't working? Can you post the top of your shader, specifically the Properties section? Are you using a standard shader? Is this for Stand Alone or mobile?

I'm managed to get it working :) what i did was make another C# class that handled getting the material , so basically making a material variable and then as you mentioned i used the set float function to get what i want and matched to the parameter i was controling so when i send the variable to the class that handles GUIs which i created (which is the posted code) the slider will move according to that float