I need to control these 2 properties from the Standard Shader, while the project is running:
_SpecularHighlights → which appears in the Inspector as checkbox named ‘Specular Highlights’
and
_GlossyReflections → which also appears in the Inspector as a checkbox named just ‘Reflections’
So I need a GUI checkbox that the user can toggle on/off while the project is running.
I already managed to do a similar script that controls other properties of the shader, as _GlossMapScale, but the same approach is not working for _SpecularHighlights or _GlossyReflections
so, this works: shapes.GetComponent<Renderer> ().material.SetFloat ("_GlossMapScale", sldfind.value);
Not really sure either. The below test code works for me.
using UnityEngine;
using System.Collections;
public class testSettings : MonoBehaviour {
public bool highlights = true;
public bool glossReflections = true;
void LateUpdate () {
gameObject.GetComponent<Renderer>().material.SetFloat("_SpecularHighlights", highlights ? 1f : 0f);
gameObject.GetComponent<Renderer>().material.SetFloat("_GlossyReflections", glossReflections ? 1f : 0f);
}
}
It’s possible you need to specifically inherit from ‘shapes.gameObject’ instead of just ‘shapes’. It’s also possible it’s not adjusting the renderer that you think it is. If you attach the above code directly to the object then it should work, you might need to do some hunting from there to see exactly what is amiss in your own code.
It´s the best I got so far, but still, not working as expected
I´m in a hurry right now, so I´ll have to perform further tests later. I added the script above directly to an object:
when I uncheck the ‘public bools’ on the script, the SpecularHigh and Reflections are toggled off but there’s no change in the object itself. It only changes when I click directly on their checkboxes, under “Forward Rendering Options”
so it appears unchecked, but does not update
and why SetFloat will work with ‘true’ and ‘false’ as a variable and not directly with SetFloat(“_parameter”, true)???
The bool ? floatA : floatB pattern is a convenience expression that automatically converts floats out of the given boolean. So the line is still sending floats to the shader. floatA gets passed when the boolen is positive, and floatB gets passed when the boolean is negative. This way you don’t have to write extra code when you just want to pass set values for true/false. You can use this expression pattern pretty much anywhere, not just with shader value assignments.
Not sure what is going on with the Standard shader values though. I didn’t test on my end whether they were actually doing anything shader-wise, I just looked at if the values were being sent properly.
it’s tricky cause there’s no “_specularhighlights_on”, instead you disable or enable “_specularhightlights_off”
I created an array for objects that are tagged “shapes”, so this code should work for every objects in this array.
problem now is that some objects are children, and for these objects, the code is not working properly.
I think I need a different way to access them, but how can I do that if they are already in a array?
Nice job finding that keyword. Never would have guessed that myself.
Now that you’ve done that, it sounds like you’re stuck on (to me) much easier issues of finding references to things. What do you mean “they are already in an array”? Can you show us your object hierarchy, and what you’re trying to do?
Hi, Joe! Thank you! the moment I clicked that checkbox and it worked…omg, only coders know the feel hahaha
and yes, I think this next problem is a simpler one! (I hope)
I have several objects (sphere, cube, cylinder etc) that can be selected via a drop down menu (wich toggles the object on/off) and some controls that should apply to all objects, like Glossiness, SpecularHighLights, Reflections etc
So I created an array with all these objects and apply changes using a for each loop.
The thing is I had nested objects, e.g. 2 cilinders, one as child of the other, and an imported .obj file that also has children.
the script worked fine with all objects, except on the children. Only the parent got affected, but once it was turned off ( specularhighs) I could not turn it back on again.
Well, there’s a logic error in that code… look at when you’re toggling onoff. You’re flipping it after every object. I’m pretty sure you only want to flip it once, after the loop.
Also, when scratching your head over something like this, add some Debug.Log calls to help you see what your code is doing. The results in this case would surprise you. So, inside the if-block where you turn the highlights on, add:
Debug.Log("Turned highlights ON for " + shapes.name, shapes);
and put a similar line in the if-block that turns them off (but saying OFF instead of ON, of course).
+1 to what @JoeStrout said… also I would make sure that none of these objects are using the same material, or you may be be overriding the previous settings that you make in the loop. As an alternative, in the case of objects using the same material, you can use sharedMaterial in order to make an instanced material that will respect different settings per object, like so:
oops, they all share the same material! but that’s intended, cause I want a single control to affect all objects at the same time - but only one is seen at a time, tho.
but I´m having a small issue that may be related to this:
I have a checkbox that toggles the specularhighlight state. If I´m seeing the sphere and turn specularhighs off, it remains unchecked. Fine. But than I select the ‘cube’ in the dropdown menu. The sphere is gone, now the cube appears. The checkbox is still unchecked but the specularhighlights for the cube is ‘on’.
now I need to make the gui checkbox copy the state of the current selected object, tho I´m not sure why this is happenning. If all of them share the same material, shouldn’t all of them be in the same state? not only because of that, but because the for each loop as well.
or inactive objects are not affected? that would explain it, since the ‘onchange’ action for the dropdown hides all objects but the one selected.
When you access .material, and it’s a material that is shared with other objects, then Unity clones the material for you on the spot, and returns a reference to the clone. (When that’s not what you want, you should use .sharedMaterial instead.)
It sounds like you should forget about getting renderers and iterating over objects entirely — if they really do all share the same material, then just give your script a reference to this material (it lives in the project), and change that. All objects will automatically get the changes, because they’re all using that same material (which you will no longer be cloning).
new challenge!
I´m have some sliders on my project to control the color of lights. There’s also checkboxes to turn each light on and off.
Now I´m trying to change the color of the checkboxes according to the light colors. So if the light 1 is blue, the checkbox1 will also be blue and so on.
It´s already ‘half working’, but the checkbox it’s not updating in real time.
and the script (which alreadys changes the main light color)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
//scrip tdos sliders de cor da luz 1.
public class GUITest : MonoBehaviour{
public Color myColor;
public Light luz;
public float ycoord;
public float xcoord;
public Toggle ligtoggle;
voidStart()
{
luz=luz.GetComponent<Light>();
ycoord=30;
xcoord=10;
}
voidOnGUI(){
myColor=RGBSlider(newRect(xcoord,ycoord,200,10),myColor);
luz.color=myColor;
ligtoggle.image.color=myColor; // shouldn't this work?!
}
// GUI RGB slider
ColorRGBSlider(RectscreenRect,Colorrgb){
rgb.r=GUI.HorizontalSlider(screenRect,rgb.r,0.0f,1.0f);
//<-Movethenextcontroldownabittoavoid overlapping
screenRect.y+=20;
rgb.g=GUI.HorizontalSlider(screenRect,rgb.g,0.0f,1.0f);
//<-Movethenextcontroldownabittoavoid overlapping
screenRect.y+=20;
rgb.b=GUI.HorizontalSlider(screenRect,rgb.b,0.0f,1.0f);
returnrgb;
}
}