Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

minus life function called more than once

Discussion in 'Scripting' started by HarryWhitelegg02, Mar 18, 2020.

  1. HarryWhitelegg02

    HarryWhitelegg02

    Joined:
    Mar 11, 2020
    Posts:
    39
    For some reason whenever my player dies in my 2D platformer game, he randomly gets two lives taken off of him and sometimes its only 1 life is taken, super confused. If someone could help would be much appreciated.

    Code for the kill floor
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class Dead : MonoBehaviour
    5. {
    6.     public GameMaster gameMaster;
    7.     public GameObject player;
    8.     public GameObject pickup1;
    9.     public GameObject pickup2;
    10.     public GameObject pickup3;
    11.     public GameObject pickup4;
    12.     public GameObject pickup5;
    13.     void OnTriggerEnter2D(Collider2D other)
    14.     {
    15.         if (other.gameObject.tag == "Player")
    16.         {
    17.          
    18.                 Debug.Log("Died");
    19.                 gameMaster.RespawnPlayer();
    20.                 other.gameObject.GetComponent<PlayerMovement>().Die();
    21.             pickup1.gameObject.SetActive(true);
    22.             pickup2.gameObject.SetActive(true);
    23.             pickup3.gameObject.SetActive(true);
    24.             pickup4.gameObject.SetActive(true);
    25.             pickup5.gameObject.SetActive(true);
    26.             pickup1.gameObject.GetComponent<GemObject>()._alreadyLooted = false;
    27.             pickup2.gameObject.GetComponent<GemObject>()._alreadyLooted = false;
    28.             pickup3.gameObject.GetComponent<GemObject>()._alreadyLooted = false;
    29.             pickup4.gameObject.GetComponent<GemObject>()._alreadyLooted = false;
    30.             pickup5.gameObject.GetComponent<GemObject>()._alreadyLooted = false;
    31.         }
    32.     }
    33. }
    Code for the player:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using UnityEngine.SceneManagement;
    6.  
    7.  
    8. public class PlayerMovement : MonoBehaviour
    9. {
    10.  
    11.     public CharacterController2D controller;
    12.     public float runSpeed = 40f;
    13.     public Animator animator;
    14.     float horizontalMove = 0f;
    15.     bool jump = false;
    16.     public Text livesText;
    17.  
    18. // Manage your max and current lives
    19.     [SerializeField] private int maxLives = 3; // settable through the inspector
    20.     private static int currentLives;
    21.  
    22.     void Start()
    23.     {
    24.         // Create a temporary reference to the current scene.
    25.         Scene currentScene = SceneManager.GetActiveScene();
    26.  
    27.         // Retrieve the name of this scene.
    28.         string sceneName = currentScene.name;
    29.  
    30.         if (sceneName == "Level_1")
    31.         {
    32.             livesText.text = "Lives: " + maxLives;
    33.             currentLives = maxLives;
    34.         }
    35.         else livesText.text = "Lives: " + currentLives;
    36.  
    37.  
    38.  
    39.     }
    40.  
    41.  
    42.     // Update is called once per frame
    43.     void Update()
    44.     {
    45.  
    46.         horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;
    47.  
    48.         animator.SetFloat("Speed", Mathf.Abs(horizontalMove));
    49.  
    50.         if (Input.GetButtonDown("Jump"))
    51.         {
    52.             jump = true;
    53.             animator.SetBool("IsJumping", true);
    54.         }
    55.      
    56.  
    57.     }
    58.  
    59.     public void OnLanding()
    60.     {
    61.         animator.SetBool("IsJumping", false);
    62.     }
    63.  
    64.  
    65.  
    66.     void FixedUpdate()
    67.     {
    68.         // Move our character
    69.         controller.Move(horizontalMove * Time.fixedDeltaTime, false, jump);
    70.         jump = false;
    71.  
    72.     }
    73.  
    74.  
    75.     // You call this method when the player collides with something that kills him
    76.     // or whenever anything else happens that kills him
    77.     public void Die()
    78.     {
    79.         Debug.Log(currentLives--);
    80.         SetLivesText();
    81.         if (currentLives <= 0)
    82.         {
    83.             ResetPlayerState();
    84.             // trigger your gameover code
    85.         }
    86.  
    87.  
    88.     }
    89.  
    90.     // you call this to reset the player state, ie when the player is completely dead,
    91.     // or when you enter the main menu.. or whatever is your condition for getting new full lives
    92.     public void ResetPlayerState()
    93.     {
    94.         currentLives = maxLives;
    95.         SceneManager.LoadScene("Menu Screen1");
    96.         // potentially some other code that happens when you want a fresh player state
    97.     }
    98.  
    99.     void SetLivesText()
    100.     {
    101.         livesText.text = "Lives: " + currentLives;
    102.     }
    103. }
    And lastly the game manager, this is for the respawning:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GameMaster : MonoBehaviour
    6. {
    7.     public static GameMaster gm;
    8.  
    9.     // Start is called before the first frame update
    10.     void Start()
    11.     {
    12.         if (gm == null)
    13.         {
    14.             gm = GameObject.FindGameObjectWithTag("GM").GetComponent<GameMaster>();
    15.         }
    16.     }
    17.  
    18.     public Transform playerPrefab;
    19.     public Transform spawnPoint;
    20.  
    21.     public void RespawnPlayer()
    22.     {
    23.         Debug.Log("Player Respawn");
    24.         playerPrefab.transform.position = spawnPoint.transform.position;
    25.  
    26.     }
    27.  
    28. }
     
  2. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    FixedUpdate has its own updating frequency.

    You're not preventing your OnTriggerEnter2D to trigger twice in a single frame. If your actual framerate was higher, it would trigger more than twice potentially. You can adjust your FixedUpdate frequency in the Physics settings and check if this statement is true. If you make the interval small enough, it will get called three or even four times.

    The solution is to make sure that your player is dead. Once the player is dead, OnTriggerEnter2D should not affect him (and call Die once again).

    Your whole setup is terribly convoluted btw. Why would you make something that confuses you with such simple things. Make a decent model of your behavior. Make a variable Dead on your player, set that variable to true if your character is dead, make everything else rely on this. Set it to false when the character respawns. Super easy to debug, super easy to be in control of.
     
  3. HarryWhitelegg02

    HarryWhitelegg02

    Joined:
    Mar 11, 2020
    Posts:
    39
    I won't lie mate but I haven't got a clue what I'm doing, I'm a beginner trying to make a game for my college assignment
     
  4. HarryWhitelegg02

    HarryWhitelegg02

    Joined:
    Mar 11, 2020
    Posts:
    39
    I tried it out mate and it really F***ed my gameplay up, dk what im doing wrong
     
  5. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Well, obviously. Your code is heavily reliant on volatile things. Your game will potentially behave differently on different computers and under different situations. It's not a good code.

    Seriously I have tried to make a quick fix for your situation, but it won't help you. It bloats the code, makes a spaghetti mess, and you're less likely to understand it anyway. I'd advise you to step back, and approach this from the ground up. First of all, learn about what you've made so far, don't just copy/paste.

    It's not that hard what you're doing. It's just a platformer ok?
     
  6. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Maybe I sound too critical.
    IT'S NOT THE WORST CODE EITHER. There. I've seen worse.

    Try to pinpoint the worst part you can imagine in this code, and ask about that, so we can try and help you to figure it out on your own. Maybe you can find your way out after you begin to perceive what it does and how. The solution is really simple, but you really need to get your S*** together.