Search code examples
unity-game-engineanimationcontroller

Player can still move after death when dying while pressing directional keys


I am currently learning unity using c# and I made the following code using someones tutorial but I think the tutorial I am currently using as a reference is not giving me much info about this current bug. I already added a bool called dead which I placed on FixedUpdate() and Update() to check whether to accept input or not. It works well if I die without pressing directional keys like dying while attacking and dying while idle... I want to know what is wrong with my code. I would be very happy for some hints. Here is my c# code.

PlayerManager.cs

using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PlayerManager : MonoBehaviour
 {
     Rigidbody rb;
     public float x, y, ms = 3;
     Animator animator;
     public Collider weaponCollider;
     public PlayerUIManager playerUIManager;
     public int maxHp = 100;
     public int hp;
     bool dead;
  
     // Start is called before the first frame update
     void Start()
     {
         hp = maxHp;
         ms = 3;        
         playerUIManager.Init(this);
         rb = GetComponent<Rigidbody>();
         animator = GetComponent<Animator>();
         DisableWeaponCollider();
     }
 
     void Update()
     {
         if (dead) return;
         x = Input.GetAxisRaw("Horizontal");
         y = Input.GetAxisRaw("Vertical");
         if(Input.GetKeyDown(KeyCode.Space))
         {
             animator.SetTrigger("Attack");
         }
     }
 
     void GetDamage(int damage)
     {
         hp -= damage;
         if (hp <= 0)
         {
             hp = 0;
             dead = true;
             animator.SetTrigger("Die");
         }
         playerUIManager.UpdateHp(hp);
     }
 
     private void FixedUpdate()
     {
         if (dead) return;
         Debug.Log("fixed updating");
         Vector3 velocity = new Vector3(x, 0, y) * 0.29f;
         Vector3 direction = transform.position + velocity;
         transform.LookAt(direction);
         rb.velocity = velocity;
         animator.SetFloat("Speed", rb.velocity.magnitude);
     }
 
     private void OnTriggerEnter(Collider other)
     {
         if (dead) return;
         Damager damager = other.GetComponent<Damager>();
         if (damager != null)
         {
             animator.SetTrigger("DamageReceive");
             GetDamage(damager.damage);
         }
     }
 
     public void EnableWeaponCollider()
     {
         weaponCollider.enabled = true;
     }
 
     public void DisableWeaponCollider()
     {
         weaponCollider.enabled = false;
     }
 }

DieBehavior.cs (for my die animation)

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class DieBehavior : StateMachineBehaviour
 {
     override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
     {
         animator.GetComponent<PlayerManager>().ms = 0;
     }
 
     //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
     //{}
 
     //override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
     //{}
 
     //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
     //{}
 
     //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
     //{}
 }
 

Solution

  • The issue comes from because rb.velocity is still set.

    So you need to reset velocity together when you set dead flag.

    if (hp <= 0)
    {
         hp = 0;
         dead = true;
         animator.SetTrigger("Die");
         // Please add this
         rb.velocity = Vector3.zero;
    }
    

    Rigidbody.velocity doesn't work once. It means once you set velocity, the GameObject moves until you reset velocity.

    Rigidbody.velocity represents the rate of change of Rigidbody position.