Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FindObjectOfType returning null

The issue I am having is with a dropped item i pick up adding ammo to a gun.

Built a Gun class with all the methods and variables. Built a Rifle class derived from the Gun class The Rifle works perfect No Issues

I now am adding a "PickUp" system where x amount of enemies drop a pickup.

This is the script on the item to pick up

public class AddARAmmo : MonoBehaviour
{
    private Rifle rifle;
    private void Awake()
    {
        rifle = FindObjectOfType<Rifle>();
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == string.Format("Player"))
        {
           rifle.AddAmmo(30);
            Destroy(gameObject);
        }

    }
}

The rifle and gun scripts are kind of long but here is the relevant stuff from the Gun base class is public abstract class ......

public int bulletsInStock;
 public void AddAmmo(int ammoToAdd)
{
    bulletsInStock += ammoToAdd; 
    UpdateAmmo();// updates on screen Ammo
}
......

Then in the Rifle Class

 public override void Modifiers() // This is where the guns starts are stored
{
    bulletSpeed = 2777f;
    bulletsInStock = 200;
    bulletsInMag = 30;
    bulletPoolSize = 40;
    desiredRPS = 15;
    muzzleFlashPoolSize = 10;
}

I am getting an Object Reference Not Set To An Instance

The Rifle script is on the rifle in the game hierarchy so it should find it. Does anyone see anything wrong?

Here is the full Gun script

public abstract class Gun : MonoBehaviour
{
    [SerializeField] protected GameObject muzzleFlash;// spawns on barrelEnd
    [SerializeField] protected Transform muzzleFlashFolder;
    [SerializeField] protected Transform bulletFolder;// is the parent of bullets
    [SerializeField] protected Transform barrelEnd;// Gameobject at the end of barrel
    [SerializeField] protected Rigidbody bullet; // The bullet Prefab
    [SerializeField] protected Text ammo; // OSD
    [SerializeField] protected Text weaponType; // OSD
    [HideInInspector] protected float bulletSpeed;
    [HideInInspector] public int bulletsInStock;
    [HideInInspector] protected int bulletsInMag;
    [HideInInspector] protected float desiredRPS;// Rounds Per Second
    [HideInInspector] protected List<Rigidbody> poolOfBullets; // Make pool for bullets
    [HideInInspector] protected int bulletPoolSize; // The size off the buletpool 10 works really well
    [HideInInspector] protected List<GameObject> muzzleFlashPool;// pool for muzzleflash
    [HideInInspector] protected int muzzleFlashPoolSize; // size of the muzzle pool
    [HideInInspector] protected int bulletsLeft; // In mag
    [HideInInspector] protected bool isReloading = false;
    [HideInInspector] protected float timeLeft;// for fire speed
    [HideInInspector] protected float fireSpeedTimer;
    [HideInInspector] protected Weapons weaponsScript;
    [HideInInspector] protected PlayerController playerController;
    protected void FixedUpdateStuff()
    {
        if (playerController.canMove && Input.GetAxisRaw(string.Format("Fire1")) > 0)
        {
            FireSpeedControl();// call the fire timer controller
        }
        if (playerController.canMove && Input.GetAxisRaw(string.Format("Fire1")) == 0)
        {
            timeLeft = 0f;
        }
        if (playerController.canMove && Input.GetKeyDown(KeyCode.R) && !isReloading)
        {
            Reload();
        }
        UpdateAmmoOnInput();
    }
    protected void UpdateStuff()
    {
        if (gameObject.activeInHierarchy)// when a gun become active it updates OSD
        {
            UpdateWeaponType();// With its Name
        }
    }
    protected void RPSFinder()//  finds the Rounds Per Second the gun will fire
    {
        fireSpeedTimer = (100 / desiredRPS) / 100;
        timeLeft = fireSpeedTimer;
    }

    protected void Fire()// Instatiates a clone of the desired bullet and fires it at bulletSpeed
    {
        if (!Empty())
        {
            Rigidbody bulletClones = GetPooledBullet();
            if (bulletClones != null)
            {

bulletClones.transform.SetPositionAndRotation(barrelEnd.position, barrelEnd.rotation);
                bulletClones.gameObject.SetActive(true);
            }
            GameObject muzzleFlashClone = GetMuzzleFlash();
            if (muzzleFlashClone != null)
            {
                muzzleFlashClone.transform.position = barrelEnd.position;
                muzzleFlashClone.gameObject.SetActive(true);
            }
            bulletClones.AddForce(-bulletClones.transform.up * bulletSpeed * .304f); //add the force in FPS * .304 = MPS
            bulletsLeft--;// the holder to know how many bullets are left in the magazine
            isReloading = false;// Gun cannot reload unless it has been fired
            UpdateAmmo();// Updates the on screen ammo count and the stock usage
            return;
        }
    }

