Hello guy I am trying to create a conditional that calculates and executes the following: If the Enemy cooldown timer exceeds the time between attacks, the Player is in range and this Player is alive then attack. I am pretty sure i understand what the error is telling me but after troubleshooting forums and attempting to tweak I can’t figure out what exactly I am missing which object it is referring to. If there is any information that I left out that is pertinent then please comment below and ask. Thank you in advance.
The full error is:
NullReferenceException: Object reference not set to an instance of an object
EnemyMovementController.Update () (at Assets/Scripts/EnemyMovementController.cs:52)
My code:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class EnemyMovementController : MonoBehaviour {
//facing
public GameObject enemyGraphic;
bool facingRight = true;
//attacking
Rigidbody2D enemyRB;
public GameObject bullet;
public Transform bulletSpawn;
GameObject player;
GameObject enemy;
float nextFire;
float range = 10f;
//string playerDistance;
float fireRate = 3f; // The time in seconds between each attack.
public int attackDamage = 10; // The amount of health taken away per attack.
//enemy health and damage
public int startingHealth = 100;
public int currentHealth;
PlayerHealth playerHealth;
EnemyHealth enemyHealth;
// Use this for initialization
void Start () {
enemyRB = GetComponent<Rigidbody2D> ();
player = GameObject.FindGameObjectWithTag ("Player");
enemy = GameObject.FindGameObjectWithTag ("Enemy");
Vector3.Distance (enemy.transform.position, player.transform.position);
enemyHealth = GetComponent<EnemyHealth> ();
playerHealth = GetComponent<PlayerHealth> ();
}
void Awake(){
currentHealth = startingHealth;
}
// Update is called once per frame
void Update ()
{
// Add the time since Update was last called to the timer.
//timer += Time.deltaTime;
// If the timer exceeds the time between attacks, the player is in range and this enemy is alive...
if ((Time.time >= nextFire) && (range <= 10f) && (enemyHealth.currentHealth > 0)) {
// ... attack.
fireGun ();
}
// If the player has zero or less health...
//if (playerHealth.currentHealth <= 0) {
//}
}
void fireGun(){
GameObject tempBullet;
tempBullet = Instantiate (bullet, bulletSpawn.transform.position, bulletSpawn.transform.rotation) as GameObject;
Rigidbody2D tempRB;
tempRB = tempBullet.GetComponent<Rigidbody2D> ();
if (facingRight) {
tempRB.AddForce (new Vector2 (-1, 0) * 10f * Time.deltaTime, ForceMode2D.Impulse);
Destroy (tempBullet, 2f);
}
// If the player has health to lose...
if (playerHealth.currentHealth > 0) {
// ... damage the player.
playerHealth.TakeDamage (attackDamage);
}
}
void OnTriggerEnter2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
void OnTriggerStay2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
}
// line 52
if((Time.time>= nextFire)&&(range <= 10f)&&(enemyHealth.currentHealth>0)){
the only object in that line is enemyHealth. If enemyHealth is null and you try to access the currentHealth member it’ll throw a null ref error.
In your start function you try to get the enemyhealth and playerhealth from the current gameobject… I’m thinking the enemyhealth is going to be on another gameobject?
so you need to specify the object
enemy.GetComponent<EnemyHealth>()
(note it could still be null if the find fails to locate the object it’s looking for)
How would I rectify this? If i change it to an int then the .currentHealth has no definition but I thought I gave it one when i declared it in the awake function.
This line here probably is incorrect. Does your gameobject with your EnemyMovementController also have an enemyHealth script on it? Since you’re also doing a GetComponent() I’m curious if you really have all three scripts on one gameobject.
Okay so I tweaked it to what the poster above said with the enemy.GetComponentHealth() and i think the error on that is gone. The scripts are childed to each of the game objects but now I get an error on the same line. Weird because its only on 53 all the other current.healths are perfectly fine.
(53,73): error CS1061: Type UnityEngine.GameObject' does not contain a definition for currentHealth’ and no extension method currentHealth' of type UnityEngine.GameObject’ could be found (are you missing a using directive or an assembly reference?)
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class EnemyMovementController : MonoBehaviour {
//facing
public GameObject enemyGraphic;
bool facingRight = true;
//attacking
Rigidbody2D enemyRB;
public GameObject bullet;
public Transform bulletSpawn;
GameObject player;
GameObject enemy;
float nextFire;
float range = 10f;
//string playerDistance;
float fireRate = 3f; // The time in seconds between each attack.
public int attackDamage = 10; // The amount of health taken away per attack.
//enemy health and damage
public int startingHealth = 100;
public int currentHealth;
PlayerHealth playerHealth;
EnemyHealth enemyHealth;
// Use this for initialization
void Start () {
enemyRB = GetComponent<Rigidbody2D> ();
player = GameObject.FindGameObjectWithTag ("Player");
enemy = GameObject.FindGameObjectWithTag ("Enemy");
Vector3.Distance (enemy.transform.position, player.transform.position);
enemy.GetComponent<EnemyHealth> ();
playerHealth = GetComponent<PlayerHealth> ();
}
void Awake(){
currentHealth = startingHealth;
}
// Update is called once per frame
void Update ()
{
// Add the time since Update was last called to the timer.
//timer += Time.deltaTime;
// If the timer exceeds the time between attacks, the player is in range and this enemy is alive...
if ((Time.time >= nextFire) && (range <= 10f) && (enemy.currentHealth > 0)) {
// ... attack.
fireGun ();
}
// If the player has zero or less health...
//if (playerHealth.currentHealth <= 0) {
//}
}
void fireGun(){
GameObject tempBullet;
tempBullet = Instantiate (bullet, bulletSpawn.transform.position, bulletSpawn.transform.rotation) as GameObject;
Rigidbody2D tempRB;
tempRB = tempBullet.GetComponent<Rigidbody2D> ();
if (facingRight) {
tempRB.AddForce (new Vector2 (-1, 0) * 10f * Time.deltaTime, ForceMode2D.Impulse);
Destroy (tempBullet, 2f);
}
// If the player has health to lose...
if (playerHealth.currentHealth > 0) {
// ... damage the player.
playerHealth.TakeDamage (attackDamage);
}
}
void OnTriggerEnter2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
void OnTriggerStay2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
}
Okay so that reference error is gone now i get these 2:
(54,82): error CS1061: Type int' does not contain a definition for currentHealth’ and no extension method currentHealth' of type int’ could be found (are you missing a using directive or an assembly reference?)
(37,17): error CS0029: Cannot implicitly convert type PlayerHealth' to int’
I thought at line 43 I defined it as equal to startingHealth? Sorry I am learning the C#.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class EnemyMovementController : MonoBehaviour {
//facing
public GameObject enemyGraphic;
bool facingRight = true;
//attacking
Rigidbody2D enemyRB;
public GameObject bullet;
public Transform bulletSpawn;
GameObject player;
GameObject enemy;
float nextFire;
float range = 10f;
//string playerDistance;
float fireRate = 3f; // The time in seconds between each attack.
public int attackDamage = 10; // The amount of health taken away per attack.
//enemy health and damage
public int startingHealth = 100;
public int currentHealth;
PlayerHealth playerHealth;
EnemyHealth enemyHealth;
// Use this for initialization
void Start () {
enemyRB = GetComponent<Rigidbody2D> ();
player = GameObject.FindGameObjectWithTag ("Player");
enemy = GameObject.FindGameObjectWithTag ("Enemy");
Vector3.Distance (enemy.transform.position, player.transform.position);
enemyHealth = enemy.GetComponent<EnemyHealth> ();
playerHealth = player.GetComponent<PlayerHealth> ();
}
void Awake(){
currentHealth = startingHealth;
}
// Update is called once per frame
void Update ()
{
// Add the time since Update was last called to the timer.
//timer += Time.deltaTime;
// If the timer exceeds the time between attacks, the player is in range and this enemy is alive...
if ((Time.time >= nextFire) && (range <= 10f) && (enemyHealth.currentHealth > 0)) {
// ... attack.
fireGun ();
}
// If the player has zero or less health...
//if (playerHealth.currentHealth <= 0) {
//}
}
void fireGun(){
GameObject tempBullet;
tempBullet = Instantiate (bullet, bulletSpawn.transform.position, bulletSpawn.transform.rotation) as GameObject;
Rigidbody2D tempRB;
tempRB = tempBullet.GetComponent<Rigidbody2D> ();
if (facingRight) {
tempRB.AddForce (new Vector2 (-1, 0) * 10f * Time.deltaTime, ForceMode2D.Impulse);
Destroy (tempBullet, 2f);
}
// If the player has health to lose...
if (playerHealth.currentHealth > 0) {
// ... damage the player.
playerHealth.TakeDamage (attackDamage);
}
}
void OnTriggerEnter2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
void OnTriggerStay2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
}
I was able to get rid one of the errors now the last one is:
(43,17): error CS0029: Cannot implicitly convert type int' to PlayerHealth’
I’ve tried tweaking and changing but I get the errors above. Im not sure how to change its type without incurring other errors such as PlayerHealth is not attached to a GameObject.
EDIT:
i tried changing PlayerHealth to an int and that does not work I get the GameObject error and the one above.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class EnemyMovementController : MonoBehaviour {
//facing
public GameObject enemyGraphic;
bool facingRight = true;
//attacking
Rigidbody2D enemyRB;
public GameObject bullet;
public Transform bulletSpawn;
GameObject player;
GameObject enemy;
float nextFire;
float range = 10f;
//string playerDistance;
float fireRate = 3f; // The time in seconds between each attack.
public int attackDamage = 10; // The amount of health taken away per attack.
//enemy health and damage
public float startingHealth = 100;
public int currentHealth;
EnemyHealth enemyHealth;
PlayerHealth playerHealth;
// Use this for initialization
void Start () {
enemyRB = GetComponent<Rigidbody2D> ();
player = GameObject.FindGameObjectWithTag ("Player");
enemy = GameObject.FindGameObjectWithTag ("Enemy");
Vector3.Distance (enemy.transform.position, player.transform.position);
enemyHealth = enemy.GetComponent<EnemyHealth> ();
}
void Awake(){
startingHealth = currentHealth;
playerHealth = currentHealth;
}
// Update is called once per frame
void Update ()
{
// Add the time since Update was last called to the timer.
//timer += Time.deltaTime;
// If the timer exceeds the time between attacks, the player is in range and this enemy is alive...
if ((Time.time >= nextFire) && (range <= 10f) && (enemyHealth.currentHealth > 0)) {
// ... attack.
fireGun ();
}
// If the player has zero or less health...
//if (playerHealth.currentHealth <= 0) {
//}
}
void fireGun(){
GameObject tempBullet;
tempBullet = Instantiate (bullet, bulletSpawn.transform.position, bulletSpawn.transform.rotation) as GameObject;
Rigidbody2D tempRB;
tempRB = tempBullet.GetComponent<Rigidbody2D> ();
if (facingRight) {
tempRB.AddForce (new Vector2 (-1, 0) * 10f * Time.deltaTime, ForceMode2D.Impulse);
Destroy (tempBullet, 2f);
}
// If the player has health to lose...
if (playerHealth.currentHealth > 0) {
// ... damage the player.
// playerHealth.TakeDamage (attackDamage);
}
}
// If the player has health to lose...
if (playerHealth.currentHealth > 0) {
// ... damage the player.
// playerHealth.TakeDamage (attackDamage);
It did not before but i edited it so now it does. Now i am getting:
(54,82): error CS1061: Type int' does not contain a definition for currentHealth’ and no extension method currentHealth' of type int’ could be found (are you missing a using directive or an assembly reference?)
(37,17): error CS0029: Cannot implicitly convert type PlayerHealth' to int’
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class EnemyMovementController : MonoBehaviour {
//facing
public GameObject enemyGraphic;
bool facingRight = true;
//attacking
Rigidbody2D enemyRB;
public GameObject bullet;
public Transform bulletSpawn;
GameObject player;
GameObject enemy;
float nextFire;
float range = 10f;
//string playerDistance;
float fireRate = 3f; // The time in seconds between each attack.
public int attackDamage = 10; // The amount of health taken away per attack.
//enemy health and damage
public int startingHealth = 100;
public int currentHealth;
EnemyHealth enemyHealth;
PlayerHealth playerHealth;
// Use this for initialization
void Start () {
enemyRB = GetComponent<Rigidbody2D> ();
player = GameObject.FindGameObjectWithTag ("Player");
enemy = GameObject.FindGameObjectWithTag ("Enemy");
Vector3.Distance (enemy.transform.position, player.transform.position);
enemyHealth = enemy.GetComponent<EnemyHealth> ();
playerHealth = player.GetComponent<PlayerHealth> ();
}
void Awake(){
enemyHealth.currentHealth = startingHealth;
playerHealth.currentHealth = currentHealth;
}
// Update is called once per frame
void Update ()
{
// Add the time since Update was last called to the timer.
//timer += Time.deltaTime;
// If the timer exceeds the time between attacks, the player is in range and this enemy is alive...
if ((Time.time >= nextFire) && (range <= 10f) && (enemyHealth.currentHealth > 0)) {
// ... attack.
fireGun ();
}
// If the player has zero or less health...
//if (playerHealth.currentHealth <= 0) {
//}
}
void fireGun(){
GameObject tempBullet;
tempBullet = Instantiate (bullet, bulletSpawn.transform.position, bulletSpawn.transform.rotation) as GameObject;
Rigidbody2D tempRB;
tempRB = tempBullet.GetComponent<Rigidbody2D> ();
if (facingRight) {
tempRB.AddForce (new Vector2 (-1, 0) * 10f * Time.deltaTime, ForceMode2D.Impulse);
Destroy (tempBullet, 2f);
}
// If the player has health to lose...
if (playerHealth.currentHealth > 0) {
// ... damage the player.
// playerHealth.TakeDamage (attackDamage);
}
}
void OnTriggerEnter2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
void OnTriggerStay2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
}
Okay I got rid of
54,82): error CS1061: Type int' does not contain a definition for currentHealth’ and no extension method currentHealth' of type int’ could be found (are you missing a using directive or an assembly reference?)
I confused currentHealth and startingHealth and then referenced them back to other scripts. I know my code is sloppy as high heavens it’s just im new and id rather comment out then delete certain sections of code in case they are needed. The last error is still:
Assets/Scripts/EnemyMovementController2.cs(37,17): error CS0029: Cannot implicitly convert type PlayerHealth' to int’
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class EnemyMovementController : MonoBehaviour {
//facing
public GameObject enemyGraphic;
bool facingRight = true;
//attacking
Rigidbody2D enemyRB;
public GameObject bullet;
public Transform bulletSpawn;
GameObject player;
GameObject enemy;
float nextFire;
float range = 10f;
//string playerDistance;
float fireRate = 3f; // The time in seconds between each attack.
public int attackDamage = 10; // The amount of health taken away per attack.
//enemy health and damage
public int startingHealth = 100;
public int currentHealth;
EnemyHealth enemyHealth;
PlayerHealth playerHealth;
// Use this for initialization
void Start () {
enemyRB = GetComponent<Rigidbody2D> ();
player = GameObject.FindGameObjectWithTag ("Player");
enemy = GameObject.FindGameObjectWithTag ("Enemy");
Vector3.Distance (enemy.transform.position, player.transform.position);
enemyHealth = enemy.GetComponent<EnemyHealth> ();
playerHealth = player.GetComponent<PlayerHealth> ();
currentHealth = GetComponent<PlayerHealth> ();
}
void Awake(){
currentHealth = startingHealth;
enemyHealth.currentHealth = startingHealth;
playerHealth.currentHealth = startingHealth;
}
// Update is called once per frame
void Update ()
{
// Add the time since Update was last called to the timer.
//timer += Time.deltaTime;
// If the timer exceeds the time between attacks, the player is in range and this enemy is alive...
if ((Time.time >= nextFire) && (range <= 10f) && (enemyHealth.currentHealth > 0)) {
// ... attack.
fireGun ();
}
// If the player has zero or less health...
//if (playerHealth.currentHealth <= 0) {
//}
}
void fireGun(){
GameObject tempBullet;
tempBullet = Instantiate (bullet, bulletSpawn.transform.position, bulletSpawn.transform.rotation) as GameObject;
Rigidbody2D tempRB;
tempRB = tempBullet.GetComponent<Rigidbody2D> ();
if (facingRight) {
tempRB.AddForce (new Vector2 (-1, 0) * 10f * Time.deltaTime, ForceMode2D.Impulse);
Destroy (tempBullet, 2f);
}
// If the player has health to lose...
if (playerHealth.currentHealth > 0) {
// ... damage the player.
// playerHealth.TakeDamage (attackDamage);
}
}
void OnTriggerEnter2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
void OnTriggerStay2D(Collider2D other){
if (Vector3.Distance (enemy.transform.position, player.transform.position) <= range) {
if (Time.time >= nextFire) {
nextFire = Time.time + fireRate;
fireGun ();
}
}
}
}
This. You’re trying to assign a PlayerHealth script to an int variable. Easy things to debug, normally you’ll get the red lines underneath things if they are off (in visual studios, maybe not in mono)
What should i change this to? I really dont know what to do I keep trying to change variables, names everything and I keep getting more errors dealing with the currentHealth value
This is the EnemyMovementController script. Firstly I think this script is doing far more than the name suggests, but that aside if you could clarify some things about your script I think it would make the problem a little easier to solve.
You have “enemyHealth” script, which has a “currentHealth”. You have “playerHealth” script, which has a “currentHealth”, and then you have a class-level “currentHealth” for the EnemyMovementController. Why does EnemyMovementController need a “currentHealth”?
You have an “enemy” GameObject, and a “player” GameObject. Each of those has its own “Health” component, which you assign here. This code also implies that your EnemyMovementController GameObject also has a “PlayerHealth” script attached? Is this correct, if so, for what purpose?
You should also keep in mind that Awake gets called before Start. So if your Awake method tries to use “enemyHealth”, but it hasn’t yet been assigned in Start, you will get null reference errors. I think you should swap the code in Awake and Start to prevent more issues.