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

LoseLife() method being called multiple times in void update()

Discussion in 'Scripting' started by MrNacho777, Jan 14, 2022.

  1. MrNacho777

    MrNacho777

    Joined:
    Jun 7, 2019
    Posts:
    6
    I have a very simple platform game. I've set up a respawn mechanic where if the player falls and goes beyond a limit, they teleport back to the start position and lose a life. My problem is that the LoseLife() method sometimes gets called 2-3 times when the player falls, 2-3 lives gone.

    if(transform.position.y < -12.0f)
    {
    LoseLife();
    }

    I know i'm missing something about void update, im guessing its something to do with fps, like, it goes beyond -12.0f and then gets called again at -12.2f or whatever. But why?



    Code (CSharp):
    1. public class Player : MonoBehaviour
    2. {
    3.     [SerializeField]
    4.     private float _playerSpeed = 2.0f;
    5.  
    6.     [SerializeField]
    7.     private float _gravity = 1.0f;
    8.  
    9.     [SerializeField]
    10.     private float _jumpHeight = 25.0f;
    11.  
    12.     private float _yVelocity;
    13.  
    14.     private bool _haveDoubleJumped = false;
    15.  
    16.     [SerializeField]
    17.     private int _coinTally = 0;
    18.  
    19.     [SerializeField]
    20.     private int _livesTally = 3;
    21.  
    22.     private UIManager _uiManager;
    23.  
    24.     private CharacterController _controller;
    25.  
    26.  
    27.     void Start()
    28.     {
    29.         _controller = GetComponent<CharacterController>();
    30.         _uiManager = GameObject.Find("Canvas").GetComponent<UIManager>();
    31.  
    32.         if(_uiManager == null)
    33.         {
    34.             Debug.LogError("The UI manager is null");
    35.         }
    36.     }
    37.  
    38.  
    39.     void Update()
    40.     {
    41.         float horizontalInput = Input.GetAxis("Horizontal");        
    42.         Vector3 direction = new Vector3(horizontalInput * -1, 0, 0);
    43.         Vector3 velocity = direction * _playerSpeed;
    44.  
    45.         velocity.y = _yVelocity;
    46.         _controller.Move(velocity * Time.deltaTime);
    47.  
    48.         if(transform.position.y < -12.0f)
    49.         {
    50.             LoseLife();
    51.         }
    52.      
    53.         if (_controller.isGrounded == true)
    54.         {
    55.             _haveDoubleJumped = false;
    56.             if (Input.GetKeyDown(KeyCode.Space))
    57.             {
    58.                 _yVelocity = _jumpHeight;
    59.              
    60.             }
    61.          
    62.          
    63.         }
    64.         else
    65.         {
    66.             if (Input.GetKeyDown(KeyCode.Space) && _haveDoubleJumped == false)
    67.             {
    68.                 _haveDoubleJumped = true;
    69.                 _yVelocity += _jumpHeight;
    70.             }
    71.             _yVelocity -= _gravity;
    72.         }
    73.  
    74.     }
    75.  
    76.     public void CollectCoin()
    77.     {
    78.         _coinTally += 1;
    79.         _uiManager.UpdateScore(_coinTally);
    80.     }
    81.  
    82.     public void LoseLife()
    83.     {
    84.         _yVelocity = 0;
    85.         _livesTally--;
    86.         _uiManager.UpdateLives(_livesTally);
    87.         transform.position = new Vector3(7.0f, 1.0f, 0);
    88.     }
    89. }
    90.  
     
    Last edited: Jan 14, 2022
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,971
    I'm thinking perhaps your CharacterController Move() call is interfering with your other call that resets the player back up to y = 1 level.

    Instead of line 87 hitting the transform.position, have you tried calling the .Move() call on Character Controller to jam the player backup there?? I think that might fix it.

    If not, you might need to use a cooldown timer, or else a boolean that latches from below to above, and only lets you lose life when you were above last frame and you are below this frame.
     
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,016
    Update() is called every frame. So once your player y position goes below -12, within 3 frames of your computer you'll have lost 3 lives. I would say that this is happening despite moving the player to the position in your code is because character controller/rigid body isn't updating until the next FixedUpdate.
     
  4. MrNacho777

    MrNacho777

    Joined:
    Jun 7, 2019
    Posts:
    6
    You were right, i fixed it by disabling the CharacterController then transform.position then re enabling the CharacterController. Definitely some mistakes in those Udemy courses :p :p
     
    Kurt-Dekker likes this.