I want to change and set 3 things after setting the new material:
First The shader type to Unlit/Color
Second The albedo color to change it for example to: 255,0,0,255
Third The metallic value from 0 to 1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DoorsLockManager : MonoBehaviour
{
public bool locked;
public Color lockedColor = Color.red;
public Color unlockedColor = Color.green;
public Renderer rend;
private GameObject[] doorPlanes;
private void Start()
{
doorPlanes = GameObject.FindGameObjectsWithTag("DoorPlane");
for (int i = 0; i < doorPlanes.Length; i++)
{
rend = doorPlanes[i].GetComponent<Renderer>();
if (locked)
{
rend.material.SetFloat("Metallic", 1);
rend.material.color = lockedColor;
}
else
{
rend.material.color = unlockedColor;
}
}
}
// Update is called once per frame
void Update ()
{
}
}
This line does nothing:
rend.material.SetFloat("Metallic", 1);
This is what I want to change:
When you need to change a shader property but you don't know what to use for the proper name to use, select the material, click on its settings icon then click on "Select Shader". From there, you will see all the shader property names and their types and you will know which function and name to use to change the shader's properties.
With the default standard shader it looks something like this:
You need to know this otherwise you would need to ask new question for each property you want to change.
Your Renderer reference:
public Renderer rend;
To set it, the SetXXX function is used:
rend.material.SetFloat("_Metallic", 1); //Metallic is a float
To get it the GetXXX function is used:
float metallic = rend.material.GetFloat("_Metallic"); //Metallic is a float
To change or get the The albedo color to 255,0,0,255.
rend.material.SetColor("_Color", new Color32(255, 0, 0, 255));
Color color = rend.material.GetColor("_Color");
Notice that I used Color32 instead of Color because Color32 takes values between 0 and 255 while Color expects values between 0 and 1.
To change the material's shader to "Unlit/Color", just find it then assign it to the material:
Shader shader = Shader.Find("Unlit/Color");
rend.material.shader = shader;
Note that the "Unlit/Color" shader doesn't have the _Metallic property. It has one one property and that is "_Color". You can use the first method I described to determine which properties it has before attempting to change them.
What if the shader is used on many different objects. I want all the
objects to change when the property is changed on one of them.
To change all the objects using the-same material, use Renderer.sharedMaterial instead of Renderer.material. The shared material changes the original material and every other objects should pick that new material up as long as you have not called Renderer.material on the material which actually makes a new copy for the said material and disconnects the renderer material from the original material.
Related
I need to set a variable of a shader without a material that wraps around it.
I'll explain the problem and why it's not like the question "How can I access shader variables from script?".
Problem
My shader is similar to this (99% of irrelevant boilerplate code removed):
Shader "Hidden/XShader"
{
Properties
{
_x ("", float) = 0
}
SubShader
{
Pass
{
float _x;
half4 frag(v2f i) : SV_Target
{
// "col" and "wpos" have been correctly defined
if (wpos.x >= _x)
{
col.r = 1;
} else {
col.r = 0;
}
return col;
}
}
}
}
This shader is set through the Edit->Project Settings->Graphics->Deferred option. It is the default shader that the main camera uses.
Now I need to set the _x value from code attached to the camera:
public class XCameraController : MonoBehaviour
{
public float x;
void Update()
{
<something>.SetFloat("_x", x);
}
}
The <something> placeholder would normally be a material, as SetFloat() is defined there. But the camera and shader do not have a material. The concept of material doesn't even apply to the default shader.
I've searched online and in the documentation for hours. I admit I failed and am at a loss here. I guess it must be simple but I can't find any documentation.
I don't expect an implemented solution, a pointer where I can find help will suffice!
But the camera and shader do not have a material. The concept of
material doesn't even apply to the default shader.
True but materials simply exposes all properties from a shader so it is relevant here since you want to change the shader properties.
You have a custom shader but that's not used to render a GameObject but the camera. A material is still needed to change the shader. If you don't want to use a material then you can use the Shader.SetGlobalXXX functions such as Shader.SetGlobalFloat("_x", 3) but it will change all the shader properties. This is unrealistic.
The proper way to do this is to create a temporary material you will use to modify the shader, change the shader properties, then update the shader the camera is using. To do this, you have to:
Find the shader or get a reference of the shader with a public variable:
Shader camShader = Shader.Find("Hidden/XShader");
Create material from the shader
Material camMat = new Material(camShader);
Modify the property as you wish
camMat.SetFloat("_x", 3);
Apply to the modified shader property to the camera
Camera.main.SetReplacementShader(camShader, "RenderType");
If you're manually rendering the camera then use Camera.main.RenderWithShader(camShader, "RenderType") instead of Camera.main.SetReplacementShader(camShader, "RenderType").
Let's suppose we have two cylinders in the scenes with red and blue materials on them. Also, we have two UI images with red and blue background. Now, what should I do to make the red image only draggable onto red cylinder and the blue image only draggable onto blue cylinder.
If I drag the red image onto the blue cylinder, then an error message should appear:
same for dragging blue image on red cylinder or vice versa.
See the picture below
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class wrench : MonoBehaviour {
public bool Dragging = false;
public bool collision = false;
Vector3 position;
public List<GameObject> UIimages;
public void BeginDrag() {
position = gameObject.transform.position;
Dragging = true;
foreach (GameObject obj in UIimages) {
obj.GetComponent<BoxCollider2D> ().enabled = false;
}
}
public void Drag() {
transform.position = Input.mousePosition;
}
public void Drop() {
if (!collision) {
gameObject.transform.position = position;
}
Dragging = false;
}
}
Assuming your dropps are already detected as you say and the question is more about how to differ between the objects I would use a simple enum e.g.
public enum WhichObject
{
red,
blue
}
the advantage is that later you can very easily add more options without having to deal with layers, tags etc.
On the GameObject you drag around add a component e.g.
public class ObjectInformation
{
public WhichObject IsObject;
}
and simply select in the Inspector (or if you spawn them via script) for each of your dragged objects which value the WhichObject variable shall have.
Than on your target objects where you detect the collision also add a WhichObject variable but this time configure the value you expect to be dropped here
public WhichObject ExpectedObject;
again set it via the inspector or script.
Than simply add a check
var info = droppedObject.GetComponent<ObjectInformation>();
// Something else dropped?
if(!info) return;
// Now check if the value matches
// the one this object expects
if(info.IsObject == ExpectedObject)
{
// Correct object
Debug.Log("Yeah!");
}
else
{
// Wrong object
Debug.LogFormat("Dropped object {0} does not match the expected object {1}!", info.IsObject, ExpectedObject);
}
Later you can also simply extend it using multiple enums like e.g. colors, forms etc.
And maybe you could as well make the check the other way round and check on the dragged object, if the values match and if the don't match not even allow to be dropped on that target object (this depends of course on your implementation).
I am new to unity engine
how to put color on the cube ?
using UnityEngine;
using System.Collections;
public class cor_cube : MonoBehaviour {
public Color colorStart = Color.red;
public Color colorEnd = Color.green;
public float duration = 1.0F;
public Renderer rend;
void Start() {
rend = GetComponent<Renderer>();
}
void Update() {
float lerp = Mathf.PingPong(Time.time, duration) / duration;
rend.material.color = Color.Lerp(colorStart, colorEnd, lerp);
}
} (I don't want like that)
I want a fixed color.
I want a fixed color.
It looks like you don't want to lerp from one color to another. You just want to set the color.
Below are the ways to change color:
Method 1: Predefined Colors
void Start() {
rend = GetComponent<Renderer>();
rend.material.color = Color.blue;
}
There many other predefined Colors such as Color.blue,Color.white,Color.black,Color.green and Color.gray.
Method 2: Custom Color with RGB or RGBA values
You can also create a custom color that is NOT defined in the Color structure.
The format is in RGBA(Red,Green,Blue,Alpha). The values are float numbers from 0.0 to 1.0.
Full Red Color
rend.material.color = new Color(1,0,0,1);
Full Blue Color
rend.material.color = new Color(0,1,0,1);
Full Green Color
rend.material.color = new Color(0,0,1,1);
Half Way Visible Blue Color
rend.material.color = new Color(0,1,0,0.5f);
Hidden Blue Color
rend.material.color = new Color(0,1,0,0);
Method 3: HSV Color
rend.material.color = Color.HSVToRGB(0,0,0);
I can't go on and on but this should get you started. Make sure to create a material in Editor and assign it to the cube so that the default one wont be used. You only need to create one and use it for all your cubes. When you change the color, a new material will be created for you. If you don't want that, use rend.sharedMaterial.color instead of rend.material.color.
In Unity 5, things changed. To get the alpha to change, you have to select the material and change the Rendering Mode from Opaque(default) to Fade or Transparent. So old tutorials may not work because of this.
Create a material with the shader Unlit/diffuse on it. Set the texture to a plain white texture adn set the color of the material.
I have an object which has for example 5 meshes where I would like to change the color in runtime. But every mesh has different colors to change. For example mesh 1 can be changed to blue, red and orange and mesh 2 can be changed to orange, yellow,green,purple and white.
I would like to have a c# script where I have an array with all 5 meshes. And for each array I would like to have another array appear in the inspector, where I can put in the different colors.
This is no problem if the mesh count would always be 5. But I want it to be flexible. For example, another object only has 3 meshes than I only need 3 color arrays instead of 5.
I have never worked with Editor Scripts, but maybe there is a easy workaround for that?
I am working with Unity 5.3
Thank you.
public class Test: MonoBehaviour
{
public Models [] models;
private int index = 0;
[SerializeField] private MeshFilter meshFilter = null;
[SerializeField] private Renderer rend = null;
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
if(++index == models.Length)index = 0;
meshFilter.mesh = models[index].mesh;
int currIndex = models[index].currentIndex;
rend.material = models[index].materials[currIndex];
}
if(Input.GetKeyDown(KeyCode.A))
{
if(++models[index].currentIndex == models[index].materials.Length)models[index].currentIndex = 0;
int currIndex = models[index].currentIndex;
rend.material = models[index].materials[currIndex];
}
}
}
[System.Serializable]
public class Models{
public Mesh mesh;
public int currentIndex;
public Material[]materials;
}
This will show the Models array in your inspector. You can give a size for it, then each element opens up a mesh slot and an array of materials. Give it a size and you can start dragging materials.
I would suggest to add 2 items in the array, then add two meshes (Unity has some default ones like sphere and cube). Then create some basic materials of colors and add them to the materials arrays of each object.
Then you can run and press Space to change mesh and A to change color. You just need to use your own after that.
I am working on a game in UNITY. For this game so far I have 3 cubes that I wish to target. I have them set up in an array and when I hit tab the targets switch between them based on distance. This is all fine but I have run into a pickle and it is that I wish to have the cubes I target turn red for visual representation. I seen on Youtube that people used the following line of code :
selectedTarget.renderer.material.color = Color.red;
However this does not work for me. I then seen a comment saying :
The function to render was deprecated. Below should work...
selectedTarget.GetComponent<Renderer>().material.color = Color.red;
This code does not work for me either. I get no errors mind you, it runs fine but the cubes do not turn red. Has anyone any idea on whether or not I am doing this right? I will post the entire script below and the code I am on about is in selectedTarget(). Any help would be appreciated and thank you!
private void SelectTarget(){
selectedTarget.renderer.material.color = Color.red;
}
I had the very very very same problem. I had no errors. You need to be able to set the color property on the material, and only CERTAIN shaders have this color property. I had to use for example Self-Illuminated/Bumped instead of say Mobile/VertexLit. Then changing the color should be fine as you can see a Main Color property in the editor/inspector.
Also make sure your mesh has Materials. If you don't have Materials, even if it's blank or a placeholder else it won't work! I'd create a texture preferably white colored and small like 5x5. Then attach the texture to your cube. After you attach it you can color it!
I've done cool stuff in my game with Color.Lerp, it'll fade from one color to the next! This example below ping pongs from white to red when the player is hit by an enemy indicating damage!
transform.renderer.material.color = Color.Lerp(Color.white, Color.red, Mathf.PingPong(Time.time * 3 * speedLerp, 1.0));
This is working for me.
using UnityEngine;
using System.Collections;
public class Tile : MonoBehaviour {
public Vector2 gridPos = Vector2.zero;
Renderer r;
public Color colorStart = Color.red;
public Color colorEnd = Color.green;
public float duration = 1.0F;
private float lerp;
// Use this for initialization
void Start () {
r = GetComponent<Renderer>();
lerp = Mathf.PingPong(Time.time, duration) / duration;
}
// Update is called once per frame
void Update () {
}
void OnMouseEnter()
{
r.material.color = Color.Lerp(colorStart, colorEnd, lerp);
//r.material.color = Color.black;
Debug.Log("X pos = "+ gridPos.x + "Y pos = "+ gridPos.y);
}
void OnMouseExit()
{
r.material.color = Color.Lerp(Color.white, Color.white,lerp);
}
}
set a bool type for color like
bool colorchange = false;
public void OnCollisionEnter (Collision col)
{
Debug.Log ("collide");
colorchange = true;
if (colorchange) {
transform.GetComponent<Renderer> ().material.color = Color.red;
}
}