    protected void Reload()
    {// this removes full magazine from the stock and the stock can still go negitive FIX FIX FIX FIX FIX FIX FIX
        if (bulletsInStock > 0)
        {
            isReloading = true;
            bulletsInStock -= bulletsInMag;
            bulletsLeft = bulletsInMag;
            UpdateAmmo();
        }
    }

    protected bool Empty()// Checks the magazine to see if there are bullets in it
    {
        if (bulletsLeft == 0)
            return true;
        else
            return false;
}

    protected void FireSpeedControl()// controls the RPS fired by the gun Controled by Update() Input
    {
        if (timeLeft > 0f)
        {
            timeLeft -= Time.deltaTime;
        }
        else if (timeLeft <= 0f)
        {
            Fire();
            timeLeft = fireSpeedTimer;
        }
    }

    protected Rigidbody GetPooledBullet()// retrieve a preInstatiated bullet from the pool to use when shooting
    {
        for (int i = 0; i < poolOfBullets.Count; i++)
        {
            if (!poolOfBullets[i].gameObject.activeInHierarchy)
            {
                return poolOfBullets[i];
            }
        }
        return null;
    }

    protected GameObject GetMuzzleFlash()
    {
        for (int i = 0; i < muzzleFlashPool.Count; i++)
        {
            if (!muzzleFlashPool[i].gameObject.activeInHierarchy)
            {
                return muzzleFlashPool[i];
            }
        }
        return null;
    }

    protected void UpdateAmmo()// Update the on screen ammo information
    {
        ammo.text = bulletsLeft + string.Format( " : ") + bulletsInStock;
    }

    protected abstract void UpdateWeaponType();

    protected void UpdateAmmoOnInput()
    {
        if (weaponsScript.updateAmmo)
        {
            UpdateAmmo();
            weaponsScript.updateAmmo = false;
        }
    }


    public abstract void Modifiers();

    protected void StartStuff()
    {
        Modifiers();// Call first to store indvidual gun stats
        playerController = FindObjectOfType<PlayerController>();
        weaponsScript = FindObjectOfType<Weapons>();
        poolOfBullets = new List<Rigidbody>();
        for (int i = 0; i < bulletPoolSize; i++)
        {
            Rigidbody bulletClone = (Rigidbody)Instantiate(bullet);
            bulletClone.gameObject.SetActive(false);// Builds the Inspector list 
            poolOfBullets.Add(bulletClone); //and populates the elements with clones
            bulletClone.transform.parent = bulletFolder.transform;
        }
        muzzleFlashPool = new List<GameObject>();
        for (int i = 0; i < muzzleFlashPoolSize; i++)
        {
            GameObject muzzleFlashClone = (GameObject)Instantiate(muzzleFlash);
            muzzleFlashClone.gameObject.SetActive(false);
            muzzleFlashPool.Add(muzzleFlashClone);
            muzzleFlashClone.transform.parent = muzzleFlashFolder.transform;
        }
            bulletsLeft = bulletsInMag;
            ammo.text = string.Format( " 0 : 0 ");
            RPSFinder();// Run last to set the RPS of the gun
        }
        public void AddAmmo(int ammoToAdd)
        {
            bulletsInStock += ammoToAdd;
            UpdateAmmo();
        }

    }
}

and here is the full Rifle script

public class Rifle : Gun
{
    //All variables are stored in the "Gun" Script 
    //Copy this onto guns 

    void Start()
    {
        StartStuff();
    }
    private void FixedUpdate()
    {
        FixedUpdateStuff();
    }

    void Update()
    {
        UpdateStuff();
    }

    public override void Modifiers() // This is where the guns starts are stored
    {
        bulletSpeed = 2777f;
        bulletsInStock = 200;
        bulletsInMag = 30;
        bulletPoolSize = 40;
        desiredRPS = 15;
        muzzleFlashPoolSize = 10;
    }

    protected override void UpdateWeaponType()
    {
        weaponType.text = string.Format("Assault Rifle");
    }


}
like image 219
Melsy Avatar asked Mar 09 '23 01:03

Melsy


1 Answers

There are three reasons why FindObjectOfType may return null:

Let's say the script name to find is Rifle:

And FindObjectOfType<Rifle>() is returning null.

1.The GameObject the Rifle script is attached to is in-active. You must make sure that the GameObject is active. enter image description here

2.The Rifle is not attached to any GameObject at-all. Make sure that the Rifle script is attached to a GameObject.enter image description here.

It doesn't matter if the script is enabled or disabled, it should find it as long as the GameObject it is attached to is active. See #1.

3.When loading new scene:

When you trigger scene loading with functions such as SceneManager.LoadScene and Application.LoadLevel, FindObjectOfType will not be able to find anything until the scene loading it done.

See here for how to check when scene has finished loading.


If you still have problems which you shouldn't, simply find the GameObject then get the Rifle component from it. Assuming that the name of the GameObject is "Rifle" too.

GameObject.Find("Rifle").GetComponent<Rifle>();
like image 157
Programmer Avatar answered Mar 21 '23 03:03

Programmer