I need help with combo score

Hi All,

I’m sorry if my question seems weird, I’m new to Unity and C#. My first game includes bunches of different game objects that the player should click on them. I stuck for my combo score.

It is working when the player clicks on the same game object three times and each time will gain a combo score. The problem is that I don’t want to write code for each game object with its tag separately. I want to group them and then tell the group to find similar tags and then just by hitting similar tags the player gains a combo score. Is it possible?

public IEnumerator ClickContorller()
{
    
    while (true)
    {
       
        yield return new WaitForSeconds(0.01f);

        if (Input.GetMouseButtonDown(0))
        {
            Vector2 mousePos2D = Camera.main.ScreenToWorldPoint(Input.mousePosition);

            RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero);

            if (hit.collider != null)
            {

                if (counter == 0)
                {
                    if (hit.collider.gameObject.tag == "Burger")
                    {
             
                        counter = 1;
                        Debug.Log("count 1");
                       
                    }
                }
                else if (counter == 1)
                {
                    if (hit.collider.gameObject.tag == "Burger")
                    {
                        counter = 2;
                        Debug.Log("count 2");
                        GainScore(2);
                       

                    }

                    else if (hit.collider.gameObject.tag != "Burger")
                    {
                        counter = 0;
                     

                    }

                }
                else if (counter == 2)
                {
                    if (hit.collider.gameObject.tag == "Burger")
                    {
                        counter = 3;
                    
                        Debug.Log("count 3");
                        GainScore(4);

                    }
                    else if (hit.collider.gameObject.tag != "Burger")
                    {
                        counter = 0;
                       
                    }

                }
                else
                {
                    counter = 0;
                   

                    yield return new WaitForSeconds(0.01f);
                }

                    Destroy(GameObject.Find(hit.collider.gameObject.name));
                    GainScore(1);
            }

        }

    }

}

public void GainScore(int score)
{
    currentScore += score;

    scoreScr.SetScore(currentScore);
}

}

Hi!

Yes, it certainly is! If you have a variable store the tag of the last collected object, you should have a system that will work with any number of objects:

private string lastCollectedObject = "";

public IEnumerator ClickContorller()
{
    while (true)
    {
        yield return null;

        if (Input.GetMouseButtonDown(0))
        {
            Vector2 mousePos2D = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero);

            if (hit.collider != null)
            {
                if (lastCollectedObject == hit.collider.gameObject.tag)
                {
                    counter += 1;

                    Debug.Log($"count {counter}");
                    GainScore((counter - 1) * 2);
                }
                else
                {
                    counter = 0;
                    lastCollectedObject = hit.collider.gameObject.tag;
                }

                GainScore(1);
                Destroy(hit.collider.gameObject);
            }
            else
            {
                counter = 0;
                lastCollectedObject = "";
            }
        }
    }
}

P.S. There was also a scenario where you would have 2 yield return new WaitForSeconds(0.01f);s in a row. This means that sometimes your controller might not register one of your clicks.

I also replaced it with yield return null; as that will always wait for the next frame: if your player has a beast PC (anything over 100fps in this case), there would be a constant risk of missing inputs.

In fact, moving the code in your Coroutine into the Update function would probably simplify things considerably (no while(true) loop, no worrying about yield returning, no need to start the coroutine…)

Hope this helps! :slight_smile: