Null Reference Exception help!

Hello again i keep ruuning into the bug

NullReferenceException: Object reference not set to an instance of an object
RPG.Combat.Fighter.EquipWeapon (RPG.Combat.Weapon weapon) (at Assets/Scripts/Combat/Fighter.cs:58)
RPG.Combat.Fighter.RestoreState (System.Object state) (at Assets/Scripts/Combat/Fighter.cs:143)
RPG.Saving.SaveableEntity.RestoreState (System.Object state) (at Assets/Scripts/Saving/SaveableEntity.cs:39)
RPG.Saving.SavingSystem.RestoreState (System.Collections.Generic.Dictionary`2[TKey,TValue] state) (at Assets/Scripts/Saving/SavingSystem.cs:85)
RPG.Saving.SavingSystem+d__0.MoveNext () (at Assets/Scripts/Saving/SavingSystem.cs:23)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)

using UnityEngine;

using RPG.Movement;

using RPG.Core;

using System;

using RPG.Saving;

namespace RPG.Combat

{

public class Fighter : MonoBehaviour, IAction, ISaveable

{

    

    [SerializeField] float timeBetweenAttacks = 1f;

    [SerializeField] Weapon defaultWeapon = null;

    [SerializeField] Transform rightHandTransform = null;

    [SerializeField] Transform leftHandTransform = null;

    

    Health target;

    float timeSinceLastAttack = Mathf.Infinity;

    Weapon currentWeapon = null;

    private void Start()

    {

        if(currentWeapon == null)

        {

            EquipWeapon(defaultWeapon);

        }

    }

    public void Update()

    {

        timeSinceLastAttack += Time.deltaTime;

        if (target == null)

        {

            return; 

        } 

        if (target.IsDead())

        {

            return;

        } 

        if (target != null && !GetIsInRange())

        {

            GetComponent<Mover>().MoveTo(target.transform.position, 1f);

        }

        else

        {

            //print("attack");

            GetComponent<Mover>().Cancel();

            AttackBehaviour();

        }

    }

    public void EquipWeapon(Weapon weapon)

    {

        currentWeapon = weapon;

        Animator animator = GetComponent<Animator>();

        weapon.Spawn(rightHandTransform, leftHandTransform, animator);

    }

    private void AttackBehaviour()

    {

        transform.LookAt(target.transform);

        if(timeSinceLastAttack > timeBetweenAttacks)

        {

            //hit event trigger

            TriggerAttack();

            timeSinceLastAttack = 0;

        }

    }

    private void TriggerAttack()

    {

        GetComponent<Animator>().ResetTrigger("stopAttack");

        GetComponent<Animator>().SetTrigger("attack");

    }

    //Animation Event

    void Hit()

    {

        if(target == null) {return;}

        if(currentWeapon.HasProjectile())

        {

            currentWeapon.LaunchProjectile(rightHandTransform, leftHandTransform, target);

        }

        else 

        {

            target.TakeDamage(currentWeapon.GetDamage());

        }

        

    }

    void Shoot()

    {

        Hit();

    }

    private bool GetIsInRange()

    {

        return Vector3.Distance(transform.position, target.transform.position) < currentWeapon.GetRange();

    }

    public bool CanAttack(GameObject combatTarget)

    {

        if(combatTarget == null){return false;}

        Health targetToTest = combatTarget.GetComponent<Health>();

        return targetToTest != null && !targetToTest.IsDead();

    }

    public void Attack(GameObject combatTarget)

    {

        target = null;

        GetComponent<ActionScheduler>().StartAction(this);

        target = combatTarget.GetComponent<Health>();

    }

    public void Cancel()

    {

        StopAttack();

        target = null;

        GetComponent<Mover>().Cancel();

        

    }

    private void StopAttack()

    {

        GetComponent<Animator>().ResetTrigger("attack");

        GetComponent<Animator>().SetTrigger("stopAttack");

    }

    public object CaptureState()

    {

        return currentWeapon.name;

    }

    public void RestoreState(object state)

    {

        string weaponName = (string)state;

        Weapon weapon = Resources.Load<Weapon>(weaponName);

        EquipWeapon(weapon);

    }

}

}

PLEASE HELP!

First thing to check is to make sure that your Weapon is stored in a folder named Resources.
This is important: the last folder in the chain must be Resources (example: Game/Weapons/Resources/) not a folder under the Resources folder (example: Game/Resources/Weapons/)

If this doesn’t turn out to be the issue, let’s add some Debug.Logs to see if we can get to the bottom of this:

public object CaptureState()

    {
        Debug.Log($"CaptureState - {currentWeapon.name}");
        return currentWeapon.name;
    }

    public void RestoreState(object state)
    {
        string weaponName = (string)state;
        Debug.Log($"RestoreState -- {weaponName}");
        Weapon weapon = Resources.Load<Weapon>(weaponName);
        if(weapon == null) 
        {
              Debug.Log("The weapon was not found in Resources");
              return;
        }
        EquipWeapon(weapon);
    }

ok thank you for replying so fast! i checked my file structure and its Game/Weapons/Resources
i put your debug code in place of mine and the null exeption error has gone. I think that the outcome is still not my intended one. im not sure though i still need to keep testing it.
I start the game and move to pick up the sword, move, save, move, load.
the player loads back with the sword. when i start the game over the player loads without the weapon(its the same way for all weapons) this is the console before i start the game again to check for the weapon. also my file structure on the right

I think I found the issue:
image
Unity is quite picky, it’s Resources

1 Like

Yes, thank you for spell checking! hahaha my spelling has some work to do, whoops.

We’ve all done it. When it’s in the code, it’s easier to spot than when it’s a directory name.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms