Restarting Unity Project - Now it doesn't run

I saved my progress after “Dependency Inversion With Interfaces” with the game running just fine. Now, when restarting later with no changes made, I am getting errors and the character will not move.

Errors:

NullReferenceException: Object reference not set to an instance of an object
RPG.Movement.Mover.StartMoveAction (UnityEngine.Vector3 destination) (at Assets/Scripts/Movement/Mover.cs:28)
RPG.Control.PlayerController.InteractWithMovement () (at Assets/Scripts/Control/PlayerController.cs:43)
RPG.Control.PlayerController.Update () (at Assets/Scripts/Control/PlayerController.cs:15)

NullReferenceException: Object reference not set to an instance of an object
RPG.Combat.Fighter.Attack (RPG.Combat.CombatTarget combatTarget) (at Assets/Scripts/Combat/Fighter.cs:36)
RPG.Control.PlayerController.InteractWithCombat () (at Assets/Scripts/Control/PlayerController.cs:28)
RPG.Control.PlayerController.Update () (at Assets/Scripts/Control/PlayerController.cs:14)

I have gone through the videos and made sure the script was the same, which it is. I cannot figure out why I am getting these errors.

Mover.cs:

using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.AI;
using RPG.Core;

namespace RPG.Movement
{
    public class Mover : MonoBehaviour, IAction
    {
        [SerializeField] Transform target;

        NavMeshAgent navMeshAgent;

        private void Start()
        {
            navMeshAgent = GetComponent<NavMeshAgent>();
        }

        private void Update()
        {
            UpdateAnimator();
        }

        public void StartMoveAction(Vector3 destination)
        {
            GetComponent<ActionScheduler>().StartAction(this);
            MoveTo(destination);
        }


        public void MoveTo(Vector3 destination)
        {
            navMeshAgent.destination = destination;
            navMeshAgent.isStopped = false;
        }

        public void Cancel()
        {
            navMeshAgent.isStopped = true;
        }

        private void UpdateAnimator()
        {
            Vector3 velocity = navMeshAgent.velocity;
            Vector3 localVelocity = transform.InverseTransformDirection(velocity);
            float speed = localVelocity.z;
            GetComponent<Animator>().SetFloat("forwardSpeed", speed);
        }
    }
}

Fighter.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPG.Movement;
using RPG.Core;

namespace RPG.Combat
{
    public class Fighter : MonoBehaviour, IAction
    {
        [SerializeField] float weaponRange = 2f;

        Transform target;

        private void Update()
        {
            if (target == null) return;

            if (!GetIsInRange())
            {
                GetComponent<Mover>().MoveTo(target.position);
            }
            else
            {
                GetComponent<Mover>().Cancel();
            }
        }

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

        public void Attack(CombatTarget combatTarget)
        {
            GetComponent<ActionScheduler>().StartAction(this);
            target = combatTarget.transform;
        }

        public void Cancel()
        {
            target = null;
        }
    }
}

IAction.cs:

using RPG.Core;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace RPG.Core
{
    public interface IAction
    {
        void Cancel();
    }
}

ActionScheduler.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace RPG.Core
{
    public class ActionScheduler : MonoBehaviour
    {
        IAction currentAction;

        public void StartAction(IAction action)
        {
            if (currentAction == action) return;
            if (currentAction != null)
            {
                currentAction.Cancel();
            }
            currentAction = action;
        }
    }
}

PlayerController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using RPG.Movement;
using RPG.Combat;

namespace RPG.Control
{
    public class PlayerController : MonoBehaviour
    {
        private void Update()
        {
            if(InteractWithCombat()) return;
            if (InteractWithMovement()) return;
        }

        private bool InteractWithCombat()
        {
            RaycastHit[] hits = Physics.RaycastAll(GetMouseRay());
            foreach (RaycastHit hit in hits)
            {
                CombatTarget target = hit.transform.GetComponent<CombatTarget>();
                if (target == null) continue;

                if (Input.GetMouseButtonDown(0))
                {
                    GetComponent<Fighter>().Attack(target);
                }
                return true;
            }
            return false;
        }

        private bool InteractWithMovement()
        {
            RaycastHit hit;
            bool hasHit = Physics.Raycast(GetMouseRay(), out hit);
            if (hasHit)
            {
                if (Input.GetMouseButton(0))
                {
                    GetComponent<Mover>().StartMoveAction(hit.point);
                }
                return true;
            }
            return false;
        }

        private static Ray GetMouseRay()
        {
            return Camera.main.ScreenPointToRay(Input.mousePosition);
        }
    }
}

FollowCamera.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

namespace RPG.Core
{
    public class FollowCamera : MonoBehaviour
    {
        [SerializeField] Transform target;

        void LateUpdate()
        {
            transform.position = target.position;
        }
    }
}

Check your Cursor Mapping in PlayerController. Enums might have gotten reset and you might not have the movement and combat one anymore.

If you are meaning the namespaces, they are included in the PlayerController script. The only thing I think I may have done before saving, was to click reset on the Player transform in the Inspector panel. I still cannot get this fixed.

Both null reference exceptions are referring to the first line of each of the methods I posted.

GetComponent<ActionScheduler>().StartAction(this);

It appears that your Player doesn’t have an ActionScheduler component attached. It’s possible that the scene or player prefab didn’t save correctly when you restarted Unity.

1 Like

That’s exactly what appears to have happened. I can’t believe I didn’t notice the script was no longer attached to the Player. Thank you so much for the help.

It happens sometimes.

1 Like

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

Privacy & Terms