I just finished the Shops section of the 4th RPG course. When I tried to test saving the shop and purse info, I received an error related to fighter.cs. I do not know how long the error has been there. Here is the error code:
NullReferenceException: Object reference not set to an instance of an object
RPG.Combat.Fighter.CaptureState () (at Assets/Scripts/Combat/Fighter.cs:190)
GameDevTV.Saving.SaveableEntity.CaptureState () (at Assets/Scripts/Saving/SaveableEntity.cs:45)
GameDevTV.Saving.SavingSystem.CaptureState (System.Collections.Generic.Dictionary`2[TKey,TValue] state) (at Assets/Scripts/Saving/SavingSystem.cs:93)
GameDevTV.Saving.SavingSystem.Save (System.String saveFile) (at Assets/Scripts/Saving/SavingSystem.cs:43)
RPG.SceneManagement.SavingWrapper.Save () (at Assets/Scripts/SceneManagement/SavingWrapper.cs:45)
RPG.SceneManagement.SavingWrapper.Update () (at Assets/Scripts/SceneManagement/SavingWrapper.cs:34)
Here is my fighter.cs:
using UnityEngine;
using RPG.Movement;
using RPG.Core;
using GameDevTV.Saving;
using RPG.Attributes;
using RPG.Stats;
using System.Collections.Generic;
using GameDevTV.Utils;
using System;
using GameDevTV.Inventories;
namespace RPG.Combat
{
public class Fighter : MonoBehaviour, IAction, ISaveable
{
[SerializeField] float timeBetweenAttacks = 1f;
[SerializeField] Transform rightHandTransform = null;
[SerializeField] Transform leftHandTransform = null;
[SerializeField] WeaponConfig defaultWeapon = null;
Health target;
Equipment equipment;
float timeSinceLastAttack = Mathf.Infinity;
WeaponConfig currentWeaponConfig;
LazyValue<Weapon> currentWeapon;
private void Awake()
{
currentWeaponConfig = defaultWeapon;
currentWeapon = new LazyValue<Weapon>(SetUpDefaultWeapon);
equipment = GetComponent<Equipment>();
if (equipment)
{
equipment.equipmentUpdated += UpdateWeapon;
}
}
private void UpdateWeapon()
{
var weapon = equipment.GetItemInSlot(EquipLocation.Weapon) as WeaponConfig;
if (weapon == null)
{
EquipWeapon(defaultWeapon);
}
else
{
EquipWeapon(weapon);
}
}
private Weapon SetUpDefaultWeapon()
{
return AttachWeapon(defaultWeapon);
}
private void Start()
{
currentWeapon.ForceInit();
}
private void Update()
{
timeSinceLastAttack += Time.deltaTime;
if (target == null) return;
if (target.IsDead()) return;
if (!GetIsInRange(target.transform))
{
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 = 0;
}
}
private void TriggerAttack()
{
GetComponent<Animator>().ResetTrigger("stopAttack");
GetComponent<Animator>().SetTrigger("attack");
}
// Animation Event
void Hit()
{
if (target == null) { return; }
float damage = GetComponent<BaseStats>().GetStat(Stat.Damage);
if (currentWeapon.value != null)
{
currentWeapon.value.OnHit();
}
if (currentWeaponConfig.HasProjectile())
{
currentWeaponConfig.LaunchProjectile(rightHandTransform, leftHandTransform, target, gameObject, damage);
}
else
{
target.TakeDamage(gameObject, damage);
}
}
void Shoot()
{
Hit();
}
private bool GetIsInRange(Transform targetTransform)
{
return Vector3.Distance(transform.position, targetTransform.position) < currentWeaponConfig.GetRange();
}
public bool CanAttack(GameObject combatTarget)
{
if (combatTarget == null)
{
return false;
}
if (!GetComponent<Mover>().CanMoveTo(combatTarget.transform.position) &&
!GetIsInRange(combatTarget.transform))
{
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>();
}
public void Cancel()
{
StopAttack();
target = null;
GetComponent<Mover>().Cancel();
}
private void StopAttack()
{
GetComponent<Animator>().ResetTrigger("attack");
GetComponent<Animator>().SetTrigger("stopAttack");
}
public void EquipWeapon(WeaponConfig weapon)
{
currentWeaponConfig = weapon;
currentWeapon.value = AttachWeapon(weapon);
}
private Weapon AttachWeapon(WeaponConfig weapon)
{
Animator animator = GetComponent<Animator>();
return weapon.Spawn(rightHandTransform, leftHandTransform, animator);
}
public Health GetTarget()
{
return target;
}
public object CaptureState()
{
return currentWeaponConfig.name; <==== Line 190
}
public void RestoreState(object state)
{
string weaponName = (string)state;
WeaponConfig weapon = UnityEngine.Resources.Load<WeaponConfig>(weaponName);
EquipWeapon(weapon);
}
}
}
I have been working on the RPG courses in my spare time as a hobby and I am thoroughly enjoying the process. This is the first time I have encountered an issue that I could not solve myself or find a solution in the forum. Thanks in advance for any help.