- Home /
Changing colour of player
Sorry for the incredibly simple question, but I'm new to Unity. I'm trying to write code which changes the colour of the player (this is a prototype so it's just a simple 3D capsule) when the player presses a button. First, I created two variables to keep track of the current colour and store all three colours.
public int currentColour;
public Material[] colours;
Then, in the "void Update()" command, I tried
{ if (Input.GetButtonDown("ColourForward"))
{ GameObject capsule = gameObject.transform.Find("Capsule").gameObject;
capsule.GetComponent<MeshRenderer>().materials[0] = colours[2]; }}
The capsule mesh is a child of the object that the code is attached to. Pressing the button definitely does something because the material on the capsule changes from "Green Material" to "Green Material (Instance)" when the button is pressed.
Sorry if this is really simple, but any help would be appreciated.
Answer by UnityCoach · Sep 15, 2017 at 09:27 AM
You're on the right path. Here's some help:
private int currentMaterial; // keep things private unless you need to access them from other components
[SerializedField] private Material [] materials; // mark them as Serialized if you want them in the Editor
[SerializedField] private Renderer renderer; // keep a reference to the object's renderer, mark it Serializable and assign it in the inspector
void Awake ()
{
// renderer = gameObject.transform.Find("Capsule").GetComponent<Renderer>(); // or assign it in awake
}
void Update ()
{
if (Input.GetButtonUp ("ColourForward") // GetButtonUp usually provides a better behaviour
SwitchMaterial (1); // use another method to make things a little more generic
}
void SwitchMaterial (int index)
{
renderer.materials[0] = materials[index]; // use this if you have more than one material on the mesh
// renderer.material = materials[index]; // otherwise, this will do the job
}
Thanks so much for replying, but that hasn't solved the issue yet. It still just changes "Green $$anonymous$$aterial" to "Green $$anonymous$$aterial (Instance)" on the mesh renderer when the button is pressed.
If no material is set, it adds "Default-$$anonymous$$aterial (Instance)". It should select the material corresponding to the number specified in Switch$$anonymous$$aterial from Colours: ![alt text][1] [1]: /storage/temp/101907-colours.png
Would it work better if I attached the code to the capsule itself (since it has the renderer on it)?
That it changes to "Green $$anonymous$$aterial (Instance)" is normal behaviour. It'll always create a new instance of a material so that you can change it without affecting other objects with the same material.
You can also use .shared$$anonymous$$aterial property if you want to replace the shared material on that object.
Anyway, it should replace the renderer's material with the indexed material from the array. Did you assign different materials in the array, in the inspector?
Okay, thanks. Yes, in the Inspector, I manually assigned three materials into the "Colours" $$anonymous$$aterial array that I defined in the line
public $$anonymous$$aterial[] colours;
The problem is that it doesn't replace the material with the indexed material, but with another instance of the material that is already applied. I've tried changing both the objects material and the index in the code and it happens in both cases. (i.e. if "Red $$anonymous$$aterial" is on "Capsule", it changes to "Red $$anonymous$$aterial (Instance)", but if "Green $$anonymous$$aterial" is on "Capsule", it changes to "Green $$anonymous$$aterial (Instance)" without me having changed the code).
Your answer
![](https://koobas.hobune.stream/wayback/20220612134907im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
Multiple Cars not working 1 Answer
Player names all displayed as local player 1 Answer
How do I highlight an object when the player is near it 1 Answer