Search Unity

Getting NullReferenceException when Spawning via GameManager

Discussion in 'Scripting' started by TheChrizZly, Dec 3, 2017.

  1. TheChrizZly

    TheChrizZly

    Joined:
    Dec 3, 2017
    Posts:
    1
    Hello,
    I do have the UnityStandardAssets Car and want to spawn this via a GameManager.
    When I spawn the car before the game start manually I have no problem at all.

    When I spawn it via the game Manager I get the Error:
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object.
    2. UnityStandardAssets.Vehicles.Car.CarController.get_CurrentSpeed() (at Assets/Car/Scripts/CarController.cs:54)
    The CarController.cs is the standard CarController from Unity:
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3.  
    4. namespace UnityStandardAssets.Vehicles.Car
    5. {
    6.     internal enum CarDriveType
    7.     {
    8.         FrontWheelDrive,
    9.         RearWheelDrive,
    10.         FourWheelDrive
    11.     }
    12.  
    13.     internal enum SpeedType
    14.     {
    15.         MPH,
    16.         KPH
    17.     }
    18.  
    19.     public class CarController : MonoBehaviour
    20.     {
    21.         [SerializeField] private CarDriveType m_CarDriveType = CarDriveType.FourWheelDrive;
    22.         [SerializeField] private WheelCollider[] m_WheelColliders = new WheelCollider[4];
    23.         [SerializeField] private GameObject[] m_WheelMeshes = new GameObject[4];
    24.         [SerializeField] private WheelEffects[] m_WheelEffects = new WheelEffects[4];
    25.         [SerializeField] private Vector3 m_CentreOfMassOffset;
    26.         [SerializeField] private float m_MaximumSteerAngle;
    27.         [Range(0, 1)] [SerializeField] private float m_SteerHelper; // 0 is raw physics , 1 the car will grip in the direction it is facing
    28.         [Range(0, 1)] [SerializeField] private float m_TractionControl; // 0 is no traction control, 1 is full interference
    29.         [SerializeField] private float m_FullTorqueOverAllWheels;
    30.         [SerializeField] private float m_ReverseTorque;
    31.         [SerializeField] private float m_MaxHandbrakeTorque;
    32.         [SerializeField] private float m_Downforce = 400f;
    33.         [SerializeField] private SpeedType m_SpeedType;
    34.         [SerializeField] private float m_Topspeed = 200;
    35.         [SerializeField] private static int NoOfGears = 5;
    36.         [SerializeField] private float m_RevRangeBoundary = 1f;
    37.         [SerializeField] private float m_SlipLimit;
    38.         [SerializeField] private float m_BrakeTorque;
    39.  
    40.         private Quaternion[] m_WheelMeshLocalRotations;
    41.         private Vector3 m_Prevpos, m_Pos;
    42.         private float m_SteerAngle;
    43.         private int m_GearNum;
    44.         private float m_GearFactor;
    45.         private float m_OldRotation;
    46.         private float m_CurrentTorque;
    47.         private Rigidbody m_Rigidbody;
    48.         private const float k_ReversingThreshold = 0.01f;
    49.         private float m_Orientation;
    50.  
    51.         public bool Skidding { get; private set; }
    52.         public float BrakeInput { get; private set; }
    53.         public float CurrentSteerAngle { get { return m_SteerAngle; } }
    54.         public float CurrentSpeed { get { return m_Rigidbody.velocity.magnitude * 2.23693629f; } }
    55.         public float MaxSpeed { get { return m_Topspeed; } }
    56.         public float Revs { get; private set; }
    57.         public float AccelInput { get; private set; }
    58.         // Use this for initialization
    59.         private void Start()
    60.         {
    61.             m_WheelMeshLocalRotations = new Quaternion[4];
    62.             for (int i = 0; i < 4; i++)
    63.             {
    64.                 m_WheelMeshLocalRotations[i] = m_WheelMeshes[i].transform.localRotation;
    65.             }
    66.             m_WheelColliders[0].attachedRigidbody.centerOfMass = m_CentreOfMassOffset;
    67.  
    68.             m_MaxHandbrakeTorque = float.MaxValue;
    69.  
    70.             m_Rigidbody = GetComponent<Rigidbody>();
    71.             m_CurrentTorque = m_FullTorqueOverAllWheels - (m_TractionControl * m_FullTorqueOverAllWheels);
    72.         }
    73.  
    74.         private void GearChanging()
    75.         {
    76.             float f = Mathf.Abs(CurrentSpeed / MaxSpeed);
    77.             float upgearlimit = (1 / (float)NoOfGears) * (m_GearNum + 1);
    78.             float downgearlimit = (1 / (float)NoOfGears) * m_GearNum;
    79.  
    80.             if (m_GearNum > 0 && f < downgearlimit)
    81.             {
    82.                 m_GearNum--;
    83.             }
    84.  
    85.             if (f > upgearlimit && (m_GearNum < (NoOfGears - 1)))
    86.             {
    87.                 m_GearNum++;
    88.             }
    89.         }
    90.  
    91.  
    92.         // simple function to add a curved bias towards 1 for a value in the 0-1 range
    93.         private static float CurveFactor(float factor)
    94.         {
    95.             return 1 - (1 - factor) * (1 - factor);
    96.         }
    97.  
    98.  
    99.         // unclamped version of Lerp, to allow value to exceed the from-to range
    100.         private static float ULerp(float from, float to, float value)
    101.         {
    102.             return (1.0f - value) * from + value * to;
    103.         }
    104.  
    105.  
    106.         private void CalculateGearFactor()
    107.         {
    108.             float f = (1 / (float)NoOfGears);
    109.             // gear factor is a normalised representation of the current speed within the current gear's range of speeds.
    110.             // We smooth towards the 'target' gear factor, so that revs don't instantly snap up or down when changing gear.
    111.             var targetGearFactor = Mathf.InverseLerp(f * m_GearNum, f * (m_GearNum + 1), Mathf.Abs(CurrentSpeed / MaxSpeed));
    112.             m_GearFactor = Mathf.Lerp(m_GearFactor, targetGearFactor, Time.deltaTime * 5f);
    113.         }
    114.  
    115.  
    116.         private void CalculateRevs()
    117.         {
    118.             // calculate engine revs (for display / sound)
    119.             // (this is done in retrospect - revs are not used in force/power calculations)
    120.             CalculateGearFactor();
    121.             var gearNumFactor = m_GearNum / (float)NoOfGears;
    122.             var revsRangeMin = ULerp(0f, m_RevRangeBoundary, CurveFactor(gearNumFactor));
    123.             var revsRangeMax = ULerp(m_RevRangeBoundary, 1f, gearNumFactor);
    124.             Revs = ULerp(revsRangeMin, revsRangeMax, m_GearFactor);
    125.         }
    126.  
    127.  
    128.         public void Move(float steering, float accel, float footbrake, float handbrake)
    129.         {
    130.             for (int i = 0; i < 4; i++)
    131.             {
    132.                 Quaternion quat;
    133.                 Vector3 position;
    134.                 m_WheelColliders[i].GetWorldPose(out position, out quat);
    135.                 m_WheelMeshes[i].transform.position = position;
    136.                 m_WheelMeshes[i].transform.rotation = quat;
    137.             }
    138.  
    139.             //clamp input values
    140.             steering = Mathf.Clamp(steering, -1, 1);
    141.             AccelInput = accel = Mathf.Clamp(accel, 0, 1);
    142.             BrakeInput = footbrake = -1 * Mathf.Clamp(footbrake, -1, 0);
    143.             handbrake = Mathf.Clamp(handbrake, 0, 1);
    144.  
    145.             //Set the steer on the front wheels.
    146.             //Assuming that wheels 0 and 1 are the front wheels.
    147.             m_SteerAngle = steering * m_MaximumSteerAngle;
    148.             m_WheelColliders[0].steerAngle = m_SteerAngle;
    149.             m_WheelColliders[1].steerAngle = m_SteerAngle;
    150.  
    151.             SteerHelper();
    152.             ApplyDrive(accel, footbrake);
    153.             CapSpeed();
    154.  
    155.             //Set the handbrake.
    156.             //Assuming that wheels 2 and 3 are the rear wheels.
    157.             if (handbrake > 0f)
    158.             {
    159.                 var hbTorque = handbrake * m_MaxHandbrakeTorque;
    160.                 m_WheelColliders[2].brakeTorque = hbTorque;
    161.                 m_WheelColliders[3].brakeTorque = hbTorque;
    162.             }
    163.  
    164.  
    165.             CalculateRevs();
    166.             GearChanging();
    167.  
    168.             AddDownForce();
    169.             CheckForWheelSpin();
    170.             TractionControl();
    171.         }
    172.  
    173.  
    174.         private void CapSpeed()
    175.         {
    176.             float speed = m_Rigidbody.velocity.magnitude;
    177.             switch (m_SpeedType)
    178.             {
    179.                 case SpeedType.MPH:
    180.  
    181.                     speed *= 2.23693629f;
    182.                     if (speed > m_Topspeed)
    183.                         m_Rigidbody.velocity = (m_Topspeed / 2.23693629f) * m_Rigidbody.velocity.normalized;
    184.                     break;
    185.  
    186.                 case SpeedType.KPH:
    187.                     speed *= 3.6f;
    188.                     if (speed > m_Topspeed)
    189.                         m_Rigidbody.velocity = (m_Topspeed / 3.6f) * m_Rigidbody.velocity.normalized;
    190.                     break;
    191.             }
    192.         }
    193.  
    194.  
    195.         private void ApplyDrive(float accel, float footbrake)
    196.         {
    197.  
    198.             float thrustTorque;
    199.             switch (m_CarDriveType)
    200.             {
    201.                 case CarDriveType.FourWheelDrive:
    202.                     thrustTorque = accel * (m_CurrentTorque / 4f);
    203.                     for (int i = 0; i < 4; i++)
    204.                     {
    205.                         m_WheelColliders[i].motorTorque = thrustTorque;
    206.                     }
    207.                     break;
    208.  
    209.                 case CarDriveType.FrontWheelDrive:
    210.                     thrustTorque = accel * (m_CurrentTorque / 2f);
    211.                     m_WheelColliders[0].motorTorque = m_WheelColliders[1].motorTorque = thrustTorque;
    212.                     break;
    213.  
    214.                 case CarDriveType.RearWheelDrive:
    215.                     thrustTorque = accel * (m_CurrentTorque / 2f);
    216.                     m_WheelColliders[2].motorTorque = m_WheelColliders[3].motorTorque = thrustTorque;
    217.                     break;
    218.  
    219.             }
    220.  
    221.             for (int i = 0; i < 4; i++)
    222.             {
    223.                 if (CurrentSpeed > 5 && Vector3.Angle(transform.forward, m_Rigidbody.velocity) < 50f)
    224.                 {
    225.                     m_WheelColliders[i].brakeTorque = m_BrakeTorque * footbrake;
    226.                 }
    227.                 else if (footbrake > 0)
    228.                 {
    229.                     m_WheelColliders[i].brakeTorque = 0f;
    230.                     m_WheelColliders[i].motorTorque = -m_ReverseTorque * footbrake;
    231.                 }
    232.             }
    233.         }
    234.  
    235.  
    236.         private void SteerHelper()
    237.         {
    238.             for (int i = 0; i < 4; i++)
    239.             {
    240.                 WheelHit wheelhit;
    241.                 m_WheelColliders[i].GetGroundHit(out wheelhit);
    242.                 if (wheelhit.normal == Vector3.zero)
    243.                     return; // wheels arent on the ground so dont realign the rigidbody velocity
    244.             }
    245.  
    246.             // this if is needed to avoid gimbal lock problems that will make the car suddenly shift direction
    247.             if (Mathf.Abs(m_OldRotation - transform.eulerAngles.y) < 10f)
    248.             {
    249.                 var turnadjust = (transform.eulerAngles.y - m_OldRotation) * m_SteerHelper;
    250.                 Quaternion velRotation = Quaternion.AngleAxis(turnadjust, Vector3.up);
    251.                 m_Rigidbody.velocity = velRotation * m_Rigidbody.velocity;
    252.             }
    253.             m_OldRotation = transform.eulerAngles.y;
    254.         }
    255.  
    256.  
    257.         // this is used to add more grip in relation to speed
    258.         private void AddDownForce()
    259.         {
    260.             m_WheelColliders[0].attachedRigidbody.AddForce(-transform.up * m_Downforce *
    261.                                                          m_WheelColliders[0].attachedRigidbody.velocity.magnitude);
    262.         }
    263.  
    264.  
    265.         // checks if the wheels are spinning and is so does three things
    266.         // 1) emits particles
    267.         // 2) plays tiure skidding sounds
    268.         // 3) leaves skidmarks on the ground
    269.         // these effects are controlled through the WheelEffects class
    270.         private void CheckForWheelSpin()
    271.         {
    272.             // loop through all wheels
    273.             for (int i = 0; i < 4; i++)
    274.             {
    275.                 WheelHit wheelHit;
    276.                 m_WheelColliders[i].GetGroundHit(out wheelHit);
    277.  
    278.                 // is the tire slipping above the given threshhold
    279.                 if (Mathf.Abs(wheelHit.forwardSlip) >= m_SlipLimit || Mathf.Abs(wheelHit.sidewaysSlip) >= m_SlipLimit)
    280.                 {
    281.                     m_WheelEffects[i].EmitTyreSmoke();
    282.  
    283.                     // avoiding all four tires screeching at the same time
    284.                     // if they do it can lead to some strange audio artefacts
    285.                     if (!AnySkidSoundPlaying())
    286.                     {
    287.                         m_WheelEffects[i].PlayAudio();
    288.                     }
    289.                     continue;
    290.                 }
    291.  
    292.                 // if it wasnt slipping stop all the audio
    293.                 if (m_WheelEffects[i].PlayingAudio)
    294.                 {
    295.                     m_WheelEffects[i].StopAudio();
    296.                 }
    297.                 // end the trail generation
    298.                 m_WheelEffects[i].EndSkidTrail();
    299.             }
    300.         }
    301.  
    302.         // crude traction control that reduces the power to wheel if the car is wheel spinning too much
    303.         private void TractionControl()
    304.         {
    305.             WheelHit wheelHit;
    306.             switch (m_CarDriveType)
    307.             {
    308.                 case CarDriveType.FourWheelDrive:
    309.                     // loop through all wheels
    310.                     for (int i = 0; i < 4; i++)
    311.                     {
    312.                         m_WheelColliders[i].GetGroundHit(out wheelHit);
    313.  
    314.                         AdjustTorque(wheelHit.forwardSlip);
    315.                     }
    316.                     break;
    317.  
    318.                 case CarDriveType.RearWheelDrive:
    319.                     m_WheelColliders[2].GetGroundHit(out wheelHit);
    320.                     AdjustTorque(wheelHit.forwardSlip);
    321.  
    322.                     m_WheelColliders[3].GetGroundHit(out wheelHit);
    323.                     AdjustTorque(wheelHit.forwardSlip);
    324.                     break;
    325.  
    326.                 case CarDriveType.FrontWheelDrive:
    327.                     m_WheelColliders[0].GetGroundHit(out wheelHit);
    328.                     AdjustTorque(wheelHit.forwardSlip);
    329.  
    330.                     m_WheelColliders[1].GetGroundHit(out wheelHit);
    331.                     AdjustTorque(wheelHit.forwardSlip);
    332.                     break;
    333.             }
    334.         }
    335.  
    336.  
    337.         private void AdjustTorque(float forwardSlip)
    338.         {
    339.             if (forwardSlip >= m_SlipLimit && m_CurrentTorque >= 0)
    340.             {
    341.                 m_CurrentTorque -= 10 * m_TractionControl;
    342.             }
    343.             else
    344.             {
    345.                 m_CurrentTorque += 10 * m_TractionControl;
    346.                 if (m_CurrentTorque > m_FullTorqueOverAllWheels)
    347.                 {
    348.                     m_CurrentTorque = m_FullTorqueOverAllWheels;
    349.                 }
    350.             }
    351.         }
    352.  
    353.  
    354.         private bool AnySkidSoundPlaying()
    355.         {
    356.             for (int i = 0; i < 4; i++)
    357.             {
    358.                 if (m_WheelEffects[i].PlayingAudio)
    359.                 {
    360.                     return true;
    361.                 }
    362.             }
    363.             return false;
    364.         }
    365.     }
    366. }
    My GameManager calls my CarManager, which spawns my Objects.

    My GameManager.cs looks like:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GameManager : MonoBehaviour {
    6.     public int m_Rounds = 100;
    7.     public GameObject m_CarPrefab;
    8.     public CarManager[] m_Cars;
    9.     private int m_RoundNumber;
    10.     // Use this for initialization
    11.     void Start () {
    12.         SpawnCars();
    13.     }
    14.  
    15.     // Update is called once per frame
    16.     void Update () {
    17.      
    18.     }
    19.     private void SpawnCars()
    20.     {
    21.         for(int i=0;i<m_Cars.Length; i++)
    22.         {
    23.             m_Cars[i].m_Instance = Instantiate(m_CarPrefab, m_Cars[i].m_SpawnPoint.position, m_Cars[i].m_SpawnPoint.rotation) as GameObject;
    24.             m_Cars[i].Setup();
    25.         }
    26.     }
    27. }
    28.  
    and my CarManager.cs looks like:
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityStandardAssets.Vehicles.Car;
    4.  
    5. [Serializable]
    6. public class CarManager {
    7.     public Transform m_SpawnPoint;
    8.     [HideInInspector] public GameObject m_Instance;
    9.     public int initialVelocity;
    10.  
    11.     private CarController car_Control;
    12.     // Use this for initialization
    13.     public void Setup()
    14.     {
    15.         car_Control = m_Instance.GetComponent<CarController>();
    16.         car_Control.m_Speed = initialVelocity;
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update () {
    21.      
    22.     }
    23. }
    24.  
    Any suggestions?

    -Kind regards,
     
  2. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    It's probably the rigidbody that is showing null.
     
  3. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I believe you are correct, @fire7side . The Setup() is being called before the car's Start(), I think.
    You could try to change your SpawnCars (or turn Start into one*, in the same script) to a Coroutine.
    Spawn all of the cars, then yield a frame and do the Setup().