- Home /
How to make the Colour parameter in coroutine work with any anything with a colour variable.
Hi, I'm trying to make a coroutine function where you can make sprites, images or text flash white. what I would do is put the script on the object, that has a SpriteRenderer, Image, text or a script with a colour variable, where I want to add that effect to, then make a script that has a public variable for the effect script and the SpriteRenderer, Image, text or a script component that has a colour variable and write it like this.
p1ColourFlash.Flash(p1CircleFill.color, 10f);
The problem is that colour parameter doesn't seem to work for some reason but if I use a Image parameter it works fine. The reason why I want to do this is that I want the flash colour script to be adaptable to anything that has a colour variable and don't have to keep writing the same function with a different parameter.
Here's the script for your perusal, thank you.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ColourFlash : MonoBehaviour
{
public Color flashColour = Color.white;
private bool canFlash = true;
IEnumerator ImageFlashIE(Image image, float flashSpeed)
{
canFlash = false;
Color oringnalColour = image.color;
float lerpTimer = 0f;
while (lerpTimer < 1)
{
image.color = Color.Lerp(image.color, flashColour, lerpTimer);
lerpTimer += Time.deltaTime * flashSpeed;
yield return null;
}
lerpTimer = 1f;
while (lerpTimer > 0)
{
image.color = Color.Lerp(oringnalColour, image.color, lerpTimer);
lerpTimer -= Time.deltaTime * flashSpeed;
yield return null;
}
image.color = oringnalColour;
canFlash = true;
}
public void ImageFlash(Image image, float flashSpeed)
{
if (canFlash)
{
StartCoroutine(ImageFlashIE(image, flashSpeed));
}
}
IEnumerator FlashIE(Color colour, float flashSpeed)
{
canFlash = false;
Color oringnalColour = colour;
float lerpTimer = 0f;
while (lerpTimer < 1)
{
colour = Color.Lerp(colour, flashColour, lerpTimer);
lerpTimer += Time.deltaTime * flashSpeed;
yield return null;
}
lerpTimer = 1f;
while (lerpTimer > 0)
{
colour = Color.Lerp(oringnalColour, colour, lerpTimer);
lerpTimer -= Time.deltaTime * flashSpeed;
yield return null;
}
colour = oringnalColour;
canFlash = true;
}
public void Flash(Color colour, float flashSpeed)
{
if (canFlash)
{
StartCoroutine(FlashIE(colour, flashSpeed));
}
}
}
Answer by ray2yar · Jul 08, 2020 at 02:14 AM
Can you explain what you mean by "flash white"? The first problem I'm seeing is that the default color is white to begin with- as in the texture or sprite renders exactly as originally drawn. I tested your code flashing red instead - it seemed to work fine when I specified SpriteRenderer. So this may be kind of hackish, and I'm sure there's a better way, but basically you could pass the GameObject to the function and check for each type of renderer and then get the color property of that renderer. I did this:
SpriteRenderer SpritePicture; Renderer TexturePicture;
public Color flashColour = Color.red;
private bool canFlash = true;
void Start()
{
Flash(0.5f, Color.white, gameObject);
}
IEnumerator FlashColor(float flashSpeed, Color OriginalColor)
{
canFlash = false;
Color oringnalColour = OriginalColor;
float lerpTimer = 0f;
while (lerpTimer < 1)
{
SetColorProperty(Color.Lerp(oringnalColour, flashColour, lerpTimer));
lerpTimer += Time.deltaTime * flashSpeed;
yield return null;
}
lerpTimer = 1f;
while (lerpTimer > 0)
{
SetColorProperty( Color.Lerp(oringnalColour, flashColour, lerpTimer));
lerpTimer -= Time.deltaTime * flashSpeed;
yield return null;
}
SetColorProperty(oringnalColour);
canFlash = true;
}
public void Flash(float flashSpeed, Color OriginalColor, GameObject GO)
{
SpritePicture = null;
TexturePicture = null;
if(GO.GetComponent<SpriteRenderer>() != null)
{
SpritePicture = GO.GetComponent<SpriteRenderer>();
}
if (GO.GetComponent<Renderer>() != null)
{
TexturePicture = GO.GetComponent<Renderer>();
}
canFlash = false;
StartCoroutine(FlashColor(flashSpeed, OriginalColor));
}
void SetColorProperty(Color c)
{
if (SpritePicture != null)
{
SpritePicture.color = c;
}
if (TexturePicture != null)
{
TexturePicture.material.color = c;
}
}
I say flash white as an example, and I'm not saying that you can only use white and What you would usually do is set the default colour in Sprite Renderer or Image, for example blue, then set what colour you want the Sprite or Image to flash to in the Flash colour script.
Then the script above does what you are describing. You just would need to add a check for the Text you wanted.
Answer by Eno-Khaon · Jul 08, 2020 at 03:48 AM
In C#, a class will typically be passed by reference while a struct will typically be passed by value. Of note, a Color is a struct, while all your examples which utilize a Color are classes.
Because of this, defining a Color will only prepare a new one for use. You can't share a struct under normal, basic circumstances. Similarly, you also can't pass a struct from another class by reference.
Unfortunately, this largely limits your options in how you can handle this. You basically have the right idea, it just might help to try and combine as much of it as you can for reuse, if they're all intended to function in the same manner. Ultimately, because of using an IEnumerator, there's not really much room to separate necessary local variables out of those functions (while keeping things otherwise simple), so there might not be any especially simple means of keeping things cheap to process while also reusable.
Sorry for the late response, thanks for letting me know that.