Weird issues with portals & Null exceptions

Hi, I got loading and saving working ok with weapons no problem. The issue was when I moved from portal to portal (yes my portals are at the root will show a screenshot) then I got a null exception error, which I solved by moving code to the awake routine, however I got default unarmed weapon in use, when I go back through the portal I get back to equiped weapon! I suspect the issue is my portal code but will show my fighter code as well can you help?

using UnityEngine;
using RPG.movement;
using RPG.core;
using RPG.Saving;

namespace RPG.combat
{
    public class Fighter : MonoBehaviour, IAction, ISaveable 
    {
        //Transform target; 
        Health target;

        float timesincelastattack = 1f;
        
        [SerializeField] float timebetweenattacks = 1f;
        [SerializeField] Transform RighthandTransform = null;
        [SerializeField] Transform LefhhandTransform = null;
        [SerializeField] Weapon defaultWeapon = null;
        [SerializeField] Weapon currentweapon = null;
        //[SerializeField] string defaultWeaponName = "Unarmed";
      
        

        private void Awake()
        {
            if (currentweapon == null) EquipWeapon(defaultWeapon);
        }
        private void Start()
        {
            //Weapon weapon = Resources.Load<Weapon>(defaultWeaponName);
            //EquipWeapon(weapon);
           // if (currentweapon == null) EquipWeapon(defaultWeapon);
        }

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

            if (target == null) return;
            if (target.IsDead()) return;
         
            if (!GetinRange())
            {
                GetComponent<Mover>().MoveTo(target.transform.position); // was target.position
            }
            else
            {
                GetComponent<Mover>().Cancel();
                //Cancel();
                AttackBehaviour();
                //print("fight not moving");
            }
            
        }

        public void EquipWeapon(Weapon weapon)
        {
            // put weapon in hand and then changes animation to match using animator overide process
            currentweapon = weapon;
            Animator animator = GetComponent<Animator>();
            weapon.Spawn(RighthandTransform, LefhhandTransform, animator);
        }

       

        private void AttackBehaviour() // attack animation
        {
            transform.LookAt(target.transform); // look at them in the eyes!
            if (timesincelastattack > timebetweenattacks)
            {
                timesincelastattack = 0;
                GetComponent<Animator>().SetTrigger("attack");
            }
        }
      
       
        bool GetinRange()
        {
            return Vector3.Distance(transform.position, target.transform.position) <= currentweapon.Weaponrange();  // was target.position
        }


        public void Attack(GameObject ctarget)
        {   
            GetComponent<ActionScheduler>().StartAction(this);
           // print("attack moving");
            target = ctarget.GetComponent<Health>();  // was ctarget.position
        }
        public bool CanAttack(GameObject ct)
        {
            if (ct == null) { return false; }
            Health targetToTest = ct.GetComponent<Health>();
            return targetToTest != null && !targetToTest.IsDead();
        }


        public void Cancel()
        {
            target = null;
            GetComponent<Animator>().SetTrigger("cancelattack");
            // print("stop attacking (cancel)");
        }

        void Hit() // attack animation state calls this 
        {
            //print("hit called");
            if (target == null) return;
            //Health health = target.GetComponent<Health>();
            if (currentweapon.HasProjectile(RighthandTransform, LefhhandTransform, target))
            {
                currentweapon.LaunchProjectile(RighthandTransform, LefhhandTransform, target);
            }
            else
            {
                target.TakeDamage(currentweapon.Weapondamage());
            }
            
        }

        void Shoot() // has shot fuction on arrow 
        {
            Hit();
        }

        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("Weapon not found in Resouces");
                return;
            }
            EquipWeapon(weapon);
        }
    }
}

Thats the fighter.cs now this is portal.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.AI;

namespace RPG.SceneManagement
{
    public class Portal : MonoBehaviour
    {
        enum DestinationIdentifier
        { A,B,C,D,E // as many as needed        
                }

        [SerializeField] int sceneToLoad = -1;
        [SerializeField] Transform spawnpoint;
        [SerializeField] DestinationIdentifier identifier;

        private void OnTriggerEnter(Collider other)
        {
            //Scene currentScene = SceneManager.GetActiveScene();
            //Debug.Log("Im at " + currentScene.);
            if (other.tag == "Player")
            {
                StartCoroutine(Transition());
            }
        }

        private IEnumerator Transition() // this runs across 2 scenes cool!
        {
            Fader fader = FindObjectOfType<Fader>();
            yield return fader.Fadeout(1.5f); // 2second white out at start
            DontDestroyOnLoad(gameObject);

            // save current level
            SavingWrapper wrapper = FindObjectOfType<SavingWrapper>();
            Debug.Log("Portal: 1st save");
            wrapper.Save();

            yield return SceneManager.LoadSceneAsync(sceneToLoad);
            // this bit of code exists between scenes
            // load current level
            Debug.Log("Portal: 1st load");
            wrapper.Load();

            Portal otherportal = GetOtherPortal(); // links to otherportal 

            UpdateOtherPlayer(otherportal);

            wrapper.Save();
            Debug.Log("Portal: 2st save");

            yield return fader.FadeIn(.75f); // 1 second back to normal at start of second scene

            Destroy(gameObject);
        }

        private Portal GetOtherPortal()
        {
            foreach (Portal portal in FindObjectsOfType<Portal>())
            {
                if (portal == this) continue;
                if (portal.identifier == identifier) return portal;
            }
            return null;
        }
            

        private void UpdateOtherPlayer(Portal otherportal)
        {
            GameObject Player = GameObject.FindWithTag("Player");
            Player.GetComponent<NavMeshAgent>().enabled = false; // needs to be turned off in order to transport it to right location
            Player.transform.position = otherportal.spawnpoint.position;
            Player.GetComponent<NavMeshAgent>().enabled = true;
        }
    }
}

update :slightly_smiling_face:
In figher script added

public object CaptureState()
        {
            if (currentweapon == null)
            {
                Debug.Log("currentweapon is null");
                //currentweapon = weapon;
                return "unarmed";
            }
            else
            {
                return currentweapon.name;
            }
            Debug.Log($"CaptureState - {currentweapon.name}");
         }

Need that if I use Start rather than Awake to do, ps I had fireball equipped.
if (currentweapon == null) EquipWeapon(defaultWeapon);

also my debug is :-
image

Solved it had nothing to do with code.

It was my prefabs I had noticed that enemy prefabs where labelled as player, not sure how that happened or when. I deleted all my prefabs and started them from scratch using prefab varients correctly. I reset code to how it should be and now it seems (touch wood) to be ok. I was going a bit mad trying to fix this!

Quoting to allow a solution to be tagged.
Good job working this out!!

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

Privacy & Terms