Hi,
I followed the course, in the Fighter script, added two functions of the ISaveable interface, after picking up the weapon in the game and saving, and then starting the game, the following error occurred ,
NullReferenceException: Object reference not set to an instance of an object
And it also occurs that FadeIn() is not executed normally when the scene is switched.
These errors come from the overrideController code written in the previous lesson (// var overridedAnimatorController = animator.runtimeAnimatorController as AnimatorOverrideController;//)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPG.Combat;
using RPG.Movement;
using RPG.Control;
using RPG.Core;
using RPG.Saving;
using System;
namespace RPG.Combat
{
public class Fighter : MonoBehaviour, IAcction, ITakeDemage, ISaveable
{
[SerializeField] Weapon defaultWeapon = null;
[SerializeField] Transform rightHandTransform = null;
[SerializeField] Transform leftHandTransform = null;
RuntimeAnimatorController preCpntroller = null;
Weapon currentWeapon = null;
float attackRange = 2f;
[SerializeField] float timeBetweenAttack = 2f;
float demage = 20f;
float timeSinceLastAttack;
Transform targetTransform;
Animator m_animator;
bool hasTarget = false;
bool isEquipment = false;
public bool isAttacking = false;
private void Start()
{
m_animator = GetComponent<Animator>();
preCpntroller = m_animator.runtimeAnimatorController;
if(currentWeapon == null)
{
EquipWeapon(defaultWeapon);
}
}
// Start is called before the first frame update
private void Update()
{
timeSinceLastAttack -= Time.deltaTime;
if (GetComponent<PlayerController>())
{
GetComponent<PlayerController>().HasTarget(ref hasTarget);
}
if (GetComponent<AIController>())
{
GetComponent<AIController>().HasTarget(ref hasTarget);
}
if (targetTransform && hasTarget && !CanAttack(targetTransform.gameObject) )
{
float distance = Vector3.Distance(transform.position, targetTransform.position);
isAttacking = true;
if (targetTransform.GetComponent<Health>().IsDead()) return;
if (distance < attackRange)
{
transform.LookAt(targetTransform);
GetComponent<Mover>().Cancel();
AttackBehaviour();
}
else
{
GetComponent<Mover>().MoveTo(targetTransform.position);
}
}
else
{
isAttacking = false;
}
void AttackBehaviour()
{
if(timeSinceLastAttack <= 0)
{
m_animator.SetTrigger("attack");
timeSinceLastAttack = timeBetweenAttack;
}
}
Debug.Log(currentWeapon);
}
public void Attack(CombatTarget combatTarget)
{
GetComponent<ActionSchedul>().StartAction(this);
targetTransform = combatTarget.gameObject.transform;
}
public void Cancel()
{
m_animator.SetTrigger("stopAttack");
targetTransform = null;
}
//Animation Event
void Hit()
{
if(targetTransform == null) { return; }
Health target = targetTransform.GetComponent<Health>();
if (currentWeapon.HasProjectile())
{
currentWeapon.LaunchProjectile(rightHandTransform, leftHandTransform, target);
}
else
{
targetTransform.GetComponent<Health>().takeDamege(currentWeapon.GetDemage());
}
}
void Shoot()
{
Hit();
}
public void TakeDemage(float Demage)
{
if (targetTransform)
{
targetTransform.GetComponent<Health>().takeDamege(Demage);
}
}
bool CanAttack(GameObject combatTarget)
{
if(combatTarget == null) { return false; }
return targetTransform.GetComponent<Health>().IsDead() || GetComponent<Health>().IsDead(); ;
}
public void EquipWeapon(Weapon weapon)
{
currentWeapon = weapon;
weapon.Spawn(leftHandTransform, rightHandTransform, m_animator);
attackRange = currentWeapon.GetAttackRange();
timeBetweenAttack = currentWeapon.GetAttackCoolTime();
demage = currentWeapon.GetDemage();
isEquipment = true;
}
public void StoreWeapon()
{
if (isEquipment)
{
Destroy(currentWeapon);
attackRange = currentWeapon.GetAttackRange();
timeBetweenAttack = currentWeapon.GetAttackCoolTime();
demage = currentWeapon.GetDemage();
isEquipment = false;
m_animator.runtimeAnimatorController = preCpntroller;
}
}
public Weapon GetCurrentWeapon()
{
return currentWeapon;
}
public Transform GetTarget()
{
return targetTransform;
}
public object CaptureState()
{
return currentWeapon.name;
}
public void RestoreState(object state)
{
string weaponName = (string)state;
Weapon lastWeapon = Resources.Load<Weapon>(weaponName);
Debug.Log((string)state);
/*EquipWeapon(lastWeapon);*/
}
}
}
In addition, when I was investigating, I found that Debug.log(currentWeapon) was called in Update() of the Fighter script, and the result showed that currentWeapon will also display Unarmed
Bow
and one of the other results (for example, if you take sword, display sword; if you take fireball, display fireball)
Can you help me find a possible cause of the problem?
Thanks!