Problems with the Transform.Find

I’m trying to implement a dynamic recoil script but it requires me to call the transform of a camera. The “Transform.Find” is what I need but it seems that the GameObject isn’t being properly recognized and I assume it’s because of how I wrote it.

Recoil_Script = transform.Find("CameraRot/CameraRecoil").GetComponent<Recoil>();


When I actually start the game in unity it comes up with NullReferenceException stating that it’s not set to an instance of an object, so I assumed I just called it improperly. I looked over the documentation for Transform.Find and it didn’t seem to enlighten me of my woes and I couldn’t find any solid workaround so I come here to see if I can find a solution.

The full scripts may have more information that I may not have provided here, so the full two scripts will be listed below with hopefully more enlightening details.

{
    [Header("References")]
    [SerializeField] GunData gunData;
    [SerializeField] private Transform muzzle;

    [Header("Shot")]
    public AudioSource source1;
    public AudioClip shot;

    [Header("Reload")]
    public AudioSource source2;
    public AudioClip reload;

    float timeSinceLastShot;

    private Recoil Recoil_Script;

    void Start()
    {
        Recoil_Script = transform.Find("CameraRot/CameraRecoil").GetComponent<Recoil>();

        PlayerShot.shootInput += Shoot;
        PlayerShot.reloadInput += StartReload;
    }

    public void StartReload()
    {
        if (!gunData.reloading)
        {
            StartCoroutine(Reload());
        }
    }

    private IEnumerator Reload()
    {
        gunData.reloading = true;

        source2.PlayOneShot(reload, 0.25f);


        yield return new WaitForSeconds(gunData.reloadTime);

        gunData.currentAmmo = gunData.magSize;

        gunData.reloading = false;
    }

    private bool CanShoot() => !gunData.reloading && timeSinceLastShot > 1f / (gunData.fireRate / 60f);

    public void Shoot()
    {
        if (gunData.currentAmmo > 0)
        {
            if (CanShoot())
            {
                Debug.Log("BANG!");

                Recoil_Script.RecoilFire();

                source1.PlayOneShot(shot, 0.25f);
                if (Physics.Raycast(transform.position, transform.forward, out RaycastHit hitInfo, gunData.maxDistance))
                {
                    Debug.Log(hitInfo.transform.name);

                    IDamagable damagable = hitInfo.transform.GetComponent<IDamagable>();
                    damagable?.Damage(gunData.damage);
                }

                gunData.currentAmmo--;
                timeSinceLastShot = 0;
                OnGunShoot();
            }
        }
    }

    void Update()
    {
        timeSinceLastShot += Time.deltaTime;
    }

    private void OnGunShoot()
    {

    }

}
{

    //Rotation
    private Vector3 currentRotation;
    private Vector3 targetRotation;

    //Hip Recoil
    [SerializeField] private float recoilX;
    [SerializeField] private float recoilY;
    [SerializeField] private float recoilZ;

    //Settings

    [SerializeField] private float snap;
    [SerializeField] private float returnSpeed;

    void Start()
    {
       
    }


    void Update()
    {
        targetRotation = Vector3.Lerp(targetRotation, Vector3.zero, returnSpeed * Time.deltaTime);
        currentRotation = Vector3.Slerp(currentRotation, targetRotation, snap * Time.fixedDeltaTime);
        transform.localRotation = Quaternion.Euler(currentRotation);
    }

    public void RecoilFire()
    {
        targetRotation += new Vector3(recoilX, Random.Range(-recoilY, recoilY), Random.Range(-recoilZ, recoilZ));
    }
}

8465198--1124372--image_2022-09-25_184734837.png
8465198--1124375--image_2022-09-25_185306995.png

Just make a public field and drag a reference in… get rid of all that silly search code, act like a Unity developer!

If that’s not it then start here because the answer is ALWAYS the same and best of all…

… you NEVER have to post for NullReferenceErrors!!!

How to fix a NullReferenceException error

https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

Three steps to success:

  • Identify what is null
  • Identify why it is null
  • Fix that

That seems like it should work, but alas even after trying both making the field public as well as [SerializeField] and dragging in the camera it needs, it still appears to be null. I looked over your whole thought process and it seems like it functions for almost all NullReferenceErrors, I just can’t seem to get it to function with this one. I thought I knew why the line was Null, but appears that was wrong. Any good ways to debug this?

Your code isn’t still trying to find the object in Start, is it?

1 Like

Like Spiney said, are you sure you removed / commented out that transform.Find line? Assigning something through the inspector wouldn’t help much, if you’re still overwriting the value manually.

Also note: if the player is a prefab, things can get tricky. Though as long as the structure is all inside a single prefab, you can have referenced inside the prefab itself and those would be fixed when the object is instantiated.

Anyways, just to make this clear, the “Gun” script you’ve posted is attached to the “Player” object, right? And that recoil script is actually attached to the object “CameraRecoil”? If those two things are true, your code should work just fine, even though it’s not a good idea to do it this way :slight_smile:

If you don’t want / can’t assign the reference through the inspector (which you should be able when you make that reference public) you can also simply use GetComponentInChildren<Recoil>() instead. It would search on the player for that component and if not found it would traverse all the children of the player and return the first component of that type it can find, or null if no such component was found.

If you click the error message, it will ping the object that has the error in the hierarchy window.

A very common mistake is to have two copies of a script in a scene, but forget about one of them. So you try to fix the problem in the copy that you’re looking at, while the problem is in the other one. You can find all the instances of the Gun script you have by searching for t:gun in the hierarchy.

Problem was solved, thanks!

8467448--1125023--image_2022-09-26_125331608.png
8467448--1125026--upload_2022-9-26_12-54-39.png