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
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 :-
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!