context: //============================================================================================
  // Racing Game Kit v1.0
  // http://www.unityracingkit.com
  // by Yusuf AKDAG - http://www.yusufakdag.com
  // Vehicle Script
  // Last Change : 12/09/2012
  // You can use freely on commercial or other projects. You cant modify and resell.
  //============================================================================================
  
  
  using System;
  using UnityEngine;
  using RacingGameKit.Interfaces;
  using RacingGameKit.RGKCar;
  using System.Collections.Generic;
  
  namespace RacingGameKit.RGKCar.CarControllers
  {
  
      [RequireComponent(typeof(RGKCar_Engine))]
      [AddComponentMenu("Racing Game Kit/Vehicle Controllers/RGKCar C2 - Human Controller")]
      public class RGKCar_C2_Human : RGKCar_C2_ControllerControllerBase
      {
  
          public string ControlsThrottleBinding = "Throttle";
          public string ControlsBrakeBinding = "Brake";
          public string ControlsSteeringBinding = "Horizontal";
          public string ControlsHandbrakeBinding = "Handbrake";
          public string ControlsShiftUpBinding = "ShiftUp";
          public string ControlsShiftDownBinding = "ShiftDown";
          public string ControlsHeadlightsBinding = "Lights";
          public string ControlsResetBinding = "ResetVehicle";
  
          private GameObject waypointContainer;
          private List<Transform> waypoints;
  
          protected Race_Manager RaceManager;
          protected Racer_Register RaceRegister;
  
          private bool IsFirstGearShifted = false;
  
          // Initialize
          void Start()
          {
              GameObject GameManagerContainerGameObject = GameObject.Find("_RaceManager");
              RaceManager = (Race_Manager)GameManagerContainerGameObject.GetComponent(typeof(Race_Manager));
              RaceRegister = (Racer_Register)transform.GetComponent(typeof(Racer_Register));
  
              waypointContainer = RaceManager.Waypoints;
              GetWaypoints();
              base.Start();
          }
  
  
          void Update()
          {
  
              ThrottlePressed = (Input.GetAxisRaw(ControlsThrottleBinding) > 0) ? true : false;
              BrakePressed = (Input.GetAxisRaw(ControlsBrakeBinding) > 0) ? true : false;
  
              if (CarSetup.EngineData.Automatic && CarEngine.CurrentGear == 0)
              {
                  ThrottlePressed = (Input.GetAxisRaw(ControlsBrakeBinding) > 0) ? true : false;
                  BrakePressed = (Input.GetAxisRaw(ControlsThrottleBinding) > 0) ? true : false;
              }
  
              throttleInput = Input.GetAxisRaw(ControlsThrottleBinding);
  
              steerInput = 0;
              steerInput = Input.GetAxisRaw(ControlsSteeringBinding);
  
  
  
  
              if (RaceManager.IsRaceStarted && !RaceRegister.IsRacerFinished)
              {
                  CarSetup.EngineData.Automatic = true;
  
                  if (!IsFirstGearShifted)
                  {
                      CarEngine.CurrentGear = 2;
                      IsFirstGearShifted = true;
                  }
  
                  if (Input.GetButtonDown(ControlsShiftUpBinding))
                  {
                      CarEngine.ShiftUp();
                  }
                  if (Input.GetButtonDown(ControlsShiftDownBinding))
                  {
                      CarEngine.ShiftDown();
                  }
  
                  // Handbrake
                  if (Input.GetAxisRaw(ControlsHandbrakeBinding) > 0)
                  {
                      handbrake = 1;
                  }
                  else
                  {
                      handbrake = 0;
                  }
              }
              else if (RaceRegister.IsRacerFinished)
              {
                  steerInput = 0;
                  throttle = 0f;
                  handbrake = 0.5f;
                  CarSetup.EngineData.Automatic = true;
                  CarEngine.CurrentGear = 1;
              }
              else
              {
                  steerInput = 0;
                  CarSetup.EngineData.Automatic = false;
                  CarEngine.CurrentGear = 1;
                  handbrake = 1f;
              }
  
             
  
              if (Input.GetButtonDown(ControlsHeadlightsBinding))
              {
                  if (isHeadlightsOn)
                  {
                      isHeadlightsOn = false;
                  }
                  else
                  {
                      isHeadlightsOn = true;
                  }
              }
              base.Update();
              CheckIsCarStuck();
          }
  
  
          #region STUCKREMOVAL
  
          /// <summary>
          /// Receives waypint info from waypoint container
          /// </summary>
          private void GetWaypoints()
          {
              Transform[] potentialWaypoints = waypointContainer.GetComponentsInChildren<Transform>();
              waypoints = new List<Transform> { };
  
              foreach (Transform potentialWaypoint in potentialWaypoints)
              {
                  if (potentialWaypoint != waypointContainer.transform)
                  {
                      waypoints.Add(potentialWaypoint);
                  }
              }
  
          }
          protected void CheckIsCarStuck()
          {
              if (RaceRegister.IsRacerStarted && !RaceRegister.IsRacerFinished && !RaceRegister.IsRacerDestroyed && Input.GetButtonDown(ControlsResetBinding))
              {
                  RecoverCar();
                  Debug.Log("Resetting Player Car");
              }
  
              if (layerChangeStarted)
              {
                  layerChangeForIgnoreProcessor();
              }
          }
          public float StuckResetTimer = 0f;
  
          private void RecoverCar()
          {
              Transform[] WaypointArray = waypoints.ToArray();
              Transform ClosestWP = GetClosestWP(WaypointArray, transform.position);
              Vector3 RelativeWPPosition = transform.InverseTransformPoint(ClosestWP.transform.position);
                          
              int nextWPIndex = 0;
  
              if (RelativeWPPosition.z > 0) // close to forward
              {
                  nextWPIndex = Array.FindIndex(WaypointArray, tr => tr.name == ClosestWP.name) - 1;
              }
              else // close to back
              {
                  nextWPIndex = Array.FindIndex(WaypointArray, tr => tr.name == ClosestWP.name) + 1;
              }
              Vector3 nearestPoint;
              if (nextWPIndex > 0)
              {
                  nearestPoint = NearestPoint(ClosestWP.position, WaypointArray[nextWPIndex].position, transform.position);
              }
              else
              {
                  nearestPoint = WaypointArray[0].position;
              }
  
         
              Debug.DrawLine(transform.position, nearestPoint);
  
              
              transform.rotation = Quaternion.LookRotation(ClosestWP.forward);
              transform.position = nearestPoint;
              transform.position += Vector3.up * 0.1f;
              transform.position += Vector3.right * 0.1f;
              rigidbody.velocity = Vector3.zero;
              rigidbody.angularVelocity = Vector3.zero;
              StuckResetTimer = 0;
  
              layerChangeTimer = layerChangeTimerValue;
              currentLayerCache = LayerMask.LayerToName(gameObject.layer);
              ChangeLayersRecursively(gameObject.transform, "IGNORE");
  
              layerChangeStarted = true;
  
          }
  
          public void RecoverCar(Transform TargetPosition)
          {
              transform.rotation = Quaternion.LookRotation(TargetPosition.forward);
              transform.position = TargetPosition.position;
              transform.position += Vector3.up * 0.1f;
              transform.position += Vector3.right * 0.1f;
              rigidbody.velocity = Vector3.zero;
              rigidbody.angularVelocity = Vector3.zero;
              StuckResetTimer = 0;
  
              layerChangeTimer = layerChangeTimerValue;
              currentLayerCache = LayerMask.LayerToName(gameObject.layer);
              ChangeLayersRecursively(gameObject.transform, "IGNORE");
  
              layerChangeStarted = true;
  
          }
          //Ignore Collision stuff
          string currentLayerCache;
          float layerChangeTimerValue = 7;
          float layerChangeTimer = 0;
          bool layerChangeStarted = false;
  
          private void layerChangeForIgnoreProcessor()
          {
              layerChangeTimer -= Time.deltaTime;
  
              if (layerChangeTimer <= 0)
              {
                  ChangeLayersRecursively(gameObject.transform, currentLayerCache);
                  layerChangeTimer = layerChangeTimerValue;
              }
          }
  
          void ChangeLayersRecursively(Transform trans, String LayerName)
          {
  
gt:             for (int i = 0; i < trans.childCount; i++)