예제 #1
0
        protected override void UpdateTargetDirection(Driver.Sensors sensors, Driver.Actuators actuators)
        {
            // Read player input.
            float turningInput = Input.GetAxis("Turning");

            if (turningInput == 0)
            {
                // If the input was just released, square to 90 degrees.
                if (lastTurningInput != 0)
                {
                    CardinalDirection cardinalDirection = DirectionHelpers.GetCardinalDirectionForVector(sensors.transform.forward);
                    actuators.targetDirection = DirectionHelpers.cardinalDirectionVectors[cardinalDirection];

                    // Reset turning input time for next time.
                    turningInputNonZeroTime = 0;
                }
            }
            else
            {
                // If the input was just changed, change lane.
                if (turningInput < 0 && lastTurningInput >= 0)
                {
                    // We want to go left, but if our current target was to go right, just return to current lane.
                    if (actuators.targetLane > sensors.carTracker.currentLane)
                    {
                        actuators.targetLane = sensors.carTracker.currentLane;
                    }
                    else
                    {
                        actuators.targetLane = Math.Max(sensors.carTracker.currentLane - 1, 0);
                    }
                }
                else if (turningInput > 0 && lastTurningInput <= 0)
                {
                    // We want to go right, but if our current target was to go left, just return to current lane.
                    if (actuators.targetLane < sensors.carTracker.currentLane)
                    {
                        actuators.targetLane = sensors.carTracker.currentLane;
                    }
                    else
                    {
                        actuators.targetLane = Math.Min(sensors.carTracker.currentLane + 1, sensors.carTracker.representativeStreet.lanesCount + 1);
                    }
                }

                // If turning has been active enough time, change target direction.
                turningInputNonZeroTime += Time.deltaTime;

                if (turningInputNonZeroTime > laneChangeOnlyDuration)
                {
                    float      rotationAngleDegrees = turningInput * maxAngleChangeDifferenceDegrees * Mathf.Sign(sensors.car.speed);
                    Quaternion rotation             = Quaternion.Euler(0, rotationAngleDegrees, 0);
                    actuators.targetDirection = rotation * sensors.transform.forward;
                }
            }

            lastTurningInput = turningInput;
        }
예제 #2
0
 public static CardinalDirection GetCardinalDirection(this Vector3 vector)
 {
     return(DirectionHelpers.GetCardinalDirectionForVector(vector));
 }
        protected virtual void UpdateTargetDirection(Driver.Sensors sensors, Driver.Actuators actuators)
        {
            float turningInput = Input.GetAxis("Turning");
            bool  performTurn  = false;

            if (Input.GetButtonDown("Turning"))
            {
                // See if the turn button is down.
                if (Input.GetButton("Turn"))
                {
                    // We want to make a turn.
                    performTurn = true;
                }
                else
                {
                    // Turn button is not down, so do a lane switch.
                    if (turningInput < 0)
                    {
                        // We want to go left, but if our current target was to go right, just return to current lane.
                        if (actuators.targetLane > sensors.carTracker.currentLane)
                        {
                            actuators.targetLane = sensors.carTracker.currentLane;
                        }
                        else
                        {
                            actuators.targetLane = Math.Max(sensors.carTracker.currentLane - 1, 0);
                        }
                    }
                    else
                    {
                        // We want to go right, but if our current target was to go left, just return to current lane.
                        if (actuators.targetLane < sensors.carTracker.currentLane)
                        {
                            actuators.targetLane = sensors.carTracker.currentLane;
                        }
                        else
                        {
                            actuators.targetLane = Math.Min(sensors.carTracker.currentLane + 1, sensors.carTracker.representativeStreet.lanesCount + 1);
                        }
                    }
                }
            }

            // If turn button is pressed and we have a direction, we should turn.
            if (Input.GetButtonDown("Turn") && turningInput != 0)
            {
                performTurn = true;
            }

            // Perform the turn if controls dictated it.
            if (performTurn)
            {
                // When going backwards, turning needs to be reversed.
                if (sensors.car.speed < 0)
                {
                    turningInput *= -1;
                }

                // Determine to which side we're currently turning.
                Vector3    forward            = sensors.car.transform.forward;
                Quaternion currentTargetDelta = Quaternion.FromToRotation(forward, actuators.targetDirection);

                // Use delta angle to wrap the angle to -180..180 range.
                float currentTargetDeltaAngle = Mathf.DeltaAngle(0, currentTargetDelta.eulerAngles.y);

                Vector3 newDirection;

                if (turningInput < 0)
                {
                    // We want to go left, but if our current target was to go right, just return to current direction.
                    if (currentTargetDeltaAngle > 45)
                    {
                        newDirection = forward;
                    }
                    else
                    {
                        newDirection = Quaternion.Euler(0, -90, 0) * forward;
                    }
                }
                else
                {
                    // We want to go right, but if our current target was to go left, just return to current direction.
                    if (currentTargetDeltaAngle < -45)
                    {
                        newDirection = forward;
                    }
                    else
                    {
                        newDirection = Quaternion.Euler(0, 90, 0) * forward;
                    }
                }

                // Square rotation to 90 degrees.
                CardinalDirection cardinalDirection = DirectionHelpers.GetCardinalDirectionForVector(newDirection);
                actuators.targetDirection = DirectionHelpers.cardinalDirectionVectors[cardinalDirection];
            }
        }