-1

I keep getting the error:

NullReferenceException: Object reference not set to an instance of an object

which brings me to the line:

if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, enemy.groundCheckDistance))

I did some testing and found out that the enemy was in fact set to the instance of this object because I printed the value for enemy.groundCheckDistance every update and it successfully printed the correct value from the from the enemy object every time. I even changed it in the inspector and it retrieved the correct value. I later discovered that all of the objects I set in the Start() method are turning to null only outside of the Start() method. (By this I mean the Animator, Rigidbody, Capsule Collider, etc. are turning null) I am 100% sure that an animator, capsule collider, rigidbody, and enemy are attached to this gameobject. However, I am creating them on Awake() in a different class. Could that be why I am getting the error? If it is how do I fix it?

This is the script where I add the components on Awake(). When I run the game I see that they have successfully been added.

using UnityEngine;
using UnityEngine.AI;

namespace MGCO.Characters.EnemyScripts
{
    //USED TO CONSTRUCT THE COMPONENTS ON AN ENEMY AT RUNTIME
    public class EnemyComponents : MonoBehaviour
    {
        //INITIALIZE ENEMY OBJECT
        Enemy enemy;

        void Awake()
        {
            enemy = GetComponent<Enemy>();

            //MAKE SURE ENEMY IS NOT HUMANOID
            if (!enemy.isHumanoid)
            {
                //CHECK TO SEE IF MESH FILTER ALREADY EXISTS
                if (!GetComponent<MeshFilter>())
                {
                    //INITIALIZE "MeshFilter"
                    MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();

                    //SET MESH OF MESHFILTER
                    meshFilter.mesh = enemy.enemyMesh;
                }

                //CHECK TO SEE IF MESH RENDERER ALREADY EXISTS
                if (!GetComponent<MeshRenderer>())
                {
                    //INITIALIZE "MeshRenderer"
                    MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();

                    //SET MESH MATERIAL
                    meshRenderer.material = enemy.meshMaterial;
                }
            }
            //MAKE SURE ENEMY IS NOT HUMANOID
            else
            {
                //CHECK TO SEE IF ANIMATOR ALREADY EXISTS
                if (!GetComponent<Animator>())
                {
                    //INITIALIZE "RuntimeAnimatorController"
                    Animator animator = gameObject.AddComponent<Animator>();

                    //SET RUNTIMEANIMATORCONTROLLER
                    animator.runtimeAnimatorController = enemy.runtimeAnimatorController;

                    //SET AVATAR
                    animator.avatar = enemy.avatar;

                    //SET ROOT ANIMATION BOOL
                    animator.applyRootMotion = enemy.applyRootMotion;
                }
            }

            //CHECK TO SEE IF RIGIDBODY ALREADY EXISTS
            if (!GetComponent<Rigidbody>())
            {
                //INITIALIZE "Rigidbody"
                Rigidbody enemyRigidbody = gameObject.AddComponent<Rigidbody>();

                //SET MASS
                enemyRigidbody.mass = enemy.mass;

                //SET DRAG
                enemyRigidbody.drag = enemy.drag;

                //SET ANGULAR DRAG
                enemyRigidbody.angularDrag = enemy.angularDrag;

                //SET USE GRAVITY
                enemyRigidbody.useGravity = enemy.useGravity;
            }

            //CHECK TO SEE IF NAVMESHAGENT ALREADY EXISTS
            if (!GetComponent<NavMeshAgent>())
            {
                //INITIALIZE "NavMeshAgent"
                NavMeshAgent navMeshAgent = gameObject.AddComponent<NavMeshAgent>();

                //SET NAVMESH SPEED
                navMeshAgent.speed = enemy.speed;

                //SET BASE OFFSET
                navMeshAgent.baseOffset = enemy.baseOffset;

                //SET ANGULAR SPEED (HOW FAST ENEMY TURNS CORNERS)
                navMeshAgent.angularSpeed = enemy.angularSpeed;

                //SET ACCELERATION
                navMeshAgent.acceleration = enemy.acceleration;

                //SET STOPPING DISTANCE
                navMeshAgent.stoppingDistance = enemy.stoppingDistance;

                //SET OBSTACLE AVOIDANCE RADIUS
                navMeshAgent.radius = enemy.navmeshRadius;

                //SET OBSTACLE AVOIDANCE HEIGHT
                navMeshAgent.radius = enemy.navmeshHeight;
            }

            //CHECK TO SEE IF COLLIDER ALREADY EXISTS
            if (!GetComponent<CapsuleCollider>())
            {
                //INITIALIZE "CapsuleCollider"
                CapsuleCollider capsuleCollider = gameObject.AddComponent<CapsuleCollider>();

                //SET CENTER
                capsuleCollider.center = enemy.center;

                //SET COLLIDER RADIUS
                capsuleCollider.radius = enemy.colliderRadius;

                //SET COLLIDER HEIGHT
                capsuleCollider.height = enemy.colliderHeight;
            }
        }
    }
}

