0
\$\begingroup\$

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: The axe is assigned

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: The axe is assigned

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;
    }
}
\$\endgroup\$
10
  • \$\begingroup\$ You didnt say that you assigned axe as well (and axe is not getting loaded from your Start). If in doubt, add a screenshot of your scene setup with the gameobject in question. \$\endgroup\$
    – Zibelas
    Nov 26, 2023 at 7:46
  • \$\begingroup\$ With some debug log testing, destroy is NOT null, meaning it might have to do with the axe, but the error occurs when the axe is touching the tree. So therefore the tree is causing the error, not the axe. \$\endgroup\$ Nov 26, 2023 at 12:52
  • \$\begingroup\$ With even more testing, apparently destroySelf is null? destroySelf IS assigned to the tree. \$\endgroup\$ Nov 26, 2023 at 12:58
  • \$\begingroup\$ Can you add the full view of the game object in question with all scripts that are on it? For your question that would mean everything on tree and everything on axe. The code right now reads to me like you try to dmg the axe over the ds which is attached to that one. \$\endgroup\$
    – Zibelas
    Nov 26, 2023 at 14:50
  • \$\begingroup\$ If your axe is checking and dealing dmg, you don't need update logic on the tree. You could simply call a method on the tree health that updates and destroys it \$\endgroup\$
    – Zibelas
    Nov 26, 2023 at 15:04

1 Answer 1

0
\$\begingroup\$

Ok so apparently the blender imported object is an empty game object, and so therefore I had to apply the script to the child objects.

\$\endgroup\$
1
  • \$\begingroup\$ Nothing in your posted code interacts with the actual model. Next time you should include the full error message you get. Got job finding the error yourself \$\endgroup\$
    – Zibelas
    Dec 6, 2023 at 6:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .