Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by LaraCanara · Aug 10, 2020 at 09:19 AM · inputsystemdeathenable and disable script

new input system 2020 - character still can be moved after death

Hi, I am creating a local multiplayer fight game with the new input system from 2020. Everything works fine, but when the character dies you can still move him and attack. Only the first player can't move but still can attack. I don't know why their still moving, the fact that the first player can' move anymore makes me think I am on the right direction, but can't figure out what is missing.

I saw a lot of methods how to fix this problem when i researched it, but honestly i really don't understand how to adapt them to my script/s, so that it functions as it should.

i have three scripts: MovementInputHandler, Movement and the Damage_Script.

Here you can see them:

First the MovementInputHandler Script: using System.Linq; using UnityEngine; using UnityEngine.InputSystem;

 public class MovementInputHandler : MonoBehaviour
  {
      private PlayerInput playerInput;
      private Movement movementScript;
  
      void Awake()
      {
          playerInput = gameObject.GetComponent<PlayerInput>();
  
          var movementScripts = FindObjectsOfType<Movement>();
  
          var newIndex = playerInput.playerIndex;
  
          movementScript = movementScripts.FirstOrDefault(move => move.playerIndex == newIndex);
      }
  
      public void OnMove(InputAction.CallbackContext ctx)
      {
          if (movementScript != null)
          {
              movementScript.move = ctx.ReadValue<Vector2>();
          }
      }
  
      public void OnAttack(InputAction.CallbackContext ctx)
      {
          if (ctx.ReadValue<float>() != 0 && movementScript != null)
          {
              movementScript.Attack();
          }
      }
  }

This is the Movement Script: using UnityEngine;

 public class Movement : MonoBehaviour
  {
      public int playerIndex = 0;
      
      [HideInInspector]public Vector2 move;
  
      float moveSpeed = 25f;
  
      private bool facingLeft = false;
      private Animator anim;
      private Rigidbody2D rb;
  
      private BoxCollider2D boxCollider2d;
  
      [SerializeField] private Transform attackPoint;
      public LayerMask enemyLayers;
  
      public float attackRange = 0.5f;
      public int attackDamage = 10;
  
      void Awake()
      {
          boxCollider2d = transform.GetComponent<BoxCollider2D>();
      }
  
      void Start()
      {
          anim = GetComponent<Animator>();
          rb = GetComponent<Rigidbody2D>();
      }
  
      public void Attack()
      {
          anim.SetTrigger("Attack");
  
          Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackPoint.position, attackRange, enemyLayers);
  
          foreach (Collider2D enemy in hitEnemies)
          {
              enemy.GetComponent<Damage_Script>().TakeDamage(attackDamage);
          }
  
      }
  
      void OnDrawGizmosSelected()
      {
          if (attackPoint == null)
              return;
  
          Gizmos.DrawWireSphere(attackPoint.position, attackRange);
      }
  
      void FixedUpdate()
      {
          rb.velocity = new Vector2(move.x * moveSpeed, rb.velocity.y);
          anim.SetFloat("speed", Mathf.Abs(rb.velocity.x));
  
          if (move.x < 0 && !facingLeft)
              reverseImage();
          else if (move.x > 0 && facingLeft)
              reverseImage();
      }
  
      void reverseImage()
      {
          facingLeft = !facingLeft;
  
          Vector2 theScale = rb.transform.localScale;
  
          theScale.x *= -1;
          rb.transform.localScale = theScale;
      }
  }

And finally the Damage Script:

 using UnityEngine;
  
  public class Damage_Script : MonoBehaviour
  {
  
      public Animator anim;
      private int currentHealth;
      public HealthBar healthBar;
      public int maxHealth = 100;
  
      void Start()
      {
          currentHealth = maxHealth;
          healthBar.SetMaxHealth(maxHealth);
      }
  
      public void TakeDamage(int damage)
      {
          currentHealth -= damage;
          anim.SetTrigger("Hurt");
          healthBar.SetHealth(currentHealth);
  
          if (currentHealth <= 0)
          {
              Die();
          }
      }
  
      void Die()
      {
               GameObject.FindObjectOfType<Movement>().enabled = false;
      }
  }

Hope you can help..

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Mashimaro7 · Aug 10, 2020 at 11:28 AM

Why not have an isDead bool? Encapsulate the attack and OnMove in a if(!isDead), on the Die() method set it to true.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image LaraCanara · Aug 10, 2020 at 12:05 PM 0
Share

