Made the Color on collision first change than transition back to initial

Used a timer instead of a Coroutine

ezgif-2-eb1966b76e

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectHit : MonoBehaviour
{
    [SerializeField] private float collisionColorDuration = 3f;
    [SerializeField] private Color collisionColor = Color.black;
    private Color initialColor;
    private MeshRenderer meshRenderer;
    private float transitionTimer = 0f;
    private bool isTransitioning = false;

    private void Awake() {
        meshRenderer = GetComponent<MeshRenderer>();
    }

    private void Update() {
        if(isTransitioning) {
            TransitionColor();
        }
    }

    private void OnCollisionEnter(Collision collision) {
        initialColor = meshRenderer.material.color;
        meshRenderer.material.color = collisionColor;
        isTransitioning = true;
    }

    private void ResetColor() {
        meshRenderer.material.color = initialColor;
    }

    private void TransitionColor() {
        transitionTimer += Time.deltaTime;
        float timeFraction = transitionTimer / collisionColorDuration;
        if (timeFraction < 1) {
            float r, g, b, a;
            r = Mathf.Lerp(collisionColor.r, initialColor.r, timeFraction);
            g = Mathf.Lerp(collisionColor.g, initialColor.g, timeFraction);
            b = Mathf.Lerp(collisionColor.b, initialColor.b, timeFraction);
            a = Mathf.Lerp(collisionColor.a, initialColor.a, timeFraction);
            meshRenderer.material.color = new Color(r, g, b, a);
        } else {
            isTransitioning = false;
            transitionTimer = 0f;
        }
    }
}

…and then learned that it’s easier with Color.Lerp

3 Likes

Great job with the code. It looks clean. How are you feeling about your code?

I’ve started (slowly) reading up on Clean Coding, so hopefully I’m getting better :crossed_fingers:

Hey there. I’m new to coding so I was wondering if I could ask you some questions about your code.

  1. In your method for TransitionColor
    You had to use Red, Blue, Green, and Alpha because you need to reset each color? Basically to reset to your original color?

  2. And you say you found it easier with color.lerp at the end of your post. How do you set your walls to one of the colors in the list? Because the code I read (on the link you have) says transitions from one defined color to another defined color. But we picked our own color for the walls in the beginning, so again; how would you set your walls to one of the defined colors in the list?

Thank you so much for your post. I would have never thought to do that. Your animated gif looks great of the walls changing color and then changing back to normal. Very professional looking.

Cheers.
H,

Hey @Tooncis,

Glad you’ve enjoyed the post, happy to see some engagement :slight_smile:
Let me try and do my best in answering your questions.
Keep in mind that I’m also “new”.

In Unity, Color has 4 components as you can see either in the docs or in the Editor:

  • red - Color.r
  • green - Color.g
  • blue - Color.b
  • alpha - Color.a

As per docs: “Components (r,g,b) define a color in RGB color space. Alpha component (a) defines transparency - alpha of one is completely opaque, alpha of zero is completely transparent.”

And since you can’t edit a color component (r, g, b, a) directly I’ve used 4 float variables to store the wanted change and then assign the change with meshRenderer.material.color = new Color(r, g, b, a);

The Mathf.Lerp is there to interpolate from one color’s components to another color’s components which results in interpolating the color itself.

I only learned about Color.Lerp after I’ve already implemented the component Lerp. We would need fewer lines of code if we use Color.Lerp (just 1 line) instead of what I’ve used - Mathf.Lerp on each of the Color components.

Here’s an example of it on YouTube:

There are two Color variables in my ObjectHit script:

  • [SerializeField] private Color collisionColor = Color.black;
  • private Color initialColor;

The Color.black is usually overridden with whatever color you pick in the Editor since the Color collisionColor is serialized.

And the initialColor is used to store the default Color of your obstacle to which this script is attached to.

The logic in the script is:

  • Awake - get a reference to the meshRenderer of your obstacle object
  • OnCollisionEnter - remember the initial Color, change the current one to the collisionColor and start the transition from the collisionColor back to the initialColor with a timer.

Hope I was able to give you some insight into how I approached it.

Feel free to ask more questions if it’s still unclear, will do my best to help.

Cheers,

1 Like

Privacy & Terms