Null reference exception

Hey. Like a bunch of other people here, I’m getting a null reference exception that I can’t see to figure out. I tried looking in the other threads, but I can’t for the life of me figure out what is going on. I’ve switched stuff to use Awake, tripled checked my Resources folder is spelled correctly, even made my currentWeapon public so I could see if that was causing an issue. Nothing has worked thus far.

Here’s the errors: 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:35)
RPG.Combat.Fighter.Awake () (at Assets/Scripts/Combat/Fighter.cs:27)

and: NullReferenceException: Object reference not set to an instance of an object
RPG.Combat.Fighter.CaptureState () (at Assets/Scripts/Combat/Fighter.cs:127)
RPG.Saving.SaveableEntity.CaptureState () (at Assets/Scripts/Saving/SaveableEntity.cs:26)
RPG.Saving.SavingSystem.CaptureState (System.Collections.Generic.Dictionary`2[TKey,TValue] state) (at Assets/Scripts/Saving/SavingSystem.cs:72)
RPG.Saving.SavingSystem.Save (System.String saveFile) (at Assets/Scripts/Saving/SavingSystem.cs:29)
RPG.SceneManagement.SavingWrapper.Save () (at Assets/Scripts/SceneManagement/SavingWrapper.cs:37)
RPG.SceneManagement.SavingWrapper.Update () (at Assets/Scripts/SceneManagement/SavingWrapper.cs:31)

Here’s my fighter code:

    public class Fighter : MonoBehaviour, IAction, ISaveable
    {
        [SerializeField] float timeBetweenAttacks = 1f;
        [SerializeField] Transform rightHandTransform = null;
        [SerializeField] Transform leftHandTransform = null;
        [SerializeField] Weapon defaultWeapon = null;

        Health target;
        float timeSinceLastAttack = Mathf.Infinity;
        public Weapon currentWeapon = null;
        Animator animator;

        private void Awake() 
        {
            if (currentWeapon == null)
            {
                EquipWeapon(defaultWeapon);
            }
        }

        public void EquipWeapon(Weapon weapon)
        {
            animator = GetComponent<Animator>();
            currentWeapon = weapon;
            weapon.Spawn(rightHandTransform, leftHandTransform, animator);
        }

        private void Update()
        {
            timeSinceLastAttack += Time.deltaTime;

            if (target == null) return;
            if (target.IsDead()) return;

            if (!GetIsInRange())
            {
                GetComponent<Mover>().MoveTo(target.transform.position, 1f);
            }
            else
            {
                GetComponent<Mover>().Cancel();
                AttackBehaviour();
            }
        }

        private void AttackBehaviour()
        {
            transform.LookAt(target.transform);
            if (timeSinceLastAttack > timeBetweenAttacks)
            {
                //This will trigger the Hit() event.
                TriggerAttack();
                timeSinceLastAttack = 0f;
            }
        }

        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.WeaponDamage());
            }
        }

        void Shoot()
        {
            Hit();
        }

        private bool GetIsInRange()
        {
            return Vector3.Distance(transform.position, target.transform.position) < currentWeapon.WeaponRange();
        }

        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)
        {
            GetComponent<ActionScheduler>().StartAction(this);
            target = combatTarget.GetComponent<Health>();
            //print("Blood for the blood god!");
        }

        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);
        }
    }

Any help would be apricated

At first glance, it looks like the default weapon isn’t set in the inspector…
Let’s slip a couple Debugs to see if we can figure out what’s going on…
In EquipWeapon, start with this:

if(weapon==null) Debug.LogWarning($"{name} is trying to equip a null weapon");
if(rightHandTransform==null) Debug.LogWarning($"{name} does not have the Right Hand Transform set in the Fighter Inspector");
if(leftHandTransform==null) Debug.LogWarning($"{name} does not have the Left Hand Transform set in the inspector");

Ok, I took a look in the inspector and some how the relationship between my main character prefab, and the enemy prefab variants was broken. Setting the default unarmed weapon in the character prefab didn’t update all the enemies. Once I set the default weapon for all the enemies, all the errors went away and everything worked like it was supposed to.

1 Like

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

Privacy & Terms