So I have a 2D platformer game, and my enemy has a health bar over its head and what I’m trying to do is make the health bar’s scale change to be proportional to the enemy’s health. The enemy has 2 health by the way. But I get these errors:
NullReferenceException: Object reference not set to an instance of an object
Zombie.UpdateHealthBar () (at Assets/Scripts/Zombie.cs:158)
Zombie.Hurt () (at Assets/Scripts/Zombie.cs:116)
Bullet.OnTriggerEnter2D (UnityEngine.Collider2D col) (at Assets/Scripts/Bullet.cs:38)
and…
NullReferenceException: Object reference not set to an instance of an object
Zombie.Death () (at Assets/Scripts/Zombie.cs:149)
Zombie.FixedUpdate () (at Assets/Scripts/Zombie.cs:94)
So, when the “Bullet” hits the “Zombie” its supposed to lose 1 “HP” and then change the “Z_HealthBar” to be proportionate to the enemy’s health. This code works fine for my player by the way, so I don’t know why I get errors for this.
Enemy’s Script:
public class Zombie : MonoBehaviour {
public Transform target;
public int moveSpeed = 2;
public int rotationSpeed;
public int maxDistance;
public float jumpPower = 300;
private bool hasJumped = false;
public int HP = 2; // How many times the enemy can be hit before it dies.
private bool dead = false; // Whether or not the enemy is dead.
[HideInInspector]
public bool facingRight = true;
public Transform myTransform;
private SpriteRenderer spriteRenderX;
private Animator anim; // Reference to the Animator on the player
private SpriteRenderer z_HealthBar; // Reference to the sprite renderer of the health bar.
private Vector3 healthScale; // The local scale of the health bar initially (with full health).
private Bullet bulletHit;
void Awake()
{
myTransform = transform;
spriteRenderX = GetComponent<SpriteRenderer>();
// Setting up the references.
bulletHit = GetComponent<Bullet>();
}
// Use this for initialization
void Start()
{
GameObject go = GameObject.FindGameObjectWithTag("Player");
target = go.transform;
maxDistance = 5;
}
void OnCollisionEnter2D(Collision2D coll)
{
if (GetComponent<Rigidbody2D>().velocity.y == 0 && coll.gameObject.tag == ("Z_Surface"))
{
hasJumped = true;
}
}
void FixedUpdate()
{
// Set the enemy's velocity to moveSpeed in the x direction.
//GetComponent<Rigidbody2D>().velocity = new Vector2(transform.localScale.x * moveSpeed, GetComponent<Rigidbody2D>().velocity.y);
if (Vector3.Distance(target.position, myTransform.position) < maxDistance)
{
if (target.position.x < myTransform.position.x) myTransform.position -= myTransform.right * moveSpeed * Time.deltaTime; // player is left of enemy, move left
{
if (target.position.x < myTransform.position.x && facingRight)
FlipL();
}
if (target.position.x > myTransform.position.x) myTransform.position += myTransform.right * moveSpeed * Time.deltaTime; // player is right of enemy, move right
{
if (target.position.x > myTransform.position.x && !facingRight)
FlipR();
}
}
if (hasJumped)
{
GetComponent<Rigidbody2D>().AddForce(transform.up * jumpPower);
hasJumped = false;
}
// If the enemy has zero or fewer hit points and isn't dead yet...
if (HP <= 0 && !dead)
// ... call the death function.
Death();
}
//Flips sprite
void FlipL()
{
facingRight = !facingRight;
spriteRenderX.flipX = true;
}
void FlipR()
{
facingRight = !facingRight;
spriteRenderX.flipX = false;
}
public void Hurt()
{
// Reduce the number of hit points by one.
HP--;
// Update what the health bar looks like.
UpdateHealthBar();
}
void Death()
{
// Find all of the sprite renderers on this object and it's children.
SpriteRenderer[] otherRenderers = GetComponentsInChildren<SpriteRenderer>();
// Disable all of them sprite renderers.
foreach (SpriteRenderer s in otherRenderers)
{
s.enabled = false;
}
// Set dead to true.
dead = true;
// Find all of the colliders on the gameobject and set them all to be triggers.
Collider2D[] cols = GetComponents<Collider2D>();
foreach (Collider2D c in cols)
{
c.isTrigger = true;
}
// Move all sprite parts of the enemy to the front
SpriteRenderer[] spr = GetComponentsInChildren<SpriteRenderer>();
foreach (SpriteRenderer s in spr)
{
s.sortingLayerName = "UI";
}
// ... disable Zombie script
GetComponent<Zombie>().enabled = false;
// ... disable Z Health Bar script
GetComponent<Z_HealthBarFollow>().enabled = false;
// Play a random audioclip from the deathClips array.
/*int i = Random.Range(0, deathClips.Length);
AudioSource.PlayClipAtPoint(deathClips_, transform.position);*/_
}
void UpdateHealthBar()
{
// Set the scale of the health bar to be proportional to the enemy’s health.
z_HealthBar.transform.localScale = new Vector3(healthScale.x * HP * 0.01f, 1, 1);
}
}
Bullet Script:
public class Bullet : MonoBehaviour {
public GameObject hit; // Prefab of hit effect.
private Zombie bulletHit;
void Awake()
{
// Setting up the references.
bulletHit = GetComponent();
}
void Start()
{
// Destroy the bullet after 1 seconds if it doesn’t get destroyed before then.
Destroy(gameObject, 1);
}
void OnHit()
{
// Create a quaternion with a random rotation in the z-axis.
Quaternion randomRotation = Quaternion.Euler(0f, 0f, Random.Range(0f, 360f));
// Instantiate the hit where the bullet is with the random rotation.
Instantiate(hit, transform.position, randomRotation);
}
void OnTriggerEnter2D(Collider2D col)
{
// If it hits an enemy…
if (col.tag == “Enemy”)
{
// … find the Enemy script and call the Hurt function.
col.gameObject.GetComponent().Hurt();
// Call the hit instantiation.
OnHit();
// Destroy the bullet.
Destroy(gameObject);
}
if (col.tag == “Surface”)
{
// Call the hit instantiation.
OnHit();
// Destroy the bullet.
Destroy(gameObject);
}
}
}