RPG => 3RD Person Chap 31 Enemies no chase

Hello Brian.

I’m in chapter 31 in your tuto to transform actual RPG course to Nathan’s 3RD person Course and I’ve this error message in the console:

My enemies don’t surrond me …

NullReferenceException: Object reference not set to an instance of an object
RPG.States.Enemies.EnemyBaseState.Move (UnityEngine.Vector3 direction, System.Single deltaTime) (at Assets/Scripts/States/Enemies/EnemyBaseState.cs:26)
RPG.States.Enemies.EnemyBaseState.Move (System.Single deltaTime) (at Assets/Scripts/States/Enemies/EnemyBaseState.cs:21)
RPG.States.Enemies.EnemyIdleState.Tick (System.Single deltaTime) (at Assets/Scripts/States/Enemies/EnemyIdleState.cs:23)
RPG.States.StateMachine.Update () (at Assets/Scripts/States/StateMachine.cs:18)

Here are my scripts.

EnemyBaseState:

using UnityEngine;

namespace RPG.States.Enemies
{
    public abstract class EnemyBaseState : State
    {
        public EnemyBaseState(EnemyStateMachine stateMachine)
        {
            this.stateMachine = stateMachine;
        }

        protected EnemyStateMachine stateMachine;

        protected bool IsInChaseRange()
        {
            return Vector3.SqrMagnitude(stateMachine.transform.position - stateMachine.Player.transform.position) <= stateMachine.PlayerChasingRangedSquared;
        }
        
        protected void Move(float deltaTime)
        {
            Move(Vector3.zero, deltaTime);
        }
        
        protected void Move(Vector3 direction, float deltaTime)
        {
            stateMachine.CharacterController.Move((direction + stateMachine.ForceReceiver.Movement) * deltaTime);
        }
        
        protected void FaceTarget(Vector3 target, float deltaTime)
        {
            Vector3 directionToTarget = target - stateMachine.transform.position;
            directionToTarget.y = 0;
            stateMachine.transform.rotation = Quaternion.Slerp(stateMachine.transform.rotation, Quaternion.LookRotation(directionToTarget), stateMachine.RotationSpeed * deltaTime);
        }
        
        protected float GetNormalizedTime(string tag = "Attack")
        {
            var currentInfo= stateMachine.Animator.GetCurrentAnimatorStateInfo(0);
            var nextInfo = stateMachine.Animator.GetNextAnimatorStateInfo(0);
            if (stateMachine.Animator.IsInTransition(0) && nextInfo.IsTag(tag))
            {
                return nextInfo.normalizedTime;
            }
            else if(!stateMachine.Animator.IsInTransition(0) && currentInfo.IsTag(tag))
            {
                return currentInfo.normalizedTime;
            }

            return 0;
        }
    }
}

My Enemy

My EnemyIdleState:

using UnityEngine;

namespace RPG.States.Enemies
{
    public class EnemyIdleState : EnemyBaseState
    {
        public EnemyIdleState(EnemyStateMachine stateMachine) : base(stateMachine)
        {
        }
                
        private static readonly int FreeLookBlendTreeHash = Animator.StringToHash("FreeLookBlendTree");
        private static readonly int FreeLookSpeedHash = Animator.StringToHash("FreeLookSpeed");
        private bool idleSpeedReached;

        public override void Enter()
        {
            
            stateMachine.Animator.CrossFadeInFixedTime(FreeLookBlendTreeHash, stateMachine.CrossFadeDuration);
        }

        public override void Tick(float deltaTime)
        {
            Move(deltaTime);
            if (IsInChaseRange())
            {
                stateMachine.SwitchState(new EnemyChasingState(stateMachine));
                return;
            }
            if(!idleSpeedReached)
            {
                stateMachine.Animator.SetFloat(FreeLookSpeedHash, 0f, stateMachine.AnimatorDampTime, deltaTime);
                if (stateMachine.Animator.GetFloat(FreeLookSpeedHash) < .05f)
                {
                    idleSpeedReached = true;
                }
            }
        }

        public override void Exit()
        {
            
        }
    }
}

And, I don’t know why my StateMachine…

using UnityEngine;

namespace RPG.States
{
    public abstract class StateMachine : MonoBehaviour
    {
        private State currentState;

        public void SwitchState(State newState)
        {
            currentState?.Exit();
            currentState = newState;
            currentState?.Enter();
        }
        
        private void Update()
        {
            currentState?.Tick(Time.deltaTime); 
        }
    }
}

It’s according Move method.

Line 21:(Move(Vector3.zero, deltaTime):wink:

        protected void Move(float deltaTime)
        {
            Move(Vector3.zero, deltaTime);
        }

Line 26: (stateMachine.CharacterController.Move((direction + stateMachine.ForceReceiver.Movement) * deltaTime):wink:


        protected void Move(Vector3 direction, float deltaTime)
        {
            stateMachine.CharacterController.Move((direction + stateMachine.ForceReceiver.Movement) * deltaTime);
        }

and the move call in the EnemyIdleState

        public override void Tick(float deltaTime)
        {
            Move(deltaTime);
            if (IsInChaseRange())

My Enemy looks correctly filled in the inspector:

I must admitt I don’t understand too much what happens…

I’ve double/triple check the script and your in the GitHub.

I don’t understand…

Any Idea?

Thanks.

François.

PS:

As I remove override animator as you said, I had an error in my weaponConfig script but in the EDITOR part.

I followed your other tuto to have an nice object creator.

So in my WeaponConfig script I have quoted SetAnimatorOverride method:

        /*void SetAnimatorOverride(AnimatorOverrideController newOverride)
        {
            if (newOverride == animatorOverride) return;
            SetUndo("Change AnimatorOverride");
            animatorOverride = newOverride;
            Dirty();
        }*/

And

//SetAnimatorOverride((AnimatorOverrideController)EditorGUILayout.ObjectField("Outrepasser l'Animator", animatorOverride, typeof(AnimatorOverrideController), false));

in the final public override void DrawCustomInspector() method.

You’re gonna laugh when you see it…

lol :slight_smile: my player has so much friends now :smiley:

A little bit hard to escape lol :smiley:

Thank you Brian !

Have a nice day.

François

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