- Home /
How to change guitext alpha value without error cs1612?
I get this error while trying to change the alpha value of a guitext: "Assets/FloatingText.cs(47,34): error CS1612: Cannot modify a value type return value of `UnityEngine.Material.color'. Consider storing the value in a temporary variable"
I did a ton of googling around, and no matter how I try to adapt the things I found I just can't get it working. The example script this is based on is unfortunately in Javascript, which apparently handles the thing that causes this error a bit different.
public class FloatingText : MonoBehaviour {
private float speed = 0.03f;
private float alpha;
public float guiTime = 5f;
private float duration = 1.5f;
void Start()
{
guiText.material.color = Color.red;
alpha = 1f;
StartCoroutine(GuiDisplayTimer());
}
void Update()
{
//Debug.Log(guiText.material.color.a);
transform.Translate(new Vector3(0f, 2f, 0f) * (speed * Time.deltaTime));
//alpha = guiText.material.color.a; //Tried setting alpha into a temp variable but ain't working
alpha -= Time.deltaTime/duration;
guiText.material.color.a = alpha;
}
IEnumerator GuiDisplayTimer()
{
yield return new WaitForSeconds(guiTime);
Destroy(this.gameObject);
}
}
It must be a very simple thing to do, but every place that advices how to get around this error does it in a way that just seems totally incomprehensible. I have tried so many things with this it's really frustrating right now. Here's the script I have based this on : http://answers.unity3d.com/questions/122479/attack-damage-scrolling.html
Thanks in advance.
Just a "short" explanation:
.color is a property of the $$anonymous$$aterial class. The property have a getter and setter method. If you "read" the property the getter is called and when you "write" to the property the setter is called.
The problem with valuetypes is that when you write something like:
material.color.xxxx
you just "read" the property and get a copy of the color struct because it's a valuetype not a reference type. Every changes to members of that copied color struct will be lost since it's just a copy and the setter of the property isn't called because you just "read" the property.
If you have a simple valuetype property like int, float... there's no problem
private int m_$$anonymous$$yValue = 0;
public int myProperty
{
get { return m_$$anonymous$$yValue; }
set { m_$$anonymous$$yValue = value; }
}
// This will call the getter and the setter:
myProperty++;
This will work since the ++ - operator changes the actual type of the property.
In UnityScript the compiler does the temp-variable-wrapping behind the scenes but not very effective. I'm not sure why the UnityScript compiler does this. This line:
renderer.material.color.a = 1;
will be compiled as
int num = 1;
Color color = this.renderer.material.color;
float num1 = color.a = (float)num;
Color color1 = this.renderer.material.color = color;
It seems that they don't want / can't discard the potential result of the assignment operation. It looks really strange, 3 additional temp variables and 3 additional assignments is not really optimised code. So it's very "easy" in UnityScript but when it comes to performance C# is the better choice imho ;)
Do we know what optimization happens? $$anonymous$$aybe all the guff disappears, and so it's just coded like that for simplicity.
Answer by Waz · Aug 16, 2011 at 10:45 PM
As the error says, assign the the whole Color, not one component.
var c = .....color;
c.a = alpha;
.....color = c;
Or use JavaScript which handles these things for you.
Thanks, works as it should now. I did try something very similar like this, but there must have been a small mistake somewhere. What it comes to C# and JavaScript, I prefer using C# as I'm more familiar with it. I have never really used JS. But I think the error message could be a bit more specific :P
Btw, as you might have noticed, I'm new to this site. Should I now post the working code here, or is it enough to mark the correct answer?
Certainly the docs could male it clearer when values are value types (like Color and Vector3), and when they are referenced objects (like $$anonymous$$aterial and Transform).
I deliberately answered generically, so as long as your working code follows that pseudocode, it's not necessary to post it. The idea is that Questions, once answered, have the broadest applicability.
I still don't quite understand, could you please explain how one would put this pseudo code in C#?
Your answer
Follow this Question
Related Questions
Modifying the Arial material for fading GUITexts 1 Answer
GUIText Alpha transparency not working on Android Table? 0 Answers
How do I get the current alpha value of a material? 2 Answers
Fade in text one character at a time 3 Answers
Fade TextMesh font C# 4 Answers