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;
}
}
}