Ben Parry
Ben Parry

Reputation: 141

OnTriggerEnter called multiple times

This counter would randomly increment. It's driving me crazy.

When the player picks up all the game objects on the level (10), the level should restarts again.

That works, however, randomly with picking up objects it can either add +1 to the score, which is expected, or +2.

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class Pickup : MonoBehaviour {

    //Required Variables
    public GameObject pointsObject;
    public Text scoreText;

    private int score;
    private int scoreCount;

    void Start()
    {
        score = 0;
        SetScoreText();
        scoreCount = GameObject.FindGameObjectsWithTag("Pickups").Length;
    }

    void Update()
    {
        if(score >= scoreCount)
        {
            Scene scene = SceneManager.GetActiveScene();
            SceneManager.LoadScene(scene.name);

        }
        SetScoreText();
        Debug.Log("Found " + scoreCount + " Pickup Objects!");
    }

    void OnTriggerEnter(Collider col)
    {
        if(col.gameObject.CompareTag("Pickups"))
        {
            Destroy(col.gameObject);
            score++;
        }
    }

    void SetScoreText()
    {
        scoreText.text = "Score: " + score.ToString();
    }
}

Can anyone see why I'm having this issue, as I can't see the reason why at all. Thanks in advance.

Upvotes: 3

Views: 9819

Answers (2)

TSteff
TSteff

Reputation: 31

Not to revive a dead thread, but I ran into this issue recently. Bullets would count twice when triggered. Found out it was because both object had colliders with OnTrigger enabled. I placed the enemyHitbox collider on a separate layer (to not collide with anything else) and set it to OnTrigger false, while the playerBullet was set to OnTrigger true. This resolved the issue for me.

I'm assuming that both objects somehow caused a trigger event even though it was set for one hitting another with a set tag.

Hope this helps someone with a similar issue.

Using Unity2020 at this point btw.

Upvotes: 3

Programmer
Programmer

Reputation: 125275

This would have been a case of attaching the Pickup script to multiple GameObjects but I don't think so because the Pickup script would then have multiple instances and the score wont be incremented as mentioned in your question.

Since that is eliminated, it is very likely that you have more than 1 colliders (whether trigger or not) attached the GameObjects. This causes the OnTriggerEnter function to be called multiple times.

You have 2 solutions:

1.Find the duplicated colliders and remove them from the GameObjects. Check this on the Pickups GameObjects and other GameObjects they collider with.

2.Modify your code and make it understand there is a duplicated collider.

You can do this by making a list to store each of those 10 Pickups each time the OnTriggerEnter function is called. Check if collided GameObject exist in the List. If it exist in the List, don't increment. If it does not exist in the List, increment then add it to the List. This is very simple and easy logic to implement. Not tested but should work.

The code below is what it should look like if you go with solution #2.

public class Pickup : MonoBehaviour
{

    //Required Variables
    public GameObject pointsObject;
    public Text scoreText;

    private int score;
    private int scoreCount;

    List<GameObject> pickups = new List<GameObject>();

    void Start()
    {
        score = 0;
        SetScoreText();
        scoreCount = GameObject.FindGameObjectsWithTag("Pickups").Length;
    }

    void Update()
    {
        if (score >= scoreCount)
        {
            Scene scene = SceneManager.GetActiveScene();
            SceneManager.LoadScene(scene.name);

        }
        SetScoreText();
        Debug.Log("Found " + scoreCount + " Pickup Objects!");
    }

    void OnTriggerEnter(Collider col)
    {
        if (col.gameObject.CompareTag("Pickups"))
        {
            //Increment if the gameObject is [not] already in the List
            if (!pickups.Contains(col.gameObject))
            {
                Destroy(col.gameObject);
                score++;
                //Now Add it to the List
                pickups.Add(col.gameObject);
            }
        }
    }

    //Call this after GameOver to clear List
    void resetPickupsList()
    {
        pickups.Clear();
    }

    void SetScoreText()
    {
        scoreText.text = "Score: " + score.ToString();
    }
}

Upvotes: 0

Related Questions