コード例 #1
0
    /// <summary>
    /// On every fixed frame update, will check how the car should react to its conditions
    /// </summary>
    private void FixedUpdate()
    {
        frameCount++;

        /*if (gameObject.transform.parent.gameObject.name == "AICar(Clone)")
         * {
         *  var player = GameObject.Find("Player");
         *  if (player)
         *  {
         *      UnityEngine.Debug.Log("Player object found");
         *      //float distance = Vector3.Distance(player.transform.position, gameObject.transform.position);
         *      //UnityEngine.Debug.Log("Distance from player: " + distance);
         *
         *  }
         * }*/

        // Sleep if the round is over
        if (roundOver)
        {
            foreach (AxleInfo axleInfo in axleInfos)
            {
                axleInfo.leftWheel.motorTorque  = 0;
                axleInfo.rightWheel.motorTorque = 0;
            }
            GetComponent <Rigidbody>().Sleep();
            return;
        }

        // Remove AICar if at end of path
        if (gameObject.transform.parent.gameObject.name == "AICar(Clone)" && haveReachedDestination)
        {
            UnityEngine.Debug.Log("Destroyed Car");
            GetComponent <Rigidbody>().Sleep();
            Destroy(gameObject.transform.parent.gameObject);
            return;
        }

        //Stop movement if game timer is paused
        // OR if reached the end of nodes
        if (currentNode == -1 || (timer != null && timer.isPaused()) || haveReachedDestination)
        {
            if (haveReachedDestination && !roundOver)
            {
                sm.driverReachedDest   = true;
                haveReachedDestination = false;
            }
            foreach (AxleInfo axleInfo in axleInfos)
            {
                axleInfo.leftWheel.motorTorque  = 0;
                axleInfo.rightWheel.motorTorque = 0;
            }
            GetComponent <Rigidbody>().Sleep();
            return;
        }

        var distanceToNode = Vector3.Distance(transform.position, nodes[currentNode].position);

        // If close to node
        if (distanceToNode < 20f && distanceToNode > 5f)
        {
            // Check if traffic light
            if (pathList.Count > 1 && currentNode > 0 && trafficLightController.trafficCheck(pathList[currentNode - 1], pathList[currentNode]))
            {
                if (!isAtTrafficLight)
                {
                    isAtTrafficLight = true;
                    UnityEngine.Debug.Log("Now at Traffic Light");
                }

                foreach (AxleInfo axleInfo in axleInfos)
                {
                    axleInfo.leftWheel.motorTorque  = 0;
                    axleInfo.rightWheel.motorTorque = 0;
                }
                GetComponent <Rigidbody>().Sleep();
                return;
            }
            else
            {
                if (isAtTrafficLight)
                {
                    UnityEngine.Debug.Log("Now no longer at Traffic Light");
                }

                isAtTrafficLight = false;
            }

            //check for intersection and then raycast if needed
            if (pathList.Count > 1 && currentNode > 0 && !g.trafficLights.Contains(pathList[currentNode]) && isIntersection(pathList[currentNode]) && !isAtIntersection)
            {
                Vector3 centre = nodes[currentNode].position;

                bool      clear = true;
                LayerMask layer = LayerMask.GetMask("Cars");

                //check intersection is clear
                Collider[] hits = Physics.OverlapBox(centre, transform.localScale * 50, Quaternion.identity, layer, QueryTriggerInteraction.Ignore);
                UnityEngine.Debug.Log(hits.Length + " cars detected in intersection");
                foreach (Collider collider in hits)
                {
                    if (collider == GetComponent <Collider>())
                    {
                        continue;
                    }

                    var other = collider.gameObject.GetComponent <AVController>();
                    if (!other.isAtIntersection || !other.isAtIntersection)
                    {
                        continue;
                    }

                    Vector3 direction = collider.transform.forward;
                    float   dot       = Vector3.Dot(direction, transform.forward);
                    if (dot > 0.5) // other car is travelling in same direction
                    {
                        continue;
                    }
                    else if (true)
                    {
                        clear = false;
                    }
                }

                if (turning == turningDirection.left)
                {
                    // check to the right
                    hits = Physics.OverlapBox(centre + transform.right * castDistance, new Vector3(2, 1, 1) * castDistance, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    UnityEngine.Debug.Log(hits.Length + " cars detected to the right when turning left.");
                    foreach (Collider collider in hits)
                    {
                        if (collider == this.GetComponent <Collider>())
                        {
                            continue;
                        }
                        AVController other = collider.gameObject.GetComponent <AVController>();

                        Vector3 direction = collider.transform.forward;
                        float   dot       = Vector3.Dot(direction, transform.right);
                        if (dot < 0) // other car is travelling left, i.e. towards this car
                        {
                            if (other.isAtIntersection || other.isAtTrafficLight)
                            {
                                continue;
                            }

                            // ignore cars that don't impede movement
                            if (((int)currentBearing + 1) % 4 == (int)other.currentBearing)
                            {
                                UnityEngine.Debug.Log("Turning Left: Ignoring car coming from clockwise direction");
                                continue;
                            }
                            else if ((((int)currentBearing + 4) - 1) % 4 == (int)other.currentBearing && (other.turning == turningDirection.left || other.turning == turningDirection.right))
                            {
                                UnityEngine.Debug.Log("Turning Left: Ignoring car coming from anti-clokwise direction turning left or right");
                                continue;
                            }
                            else if (Math.Abs(currentBearing - other.currentBearing) == 2 && (other.turning == turningDirection.left || other.turning == turningDirection.forward))
                            {
                                UnityEngine.Debug.Log("Turning Left: Ignoring car coming in opposite direction going forward or turning left");
                                continue;
                            }

                            // ignore cars which give way to you
                            if (other.braking)
                            {
                                continue;
                            }

                            // ignore cars with lower priority
                            if (other.roadPriority < roadPriority)
                            {
                                continue;
                            }

                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }
                    }
                }
                else if (turning == turningDirection.forward)
                {
                    // check to the right
                    hits = Physics.OverlapBox(centre + transform.right * castDistance, new Vector3(2, 1, 1) * castDistance, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    UnityEngine.Debug.Log(hits.Length + " cars detected to the right when going forward.");
                    foreach (Collider collider in hits)
                    {
                        Vector3 direction = collider.transform.forward;
                        float   dot       = Vector3.Dot(direction, transform.right);
                        if (dot < 0)
                        {
                            if (collider == this.GetComponent <Collider>())
                            {
                                continue;
                            }
                            AVController other = collider.gameObject.GetComponent <AVController>();
                            if (other.isAtIntersection || other.isAtTrafficLight)
                            {
                                continue;
                            }

                            if (other.braking)
                            {
                                continue;
                            }



                            // ignore cars with lower priority
                            if (other.roadPriority < roadPriority)
                            {
                                continue;
                            }



                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }
                    }

                    // check to the left
                    hits = Physics.OverlapBox(centre - transform.right * 20, new Vector3(2, 1, 1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    UnityEngine.Debug.Log(hits.Length + " cars detected to the left when going forward.");
                    foreach (Collider collider in hits)
                    {
                        Vector3 direction = collider.transform.forward;
                        float   dot       = Vector3.Dot(direction, -transform.right);
                        if (dot > 0)
                        {
                            if (collider == this.GetComponent <Collider>())
                            {
                                continue;
                            }
                            AVController other = collider.gameObject.GetComponent <AVController>();
                            if (other.isAtIntersection || other.isAtTrafficLight)
                            {
                                continue;
                            }

                            if (other.braking)
                            {
                                continue;
                            }
                            if (other.roadPriority < roadPriority)
                            {
                                continue;
                            }

                            // ignore cars that don't impede movement
                            //if (other.roadPriority == roadPriority && (other.turning == AVController.direction.forward || other.turning == AVController.direction.left)) continue;

                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }
                    }

                    // check forward

                    /*hits = Physics.OverlapBox(centre + transform.forward * 5, new Vector3(1, 1, 2) * 5, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                     * foreach (Collider collider in hits)
                     * {
                     *  Vector3 direction = collider.transform.forward;
                     *  float dot = Vector3.Dot(direction, transform.forward);
                     *  if (dot < 0)
                     *  {
                     *      if (collider == this.GetComponent<Collider>()) continue;
                     *      AVController other = collider.gameObject.GetComponent<AVController>();
                     *      //if (other.inIntersection) continue;
                     *
                     *      //if (other.braking) continue;
                     *
                     *      if (currentBearing == other.currentBearing)
                     *      {
                     *          UnityEngine.Debug.Log("Going forward: Car in front going in the same direction");
                     *
                     *          foreach (AxleInfo axleInfo in axleInfos)
                     *          {
                     *              axleInfo.leftWheel.brakeTorque = maxMotorTorque;
                     *              axleInfo.rightWheel.brakeTorque = maxMotorTorque;
                     *          }
                     *          braking = true;
                     *          GetComponent<Rigidbody>().Sleep();
                     *          return;
                     *      }
                     *      else
                     *      {
                     *          UnityEngine.Debug.Log("Going forward: Hitting a car so not clear");
                     *          clear = false;
                     *      }
                     *
                     *
                     *  }
                     * }*/
                }
                else // turning right
                {
                    // check to the right
                    hits = Physics.OverlapBox(centre + transform.right * 20, new Vector3(2, 1, 1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    UnityEngine.Debug.Log(hits.Length + " cars detected to the right when turning right.");
                    foreach (Collider collider in hits)
                    {
                        Vector3 direction = collider.transform.forward;
                        float   dot       = Vector3.Dot(direction, transform.right);
                        if (dot < 0)
                        {
                            if (collider == this.GetComponent <Collider>())
                            {
                                continue;
                            }
                            AVController other = collider.gameObject.GetComponent <AVController>();
                            if (other.isAtIntersection || other.isAtTrafficLight)
                            {
                                continue;
                            }

                            if (other.braking)
                            {
                                continue;
                            }
                            if (other.roadPriority < roadPriority)
                            {
                                continue;
                            }

                            // ignore cars that don't impede movement
                            //if (other.roadPriority == roadPriority && other.turning == AVController.direction.right) continue;

                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }
                    }

                    // check to the left
                    hits = Physics.OverlapBox(centre - transform.right * 20, new Vector3(2, 1, 1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    UnityEngine.Debug.Log(hits.Length + " cars detected to the left when turning right.");
                    foreach (Collider collider in hits)
                    {
                        if (collider == this.GetComponent <Collider>())
                        {
                            continue;
                        }
                        AVController other = collider.gameObject.GetComponent <AVController>();

                        if (Math.Abs(currentBearing - other.currentBearing) == 2 && other.turning == AVController.turningDirection.right)
                        {
                            UnityEngine.Debug.Log("Turning Right: Ignoring car coming in opposite direction turning right");
                            continue;
                        }

                        Vector3 direction = collider.transform.forward;
                        float   dot       = Vector3.Dot(direction, -transform.right);
                        if (dot > 0)
                        {
                            if (other.isAtIntersection || other.isAtTrafficLight)
                            {
                                continue;
                            }

                            if (other.braking)
                            {
                                continue;
                            }



                            if (other.roadPriority < roadPriority)
                            {
                                continue;
                            }

                            // ignore cars that don't impede movement
                            //if (other.roadPriority == roadPriority && other.turning == AVController.direction.right) continue;

                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }
                    }

                    // check forward
                    hits = Physics.OverlapBox(centre + transform.forward * 20, new Vector3(1, 1, 2) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    UnityEngine.Debug.Log(hits.Length + " cars detected forward when turning right.");
                    foreach (Collider collider in hits)
                    {
                        if (collider == this.GetComponent <Collider>())
                        {
                            continue;
                        }
                        AVController other = collider.gameObject.GetComponent <AVController>();

                        if (Math.Abs(currentBearing - other.currentBearing) == 2 && other.turning == AVController.turningDirection.right)
                        {
                            UnityEngine.Debug.Log("Turning Right: Ignoring car coming in opposite direction turning right");
                            continue;
                        }

                        Vector3 direction = collider.transform.forward;
                        float   dot       = Vector3.Dot(direction, transform.forward);
                        if (dot < 0)
                        {
                            if (other.isAtIntersection)
                            {
                                continue;
                            }

                            if (other.braking)
                            {
                                continue;
                            }


                            if (other.roadPriority < roadPriority)
                            {
                                continue;
                            }

                            // ignore cars that don't impede movement
                            //if (other.roadPriority == roadPriority && other.turning == AVController.direction.right) continue;

                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }
                    }
                }

                if (clear)
                {
                    isAtIntersection = true;
                    stopTime         = UnityEngine.Random.Range(0f, 1f);
                    StartCoroutine("Intersection");
                }
                else
                {
                    stopTime += 1;
                    if (!stopped)
                    {
                        StartCoroutine("Stop");
                    }
                }
            }
        }

        //Update wheel positions based on speed and angle
        Vector3 relativeVector = transform.InverseTransformPoint(nodes[currentNode].position) + new Vector3(-drivingOffset, 0, 0);
        float   newSteer       = (relativeVector.x / relativeVector.magnitude) * maxSteerAngle;

        foreach (AxleInfo axleInfo in axleInfos)
        {
            currentSpeed = 2 * Mathf.PI * axleInfo.leftWheel.radius * axleInfo.leftWheel.rpm * 60 / 1000;

            if (axleInfo.steering)
            {
                axleInfo.leftWheel.steerAngle  = newSteer;
                axleInfo.rightWheel.steerAngle = newSteer;
            }

            if (axleInfo.motor)
            {
                if (currentSpeed < maxSpeed)
                {
                    axleInfo.leftWheel.motorTorque  = maxMotorTorque;
                    axleInfo.rightWheel.motorTorque = maxMotorTorque;
                }
                else
                {
                    axleInfo.leftWheel.motorTorque  = 0;
                    axleInfo.rightWheel.motorTorque = 0;
                }
            }

            lastSpeed = currentSpeed;

            ApplyLocalPositionToVisuals(axleInfo.leftWheel);
            ApplyLocalPositionToVisuals(axleInfo.rightWheel);
        }

        if (currentSpeed == 0 && !isAtTrafficLight)
        {
            consecutiveFramesWithNoSpeed++;
            if (consecutiveFramesWithNoSpeed > minConsecutiveFramesWithNoSpeed)
            {
                var newFps = 1 / Time.unscaledDeltaTime;
                if (newFps >= 25)
                {
                    fps = newFps;
                    UnityEngine.Debug.Log("FPS:" + fps);
                }

                var consecutiveSecondsWithNoSpeed = consecutiveFramesWithNoSpeed / fps;
                UnityEngine.Debug.Log("Consecutive seconds with no speed:" + consecutiveSecondsWithNoSpeed);
                if (consecutiveSecondsWithNoSpeed >= minConsecutiveSecondsWithNoSpeed)
                {
                    var randomNumber = UnityEngine.Random.Range(minConsecutiveSecondsWithNoSpeed, maxConsecutiveSecondsWithNoSpeed);
                    if (randomNumber < consecutiveFramesWithNoSpeed)
                    {
                        if (nodes.Count > 1)
                        {
                            currentNode--;

                            gameObject.transform.position = nodes[currentNode].position;
                            gameObject.transform.LookAt(nodes[currentNode + 1]);
                            gameObject.transform.position = transform.TransformPoint(new Vector3(-drivingOffset, 0, 0));
                            UnityEngine.Debug.Log("Have been stationary for awhile, moving back to previous node");
                        }

                        consecutiveFramesWithNoSpeed = 0;
                    }
                }
            }
        }
        else
        {
            consecutiveFramesWithNoSpeed = 0;
        }

        CheckWaypointDistance();
        UpdateSteeringWheel();
    }
コード例 #2
0
    /// <summary>
    /// On every fixed frame update, will check how the car should react to its conditions
    /// </summary>
    private void FixedUpdate()
    {
        // Sleep if the round is over
        if(roundOver)
        {
            foreach (AxleInfo axleInfo in axleInfos)
            {
                axleInfo.leftWheel.motorTorque = 0;
                axleInfo.rightWheel.motorTorque = 0;
            }
            GetComponent<Rigidbody>().Sleep();
            return;
        }

        // Remove AICar if at end of path
        if (gameObject.transform.parent.gameObject.name == "AICar(Clone)" && reachedDestination)
        {
            UnityEngine.Debug.Log("Destroyed Car");
            GetComponent<Rigidbody>().Sleep();
            Destroy(gameObject.transform.parent.gameObject);
            return;
        }

        //Stop movement if game timer is paused
        // OR if reached the end of nodes
        if (currentNode == -1 || (timer != null && timer.isPaused()) || reachedDestination)
        {
            if (reachedDestination && !roundOver)
            {
                sm.driverReachedDest = true;
                reachedDestination = false;
            }
            foreach (AxleInfo axleInfo in axleInfos)
            {
                axleInfo.leftWheel.motorTorque = 0;
                axleInfo.rightWheel.motorTorque = 0;
            }
            GetComponent<Rigidbody>().Sleep();
            return;
        }

        // If close to node
        if (Vector3.Distance(transform.position, nodes[currentNode].position) < 20f && Vector3.Distance(transform.position, nodes[currentNode].position) > 5f)
        {
            // Check if traffic light
            if (pathList.Count > 1 && currentNode > 0 && trafficLightController.trafficCheck(pathList[currentNode - 1], pathList[currentNode]))
            {
                //UnityEngine.Debug.Log("At Traffic Light");
                foreach (AxleInfo axleInfo in axleInfos)
                {
                    axleInfo.leftWheel.motorTorque = 0;
                    axleInfo.rightWheel.motorTorque = 0;
                }
                GetComponent<Rigidbody>().Sleep();
                return;
            } 
            //check for intersection and then raycast if needed 
            else if (pathList.Count > 1 && currentNode > 0 && !g.trafficLights.Contains(pathList[currentNode]) && isIntersection(pathList[currentNode]) && !inIntersection)
            {
                Vector3 centre = nodes[currentNode].position;

                bool clear = true;
                LayerMask layer = LayerMask.GetMask("Cars");

                //check intersection is clear
                Collider[] hits = Physics.OverlapBox(centre, transform.localScale * 50, Quaternion.identity, layer, QueryTriggerInteraction.Ignore);
                foreach (Collider collider in hits)
                {
                    if (collider != this.GetComponent<Collider>())
                    {
                        if (collider.gameObject.GetComponent<AVController>().inIntersection)
                        {
                            Vector3 direction = collider.transform.forward;
                            float dot = Vector3.Dot(direction, transform.forward);
                            if (dot > 0.5) // other car is travelling in same direction
                            {
                                continue;
                            }
                            else if (true)
                            {
                                clear = false;
                            }
                        }
                    }
                }


                if (turning == direction.left)
                {
                    // check to the right
                    hits = Physics.OverlapBox(centre + transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    foreach (Collider collider in hits)
                    {
                        Vector3 direction = collider.transform.forward;
                        float dot = Vector3.Dot(direction, transform.right);
                        if (dot < 0) // other car is travelling left, i.e. towards this car
                        {
                            if (collider == this.GetComponent<Collider>()) continue;
                            AVController other = collider.gameObject.GetComponent<AVController>();
                            
                            if (other.inIntersection) continue;

                            // ignore cars which give way to you
                            if (other.braking) continue;
                            if (other.roadPriority < roadPriority) continue;

                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }                        
                    }                
                }
                else if (turning == direction.forward)
                {
                    // check to the right
                    hits = Physics.OverlapBox(centre + transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    foreach (Collider collider in hits)
                    {
                        Vector3 direction = collider.transform.forward;
                        float dot = Vector3.Dot(direction, transform.right);
                        if (dot < 0)
                        {
                            if (collider == this.GetComponent<Collider>()) continue;
                            AVController other = collider.gameObject.GetComponent<AVController>();
                            if (other.inIntersection) continue;

                            if (other.braking) continue;
                            if (other.roadPriority < roadPriority) continue;

                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }                        
                    } 

                    // check to the left
                    hits = Physics.OverlapBox(centre - transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    foreach (Collider collider in hits)
                    {
                        Vector3 direction = collider.transform.forward;
                        float dot = Vector3.Dot(direction, -transform.right);
                        if (dot > 0)
                        {
                            if (collider == this.GetComponent<Collider>()) continue;
                            AVController other = collider.gameObject.GetComponent<AVController>();
                            if (other.inIntersection) continue;

                            if (other.braking) continue;
                            if (other.roadPriority < roadPriority) continue;
                            
                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }                        
                    }    
                }
                else // turning right
                {
                    // check to the right
                    hits = Physics.OverlapBox(centre + transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    foreach (Collider collider in hits)
                    {
                        Vector3 direction = collider.transform.forward;
                        float dot = Vector3.Dot(direction, transform.right);
                        if (dot < 0)
                        {
                            if (collider == this.GetComponent<Collider>()) continue;
                            AVController other = collider.gameObject.GetComponent<AVController>();
                            if (other.inIntersection) continue;
                          
                            if (other.braking) continue;
                            if (other.roadPriority < roadPriority) continue;
                          
                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }                        
                    } 

                    // check to the left
                    hits = Physics.OverlapBox(centre - transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    foreach (Collider collider in hits)
                    {
                        Vector3 direction = collider.transform.forward;
                        float dot = Vector3.Dot(direction, -transform.right);
                        if (dot > 0)
                        {
                            if (collider == this.GetComponent<Collider>()) continue;
                            AVController other = collider.gameObject.GetComponent<AVController>();
                            if (other.inIntersection) continue;
                           
                            if (other.braking) continue;
                            if (other.roadPriority < roadPriority) continue;
                           
                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }                        
                    }  

                    // check forward
                    hits = Physics.OverlapBox(centre + transform.forward * 20, new Vector3(1,1,2) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore);
                    foreach (Collider collider in hits)
                    {
                        Vector3 direction = collider.transform.forward;
                        float dot = Vector3.Dot(direction, transform.forward);
                        if (dot < 0)
                        {
                            if (collider == this.GetComponent<Collider>()) continue;
                            AVController other = collider.gameObject.GetComponent<AVController>();
                            if (other.inIntersection) continue;
                            
                            if (other.braking) continue;
                            if (other.roadPriority < roadPriority) continue;
                            
                            if (other.stopTime < 1 || other.stopTime > stopTime)
                            {
                                clear = false;
                            }
                        }                        
                    }
                }

                if(clear)
                {
                    inIntersection = true;
                    stopTime = UnityEngine.Random.Range(0f, 1f);
                    StartCoroutine("Intersection");

                }
                else
                {
                    stopTime += 1;
                    if (!stopped)
                    {
                        StartCoroutine("Stop");
                    }
                }
            }
        }

        //Update wheel positions based on speed and angle
        Vector3 relativeVector = transform.InverseTransformPoint(nodes[currentNode].position) + new Vector3(-drivingOffset, 0, 0);
        float newSteer = (relativeVector.x / relativeVector.magnitude) * maxSteerAngle;

        foreach (AxleInfo axleInfo in axleInfos)
        {
            currentSpeed = 2 * Mathf.PI * axleInfo.leftWheel.radius * axleInfo.leftWheel.rpm * 60 / 1000;
            if (axleInfo.steering)
            {
                axleInfo.leftWheel.steerAngle = newSteer;
                axleInfo.rightWheel.steerAngle = newSteer;
            }
            if (axleInfo.motor)
            {
                if (currentSpeed < maxSpeed)
                {
                    axleInfo.leftWheel.motorTorque = maxMotorTorque;
                    axleInfo.rightWheel.motorTorque = maxMotorTorque;
                }
                else
                {
                    axleInfo.leftWheel.motorTorque = 0;
                    axleInfo.rightWheel.motorTorque = 0;
                }
            }
            
            ApplyLocalPositionToVisuals(axleInfo.leftWheel);
            ApplyLocalPositionToVisuals(axleInfo.rightWheel);
        }

        CheckWaypointDistance();
        UpdateSteeringWheel();
    }