• 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
Question by RedRightHand- · Oct 13, 2021 at 04:35 PM · 2d-platformercomponent2d-physicsnull reference exception

GetComponent from enemy script to player script sometimes works

Hello. Well, this is a long one.

So I'm making my first game, and I'm in the process of making enemy AI, and I had all set up for the movement of the enemies. Before that, I had made the attacking (player -> enemy) script and animations - using attack points and collision detection - and it worked just fine. But now the Attack() function I made for the player sometimes works and other don't (I get a NullReferenceException Error everytime I hit the enemy), apparently It is an error with the GetComponent that brings the enemy script to the player script. Also, I copied a couple of enemies and tried to hit them; the funny thing is, some of them register the attack, other don't, and this seems to be random, because when I restart Unity I can hit some other enemies and other don't (whereas in previous attempts I could hit 'em). I sincerely don't know what I did wrong, because I haven't touched that function since I made it, and its halting my progress. I'd love to get some help with this :(

The Attack() function:

 private void Attack()
         {
             //This indicates that, if the player is being hurt or is falling, he can't perform an attack.
             if(!Animator.GetCurrentAnimatorStateInfo(0).IsTag("5") || !Animator.GetCurrentAnimatorStateInfo(0).IsTag("4"))
             {
                 Debug.Log("Enemy damaged");
                 Animator.SetTrigger("Attack");
     
                 Collider2D[] HitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, AttackRange, EnemyLayers);
                 foreach(Collider2D Enemy in HitEnemies)
                 {
                  //This is precisely where the error occurs. As far as I know, there's nothing wrong with this, and I have everything labelled correctly.   
                  Enemy.GetComponent<EnemyScript>().TakeDamage(AttackDamage);
                 }
             }
         }

The Enemy TakeDamage() function:

     public void TakeDamage(int Damage)
     {
         Debug.Log("Enemy recieved damage");
         CurrentHealth -= Damage;
 
         Animator.SetTrigger("Hurt");
 
         if(CurrentHealth <= 0)
         {
             Die();
         }
     }

For the whole context, the player script:

 public class PlayerScript: MonoBehaviour
 {
     public float Speed = 3.5f;
     public float JumpForce;
 
     public Transform AttackPoint;
     public LayerMask EnemyLayers; 
     private int ColliderDamage = 6;
 
     public float AttackRange = 0.5f;
     public int AttackDamage = 20; 
 
     private Rigidbody2D Rigidbody2D;
     private Animator Animator;
     private float Horizontal;
     private bool Grounded;
 
     public float KnockBack;
     public float KnockBackLength;
     public float KnockBackCount;
     public bool KnockFromRight;
 
     private void Start()
     {
         Rigidbody2D = GetComponent<Rigidbody2D>();
         Animator = GetComponent<Animator>();
     }
 
     private void OnCollisionEnter2D(Collision2D Collision)
     {
       if (Collision.gameObject.tag == "Enemy" || Collision.gameObject.tag == "Hazard")
       {
         Debug.Log("Collider Damage Taken");
         TakeEnemyDamage(ColliderDamage);
       }
     }
 
     private void Update()
     {
         if(Animator.GetCurrentAnimatorStateInfo(0).IsTag("2"))
         {
             Speed = 0.0f;
             return;
         } else {
             Speed = 3.5f;
         }
 
         if(Animator.GetCurrentAnimatorStateInfo(0).IsTag("4"))
         {
             Speed = 0.0f;
 
             return;
         } else {
             Speed = 3.5f;
         }
 
         if(Animator.GetCurrentAnimatorStateInfo(0).IsTag("5"))
         {
             Speed = 0.0f;
 
             return;
         } else {
             Speed = 3.5f;
         }
 
         Animator.SetFloat("YVelocity", Rigidbody2D.velocity.y);
 
         Horizontal = Input.GetAxisRaw("Horizontal");
 
         if (Horizontal < 0.0f) transform.localScale = new Vector3(-1.0f, 1.0f, 1.0f);
         else if (Horizontal > 0.0f) transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
 
         Animator.SetBool("Run", Horizontal != 0.0f);
         Debug.DrawRay(transform.position, Vector3.down * 0.5f, Color.red);
         if (Physics2D.Raycast(transform.position, Vector3.down, 0.5f))
         {
             Grounded = true;
         }
         else Grounded = false;
         Animator.SetBool("Jumping", !Grounded);
 
         if (Input.GetKeyDown(KeyCode.Space) && Grounded)
         {
             Jump();
             Animator.SetBool("Jumping", true);
         }
 
        //Here's the call to the attack function. It works fine.
         if (Input.GetKeyDown(KeyCode.F))
         {
             Attack();
         }
 
     }
 
     private void Jump()
     {
         Rigidbody2D.AddForce(Vector2.up * JumpForce);
     }
     
     *//This is where the error appears.
     private void Attack()
     {
         //This indicates that, if the player is being hurt or is falling, he can't perform an attack.
         if(!Animator.GetCurrentAnimatorStateInfo(0).IsTag("5") || !Animator.GetCurrentAnimatorStateInfo(0).IsTag("4"))
         {
             Debug.Log("Enemy damaged");
             Animator.SetTrigger("Attack");
 
             Collider2D[] HitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, AttackRange, EnemyLayers);
             foreach(Collider2D Enemy in HitEnemies)
             {
              //This is precisely where the error occurs. As far as I know, there's nothing wrong with this, and I have everything labelled correctly.   Enemy.GetComponent<EnemyScript>().TakeDamage(AttackDamage);
             }
         }
     }*
 
     void OnDrawGizmosSelected()
     {
         if(AttackPoint == null)
             return;
         Gizmos.DrawWireSphere(AttackPoint.position, AttackRange);
     }   
 
     private void FixedUpdate()
     {
         Rigidbody2D.velocity = new Vector2(Horizontal * Speed, Rigidbody2D.velocity.y);
     }
 }



