So in the following code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Threading;
public class TreeHealthBar : MonoBehaviour
{
public GameObject axe;
public float healthBarSize;
destroyTree destroy;
RectTransform rectTransform;
Vector3 size;
Vector3 position;
Image img;
void Start()
{
destroy = axe.GetComponent<destroyTree>();
rectTransform = GetComponent<RectTransform>();
img = GetComponent<Image>();
img.enabled = false;
}
void Hide()
{
img.enabled = false;
}
void Update()
{
if (destroy??false)
{
if (destroy.touchingTree() && destroy.GetTreeHealth() > 0f)
{
img.enabled = true;
CancelInvoke();
size = transform.localScale;
size.x = destroy.GetTreeHealth() / 100f * healthBarSize;
position = rectTransform.anchoredPosition;
if (destroy.GetTreeHealth() < destroy.GetTreeMaxHealth())
position.x = 0.0f - 250.0f + (destroy.GetTreeHealth() * 5.0f) - ((50 - destroy.GetTreeHealth()) * 2.5f);
else
position.x = 0.0f;
transform.localScale = size;
rectTransform.anchoredPosition = position;
}
else
{
Invoke(nameof(Hide), 1.5f);
}
if (destroy.touchingTree() && destroy.GetTreeHealth() <= 0)
{
img.enabled = false;
}
}
}
}
it returns the NullReferenceException in the console: Object reference not set to an instance of an object.
It is on line 37, which is where the if statement is containing the "destroy" object. But the big problem is that it shows this in the console when the axe (which the destroyTree is assigned to) is colliding with the tree. Yes, destroyTree is assigned, everything has its components and everything is assigned. I even made it CHECK if it's null, including trying to use if (destroy != null)
instead of the ?? equation, but it still won't work. It's probably answered somewhere, but I actually don't even know what's causing the problem. I also put && destroy??false
in the line 37 if statement, and that seemed to always show the bar, and not even change the size or position. Ah, and the important part is, I never got this error message when I just used a cube, not a blender imported object. So it has something to do with that, and I didn't even need if (destroy??false)
Here's my setup:
I'm assuming it would be helpful to include the actual destroyTree script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class destroyTree : MonoBehaviour
{
public float globalCutCooldown = 0.5f;
private float lastCutTime;
public float axeCut;
bool touching;
cutTree cut;
destroySelf ds;
void Start()
{
cut = GetComponent<cutTree>();
axeCut = 5f;
}
public float GetTreeHealth()
{
return ds.GetCurrentHealth();
}
public float GetTreeMaxHealth()
{
return ds.GetMaxHealth();
}
public bool touchingTree()
{
return touching;
}
public void OnTriggerStay(Collider other)
{
ds = other.gameObject.GetComponent<destroySelf>();
touching = true;
if (ds != null && cut.Cutting() && Time.time - lastCutTime > globalCutCooldown)
{
ds.TakeDamage(axeCut);
lastCutTime = Time.time;
}
}
public void OnTriggerExit(Collider other)
{
touching = false;
}
}
I don't know if I need to add my cutTree script. And this happens with all the other scripts that have to do with a tree health bar, with showing and hiding etc. And it's the same problem, there is an error on the same line as an if statement with a destroy object in it. It HAS to do with the destroyTree script therefore. Edit: with testing, it is a problem with the destroySelf script: So in the following code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Threading;
public class TreeHealthBar : MonoBehaviour
{
public GameObject axe;
public float healthBarSize;
destroyTree destroy;
RectTransform rectTransform;
Vector3 size;
Vector3 position;
Image img;
void Start()
{
destroy = axe.GetComponent<destroyTree>();
rectTransform = GetComponent<RectTransform>();
img = GetComponent<Image>();
img.enabled = false;
}
void Hide()
{
img.enabled = false;
}
void Update()
{
if (destroy??false)
{
if (destroy.touchingTree() && destroy.GetTreeHealth() > 0f)
{
img.enabled = true;
CancelInvoke();
size = transform.localScale;
size.x = destroy.GetTreeHealth() / 100f * healthBarSize;
position = rectTransform.anchoredPosition;
if (destroy.GetTreeHealth() < destroy.GetTreeMaxHealth())
position.x = 0.0f - 250.0f + (destroy.GetTreeHealth() * 5.0f) - ((50 - destroy.GetTreeHealth()) * 2.5f);
else
position.x = 0.0f;
transform.localScale = size;
rectTransform.anchoredPosition = position;
}
else
{
Invoke(nameof(Hide), 1.5f);
}
if (destroy.touchingTree() && destroy.GetTreeHealth() <= 0)
{
img.enabled = false;
}
}
}
}
it returns the NullReferenceException in the console: Object reference not set to an instance of an object.
It is on line 37, which is where the if statement is containing the "destroy" object. But the big problem is that it shows this in the console when the axe (which the destroyTree is assigned to) is colliding with the tree. Yes, destroyTree is assigned, everything has its components and everything is assigned. I even made it CHECK if it's null, including trying to use if (destroy != null)
instead of the ?? equation, but it still won't work. It's probably answered somewhere, but I actually don't even know what's causing the problem. I also put && destroy??false
in the line 37 if statement, and that seemed to always show the bar, and not even change the size or position. Ah, and the important part is, I never got this error message when I just used a cube, not a blender imported object. So it has something to do with that, and I didn't even need if (destroy??false)
Here's my setup:
I'm assuming it would be helpful to include the actual destroyTree script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class destroyTree : MonoBehaviour
{
public float globalCutCooldown = 0.5f;
private float lastCutTime;
public float axeCut;
bool touching;
cutTree cut;
destroySelf ds;
void Start()
{
cut = GetComponent<cutTree>();
axeCut = 5f;
}
public float GetTreeHealth()
{
return ds.GetCurrentHealth();
}
public float GetTreeMaxHealth()
{
return ds.GetMaxHealth();
}
public bool touchingTree()
{
return touching;
}
public void OnTriggerStay(Collider other)
{
ds = other.gameObject.GetComponent<destroySelf>();
touching = true;
if (ds != null && cut.Cutting() && Time.time - lastCutTime > globalCutCooldown)
{
ds.TakeDamage(axeCut);
lastCutTime = Time.time;
}
}
public void OnTriggerExit(Collider other)
{
touching = false;
}
}
I don't know if I need to add my cutTree script. And this happens with all the other scripts that have to do with a tree health bar, with showing and hiding etc. And it's the same problem, there is an error on the same line as an if statement with a destroy object in it. It HAS to do with the destroyTree script therefore. And with further testing, apparently it is a problem with ds, the destroySelf in the ontriggerstay in destroyTree. Apparently THAT script is null, when it IS assigned. Here's the destroySelf script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class destroySelf : MonoBehaviour
{
public InventoryManager inventoryManager;
public Item[] itemsToPickup;
public void PickupItem(int id)
{
bool result = inventoryManager.AddItem(itemsToPickup[id]);
}
public float maxHealth = 50f;
private float currentHealth;
private void Start()
{
currentHealth = maxHealth;
}
public void TakeDamage(float damage)
{
currentHealth -= damage;
if (currentHealth <= 0f)
{
Destroy(gameObject);
PickupItem(0);
}
}
public float GetCurrentHealth()
{
return currentHealth;
}
public float GetMaxHealth()
{
return maxHealth;
}
}
axe
as well (andaxe
is not getting loaded from your Start). If in doubt, add a screenshot of your scene setup with the gameobject in question. \$\endgroup\$