CLONING COLORS QUEST: ‘Flashy Coin’ - Solutions

Quest: Cloning Colors Quest
Challenge: Flashy Coin

Feel free to share your solutions, ideas and creations below. If you get stuck, you can find some ideas here for completing this challenge.

There may be a better way, but I made it like this.

using System.Collections;
using UnityEngine;

public class CoinController : MonoBehaviour
{
    private bool isBlink;
    private float elapsedTime;
    private ColorChanger myColorChanger;
    private SpriteRenderer mySpriteRenderer;
    private Coroutine blinkCoroutine;

    private void Start()
    {
        myColorChanger = GetComponent<ColorChanger>();
        mySpriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Update()
    {
        if (isBlink)
        {
            mySpriteRenderer.color = new Color(mySpriteRenderer.color.r, mySpriteRenderer.color.g, mySpriteRenderer.color.b,
                Mathf.Lerp(1.0f, 0.0f, Mathf.PingPong(elapsedTime * 2, 1)));
            elapsedTime += Time.deltaTime;
        }
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        ColorChanger otherColorChanger = other.GetComponent<ColorChanger>();
        if (otherColorChanger == null)
            return;

        if (otherColorChanger.blockColor == myColorChanger.blockColor)
        {
            Destroy(gameObject);
        }
        else
        {
            if (blinkCoroutine == null)
                blinkCoroutine = StartCoroutine(StartBlink());
        }
    }

    private IEnumerator StartBlink()
    {
        elapsedTime = 0.0f;
        isBlink = true;
        
        yield return new WaitForSeconds(2.0f);
        
        isBlink = false;
        blinkCoroutine = null;
    }
}
4 Likes

I used 2 animations for this challenge. The first one is Idle, with alpha set to 1, and the second animation is changing the alpha value from 1 to 0 to 1. I used a coroutine for this.

using System.Collections;
using UnityEngine;

public class CoinCollection : MonoBehaviour
{
    private SpriteRenderer mySpriteRenderer;
    private Animator animator;
    private void Start()
    {
        mySpriteRenderer = GetComponent<SpriteRenderer>();
        animator = GetComponent<Animator>();
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.CompareTag("Coin"))
        {
            Color blockColor = mySpriteRenderer.color;
            Color coinColor = collision.gameObject.GetComponent<SpriteRenderer>().color;
            if (!blockColor.Equals(coinColor))
            {
                StartCoroutine(ChangeAlpha());
            }
            else
            {
                Destroy(collision.gameObject);
            }
        }
    }

    private IEnumerator ChangeAlpha()
    {
        animator.Play("alphaChanging");
        yield return new WaitForSeconds(1);
        animator.Play("Idle");
    }
}

2 Likes

My new solution

public class FlashCoin : MonoBehaviour
{
    private SpriteRenderer mySpriteRenderer;
    private bool isColliding = false;

    private void Start()
    {
        mySpriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Update()
    {
        if (isColliding)
        {
            StartCoroutine(CollidWithCoin());
        }
    }

    private void OnTriggerStay2D(Collider2D collision)
    {
        if(collision.gameObject.CompareTag("Block") && collision.gameObject.GetComponent<SpriteRenderer>().color != mySpriteRenderer.color)
        {
            isColliding = true;
        }
    }

    private IEnumerator CollidWithCoin()
    {
        Color color = mySpriteRenderer.color;
        color.a = Mathf.PingPong(Time.time, 1);
        mySpriteRenderer.color = color;
        yield return new WaitForSecondsRealtime(.5f);
        color.a = 1;
        mySpriteRenderer.color = color;
        isColliding = false;
    }
}

You’ll multicall the Coroutine in this solution calling it from Update…

I’d usually do something like this in the animator, but since the whole point is to challenge myself, I gave doing it in script a shot.

I started by using lerp to smoothly change the alpha, with it slowing as it approached the min and max. I didn’t like the way it looked. So I changed it to smoothly adjust the alpha at a constant rate and I’m much happier with this:

void Update()
{
    if (!isFlashing) return;

    tempColour = spriteRenderer.color;
    if (tempColour.a < 0.31f)
    {
        tempColour.a = 0.31f;
        flashSpeed = -flashSpeed;
    }
    else if (tempColour.a > 0.99f)
    {
        tempColour.a = 0.99f;
        flashSpeed = -flashSpeed;
    }
    tempColour.a += flashSpeed * Time.deltaTime;
    spriteRenderer.color = tempColour;
}

OnTriggerEnter and Exit turn that isFlashing bool flag on and off.

1 Like

Here is my approach with everything placed in an OnTriggerEnter method that caches/compares the coin/block colors to either destroy the coin or start a Coroutine. The blink quality is controlled by the WaitForSeconds value (0.25) and the blink duration by the For Loop number (3 blinks). Admittedly not the prettiest of effects…

public class CoinController : MonoBehaviour
{
    void OnTriggerEnter2D(Collider2D other)
    {
        Color coinColor = GetComponent<SpriteRenderer>().color;    
        Color blockColor = other.gameObject.GetComponent<SpriteRenderer>().color;

        if (blockColor == coinColor)
        {
            Destroy(gameObject);
        }
        else
        {
            StartCoroutine(Blink());
        }

        IEnumerator Blink()
        {
            for (int i = 0; i < 3; i++)
            {
                blockColor = new Color(blockColor.r, blockColor.g, blockColor.b, Mathf.PingPong(Time.time, 0));
                other.gameObject.GetComponent<SpriteRenderer>().color = blockColor;
                yield return new WaitForSeconds(0.25f);

                blockColor = new Color(blockColor.r, blockColor.g, blockColor.b, Mathf.PingPong(Time.time, 255));
                other.gameObject.GetComponent<SpriteRenderer>().color = blockColor;
                yield return new WaitForSeconds(0.25f);
            }
        }
    }
}
1 Like