And the whole Enemy Script:

 public class EnemyScript : MonoBehaviour
 {
     public Animator Animator;
     public LayerMask PlayerLayers;
 
     public bool PlayerInArea 
     {
         get;
         private set;
     }
     public Transform Player 
     {
         get;
         private set;
     }
 
     private string DetectionTag = "Player";
 
     public int MaxHealth = 80;
     int CurrentHealth;
 
     void Awake()
     {
         Animator = GetComponent<Animator>();
     }
 
     void Start()
     {
         CurrentHealth = MaxHealth;    
     }
 
     public void TakeDamage(int Damage)
     {
         Debug.Log("Enemy recieved damage");
         CurrentHealth -= Damage;
 
         Animator.SetTrigger("Hurt");
 
         if(CurrentHealth <= 0)
         {
             Die();
         }
     }
 
     void Die()
     {
         Debug.Log("Enemy Died");
 
         Animator.SetBool("Death", true);
 
         GetComponent<Collider2D>().enabled = false;
     }
 
     private void OnTriggerEnter2D(Collider2D Other)
     {
         if(Other.gameObject.tag == "Player")
         {
             var PlayerAp = Other.gameObject.GetComponent<PlayerScript>();
 
             if(Other.transform.position.x < transform.position.x)
             {
                 PlayerAp.KnockFromRight = true;
             } else 
             {
                 PlayerAp.KnockFromRight = false;
             }
 
             if(Other.CompareTag(DetectionTag))
             {
                 Debug.Log("Player in enemy area");
                 PlayerInArea = true;
                 Player = Other.gameObject.transform;
             }
         }
     }   
 
     private void OnTriggerExit2D(Collider2D Other)
     {
         if(Other.CompareTag(DetectionTag))
         {
             Debug.Log("Player exiting enemy area");
             PlayerInArea = false;
             Player = null;
         }
     }
 
 }




Comment

People who like this

0 Show 0
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

1 Reply

· Add your reply
  • Sort: 
avatar image

Answer by awkwardstreamer · Oct 13, 2021 at 05:18 PM

So if im to understand, your saying GetComponent sometimes doesnt work? the only thing i can think of that would cause this is if the script was on a different object than the animator. If were talking about it detecting a collision triggered event you can increase the quality of your collisions to help. but youll be able to see within the first frame if everything is where its supposed to be, Since GetComponent runs in the Start function its only called once right when it becomes active. It be nice to know which line is giving you an error, but id be willing to guess the issue is starting in line of code

if(!Animator.GetCurrentAnimatorStateInfo(0).IsTag("5") || !Animator.GetCurrentAnimatorStateInfo(0).IsTag("4"))

I would seperate this function, so you just have an straight attack function that gets called IF it meets the requirements. cause right now its basically like you tell it to attack but then after tell it to wait to see who it is, which seems convoluted and prone to issue.

Comment
RedRightHand-

People who like this

1 Show 2 · 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 RedRightHand- · Oct 13, 2021 at 06:51 PM 0
Share

Okay, this is weird. I had an older version of the same project, but the whole layout of the objects and parameters are kind of similar. The difference is that, in the newer version, I had the enemy objects inside a parent object (is that what is called?) so now the same script functions all the time, as intended. I suppose something like that messed up with the tags and layers, so now I will work with that version. Either way, thank you for your help!

avatar image RedRightHand- · Oct 13, 2021 at 06:58 PM 0
Share

I have other suspicion: When I reference the tags for the animations, I used for the controllers of both player and enemy the same tags: "0" for idle, "1" for walking, "2" for attack, etc... So maybe when I sayed "if Animator tag "5" (Hurt), then don't enable attack", but in the same function (Attack()) I call the components of the enemy script, possibly calling along the animator controller of the enemy? I don't know, but I need to test this hypothesis.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

144 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

Related Questions

Farseer Physics and Character Control 0 Answers

Unity 2D player sticks on platform corners 2 Answers

Gravity Direction Change 2D 1 Answer

,Hey! I'm trying to make a Dash move like Celeste but my Dash doesn't seem to work Horizontally(X Axis), My Dash is working perfectly fine Upward and Downwards(Y Axis). 1 Answer

Variable Jump Height 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