Looking for someone to help me solve problem(s).(long thread)

So i have made some scripts which i think should work but aren’t working. And i think i know what the problem is but i dont know why nor how to solve that problem.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class BuildingHealth : MonoBehaviour {

    public float Health;
    public float Rate = 1f;
    public Image Oxygenbar;
    public bool makeoxygen = false;

    public void Start()
    {
         Health = UnityEngine.Random.Range(0, 101);      
         checkvalue(Health);


    }


    public void checkvalue(float Health)
    {
        if (Health >= 85)
        {
            GetComponent<Renderer>().material.color = Color.white;
        }
        if (Health < 85 && Health > 50)
        {
            GetComponent<Renderer>().material.color = Color.yellow;
        }
        if (Health < 50 && Health > 25)
        {
            GetComponent<Renderer>().material.color = new Color(1, 0.647059f, 0);
        }
        if (Health < 25)
        {
            GetComponent<Renderer>().material.color = Color.red;
        }
    }


    public void AddHealth(float RepairSpeed)
    {        
            Health += RepairSpeed;
            Debug.Log(Health);

        if(Health >= 100)
        {
            Health = 100;
            makeoxygen = true;
        }

        if (Health >= 85)
        {
            GetComponent<Renderer>().material.color = Color.white;
        }
        if (Health < 85 && Health > 50)
        {
            GetComponent<Renderer>().material.color = Color.yellow;
        }
        if (Health < 50 && Health > 25)
        {
            GetComponent<Renderer>().material.color = new Color(1, 0.647059f, 0);
        }
        if (Health < 25)
        {
            GetComponent<Renderer>().material.color = Color.red;
        }

    }

    private void Update()
    {
       
    }


}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Repairing : MonoBehaviour
{
    public Transform Shootpoint;
    public float RepairSpeed = 0.25f;
   // public BuildingHealth health;
    RaycastHit hit;
    public float weaponRange = 15;
    public Switchweapon weapon;
    public float Rate = 1f;
    public OxygenCheck oxygen;

    public void Start()
    {
        gameObject.GetComponent<BuildingHealth>();
        weapon = GetComponent<Switchweapon>();
        gameObject.GetComponent<OxygenCheck>();

    }

    public void Update()
    {
        Debug.DrawRay(Shootpoint.position, Shootpoint.transform.forward * weaponRange, Color.green);
        if (Input.GetMouseButton(0))
        {
            if (Physics.Raycast(Shootpoint.position, Shootpoint.transform.forward, out hit, weaponRange))
            {
                if(hit.collider.gameObject.tag == "Chipbuilding")
                {
                    if (gameObject.GetComponent<Switchweapon>().Weldertrue == true)
                    {
                        hit.collider.gameObject.GetComponent<BuildingHealth>().AddHealth(RepairSpeed);
                    }
                    else if (hit.collider.gameObject.tag == "Wrenchbuilding")
                    {
                        if (gameObject.GetComponent<Switchweapon>().Wrenchtrue == true)
                        {
                            hit.collider.gameObject.GetComponent<BuildingHealth>().AddHealth(RepairSpeed);
                        }
                    }
                }    
            }
        }
       
       oxygen.CallProduceOxygen();
       // gameObject.GetComponent<OxygenCheck>().CallProduceOxygen(); gives null error
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class ProduceOxygen : MonoBehaviour {

    public float Oxygen = 0f;
    public Image oxygenbar;


   

    public void AddOxygen(float Rate)
    {
        Oxygen += Rate;
        oxygenbar.fillAmount = Oxygen / 100;
        Debug.Log(Oxygen);
        if (Oxygen >= 100)
        {
            Oxygen = 100;
        }
    }

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OxygenCheck : MonoBehaviour
{

    public float weaponRange = 5;
   // public Transform Shootpoint;
    RaycastHit hit;
    float Rate = 1f;
    public ProduceOxygen oxygen;
    public BuildingHealth health;
    // Use this for initialization
    void Start()
    {
        gameObject.GetComponent<ProduceOxygen>();
        //gameObject.GetComponent<BuildingHealth>();
    }

    // Update is called once per frame
    public void CallProduceOxygen()
    {
        if (health.makeoxygen == true)
            if(oxygen.Oxygen < 100)
            oxygen.AddOxygen(Rate);
      //  gameObject.GetComponent<ProduceOxygen>().AddOxygen(Rate);
    }
}

I tried working around the problem with the last 2 scripts but it wont really work.
What im trying to do is: Health on buildings get randomized, player goes to repair one till the health is 100, then (this is the part im trying to achieve) i check if health is 100 and tell the other script to start producing oxygen. Now for a single object it kinda worked. But im trying to achieve it for multiple objects. I have 5 of em.
I dont know how to work around this problem because i cant reference the BuildingHealth component anywhere it will give null.

I see this happening a lot, where you’re getting the component, but that’s it. You’re not storing the reference or anything.
You haven’t said what, exactly, the problem you’re having, but I’m guessing it’s that you’re getting a bunch of null reference errors.

This right here, not actually doing anything. When you call a function that returns something you need to actually put that something somewhere before you can use it. I’m assuming you desire the reference to the ProduceOxygen component that it returns to go into the “public ProduceOxygen oxygen;” variable but you need to actually tell it to do that. Nothings ever assigning to the oxygen variable so it’s always null and always an error to try and use it.

i.e

oxygen = gameObject.GetComponent<ProduceOxygen>();

As Vedrit mentioned you have a bunch of places we’re you’re doing this; calling GetComponent to get a reference to a component, not actually putting the reference it returns anywhere, then later trying to use the variable that you had clearly meant for it to go into (and i presume getting null reference errors)

While we’re here. The alternative to using GetComponent, which i always recommend avoiding whenever possible, is making your variable either public or putting the [SerializeField] attribute on it. It will then show up in the editor inspector and you can assign the reference when setting up the prefab in the scene.

yeah im getting null reference errors but its only from the buildinghealth so far. I cant use an alternative because the things i need are in the other script and i need to call that function from the other script.

I think that @Mordus meant if you link the Script via the inspector, you won’t have to call GetComponent on that particular GameObject. You can still call that script’s methods when it’s linked that way. :slight_smile:

Because you’re doing the exact some thing with buildinghealth as the oxygen one i quoted. Calling get component, doing nothing with the reference it returns, then trying to access a variable you’ve never assigned anything to.

gameObject.GetComponent<BuildingHealth>();

is not doing anything, the same as the oxygen one i quoted before. You need to actually put the reference it returns somewhere if you want to use it. You have a variable called health, which is of type BuildingHealth, which i assume you want to put this into but you need to actually tell it to do that.

health = gameObject.GetComponent<BuildingHealth>();

You’re ‘only’ getting this error with buildinghealth because the error is terminating your code. As soon as you fix this one and the code can actually reach the others they will throw the same error for the same reason.

Make your variable that you want to contain a reference to another script public or put [SerializeField] on it. in the unity editor that variable will now be visible on the component. Drag the other component on to it. You now have a reference to the other component and can call its functions.

1 Like

What do you mean by that? like public ProduceOxygen oxygen;?

But what if i have many objects with the same script? and i dont want em all to get affected at the same time.

I think to my post, and Mordus’ … we mean that you appear to be referencing scripts that all reside on the same object. Even if you have many objects, you reference the script to the other script on the same gameobject .
Hopefully that makes sense? Another (almost identical way), is just fix the Start() method to :

public void Start()
    {
        gameObject.GetComponent<BuildingHealth>();
        weapon = GetComponent<Switchweapon>();
        gameObject.GetComponent<OxygenCheck>();
    }

See how ‘weapon’ is being assigned but the BuildingHealth and OxygenCheck are not?
assign them there and it’s all good, too. :slight_smile:

That’s not how it works. It’s a reference to that component (instance of a script) that you dragged on to it, not EVERY component of that type.

so i did what you told me to do and i still get the same null reference error any idea why?

Can you repost your modified code and indicate the line that is giving you the error?

I fixed it already. i just forgot that when i reference i.e Oxygen oxygen; and if i now do in start oxygen = getcomponent(); it will override it and make it null so i just let the reference be public and dragged it from the inspector and now everything is fine.

Cool. I am glad that you have it working :slight_smile:
For the record, though, “getcomponent();” will not make it null. What that snippet is saying is “find me this type/script and return me a reference to it, if you do”. When you call it all by its lonesome and do not store a variable on the left-hand side, or (add more on the right), nothing happens. The program would have returned the variable to you, but there’s no where for it to go… Hopefully that makes sense, and you’ll see what I mean as you continue programming =)

1 Like

and if it returned null it means there’s no component of that type on the game object. If you’re trying to find a component on a different gameobject then you need to call getcomponent on THAT gameobject.

1 Like