hi @$$anonymous$$ashimaro7 , that sounds like a good idea, but since I am using the new Input System from 2020 I am very confused where I have to inplement the IsDead bool in the Script.

avatar image Mashimaro7 · Aug 10, 2020 at 12:30 PM 0
Share

Declare the damage script in the other two scripts like,

 Damage_Script damage;

And put a public bool isDead on top of the damage script, then check for it like this

    public void Attack()
       {
 if(!damage.isDead)
 {
           anim.SetTrigger("Attack");
   
           Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackPoint.position, attackRange, enemyLayers);
   
           foreach (Collider2D enemy in hitEnemies)
           {
               enemy.GetComponent<Damage_Script>().TakeDamage(attackDamage);
           }
   }

   public void On$$anonymous$$ove(InputAction.CallbackContext ctx)
   {
       if (movementScript != null && !damage.isDead)
       {
           movementScript.move = ctx.ReadValue<Vector2>();
       }
   }

Also, lastly,

       void Die()
       {
                isDead = true;
                GameObject.FindObjectOfType<$$anonymous$$ovement>().enabled = false;
       }


avatar image Mashimaro7 Mashimaro7 · Aug 10, 2020 at 12:31 PM 0
Share

Sorry it's sloppy, it wasn't letting me preview where the code was until I sent it haha

avatar image LaraCanara Mashimaro7 · Aug 21, 2020 at 10:34 AM 0
Share

Hello @$$anonymous$$ashimaro7 , thank you for your help! Before you started helping me andrew-lukasik helped me and now it works fine! Later I will also test your version!

avatar image
0

Answer by andrew-lukasik · Aug 10, 2020 at 10:13 AM

Don't use FindObjectsOfType. It makes code like GameObject.FindObjectOfType<Movement>().enabled = false; affect one of the players only.

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image LaraCanara · Aug 10, 2020 at 10:56 AM 0
Share

Hi @andrew-lukasik , thanks for the answer. When I don't use "FindObjectOfType" the Script will not find my $$anonymous$$ovement Script anymore. I get the information " Cannot resolve symbol '$$anonymous$$ovement' ". Could you explain what I need to use instead?

avatar image andrew-lukasik LaraCanara · Aug 10, 2020 at 11:06 AM 0
Share

Add [SerializeField] $$anonymous$$ovement _movement = null field in Damage_Script class, fill this field in inspector and then replace GameObject.FindObjectOfType<$$anonymous$$ovement>().enabled = false; with _movement.enabled = false;. This way FindObjectOfType will not be needed at all and execute in correct context.

avatar image LaraCanara andrew-lukasik · Aug 10, 2020 at 11:36 AM 0
Share

Thank you, they now stop moving if they die, that's great! But they still can attack after their death, do you have a solution for this? The attacking script is within the movement script, I don't get why it still works after disabling it.

Show more comments
avatar image
0

Answer by andrew-lukasik · Aug 10, 2020 at 12:14 PM

Overall I think you should rethink your code architecture here. I say that because your code right now breaks **Single responsibility principle** and that makes it harder to reason about it even for you.


Here is an example:

 /// 
 /// RESPONSIBILITY: centralize information about given player instance
 ///                 and provide references to other important components
 /// 
 public class PlayerInfoComponent : MonoBehaviour
 {
     public int playerIndex = 0;
     public HealthComponent health;
     public MovementComponent movement;
 
     public LayerMask enemyLayers;
     public float attackRange = 0.5f;
     public int attackDamage = 10;
     public Transform attackPoint;
 
     public bool isAlive => health.isAlive;
     public bool isDead => health.isDead;
 
     #if UNITY_EDITOR
     void OnDrawGizmosSelected ()
     {
         if( attackPoint!=null ) Gizmos.DrawWireSphere( attackPoint.position , attackRange );
     }
     #endif
 }

 /// 
 /// RESPONSIBILITY: forwards human-player inputs to corresponding components for given player
 /// 
 public class PlayerInputHandler : MonoBehaviour
 {
     [SerializeField] PlayerInfoComponent _player;
     [SerializeField] PlayerInput _input;
 
     #if UNITY_EDITOR
     void OnValidate ()
     {
         if( _player==null ) _player = GetComponent<PlayerInfoComponent>();
         if( _input==null ) _input = GetComponent<PlayerInput>();
     }
     #endif
 
     public void OnMove ( UnityEngine.InputSystem.InputAction.CallbackContext ctx )
     {
         if( _player.isDead ) return;

         _player.movement.move = ctx.ReadValue<Vector2>();
     }
 
     public void OnAttack ( UnityEngine.InputSystem.InputAction.CallbackContext ctx )
     {
         if( _player.isDead ) return;
 
         if( ctx.ReadValue<float>()!=0 )
         {
             Collider2D[] hitEnemies = Physics2D.OverlapCircleAll( _player.attackPoint.position , _player.attackRange , _player.enemyLayers );
             foreach( Collider2D collider in hitEnemies )
             {
                 var damagable = collider.GetComponent<IDamageable>();
                 if( damagable!=null && damagable.isAlive && damagable!=(IDamageable)_player.health )
                 {
                     damagable.TakeDamage( _player.attackDamage );
                 }
             }
             
             _player.movement.ActAttack();
         }
     }
 }

 /// 
 /// RESPONSIBILITY: sole control over movement on screen and Animator
 /// 
 public class MovementComponent : MonoBehaviour
 {
     [HideInInspector] public Vector2 move;
     float moveSpeed = 25f;
     bool facingLeft = false;
 
     [SerializeField] PlayerInfoComponent _player;
     [SerializeField] Animator _animator;
     [SerializeField] Rigidbody2D _rigidbody;
     [SerializeField] Collider2D _collider;
 
 
     #if UNITY_EDITOR
     void OnValidate ()
     {
         if( _player==null ) _player = GetComponent<PlayerInfoComponent>();
         if( _collider==null ) _collider = GetComponent<Collider2D>();
         if( _animator==null ) _animator = GetComponent<Animator>();
         if( _rigidbody==null ) _rigidbody = GetComponent<Rigidbody2D>();
     }
     #endif
 
     void FixedUpdate ()
     {
         _rigidbody.velocity = new Vector2(move.x * moveSpeed, _rigidbody.velocity.y);
         _animator.SetFloat("speed", Mathf.Abs(_rigidbody.velocity.x));
 
         if (move.x < 0 && !facingLeft)
             ReverseImage();
         else if (move.x > 0 && facingLeft)
             ReverseImage();
     }
 
     public void ActAttack ()
     {
         _animator.SetTrigger("Attack");
     }
     
     public void ActHurt ()
     {
         _animator.SetTrigger("Hurt");
     }
 
     public void ActKilled ()
     {
         enabled = false;
         _animator.SetTrigger("Killed");
     }
 
     public void ActRevived ()
     {
         enabled = true;
         _animator.SetTrigger("Revived");
     }
 
     void ReverseImage ()
     {
         facingLeft = !facingLeft;
 
         Vector2 scale = transform.localScale;
         scale.x *= -1;
         transform.localScale = scale;
     }
 }

Damage_Script

 /// 
 /// RESPONSIBILITY: keep track of health, notify other components when it changes
 /// 
 public class HealthComponent : MonoBehaviour, IDamageable, IHealable
 {
 
     int _currentHealth = 0;
     [SerializeField] int _maxHealth = 100;
 
     [SerializeField] MovementComponent _movement;
     [SerializeField] HealthBar _healthBar;
 
     public bool isAlive => _currentHealth > 0;
     public bool isDead => !isAlive;
 
     void Start ()
     {
         _currentHealth = _maxHealth;
         _healthBar.SetMaxHealth( _maxHealth );
     }
 
     public void TakeDamage ( int damage )
     {
         _currentHealth -= damage;
         _healthBar.SetHealth( _currentHealth );
         
         if( _currentHealth>0 )
         {
             _movement.ActHurt();
         }
         else
         {
             _movement.ActKilled();
         }
     }
 
     public void Heal ( int healing )
     {
         _currentHealth += healing;
         _healthBar.SetHealth( _currentHealth );
     }
     public void Heal ()
     {
         _currentHealth = _maxHealth;
         _healthBar.SetHealth( _currentHealth );
     }
 }

 public interface IHealth
 {
     bool isAlive { get; }
     bool isDead { get; }
 }

 public interface IDamageable : IHealth
 {
     void TakeDamage ( int damage );
 }

 public interface IHealable : IHealth
 {
     void Heal ( int healing );
     void Heal ();
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image LaraCanara · Aug 21, 2020 at 10:29 AM 0
Share

Hello @andrew-lukasik , this looks very interesting! Thank you so much for your advice! :-)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

162 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Write custom input manager 0 Answers

Accessing local system ( File Browser ) 2 Answers

Organizing Unity Input System Code? 0 Answers

Use iOS "ESC" back swipe from left edge 0 Answers

Does SerializeField work when extending the Input System? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges