Search Unity

MissingReferenceException error when loading new scene

Discussion in 'Scripting' started by fullerfusion, Mar 24, 2019.

  1. fullerfusion

    fullerfusion

    Joined:
    Dec 2, 2018
    Posts:
    23
    Hello, I'm creating this adventure game that has three scenes (will plan to add more in the future). I want my player to gain XP and carries any XP gains to the next scene, so I'm using DontDestroyOnLoad. However, when my player enters the next scene I can not longer move my player around the scene. The player's movements and animations are controlled with my Xbox controller. I have animations that trigger when I do Input.GetButton and they work perfectly, but when I try to move my character horizontal or vertical with the Input.GetAxisRaw those movements no longer work in the new scene.

    Unity gave this MissingReferenceException error from my character controller.

    MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    UnityEngine.Transform.get_rotation () <0x14bea53b0 + 0x00072> in <87f35bae0d0044ee81a6d75ba47715a8>:0
    UnityEngine.Transform.get_eulerAngles () (at /Users/builduser/buildslave/unity/build/Runtime/Transform/ScriptBindings/Transform.bindings.cs:38)
    XavianController.Move (UnityEngine.Vector2 inputDir, System.Boolean running) (at Assets/Scripts/Player/XavianController.cs:104)

    Below is my code from my character controller that the error is coming from. I believe it says line 104 but I can't seem to find the error. I would greatly appreaciate if anybody could help with this error. Been struggling for the past hour.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class XavianController : MonoBehaviour {
    6.  
    7.     public float walkSpeed = 2;
    8.     public float runSpeed = 6;
    9.     public float gravity = -12;
    10.     public float jumpHeight = 2;
    11.     [Range(0, 1)]
    12.     public float airControlPercent;
    13.  
    14.     public float turnSmoothTime = 0.2f;
    15.     float turnSmoothVelocity;
    16.  
    17.     public float speedSmoothTime = 0.1f;
    18.     float speedSmoothVelocity;
    19.     float currentSpeed;
    20.     float velocityY;
    21.  
    22.     Animator animator;
    23.     Transform cameraT;
    24.     CharacterController controller;
    25.  
    26.     public bool isJumping;
    27.     public float jumpTimer = 0.7f;                                              //Adjust the timer for jumping
    28.     public bool isKicking;
    29.     public float kickTimer = 0.7f;                                              //Adjust the timer for kicking
    30.  
    31.     private bool playerExists;                                                  //Check for any duplicates of the gameobject
    32.  
    33.     void Start()
    34.     {
    35.         animator = GetComponent<Animator>();
    36.         cameraT = Camera.main.transform;
    37.         controller = GetComponent<CharacterController>();
    38.  
    39.         //Don't destroy game object or duplicate game object when entering a new scene
    40.         if(!playerExists)
    41.         {
    42.            playerExists = true;
    43.            DontDestroyOnLoad(transform.gameObject);
    44.         }
    45.         else
    46.         {
    47.            Destroy(gameObject);
    48.        }
    49.  
    50.     }
    51.  
    52.     void Update()
    53.     {
    54.  
    55.         // Controls for movement and running
    56.         Vector2 input = new Vector2(Input.GetAxisRaw("Xbox_Horizontal"), Input.GetAxisRaw("Xbox_Vertical"));
    57.         Vector2 inputDir = input.normalized;
    58.         bool running = Input.GetButton("Xbox_Running");
    59.  
    60.         Move(inputDir, running);
    61.  
    62.         //Stop player from spamming the jump button
    63.         if (isJumping == false && Input.GetButton("Xbox_Jump"))
    64.         {
    65.             animator.SetTrigger("Jump");
    66.             isJumping = true;
    67.         }
    68.         if (isJumping == true)
    69.         {
    70.             jumpTimer -= Time.deltaTime;
    71.         }
    72.         if (jumpTimer <= 0)
    73.         {
    74.             isJumping = false;
    75.             jumpTimer = 0.7f;
    76.         }
    77.  
    78.         //Stop player from spamming the kick button
    79.         if (isKicking == false && Input.GetButton("Xbox_Kick"))
    80.         {
    81.             animator.SetTrigger("Kicking");
    82.             isKicking = true;
    83.         }
    84.         if (isKicking == true)
    85.         {
    86.             kickTimer -= Time.deltaTime;
    87.         }
    88.         if (kickTimer <= 0)
    89.         {
    90.             isKicking = false;
    91.             kickTimer = 0.7f;
    92.         }
    93.  
    94.         // animator
    95.         float animationSpeedPercent = ((running) ? currentSpeed / runSpeed : currentSpeed / walkSpeed * .5f);
    96.         animator.SetFloat("speedPercent", animationSpeedPercent, speedSmoothTime, Time.deltaTime);
    97.  
    98.     }
    99.  
    100.     void Move(Vector2 inputDir, bool running)
    101.     {
    102.         if (inputDir != Vector2.zero)
    103.         {
    104.             float targetRotation = (Mathf.Atan2(inputDir.x, inputDir.y) * Mathf.Rad2Deg) + cameraT.eulerAngles.y;
    105.             transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref turnSmoothVelocity, GetModifiedSmoothTime(turnSmoothTime));
    106.         }
    107.  
    108.         float targetSpeed = ((running) ? runSpeed : walkSpeed) * inputDir.magnitude;
    109.         currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedSmoothVelocity, GetModifiedSmoothTime(speedSmoothTime));
    110.  
    111.         velocityY += Time.deltaTime * gravity;
    112.         Vector3 velocity = transform.forward * currentSpeed + Vector3.up * velocityY;
    113.  
    114.         controller.Move(velocity * Time.deltaTime);
    115.         currentSpeed = new Vector2(controller.velocity.x, controller.velocity.z).magnitude;
    116.  
    117.         if (controller.isGrounded)
    118.         {
    119.             velocityY = 0;
    120.         }
    121.  
    122.     }
    123.  
    124.     void Jump()
    125.     {
    126.         if (controller.isGrounded)
    127.         {
    128.             float jumpVelocity = Mathf.Sqrt(-2 * gravity * jumpHeight);
    129.             velocityY = jumpVelocity;
    130.         }
    131.     }
    132.  
    133.     float GetModifiedSmoothTime(float smoothTime)
    134.     {
    135.         if (controller.isGrounded)
    136.         {
    137.             return smoothTime;
    138.         }
    139.  
    140.         if (airControlPercent == 0)
    141.         {
    142.             return float.MaxValue;
    143.         }
    144.         return smoothTime / airControlPercent;
    145.     }
    146. }
     
  2. WheresMommy

    WheresMommy

    Joined:
    Oct 4, 2012
    Posts:
    890
    Are you having players inside your other scripts? You should make it a global variable instead of private, because in that case it is always false when start is being called on a new instance of your player. Make a public static XavianController instance and assign this on your awake for example.
     
  3. fullerfusion

    fullerfusion

    Joined:
    Dec 2, 2018
    Posts:
    23
    Thanks for your comment! Alright, I made a public static instance and created a Void Awake:
    Code (CSharp):
    1.  
    2. public static XavianController instance = null;
    3. void Awake()
    4.        {
    5.            //Check if instance already exists
    6.             if (instance == null)
    7.              
    8.                //if not, set instance to this
    9.                 instance = this;
    10.          
    11.            //If instance already exists and it's not this:
    12.             else if (instance != this)
    13.              
    14.                //Then destroy this
    15.                 Destroy(gameObject);
    16.          
    17.            //Sets this to not be destroyed when reloading scene
    18.             DontDestroyOnLoad(gameObject);
    19. }
    20.  
    However, when I tried to go to the next scene I'm still not able to move my character. I get this same error:
    MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    UnityEngine.Transform.get_rotation () <0x14f544fa0 + 0x00072> in <87f35bae0d0044ee81a6d75ba47715a8>:0
    UnityEngine.Transform.get_eulerAngles () (at /Users/builduser/buildslave/unity/build/Runtime/Transform/ScriptBindings/Transform.bindings.cs:38)
    XavianController.Move (UnityEngine.Vector2 inputDir, System.Boolean running) (at Assets/Scripts/Player/XavianController.cs:125)

    It's saying the error is coming from line 125 with my bool running. Here's the area around that line of coding.
    Code (CSharp):
    1.      
    2. void Move(Vector2 inputDir, bool running)
    3.         {
    4.             if (inputDir != Vector2.zero)
    5.             {
    6.       //Line125    [B]float targetRotation = (Mathf.Atan2(inputDir.x, inputDir.y) * Mathf.Rad2Deg) + cameraT.eulerAngles.y;[/B]
    7.                 transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref turnSmoothVelocity, GetModifiedSmoothTime(turnSmoothTime));
    8.             }
    9.    
    10.             float targetSpeed = ((running) ? runSpeed : walkSpeed) * inputDir.magnitude;
    11.             currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedSmoothVelocity, GetModifiedSmoothTime(speedSmoothTime));
    12.    
    13.             velocityY += Time.deltaTime * gravity;
    14.             Vector3 velocity = transform.forward * currentSpeed + Vector3.up * velocityY;
    15.    
    16.             controller.Move(velocity * Time.deltaTime);
    17.             currentSpeed = new Vector2(controller.velocity.x, controller.velocity.z).magnitude;
    18.    
    19.             if (controller.isGrounded)
    20.             {
    21.                 velocityY = 0;
    22.             }
    23.    
    24.         }
    25.  
    The only thing in my next scene is an empty game job that spawns the player to a specific location. I added a script to it call Spawn Manager. I don't know if that's the issue or not but I'll include that code as well.
    Code (CSharp):
    1.  
    2. public class SpawnManager : MonoBehaviour
    3. {
    4.     public GameObject XavianPlayer;
    5.     public GameObject PlayerPrefab;
    6.     public GameObject SpawnLocation;
    7.     void Awake()
    8.     {
    9.         if (GameObject.FindGameObjectWithTag("Player") != null)
    10.         {
    11.             //player already exists, so just move it to the spawn location and set the Player gameobject parameter
    12.             XavianPlayer = GameObject.Find("Player");
    13.             XavianPlayer.transform.position = SpawnLocation.transform.position;
    14.         }
    15.         else
    16.         {
    17.             //instantiate the player
    18.             XavianPlayer = Instantiate(PlayerPrefab);
    19.             XavianPlayer.transform.position = SpawnLocation.transform.position;
    20.         }
    21.     }
    22. }
     
  4. Tydin

    Tydin

    Joined:
    Jul 10, 2015
    Posts:
    1
    Hi fullerfusion, i have this same problem. Have you been able to figure it out?