The unity docs say that the alpha component of the Color struct is public:
Shouldn’t this mean that I can set the alpha as below? Instead I get the error in editor: “Cannot modify a value type return value of `UnityEngine.UI.Graphic.color’. Consider storing the value in a temporary variable”
Methinks I am missing something basic - thanks in advance for letting me know.
public class FadeInOut : MonoBehaviour {
public Image panel;
public float StartTime;
public float EndTime;
public float FadeDuration;
Color panelColor = panel.color;
panelColor.a = 1.0f;
panelImage.color = panelColor;
Should work. When you have a compound object like this color that has lots of parameters, it’s best to create a temporary variable copying that object, changing temporary variable’s parameters to your liking and then assigning it back to where you want it.
Thanks eses - I worked out that would solve the problem.
But I’m not understanding the principle of why I can’t set it as shown. The example in the unity docs below even shows the alpha being set individually. Its a public variable?
I’ve got my two C# textbooks on hand and looking up structs and access, and I’m still not getting it.
public class ExampleClass : MonoBehaviour {
public Color color = Color.white;
void Example() {
color.a = 0;
}
}
Actually in this case it’s more related to fact that Unity material color is getter/setter that only accepts Color as parameters .
So you have to take color (which is a struct), then modify it, and pass it back to material color. You can manipulate struct like like in you example, but you can’t modify (set) material color (one channel at time) like that, you have to first modify color struct, then pass it back to material.
void Start ()
{
renderer = GetComponent<Renderer>();
// Get color struct
Color col = renderer.material.color;
// Manipulate color struct
col.r = 0f;
col.g = 0.7f;
col.b = 0f;
col.a = 1.0f;
// Reassign color - works
renderer.material.color = col;
// Try to change material's color - won't work
// renderer.material.color.a = 0f;
}
You can absolutely set the value of alpha on a Color variable. However, as the error you mentioned says you cannot modify the Color directly off an Image.
This is because Color is a struct, meaning when you access panel.color you don’t get a reference to the Color variable, you get a copy of it.
So, as @eses and @Meri said, you have to create a temporary variable to copy it to, modify the values of that, and then re-assign it.
Too see the same behaviour from your own code, try this:
public class TestScript : MonoBehaviour {
public struct TestStruct {
public int a;
}
public TestStruct testStruct { get; set; }
void Start() {
testStruct.a = 15;
}
}
It won’t compile!
In the background, that property would turn into pretty much this:
public class TestScript : MonoBehaviour {
public struct TestStruct {
public int a;
}
privateTestStruct testStruct_backer;
public TestStruct testStruct_Getter() {
return testStruct_backer;
}
public TestStruct testStruct_Setter() {
testStruct_backer = testStruct_Setter;
}
void Start() {
testStruct_Getter().a = 15;
}
}
Structs are passed by value. This means that the getter (and in the same way, panel.color) sends you a copy of the struct. Changing a value on the copy will, of course, not do anything to the original.
C# could have let your code compile, and just let you set the .a on the copy of panel.color. Of course, then your code would do nothing, and it would be really hard to understand why it didn’t do anything. So this is much better.
Thank you so much for taking the time to explain this - you guys rock.
I kept thinking that structs are passed by value and that must somehow be relevant - the penny has finally dropped that even in attempting to access/modify/read the original struct in any way shape or form I am only ever getting a copy.
Baste particular thanks for explaining the logic about why it prevents the code from compiling.