How Do I Sync Material Color on One Object with Another?

I have a ‘Change Color’ script that changes the current color of the attached game object when the middle mouse button is scrolled.

This script is attached to a FPS rifle. After changing the rifle’s color, it fires a splatter prefab that needs to be the current color of the rifle. The splatter shoots away from the rifle’s ‘InstantiatePoint’ and rapidly cycles through different colors. When the splatter hits the ground or a wall, it is still its original color.

I need the splatter to change to the rifle’s current color when the rifle is fired, and remain that color.

Here is the Color Changer script:

using UnityEngine;

public class ColorChanger : MonoBehaviour

{

// The Array of Colors to cycle through

public Color[ ] colors = new Color[ ] { Color.red, Color.green, Color.blue };

private int currentIndex = 0; // Current color index

void Update()

{

// Checks for Mouse Wheel Input

float scroll = Input.GetAxis(“Mouse ScrollWheel”);

if (scroll != 0)

{

UpdateColorIndex(scroll);

UpdateObjectColor();

}

}

// Updates the Color Index, based on the scroll direction

void UpdateColorIndex(float scrollDirection)

{

if (scrollDirection > 0) // Scroll up

{

currentIndex = (currentIndex + 1) % colors.Length;

}

else if (scrollDirection < 0) // Scroll down

{

if (currentIndex == 0)

currentIndex = colors.Length - 1;

else

currentIndex–;

}

}

// Applies the selected color to the object’s Material

void UpdateObjectColor()

{

Renderer renderer = GetComponent();

if (renderer != null)

{

renderer.material.color = colors[currentIndex];

}

}

}

Hi rcottonjr,

I’m assuming you have a script somewhere that Instantiates the prefab whenever the rifle is fired. To get the splatter color to match the color of the rifle when it was fired, just set the color of the splatter to the rifle’s color when it’s instantiated.

Something like:

var newSplatter = Instantiate(prefab);
newSplatter.GetComponent<Renderer>.material.color = rifleRenderer.material.color;

To make this work, you need to add this to your color changer:
public Renderer rifleRenderer;
then drag in the renderer field in the editor.

Thank you very much for your help.

Do I add:

var newSplatter = Instantiate(prefab);
newSplatter.GetComponent.material.color = rifleRenderer.material.color;

to the script that fires the rifle?

I added:

public Renderer rifleRenderer;

to the Color Changer script:

using UnityEngine;

public class ColorChanger : MonoBehaviour

public Renderer rifleRenderer;

{

// The Array of Colors to cycle through

public Color[ ] colors = new Color[ ] { Color.red, Color.green, Color.blue };

private int currentIndex = 0; // Current color index

void Update()

{

// Checks for Mouse Wheel Input

float scroll = Input.GetAxis(“Mouse ScrollWheel”);

if (scroll != 0)

{

UpdateColorIndex(scroll);

UpdateObjectColor();

}

}

// Updates the Color Index, based on the scroll direction

void UpdateColorIndex(float scrollDirection)

{

if (scrollDirection > 0) // Scroll up

{

currentIndex = (currentIndex + 1) % colors.Length;

}

else if (scrollDirection < 0) // Scroll down

{

if (currentIndex == 0)

currentIndex = colors.Length - 1;

else

currentIndex–;

}

}

// Applies the selected color to the object’s Material

void UpdateObjectColor()

{

Renderer renderer = GetComponent();

if (renderer != null)

{

renderer.material.color = colors[currentIndex];

}

}

}

No problem.

The rifle is currently shooting the splatter prefabs, right? So the first step is step is to find where you are instantiating the splatter prefab. It will have a line that uses Instantiate() like my code does above. You’ll want to add var newSplatter = in front of the Instantiate function, then add the second line of my code above.

And sorry, the public Renderer rifleRenderer; needs to go in the same script as the Instantiate code. You will need to drag in the rifle’s renderer component into that field in the editor after you add that line. Let me know if this works!

Here is the script in full:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class SplatterBehavior : MonoBehaviour

{

[SerializeField]

GameObject splatterPrefab;

[SerializeField]

LayerMask hitableLayers;

public Renderer rifleRenderer;

private void OnCollisionEnter(Collision collision)

{

//Quaternion spawnRotation = Quaternion.LookRotation(collision.contacts[0].normal,Vector3.up);

if (Physics.Raycast(transform.position, collision.contacts[0].point - transform.position, out RaycastHit hit, 5f, hitableLayers, QueryTriggerInteraction.Ignore))

{

Vector3 trueForward = Vector3.Cross(transform.right, hit.normal);

var splatter = Instantiate(splatterPrefab, hit.point, Quaternion.LookRotation(trueForward, hit.normal));

{
splatter.GetComponent.material.color = rifleRenderer.material.color;
}

Destroy(splatter, 15);

}

Destroy(this.gameObject);

}

}

There is an error showing for the bolded logic. ‘Method not valid in given context’.

What am I missing or doing wrong?

Try this:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;



public class SplatterBehavior : MonoBehaviour

{

[SerializeField]

GameObject splatterPrefab;


[SerializeField]

LayerMask hitableLayers;


public Renderer rifleRenderer;



private void OnCollisionEnter(Collision collision)

{

//Quaternion spawnRotation = Quaternion.LookRotation(collision.contacts[0].normal,Vector3.up);

if (Physics.Raycast(transform.position, collision.contacts[0].point - transform.position, out RaycastHit hit, 5f, hitableLayers, QueryTriggerInteraction.Ignore))

{

Vector3 trueForward = Vector3.Cross(transform.right, hit.normal);


var splatter = Instantiate(splatterPrefab, hit.point, Quaternion.LookRotation(trueForward, hit.normal));

splatter.GetComponent<Renderer>().material.color = rifleRenderer.material.color;


Destroy(splatter, 15);

}

Destroy(this.gameObject);

}

}