This is the script that gets the error:

using UnityEngine;

namespace MGCO.Characters.EnemyScripts
{
    public class EnemyAnimation : MonoBehaviour
    {
        //REFERENCE GAMEOBJECTS
        Enemy enemy;
        Animator animator;
        Rigidbody enemyRigidbody;
        CapsuleCollider capsuleCollider;


        //INITIALIZE VARS
        Vector3 groundNormal;
        Vector3 capsuleCenter;

        private bool isCrouching;
        private bool isGrounded;

        private float originalGroundCheckDistance;
        private float turnAmount;
        private float forwardAmount;
        private float capsuleHeight;

        //VALUE FOR HALF (NEVER CHANGES)
        const float half = 0.5f;

        //RUNS ON START
        void Start()
        {
            enemy = GetComponent<Enemy>();

            animator = GetComponent<Animator>();
            enemyRigidbody = GetComponent<Rigidbody>();
            capsuleCollider = GetComponent<CapsuleCollider>();
            capsuleHeight = capsuleCollider.height;
            capsuleCenter = capsuleCollider.center;

            //FREEZE RIGIDBODY ROTATION
            enemyRigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
            //SET LOCAL VARIABLE
            originalGroundCheckDistance = enemy.groundCheckDistance;
        }

        ...

        //CHECKS POSITION OF GROUND BENEATH PLAYER
        void CheckGroundStatus()
        {
            //INITIALIZE RAYCASTHIT
            RaycastHit hitInfo;

            //IF RAYCASTS DOWN TO "GroundCheckDistance" VARIABLE
            if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, enemy.groundCheckDistance))
            {
                //SET GROUNDNORMAL TO THE SURFACE OF THE RAYCASTHIT
                groundNormal = hitInfo.normal;
                //SET JUMPING FALSE
                isGrounded = true;
                //ANIMATOR APPLY ROOT MOTION
                animator.applyRootMotion = true;
            }
            else
            {
                //SET JUMPING TO TRUE
                isGrounded = false;
                //SET GROUNDNORMAL TO GO UP
                groundNormal = Vector3.up;
                //ANIMATOR DO NOT APPLY ROOT MOTION
                animator.applyRootMotion = false;
            }
        }
    }
}

And thank you for your help :)

Moses
  • 43
  • 1
  • 7
  • 1
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – BugFinder May 01 '18 at 13:55
  • 1
    The error is clear - why would the animator exist outside that start function? you never set it to anything that persists out side of it – BugFinder May 01 '18 at 13:59
  • Use the debugger – Ben May 01 '18 at 14:01
  • @BugFinder Where else would I set it? – Moses May 01 '18 at 14:05
  • 1
    Is not the setting of it thats the issue its the scope of it.. you declared and set the variable in start, so thats the only place it existed once you leave start, its gone – BugFinder May 01 '18 at 14:06
  • Could you add a screenshot of the enemy at runtime after the enemy is created? (I mean the inspector.) – Gunnar B. May 01 '18 at 15:13

1 Answers1

1
//REFERENCE GAMEOBJECTS  
Enemy enemy;  
Animator animator;  
Rigidbody enemyRigidbody;  
CapsuleCollider capsuleCollider;

Here you declare your references but you are not ASSIGNING them anywhere.

Rigidbody enemyRigidbody = gameObject.AddComponent<Rigidbody>();

Here, you add the rigidbody component and it returns a reference to itself. However, you assigned the reference to a DIFFERENT variable called enemyRigidbody instead of the one you declared above.

Even though the variable names are similar, declaring a variable within a smaller scope/declaration space (One within a class, another within a method) creates a ENTIRELY NEW variable with the same name but ONLY USABLE WITHIN THE METHOD ITSELF.

What you want is:

enemyRigidbody = gameObject.AddComponent<Rigidbody>();

which is a reference to the Rigidbody you declared above.

Swift
  • 3,250
  • 1
  • 19
  • 35