Reputation: 15
Basically I want to change the colour of an image acording to a bool, but everything I tried made the whole canvas change colour together with it. Any solutions on how to limit it to the omject with the script?
here is the script that I am curently using:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class VentCor : MonoBehaviour
{
static bool fechado;
void Update()
{
if (fechado == true)
{
gameObject.GetComponent<RawImage>().material.color = new Color(255, 0, 0 );
}
else
{
gameObject.GetComponent<RawImage>().material.color = new Color(0, 255, 0);
}
}
public void fecha()
{
fechado = !fechado;
}
Upvotes: 0
Views: 5761
Reputation: 6275
The reason that the Canvas
is also changing is that you are not changing the color of the object, but the material
color of the object. As objects share materials
and you are not instancing it in your code, you are effectively changing the default material
for every UI object to the color you are setting. By changing this default material
, all objects that use this material
, which by default is all UI objects, will change color.
Here is your old code with the proper call to the color
field instead of setting the material
color.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class VentCor : MonoBehaviour
{
static bool fechado;
void Update()
{
if (fechado == true)
{
gameObject.GetComponent<RawImage>().color = new Color(255, 0, 0 );
}
else
{
gameObject.GetComponent<RawImage>().color = new Color(0, 255, 0);
}
}
public void fecha()
{
fechado = !fechado;
}
}
I also attached a snippet where I made a few edits. I wrote out why I made each change.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(RawImage))]
public class VentCor : MonoBehaviour
{
[SerializeField] private RawImage img = null;
private bool fechado;
private void Start()
{
if(img == null)
img = GetComponent<RawImage>();
}
public void SetFechado(bool b)
{
fechado = b;
UpdateImageColor();
}
public void fecha()
{
fechado = !fechado;
UpdateImageColor();
}
private void UpdateImageColor()
{
img.color = fechado ? Color.red : Color.green;
}
}
Firstly, I removed the static
accessor for your variable Fechado
and made it private. Instead, I created a public setter
method SetFechado
that takes a bool
parameter. Instead of directly setting the variable, you can now set it by calling the method and passing in the bool
state.
private bool fechado;
Next, I stored the RawImage
component instead of using GetComponent
as caching components is performantly better if you intend to set the color often enough.
[SerializeField] private RawImage img = null;
private bool fechado;
private void Start()
{
if(img == null)
img = GetComponent<RawImage>();
}
After this, I removed the Update
method as the only time you need to make a check for what the bool
is, is when it changes. As I had removed the static keyword from the variable, you now need to add a setter
method to allow to set the bool
from outside the script.
public void SetFechado(bool b)
{
fechado = b;
UpdateImageColor();
}
private void UpdateImageColor()
{
img.color = fechado ? Color.red : Color.green;
}
The final change I made was to use the predefined colors
red
and green
. If you ever would like to change the colors to a color Unity does not predefined, you can change the code back to creating a new Color
struct. I would advise creating the Color
at compile time or as a SerializedField
to define it in the inspector.
Upvotes: 2