If I instantiate a number of Game Objects from a PreFab, is it possible to change the color of an individual Game Object? I know how to do this using Sprites, but can’t figure out how to do it for an individual Game Object.
That should be fairly simple, but this is untested, so look out for minor mistakes
GameObject whateverGameObject = whatever;
Color whateverColor = new Color(whateverRValue,whateverGValue,whateverBValue,1);
MeshRenderer gameObjectRenderer = whateverGameObject.GetComponent<MeshRenderer>();
Material newMaterial = new Material(Shader.Find("Whatever name of the shader you want to use"));
newMaterial.color = whateverColor;
gameObjectRenderer.material = newMaterial ;
Good luck
If all the Game Objects are using the same material, is it possible to change the color of one Game Object and not the others?
Yeah, I think so. In my code example I did just create a new material, and put that on, though.
If you do changes on the material property of a MeshRenderer, I believe it will become an instanced material (you can check this in the editor. then material in the meshrender will get “(instance)” added to its name) and therefore your changes shouldn’t affect other objects using it.
This is in contrast to using the sharedMaterial property, which will modify all objects using this material.
If you want to use model batching to reduce draw calls, you cannot modify the materials colour (if it’s a shared material). using the above method will remove the model batching ability as well.
A good way to retain the ability to have all those models in one draw call and have different coloured models is to change the vertex colours (and use a shader that supports vertex colours)
A quick sample of how to change the vertex Colours:
Mesh mesh = (gameObject.GetComponent(typeof(MeshFilter))as MeshFilter).mesh;
Color[] colours = mesh.colors;
for(int i = 0; i < colours.Length; i++)
{
colours[i] = newColour;//the new colour you want to set it to.
}
Sorry about the funny syntax on the GetComponent, I"m used to the iPhones missing features and can’t recall what is easiest on PC.
But if you use the right Shader and modify the colours of the vertices you can get a colour swap while retaining the same material. It’s how the SpriteManager does it so that it I believe.
var go = Instantiate(myPrefab);
go.GetComponent(Renderer).material.color = Color.blue; // or whatever
–Eric
Hi,
I don’t undestend.
I make new mono script with code find in this thread.
Then put it on geometry or material?
It function with touch interaction on mobile? (iOS)
var a : gameobject;
a.renderer.material.color = Color.blue;
works perfectly
The best way to do this is to copy the existing Material ( Ctrl-D ) and then change the color on that new Material.
And then in the code or in PlayMaker you can assign the new Material, that works much better and leaves other instances alone.
target.GetComponent<MeshRenderer>().material.color = Color.red;
And depending on your code sometime you will nee to make a check if the MeshRenderer is not nul, like:
if (target.GetComponent<MeshRenderer>() != null){
target.GetComponent<MeshRenderer>().material.color = Color.red
}
I am a beginner, so I may ask some dumb questions, what do you type in the variable: GameObject whateverGameObject = whatever;
I am a beginner and I need to know what to type in the variable: GameObject whateverGameObject = whatever;
in the whatever part.
Oops I accidentally posted the reply two times since I did not see the first one I posted.
The answer is literally just above your question.
But you’ll have to take the answer contextually. The variable names, the reference to the object etc depend on your actual implementation.
This doesn’t work for me. It says it’s an obsolete/out of date API. It also won’t let me auto-update the API.
YourMaterial.SetColor("_Color", Color.red);
you will be in trouble if you necro they will tell you to create a new thread if you have questions.
Here’s a solution I’ve used for several years now that will allow you to change an object’s material color without affecting other objects using the same material.
The tl;dr is that you can do this by creating a materialPropertyBlock, calling its SetColor function to change the “_Color” property, then using Renderer.SetPropertyBlock. A script that does this can be found below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Allows the changing of an object's color by changing it's renderer's Color materialPropertyBlock
/// </summary>
[ExecuteInEditMode]
public class ARX_Script_IndividualColor : MonoBehaviour {
#region Variables
/// <summary>
/// The name of the Color property in the target shader.
/// Unity's naming convention prepends these names with an underscore. eg "_Color"
/// </summary>
public string mstr_colorPropertyName = "_Color";
/// <summary>
/// The current color of the material block.
/// This is the color shown during Edit Mode.
/// When Play mode starts, this color will be set to
/// the value of mo_setOnStartColor
/// </summary>
[Tooltip("This is the color shown during Edit Mode.When Play mode starts, this color will be set to the value of mo_setOnStartColor")]
public Color mo_color;
/// <summary>
/// The first color the material block will be set to when Play Mode Activates.
/// </summary>
[Tooltip("The first color the material block will be set to when Play Mode Activates.")]
public Color mo_setOnStartColor;
/// <summary>
/// Set to a random color?
/// </summary>
public bool mb_makeRandomColor = false;
/// <summary>
/// Change the color to setOnStartColor when Play Mode starts?
/// </summary>
public bool mb_setColorOnStart = false;
/// <summary>
/// The default Alpha value of the random colors
/// </summary>
public float mnf_defaultAlpha = 0.5F;
/// <summary>
/// The renderer component attached to this object
/// </summary>
Renderer mo_renderer;
/// <summary>
/// The renderer's property block pointing to the "_Color" property
/// </summary>
MaterialPropertyBlock mo_propertyBlock;
#endregion
#region Get
/// <summary>
/// Returns the renderer component.
/// </summary>
Renderer GetRenderer { get
{
if(mo_renderer == null)
mo_renderer = GetComponent<Renderer>();
return mo_renderer;
} }
/// <summary>
/// Returns the MaterialPropertyBlock component
/// </summary>
MaterialPropertyBlock GetPropertyBlock { get
{
if(mo_propertyBlock == null)
mo_propertyBlock = new MaterialPropertyBlock();
return mo_propertyBlock;
} }
/// <summary>
/// Returns a random float Value between 0 and 0.5
/// </summary>
float RandomValueFromZeroToPointFive
{
get
{
return UnityEngine.Random.Range(0, 0.5F);
}
}
#endregion
#region Functions
/// <summary>
/// Set's the mo_color variable to a random color.
/// The material's color will change on the next frame.
/// </summary>
public void SetToRandomColor()
{
mo_color = new Color(RandomValueFromZeroToPointFive, RandomValueFromZeroToPointFive, RandomValueFromZeroToPointFive, mnf_defaultAlpha);
}
#endregion
#region Unity Overrides
// Use this for initialization
void Start () {
if (Application.isPlaying == false)
return;
if (mb_setColorOnStart)
{
mo_color = mo_setOnStartColor;
}
}
// Update is called once per frame
void Update () {
if (mb_makeRandomColor)
{
SetToRandomColor();
mb_makeRandomColor = false;
}
// Get the current value of the material properties in the renderer.
GetRenderer.GetPropertyBlock(GetPropertyBlock);
// Assign our new value.
GetPropertyBlock.SetColor(mstr_colorPropertyName, mo_color);
// Apply the edited values to the renderer.
GetRenderer.SetPropertyBlock(GetPropertyBlock);
}
#endregion
}