Events and Instantiated Prefabs

Hi guys !

I’m still trying my best with Unity and I’m trying to understand events. To train I tried to use an event on my obstacle ; once it’s passed it Invokes “OnObstaclePassed” event, which my GameManager is subscribed to. My objective was to update my score like this.

However, it only updates once, and then nothing. I’m guessing my GameManager is not subscribed to the next instances of prefabs that spawn, since I subscribe in the Start method.

Do you know how I could solve that ? (While keeping events)

Here is my GameManager

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

public class GameManager : MonoBehaviour
{
    Obstacle obstacle; 
    [SerializeField] private int score = 0;
    public GameObject obstaclePrefab; 
    public TextMeshProUGUI scoreText;
    public float spawnInterval = 2.0f;


    void Start()
    {
        obstacle = FindObjectOfType<Obstacle>();    
        obstacle.OnPlayerPassedObstacle += UpdateScore;
    }

    // Update is called once per frame
    void Update()
    {

       


       if (Time.time >= spawnInterval)

        {
            
            spawnObstacle();
            spawnInterval += 2.0f;


        }
    }

    void UpdateScore()
    {
        score++; 
        scoreText.text = score.ToString();
    }

  


    private void spawnObstacle()
    {
        Instantiate(obstaclePrefab, new Vector3(obstaclePrefab.transform.position.x, obstaclePrefab.transform.position.y, 10), Quaternion.identity);
    }
}

You would need to subscribe to the event as you instantiate these obstacles.

The Instantiate method returns the instantiated object. You can use this to do any work you need with it after it has been instanced.

This will be easier if you reference the prefab by a component on it, rather than as a game object. Just referencing as a game object usually isn’t very useful.

So reference it as so (will likely need to drag the prefab into the field, if you’re not using the new object selector):

[SerializeField]
private Obstacle obstaclePrefab;

Then when you instance it, it will copy the whole prefab and return a reference to the new component. At which you can then subscribe to the delegate:

private void spawnObstacle()
{
	Vector3 position = //calculate position
	var obstacleInstance = Instantiate(obstaclePrefab, position, Quaternion.identity);
	obstacleInstance.OnPlayerPassedObstacle += UpdateScore;
}