What am I doing wrong??

I am completely new to Unity and have minimal experience with coding. I thought I could acquaint myself with Unity by following a tutorial by the Renaissance Coders on YouTube to recreate the game Flappy Bird.

This is the code for the “Tap Controller” that controls the bird. Starting on Line 59, there is code to decide what happens when the bird hits an object or scorezone. OnPlayerScored(); and OnPlayerDied(); events are supposed to be sent to the game manager but nothing happens. I have checked the code for errors but I can’t seem to find anything that is wrong! (Game Manager code is on line 56 through line 68). Any help would be much appreciated!

Tap Controller:

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

[RequireComponent(typeof(Rigidbody2D))]
public class TapController : MonoBehaviour {

    public delegate void PlayerDelegate();
    public static event PlayerDelegate OnPlayerDied;
    public static event PlayerDelegate OnPlayerScored;

    public float tapForce = 10;
    public float tiltSmooth = 5;
    public Vector3 startPos;
    new Rigidbody2D rigidBody;
    Quaternion downRotation;
    Quaternion forwardRotation;

    GameManager game;

void Start(){
    rigidBody = GetComponent<Rigidbody2D>();
    downRotation = Quaternion.Euler(0, 0, -90);
    forwardRotation = Quaternion.Euler(0, 0, 35);
    game = GameManager.Instance;
    rigidBody.simulated = false;
}

void OnEnable() {
    GameManager.OnGameStarted += OnGameStarted;
    GameManager.OnGameOverConfirmed += OnGameOverConfirmed;
}

void OnDisable() {
    GameManager.OnGameStarted -= OnGameStarted;
    GameManager.OnGameOverConfirmed -= OnGameOverConfirmed;
}

void OnGameStarted(){
    rigidBody.velocity = Vector3.zero;
    rigidBody.simulated = true;
}

void OnGameOverConfirmed() {
    transform.localPosition = startPos;
    transform.rotation = Quaternion.identity;
}

void Update(){
    if (game.GameOver) return;
    if (Input.GetMouseButtonDown(0)){
        transform.rotation = forwardRotation;
        rigidBody.velocity = Vector2.zero;
        rigidBody.AddForce(Vector2.up * tapForce, ForceMode2D.Force);
    }
   
    transform.rotation = Quaternion.Lerp(transform.rotation, downRotation, tiltSmooth * Time.deltaTime);
}
    public void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.tag == "Scorezone")
        {
            //register a score event
            OnPlayerScored(); //event sent to game manager;
                              //play sound
        }

        if (col.gameObject.tag == "Deadzone")
        {
            rigidBody.simulated = false;
            //play a sound
            //register a dead event
            OnPlayerDied(); //event sent to game manager

        }
    }

}

Game Manager:

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

public class GameManager : MonoBehaviour {

    public delegate void GameDelegate();
    public static event GameDelegate OnGameStarted;
    public static event GameDelegate OnGameOverConfirmed;

    public static GameManager Instance;

    public GameObject StartPage;
    public GameObject GameOverPage;
    public GameObject CountdownPage;
    public Text ScoreText;

    enum PageState {
        None,
        Start,
        GameOver,
        Countdown
    }

    int score = 0;
    bool gameOver = true;

    public bool GameOver { get { return gameOver; } }
    public int Score { get { return score; } }

    void Awake() {
        Instance = this;
    }

    void OnEnable()
    {
        CountdownText.OnCountdownFinished += OnCountdownFinished;
        TapController.OnPlayerDied += OnCountdownFinished;
        TapController.OnPlayerScored += OnCountdownFinished;
    }

    void OnDisable() {
        CountdownText.OnCountdownFinished -= OnCountdownFinished;
        TapController.OnPlayerDied -= OnCountdownFinished;
        TapController.OnPlayerScored -= OnCountdownFinished;
    }

    void OnCountdownFinished() {
        SetPageState(PageState.None);
        OnGameStarted();
        score = 0;
        gameOver = false;
    }

    void OnPlayerDied() {
        gameOver = true;
        int savedScore = PlayerPrefs.GetInt("HighScore");
        if (score > savedScore) {
            PlayerPrefs.SetInt("HighScore", score);
        }
        SetPageState(PageState.GameOver);
    }

    void OnPlayerScored() {
        score++;
        ScoreText.text = score.ToString();
    }

    void SetPageState(PageState state) {
        switch (state) {
            case PageState.None:
                StartPage.SetActive(false);
                GameOverPage.SetActive(false);
                CountdownPage.SetActive(false);
                break;
           
            case PageState.Start:
                StartPage.SetActive(true);
                GameOverPage.SetActive(false);
                CountdownPage.SetActive(false);
                break;

            case PageState.GameOver:
                StartPage.SetActive(false);
                GameOverPage.SetActive(true);
                CountdownPage.SetActive(false);
                break;
           
            case PageState.Countdown:
                StartPage.SetActive(false);
                GameOverPage.SetActive(false);
                CountdownPage.SetActive(true);
                break;
        }
    }

