Search Unity

Player and Enemy no longer collide after resetting scene

Discussion in 'Scripting' started by CaringKarol, Aug 12, 2019.

  1. CaringKarol

    CaringKarol

    Joined:
    Jan 22, 2018
    Posts:
    28
    Hi, I was wondering if anyone could help me. I have a reset button that resets the entire level. Before this button is pressed, all collisions work properly. However, once I have the scene reset (SceneManager.LoadScene(SceneManager.GetActiveScene().name);) , the game doesn't register any collisions the object tagged as "Player" and objects tagged as "Enemy" have with each other. Every other collision works.

    I'm not sure if this will help, but the circle colliders the enemies have are triggers.

    Thanks.
     
    sofiykafedor_unity likes this.
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    What's different between the first and second time the scene is loaded? Do you have anything that is DontDestroyOnLoad? Do you have non-Unity classes that do their initialization at program startup rather than when the scene is loaded?
     
    Joe-Censored likes this.
  3. CaringKarol

    CaringKarol

    Joined:
    Jan 22, 2018
    Posts:
    28
    No, I don't have any of those.
    The only things I have (in the Start function) are setting up variables that still work when I reset the scene and one function that counts the amount of items in the scene (which works as well
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Are any of your variables marked static ? Those don't reset when the scene is reloaded unless code actually changes them back to their default values.
     
  5. CaringKarol

    CaringKarol

    Joined:
    Jan 22, 2018
    Posts:
    28
    The only variable I have that's static is one that references my entire GameManager script, but every command that I've done that requires it still works.
     
  6. CaringKarol

    CaringKarol

    Joined:
    Jan 22, 2018
    Posts:
    28
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class EnemyController : MonoBehaviour
    6. {
    7.     public float enemyHealth;
    8.  
    9.     private void OnTriggerEnter2D(Collider2D other)
    10.     {
    11.         if (other.gameObject.tag == "Player")
    12.         {
    13.             other.gameObject.GetComponent<Health>().health -= 1;
    14.             StartCoroutine(other.gameObject.GetComponent<Invulnerability>().Invulnerable());
    15.         }
    16.     }
    17.  
    18.     private void OnCollisionEnter2D(Collision2D other)
    19.     {
    20.         if (other.gameObject.tag == "Player")
    21.         {
    22.             other.gameObject.GetComponent<Health>().health -= 1;
    23.             StartCoroutine(other.gameObject.GetComponent<Invulnerability>().Invulnerable());
    24.         }
    25.     }
    26. }
    This is the code I have with my enemy

    Code (CSharp):
    1. public void RestartLevel()
    2.     {
    3.         SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    4.         Time.timeScale = 1f;
    5.     }
    and this is just a snippet of the code I use when restarting the level/scene
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    It may be "still working" because that variable is pointing to the OLD GameManager, and now that you reloaded you created a new one, or vice-versa. That's what @Antistone above noted, asking about the DontDestroyOnLoads(). Be sure you either implement a singleton pattern properly, or don't implement it at all, which ever is appropriate.
     
  8. CaringKarol

    CaringKarol

    Joined:
    Jan 22, 2018
    Posts:
    28
    Okay. If you don't mind me asking, how could I implement a singleton pattern properly? Or should I just not implement it into my code?
     
  9. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    If you're getting different behavior, then something is different. Even if none of my guesses about the nature of that difference turn out to be correct, you still need to figure out what the difference is.

    If you've got no idea what it is, focus on the part of your game that isn't behaving as expected, and start doing tests to narrow down the problem. Does the EnemyController exist? Is the player still tagged as a "Player"? Is it really that the collision isn't happening, or are you just not seeing the results--maybe because the player's health display is broken?

    You can learn a lot by adding some well-chosen Debug.Log() commands into your code.
     
  10. CaringKarol

    CaringKarol

    Joined:
    Jan 22, 2018
    Posts:
    28
    Okay, I'll try that. Thank you.
     
  11. CaringKarol

    CaringKarol

    Joined:
    Jan 22, 2018
    Posts:
    28
    I found the issue. I really appreciate both of your guys' help! :)
     
  12. RedForceFT

    RedForceFT

    Joined:
    Aug 5, 2019
    Posts:
    19
    I have the same problem when a new level is loaded. Can you tell us how to fix it?
     
  13. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    This is a great question and in Unity there are a few options.

    The simplest thing is a non-Unity singleton: basically every C# way of doing singletons. There is only ever one, that's it. Things that fall into this might be ApplicationContext for instance.

    The next simplest is a UnitySingleton, of which there are many open source implementations. It is code-wise like a singleton (only one exists), but it is a MonoBehavior so it can interoperate with Unity stuff for the life of your game. This would be your typical GameManager. Here's one example: https://wiki.unity3d.com/index.php/Singleton You might want to tweak it for your own preferences.

    Finally there's one that I call a SceneSingleton, which basically allows itself to be destroyed when the scene changes, but when a new scene comes in, it only allows one of itself, like maybe an EnemyManager or a MissionManager. You don't need them to live forever, but for a given scene, you want them to persist and be unitary.
     
  14. CaringKarol

    CaringKarol

    Joined:
    Jan 22, 2018
    Posts:
    28
    Ohhh okay thank you!
     
  15. CaringKarol

    CaringKarol

    Joined:
    Jan 22, 2018
    Posts:
    28
    Oh, it was because of one of my invulnerability scripts. It turns out I never made the player stop ignoring the enemy layer when it collided.
     
    Rules101 and Remy-Limelight like this.
  16. Remy-Limelight

    Remy-Limelight

    Joined:
    Dec 3, 2019
    Posts:
    1
    What a legend!! i would have sat here for days trying to figure out that it was because of the invulnerability... I just created a function that resets the player collisions on start... this fixed my problem