    public void ConfirmGameOver() {
        //activated when restart button is hit
        OnGameOverConfirmed(); //events
        ScoreText.text = "0";
        SetPageState(PageState.Start);
    }

    public void StartGame() {
        //activated when play button is hit
        SetPageState(PageState.Countdown);
    }

    }

Thanks in advance ;)!

Welcome!

Start inserting many Debug.Log() statements throughout your code in order to determine which code is actually running. Just typing in some code does not cause it to run. Unity is about 10% coding and 90% setting up your scene to work properly with the scripts.

Ain’t ontriggerenter private ?

Trigger events are only sent if one of the Colliders also has a Rigidbody2D attached. Trigger events are sent to disabled MonoBehaviours, to allow enabling Behaviours in response to collisions.

Thanks for the tip - I’ll try it and see what happens. In case this helps, I used Visual Studio and added breaks into the code to see what was actually running. For example, Line 70 of the Tap Manager would only execute if the following OnPlayerDied(); wasn’t there. Once I added OnPlayerDied(); back nothing would happen :(. Also, the Game Manager script on Line 56 says “Private Member ‘GameManager.OnPlayerDied’ is unused.” Same message on Line 65. I appreciate the help!

Hey! I don’t understand exactly what you mean. Line 59 of Tap Controller says:
public void OnTriggerEnter2D(Collider2D col)
Simply writing “public” should make it public, right? Anyways: My bird has a Rigidbody2D. The bird, pipes, and ground have Circle/Box Collider 2D on them. Thank you for helping me!

I mean private because like start and update you cant make it public …so the i think you put it as public won’t work as the system is calling it automatically? Not sure…
And what is the reason to set it for public …?

I’m afraid I don’t know much. Like I said, I’m a beginner and I’ve been following a tutorial on YouTube. The tutorial was made 3 years ago (has C# changed since then?) and their code definitely works as I’ve downloaded their Flappy Bird app and played it. I followed the tutorial and I have no idea why it isn’t working. Do you have any thoughts on what I should change exactly? Thanks again for your help!

Hey my fault sorry lol when I first reply I hardly had any sleep I thought the problem was ontriggerenter not working.my fault sorry . And you could try to use action instead of delegate

and double check the tags see it is set up correctly

public void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.tag == "Scorezone")
        {
            //register a score event
            OnPlayerScored(); //event sent to game manager;
                              //play sound
        }
        if (col.gameObject.tag == "Deadzone")
        {
            rigidBody.simulated = false;
            //play a sound
            //register a dead event
            OnPlayerDied(); //event sent to game manager
        }
    }

Is the other GameObjects have the correct tag on them ?

Yup, they are tagged the same as the code says: “Scorezone” and “Deadzone”. When you say use action instead of delegate, does that mean I should write public action void PlayerDelegate(); instead of public delegate void PlayerDelegate();?

1 Like
void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.tag == "Scorezone")
        {
             Debug.Log("Scorezone");
            //register a score event
            OnPlayerScored(); //event sent to game manager;
                              //play sound
        }
        if (col.gameObject.tag == "Deadzone")
        {
             Debug.Log("Deadzone");
            rigidBody.simulated = false;
            //play a sound
            //register a dead event
            OnPlayerDied(); //event sent to game manager
        }
    }

Can you try this? And check the console see if the log have come up when you trigger
For action you could do this

Public static Action Onsomething;

void something()
{
    If(Onsomething != null)
        {
           Onsomething();
         }
}
void listener()
{
   Onsomething += methodA;
   Onsomething  += methodB;
 }

Note need using System; for action

Sorry, was away from my cpu for a few days. I tried it, and the console says this:
Scorezone
UnityEngine.Debug:Log(Object)
and
Deadzone
UnityEngine.Debug:Log(Object)
Does that mean anything?

Hey it mean trigger working fine
I’ve just look at you code again I think I know now whats wrong

        CountdownText.OnCountdownFinished += OnCountdownFinished;
        TapController.OnPlayerDied += OnCountdownFinished;
        TapController.OnPlayerScored += OnCountdownFinished

Should be

        CountdownText.OnCountdownFinished += OnCountdownFinished;
        TapController.OnPlayerDied += OnPlayerDied;
        TapController.OnPlayerScored += OnPlayerScored;

You set it up wrong thats why it didn’t get called .

Thank you so much!!! I didn’t realize before that those lines were wrong but now it makes sense. It works perfectly now!