Untitled
unknown
plain_text
4 months ago
34 kB
3
Indexable
/* MESSAGE FROM CREATOR: This script was coded by Mena. You can use it in your games either these are commercial or personal projects. You can even add or remove functions as you wish. However, you cannot sell copies of this script by itself, since it is originally distributed as a free product. I wish you the best for your project. Good luck! P.S: If you need more cars, you can check my other vehicle assets on the Unity Asset Store, perhaps you could find something useful for your game. Best regards, Mena. */ using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class PrometeoCarController : MonoBehaviour { //CAR SETUP [Space(20)] //[Header("CAR SETUP")] [Space(10)] [Range(20, 190)] public int maxSpeed = 90; //The maximum speed that the car can reach in km/h. [Range(10, 120)] public int maxReverseSpeed = 45; //The maximum speed that the car can reach while going on reverse in km/h. [Range(1, 10)] public int accelerationMultiplier = 2; // How fast the car can accelerate. 1 is a slow acceleration and 10 is the fastest. [Space(10)] [Range(10, 45)] public int maxSteeringAngle = 27; // The maximum angle that the tires can reach while rotating the steering wheel. [Range(0.1f, 1f)] public float steeringSpeed = 0.5f; // How fast the steering wheel turns. [Space(10)] [Range(100, 600)] public int brakeForce = 350; // The strength of the wheel brakes. [Range(1, 10)] public int decelerationMultiplier = 2; // How fast the car decelerates when the user is not using the throttle. [Range(1, 10)] public int handbrakeDriftMultiplier = 5; // How much grip the car loses when the user hit the handbrake. [Space(10)] public Vector3 bodyMassCenter; // This is a vector that contains the center of mass of the car. I recommend to set this value // in the points x = 0 and z = 0 of your car. You can select the value that you want in the y axis, // however, you must notice that the higher this value is, the more unstable the car becomes. // Usually the y value goes from 0 to 1.5. //WHEELS //[Header("WHEELS")] /* The following variables are used to store the wheels' data of the car. We need both the mesh-only game objects and wheel collider components of the wheels. The wheel collider components and 3D meshes of the wheels cannot come from the same game object; they must be separate game objects. */ public GameObject frontLeftMesh; public WheelCollider frontLeftCollider; [Space(10)] public GameObject frontRightMesh; public WheelCollider frontRightCollider; [Space(10)] public GameObject rearLeftMesh; public WheelCollider rearLeftCollider; [Space(10)] public GameObject rearRightMesh; public WheelCollider rearRightCollider; //PARTICLE SYSTEMS [Space(20)] //[Header("EFFECTS")] [Space(10)] //The following variable lets you to set up particle systems in your car public bool useEffects = false; // The following particle systems are used as tire smoke when the car drifts. public ParticleSystem RLWParticleSystem; public ParticleSystem RRWParticleSystem; [Space(10)] // The following trail renderers are used as tire skids when the car loses traction. public TrailRenderer RLWTireSkid; public TrailRenderer RRWTireSkid; //SPEED TEXT (UI) [Space(20)] //[Header("UI")] [Space(10)] //The following variable lets you to set up a UI text to display the speed of your car. public bool useUI = false; public Text carSpeedText; // Used to store the UI object that is going to show the speed of the car. //SOUNDS [Space(20)] //[Header("Sounds")] [Space(10)] //The following variable lets you to set up sounds for your car such as the car engine or tire screech sounds. public bool useSounds = false; public AudioSource carEngineSound; // This variable stores the sound of the car engine. public AudioSource tireScreechSound; // This variable stores the sound of the tire screech (when the car is drifting). float initialCarEngineSoundPitch; // Used to store the initial pitch of the car engine sound. //CONTROLS [Space(20)] //[Header("CONTROLS")] [Space(10)] //The following variables lets you to set up touch controls for mobile devices. public bool useTouchControls = false; public GameObject throttleButton; PrometeoTouchInput throttlePTI; public GameObject reverseButton; PrometeoTouchInput reversePTI; public GameObject turnRightButton; PrometeoTouchInput turnRightPTI; public GameObject turnLeftButton; PrometeoTouchInput turnLeftPTI; public GameObject handbrakeButton; PrometeoTouchInput handbrakePTI; //CAR DATA [HideInInspector] public float carSpeed; // Used to store the speed of the car. [HideInInspector] public bool isDrifting; // Used to know whether the car is drifting or not. [HideInInspector] public bool isTractionLocked; // Used to know whether the traction of the car is locked or not. //PRIVATE VARIABLES /* IMPORTANT: The following variables should not be modified manually since their values are automatically given via script. */ Rigidbody carRigidbody; // Stores the car's rigidbody. float steeringAxis; // Used to know whether the steering wheel has reached the maximum value. It goes from -1 to 1. float throttleAxis; // Used to know whether the throttle has reached the maximum value. It goes from -1 to 1. float driftingAxis; float localVelocityZ; float localVelocityX; bool deceleratingCar; bool touchControlsSetup = false; /* The following variables are used to store information about sideways friction of the wheels (such as extremumSlip,extremumValue, asymptoteSlip, asymptoteValue and stiffness). We change this values to make the car to start drifting. */ WheelFrictionCurve FLwheelFriction; float FLWextremumSlip; WheelFrictionCurve FRwheelFriction; float FRWextremumSlip; WheelFrictionCurve RLwheelFriction; float RLWextremumSlip; WheelFrictionCurve RRwheelFriction; float RRWextremumSlip; // Start is called before the first frame update void Start() { //In this part, we set the 'carRigidbody' value with the Rigidbody attached to this //gameObject. Also, we define the center of mass of the car with the Vector3 given //in the inspector. carRigidbody = gameObject.GetComponent<Rigidbody>(); carRigidbody.centerOfMass = bodyMassCenter; //Initial setup to calculate the drift value of the car. This part could look a bit //complicated, but do not be afraid, the only thing we're doing here is to save the default //friction values of the car wheels so we can set an appropiate drifting value later. FLwheelFriction = new WheelFrictionCurve (); FLwheelFriction.extremumSlip = frontLeftCollider.sidewaysFriction.extremumSlip; FLWextremumSlip = frontLeftCollider.sidewaysFriction.extremumSlip; FLwheelFriction.extremumValue = frontLeftCollider.sidewaysFriction.extremumValue; FLwheelFriction.asymptoteSlip = frontLeftCollider.sidewaysFriction.asymptoteSlip; FLwheelFriction.asymptoteValue = frontLeftCollider.sidewaysFriction.asymptoteValue; FLwheelFriction.stiffness = frontLeftCollider.sidewaysFriction.stiffness; FRwheelFriction = new WheelFrictionCurve (); FRwheelFriction.extremumSlip = frontRightCollider.sidewaysFriction.extremumSlip; FRWextremumSlip = frontRightCollider.sidewaysFriction.extremumSlip; FRwheelFriction.extremumValue = frontRightCollider.sidewaysFriction.extremumValue; FRwheelFriction.asymptoteSlip = frontRightCollider.sidewaysFriction.asymptoteSlip; FRwheelFriction.asymptoteValue = frontRightCollider.sidewaysFriction.asymptoteValue; FRwheelFriction.stiffness = frontRightCollider.sidewaysFriction.stiffness; RLwheelFriction = new WheelFrictionCurve (); RLwheelFriction.extremumSlip = rearLeftCollider.sidewaysFriction.extremumSlip; RLWextremumSlip = rearLeftCollider.sidewaysFriction.extremumSlip; RLwheelFriction.extremumValue = rearLeftCollider.sidewaysFriction.extremumValue; RLwheelFriction.asymptoteSlip = rearLeftCollider.sidewaysFriction.asymptoteSlip; RLwheelFriction.asymptoteValue = rearLeftCollider.sidewaysFriction.asymptoteValue; RLwheelFriction.stiffness = rearLeftCollider.sidewaysFriction.stiffness; RRwheelFriction = new WheelFrictionCurve (); RRwheelFriction.extremumSlip = rearRightCollider.sidewaysFriction.extremumSlip; RRWextremumSlip = rearRightCollider.sidewaysFriction.extremumSlip; RRwheelFriction.extremumValue = rearRightCollider.sidewaysFriction.extremumValue; RRwheelFriction.asymptoteSlip = rearRightCollider.sidewaysFriction.asymptoteSlip; RRwheelFriction.asymptoteValue = rearRightCollider.sidewaysFriction.asymptoteValue; RRwheelFriction.stiffness = rearRightCollider.sidewaysFriction.stiffness; // We save the initial pitch of the car engine sound. if(carEngineSound != null){ initialCarEngineSoundPitch = carEngineSound.pitch; } // We invoke 2 methods inside this script. CarSpeedUI() changes the text of the UI object that stores // the speed of the car and CarSounds() controls the engine and drifting sounds. Both methods are invoked // in 0 seconds, and repeatedly called every 0.1 seconds. if(useUI){ InvokeRepeating("CarSpeedUI", 0f, 0.1f); }else if(!useUI){ if(carSpeedText != null){ carSpeedText.text = "0"; } } if(useSounds){ InvokeRepeating("CarSounds", 0f, 0.1f); }else if(!useSounds){ if(carEngineSound != null){ carEngineSound.Stop(); } if(tireScreechSound != null){ tireScreechSound.Stop(); } } if(!useEffects){ if(RLWParticleSystem != null){ RLWParticleSystem.Stop(); } if(RRWParticleSystem != null){ RRWParticleSystem.Stop(); } if(RLWTireSkid != null){ RLWTireSkid.emitting = false; } if(RRWTireSkid != null){ RRWTireSkid.emitting = false; } } if(useTouchControls){ if(throttleButton != null && reverseButton != null && turnRightButton != null && turnLeftButton != null && handbrakeButton != null){ throttlePTI = throttleButton.GetComponent<PrometeoTouchInput>(); reversePTI = reverseButton.GetComponent<PrometeoTouchInput>(); turnLeftPTI = turnLeftButton.GetComponent<PrometeoTouchInput>(); turnRightPTI = turnRightButton.GetComponent<PrometeoTouchInput>(); handbrakePTI = handbrakeButton.GetComponent<PrometeoTouchInput>(); touchControlsSetup = true; }else{ String ex = "Touch controls are not completely set up. You must drag and drop your scene buttons in the" + " PrometeoCarController component."; Debug.LogWarning(ex); } } } // Update is called once per frame void Update() { //CAR DATA // We determine the speed of the car. carSpeed = (2 * Mathf.PI * frontLeftCollider.radius * frontLeftCollider.rpm * 60) / 1000; // Save the local velocity of the car in the x axis. Used to know if the car is drifting. localVelocityX = transform.InverseTransformDirection(carRigidbody.velocity).x; // Save the local velocity of the car in the z axis. Used to know if the car is going forward or backwards. localVelocityZ = transform.InverseTransformDirection(carRigidbody.velocity).z; //CAR PHYSICS /* The next part is regarding to the car controller. First, it checks if the user wants to use touch controls (for mobile devices) or analog input controls (WASD + Space). The following methods are called whenever a certain key is pressed. For example, in the first 'if' we call the method GoForward() if the user has pressed W. In this part of the code we specify what the car needs to do if the user presses W (throttle), S (reverse), A (turn left), D (turn right) or Space bar (handbrake). */ if (useTouchControls && touchControlsSetup){ if(throttlePTI.buttonPressed){ CancelInvoke("DecelerateCar"); deceleratingCar = false; GoForward(); } if(reversePTI.buttonPressed){ CancelInvoke("DecelerateCar"); deceleratingCar = false; GoReverse(); } if(turnLeftPTI.buttonPressed){ TurnLeft(); } if(turnRightPTI.buttonPressed){ TurnRight(); } if(handbrakePTI.buttonPressed){ CancelInvoke("DecelerateCar"); deceleratingCar = false; Handbrake(); } if(!handbrakePTI.buttonPressed){ RecoverTraction(); } if((!throttlePTI.buttonPressed && !reversePTI.buttonPressed)){ ThrottleOff(); } if((!reversePTI.buttonPressed && !throttlePTI.buttonPressed) && !handbrakePTI.buttonPressed && !deceleratingCar){ InvokeRepeating("DecelerateCar", 0f, 0.1f); deceleratingCar = true; } if(!turnLeftPTI.buttonPressed && !turnRightPTI.buttonPressed && steeringAxis != 0f){ ResetSteeringAngle(); } }else{ if(Input.GetKey(KeyCode.W)){ CancelInvoke("DecelerateCar"); deceleratingCar = false; GoForward(); } if(Input.GetKey(KeyCode.S)){ CancelInvoke("DecelerateCar"); deceleratingCar = false; GoReverse(); } if(Input.GetKey(KeyCode.A)){ TurnLeft(); } if(Input.GetKey(KeyCode.D)){ TurnRight(); } if(Input.GetKey(KeyCode.Space)){ CancelInvoke("DecelerateCar"); deceleratingCar = false; Handbrake(); } if(Input.GetKeyUp(KeyCode.Space)){ RecoverTraction(); } if((!Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.W))){ ThrottleOff(); } if((!Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.W)) && !Input.GetKey(KeyCode.Space) && !deceleratingCar){ InvokeRepeating("DecelerateCar", 0f, 0.1f); deceleratingCar = true; } if(!Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.D) && steeringAxis != 0f){ ResetSteeringAngle(); } } // We call the method AnimateWheelMeshes() in order to match the wheel collider movements with the 3D meshes of the wheels. AnimateWheelMeshes(); } // This method converts the car speed data from float to string, and then set the text of the UI carSpeedText with this value. public void CarSpeedUI(){ if(useUI){ try{ float absoluteCarSpeed = Mathf.Abs(carSpeed); carSpeedText.text = Mathf.RoundToInt(absoluteCarSpeed).ToString(); }catch(Exception ex){ Debug.LogWarning(ex); } } } // This method controls the car sounds. For example, the car engine will sound slow when the car speed is low because the // pitch of the sound will be at its lowest point. On the other hand, it will sound fast when the car speed is high because // the pitch of the sound will be the sum of the initial pitch + the car speed divided by 100f. // Apart from that, the tireScreechSound will play whenever the car starts drifting or losing traction. public void CarSounds(){ if(useSounds){ try{ if(carEngineSound != null){ float engineSoundPitch = initialCarEngineSoundPitch + (Mathf.Abs(carRigidbody.velocity.magnitude) / 25f); carEngineSound.pitch = engineSoundPitch; } if((isDrifting) || (isTractionLocked && Mathf.Abs(carSpeed) > 12f)){ if(!tireScreechSound.isPlaying){ tireScreechSound.Play(); } }else if((!isDrifting) && (!isTractionLocked || Mathf.Abs(carSpeed) < 12f)){ tireScreechSound.Stop(); } }catch(Exception ex){ Debug.LogWarning(ex); } }else if(!useSounds){ if(carEngineSound != null && carEngineSound.isPlaying){ carEngineSound.Stop(); } if(tireScreechSound != null && tireScreechSound.isPlaying){ tireScreechSound.Stop(); } } } // //STEERING METHODS // //The following method turns the front car wheels to the left. The speed of this movement will depend on the steeringSpeed variable. public void TurnLeft(){ steeringAxis = steeringAxis - (Time.deltaTime * 10f * steeringSpeed); if(steeringAxis < -1f){ steeringAxis = -1f; } var steeringAngle = steeringAxis * maxSteeringAngle; frontLeftCollider.steerAngle = Mathf.Lerp(frontLeftCollider.steerAngle, steeringAngle, steeringSpeed); frontRightCollider.steerAngle = Mathf.Lerp(frontRightCollider.steerAngle, steeringAngle, steeringSpeed); } //The following method turns the front car wheels to the right. The speed of this movement will depend on the steeringSpeed variable. public void TurnRight(){ steeringAxis = steeringAxis + (Time.deltaTime * 10f * steeringSpeed); if(steeringAxis > 1f){ steeringAxis = 1f; } var steeringAngle = steeringAxis * maxSteeringAngle; frontLeftCollider.steerAngle = Mathf.Lerp(frontLeftCollider.steerAngle, steeringAngle, steeringSpeed); frontRightCollider.steerAngle = Mathf.Lerp(frontRightCollider.steerAngle, steeringAngle, steeringSpeed); } //The following method takes the front car wheels to their default position (rotation = 0). The speed of this movement will depend // on the steeringSpeed variable. public void ResetSteeringAngle(){ if(steeringAxis < 0f){ steeringAxis = steeringAxis + (Time.deltaTime * 10f * steeringSpeed); }else if(steeringAxis > 0f){ steeringAxis = steeringAxis - (Time.deltaTime * 10f * steeringSpeed); } if(Mathf.Abs(frontLeftCollider.steerAngle) < 1f){ steeringAxis = 0f; } var steeringAngle = steeringAxis * maxSteeringAngle; frontLeftCollider.steerAngle = Mathf.Lerp(frontLeftCollider.steerAngle, steeringAngle, steeringSpeed); frontRightCollider.steerAngle = Mathf.Lerp(frontRightCollider.steerAngle, steeringAngle, steeringSpeed); } // This method matches both the position and rotation of the WheelColliders with the WheelMeshes. void AnimateWheelMeshes(){ try{ Quaternion FLWRotation; Vector3 FLWPosition; frontLeftCollider.GetWorldPose(out FLWPosition, out FLWRotation); frontLeftMesh.transform.position = FLWPosition; frontLeftMesh.transform.rotation = FLWRotation; Quaternion FRWRotation; Vector3 FRWPosition; frontRightCollider.GetWorldPose(out FRWPosition, out FRWRotation); frontRightMesh.transform.position = FRWPosition; frontRightMesh.transform.rotation = FRWRotation; Quaternion RLWRotation; Vector3 RLWPosition; rearLeftCollider.GetWorldPose(out RLWPosition, out RLWRotation); rearLeftMesh.transform.position = RLWPosition; rearLeftMesh.transform.rotation = RLWRotation; Quaternion RRWRotation; Vector3 RRWPosition; rearRightCollider.GetWorldPose(out RRWPosition, out RRWRotation); rearRightMesh.transform.position = RRWPosition; rearRightMesh.transform.rotation = RRWRotation; }catch(Exception ex){ Debug.LogWarning(ex); } } // //ENGINE AND BRAKING METHODS // // This method apply positive torque to the wheels in order to go forward. public void GoForward(){ //If the forces aplied to the rigidbody in the 'x' asis are greater than //3f, it means that the car is losing traction, then the car will start emitting particle systems. if(Mathf.Abs(localVelocityX) > 2.5f){ isDrifting = true; DriftCarPS(); }else{ isDrifting = false; DriftCarPS(); } // The following part sets the throttle power to 1 smoothly. throttleAxis = throttleAxis + (Time.deltaTime * 3f); if(throttleAxis > 1f){ throttleAxis = 1f; } //If the car is going backwards, then apply brakes in order to avoid strange //behaviours. If the local velocity in the 'z' axis is less than -1f, then it //is safe to apply positive torque to go forward. if(localVelocityZ < -1f){ Brakes(); }else{ if(Mathf.RoundToInt(carSpeed) < maxSpeed){ //Apply positive torque in all wheels to go forward if maxSpeed has not been reached. frontLeftCollider.brakeTorque = 0; frontLeftCollider.motorTorque = (accelerationMultiplier * 50f) * throttleAxis; frontRightCollider.brakeTorque = 0; frontRightCollider.motorTorque = (accelerationMultiplier * 50f) * throttleAxis; rearLeftCollider.brakeTorque = 0; rearLeftCollider.motorTorque = (accelerationMultiplier * 50f) * throttleAxis; rearRightCollider.brakeTorque = 0; rearRightCollider.motorTorque = (accelerationMultiplier * 50f) * throttleAxis; }else { // If the maxSpeed has been reached, then stop applying torque to the wheels. // IMPORTANT: The maxSpeed variable should be considered as an approximation; the speed of the car // could be a bit higher than expected. frontLeftCollider.motorTorque = 0; frontRightCollider.motorTorque = 0; rearLeftCollider.motorTorque = 0; rearRightCollider.motorTorque = 0; } } } // This method apply negative torque to the wheels in order to go backwards. public void GoReverse(){ //If the forces aplied to the rigidbody in the 'x' asis are greater than //3f, it means that the car is losing traction, then the car will start emitting particle systems. if(Mathf.Abs(localVelocityX) > 2.5f){ isDrifting = true; DriftCarPS(); }else{ isDrifting = false; DriftCarPS(); } // The following part sets the throttle power to -1 smoothly. throttleAxis = throttleAxis - (Time.deltaTime * 3f); if(throttleAxis < -1f){ throttleAxis = -1f; } //If the car is still going forward, then apply brakes in order to avoid strange //behaviours. If the local velocity in the 'z' axis is greater than 1f, then it //is safe to apply negative torque to go reverse. if(localVelocityZ > 1f){ Brakes(); }else{ if(Mathf.Abs(Mathf.RoundToInt(carSpeed)) < maxReverseSpeed){ //Apply negative torque in all wheels to go in reverse if maxReverseSpeed has not been reached. frontLeftCollider.brakeTorque = 0; frontLeftCollider.motorTorque = (accelerationMultiplier * 50f) * throttleAxis; frontRightCollider.brakeTorque = 0; frontRightCollider.motorTorque = (accelerationMultiplier * 50f) * throttleAxis; rearLeftCollider.brakeTorque = 0; rearLeftCollider.motorTorque = (accelerationMultiplier * 50f) * throttleAxis; rearRightCollider.brakeTorque = 0; rearRightCollider.motorTorque = (accelerationMultiplier * 50f) * throttleAxis; }else { //If the maxReverseSpeed has been reached, then stop applying torque to the wheels. // IMPORTANT: The maxReverseSpeed variable should be considered as an approximation; the speed of the car // could be a bit higher than expected. frontLeftCollider.motorTorque = 0; frontRightCollider.motorTorque = 0; rearLeftCollider.motorTorque = 0; rearRightCollider.motorTorque = 0; } } } //The following function set the motor torque to 0 (in case the user is not pressing either W or S). public void ThrottleOff(){ frontLeftCollider.motorTorque = 0; frontRightCollider.motorTorque = 0; rearLeftCollider.motorTorque = 0; rearRightCollider.motorTorque = 0; } // The following method decelerates the speed of the car according to the decelerationMultiplier variable, where // 1 is the slowest and 10 is the fastest deceleration. This method is called by the function InvokeRepeating, // usually every 0.1f when the user is not pressing W (throttle), S (reverse) or Space bar (handbrake). public void DecelerateCar(){ if(Mathf.Abs(localVelocityX) > 2.5f){ isDrifting = true; DriftCarPS(); }else{ isDrifting = false; DriftCarPS(); } // The following part resets the throttle power to 0 smoothly. if(throttleAxis != 0f){ if(throttleAxis > 0f){ throttleAxis = throttleAxis - (Time.deltaTime * 10f); }else if(throttleAxis < 0f){ throttleAxis = throttleAxis + (Time.deltaTime * 10f); } if(Mathf.Abs(throttleAxis) < 0.15f){ throttleAxis = 0f; } } carRigidbody.velocity = carRigidbody.velocity * (1f / (1f + (0.025f * decelerationMultiplier))); // Since we want to decelerate the car, we are going to remove the torque from the wheels of the car. frontLeftCollider.motorTorque = 0; frontRightCollider.motorTorque = 0; rearLeftCollider.motorTorque = 0; rearRightCollider.motorTorque = 0; // If the magnitude of the car's velocity is less than 0.25f (very slow velocity), then stop the car completely and // also cancel the invoke of this method. if(carRigidbody.velocity.magnitude < 0.25f){ carRigidbody.velocity = Vector3.zero; CancelInvoke("DecelerateCar"); } } // This function applies brake torque to the wheels according to the brake force given by the user. public void Brakes(){ frontLeftCollider.brakeTorque = brakeForce; frontRightCollider.brakeTorque = brakeForce; rearLeftCollider.brakeTorque = brakeForce; rearRightCollider.brakeTorque = brakeForce; } // This function is used to make the car lose traction. By using this, the car will start drifting. The amount of traction lost // will depend on the handbrakeDriftMultiplier variable. If this value is small, then the car will not drift too much, but if // it is high, then you could make the car to feel like going on ice. public void Handbrake(){ CancelInvoke("RecoverTraction"); // We are going to start losing traction smoothly, there is were our 'driftingAxis' variable takes // place. This variable will start from 0 and will reach a top value of 1, which means that the maximum // drifting value has been reached. It will increase smoothly by using the variable Time.deltaTime. driftingAxis = driftingAxis + (Time.deltaTime); float secureStartingPoint = driftingAxis * FLWextremumSlip * handbrakeDriftMultiplier; if(secureStartingPoint < FLWextremumSlip){ driftingAxis = FLWextremumSlip / (FLWextremumSlip * handbrakeDriftMultiplier); } if(driftingAxis > 1f){ driftingAxis = 1f; } //If the forces aplied to the rigidbody in the 'x' asis are greater than //3f, it means that the car lost its traction, then the car will start emitting particle systems. if(Mathf.Abs(localVelocityX) > 2.5f){ isDrifting = true; }else{ isDrifting = false; } //If the 'driftingAxis' value is not 1f, it means that the wheels have not reach their maximum drifting //value, so, we are going to continue increasing the sideways friction of the wheels until driftingAxis // = 1f. if(driftingAxis < 1f){ FLwheelFriction.extremumSlip = FLWextremumSlip * handbrakeDriftMultiplier * driftingAxis; frontLeftCollider.sidewaysFriction = FLwheelFriction; FRwheelFriction.extremumSlip = FRWextremumSlip * handbrakeDriftMultiplier * driftingAxis; frontRightCollider.sidewaysFriction = FRwheelFriction; RLwheelFriction.extremumSlip = RLWextremumSlip * handbrakeDriftMultiplier * driftingAxis; rearLeftCollider.sidewaysFriction = RLwheelFriction; RRwheelFriction.extremumSlip = RRWextremumSlip * handbrakeDriftMultiplier * driftingAxis; rearRightCollider.sidewaysFriction = RRwheelFriction; } // Whenever the player uses the handbrake, it means that the wheels are locked, so we set 'isTractionLocked = true' // and, as a consequense, the car starts to emit trails to simulate the wheel skids. isTractionLocked = true; DriftCarPS(); } // This function is used to emit both the particle systems of the tires' smoke and the trail renderers of the tire skids // depending on the value of the bool variables 'isDrifting' and 'isTractionLocked'. public void DriftCarPS(){ if(useEffects){ try{ if(isDrifting){ RLWParticleSystem.Play(); RRWParticleSystem.Play(); }else if(!isDrifting){ RLWParticleSystem.Stop(); RRWParticleSystem.Stop(); } }catch(Exception ex){ Debug.LogWarning(ex); } try{ if((isTractionLocked || Mathf.Abs(localVelocityX) > 5f) && Mathf.Abs(carSpeed) > 12f){ RLWTireSkid.emitting = true; RRWTireSkid.emitting = true; }else { RLWTireSkid.emitting = false; RRWTireSkid.emitting = false; } }catch(Exception ex){ Debug.LogWarning(ex); } }else if(!useEffects){ if(RLWParticleSystem != null){ RLWParticleSystem.Stop(); } if(RRWParticleSystem != null){ RRWParticleSystem.Stop(); } if(RLWTireSkid != null){ RLWTireSkid.emitting = false; } if(RRWTireSkid != null){ RRWTireSkid.emitting = false; } } } // This function is used to recover the traction of the car when the user has stopped using the car's handbrake. public void RecoverTraction(){ isTractionLocked = false; driftingAxis = driftingAxis - (Time.deltaTime / 1.5f); if(driftingAxis < 0f){ driftingAxis = 0f; } //If the 'driftingAxis' value is not 0f, it means that the wheels have not recovered their traction. //We are going to continue decreasing the sideways friction of the wheels until we reach the initial // car's grip. if(FLwheelFriction.extremumSlip > FLWextremumSlip){ FLwheelFriction.extremumSlip = FLWextremumSlip * handbrakeDriftMultiplier * driftingAxis; frontLeftCollider.sidewaysFriction = FLwheelFriction; FRwheelFriction.extremumSlip = FRWextremumSlip * handbrakeDriftMultiplier * driftingAxis; frontRightCollider.sidewaysFriction = FRwheelFriction; RLwheelFriction.extremumSlip = RLWextremumSlip * handbrakeDriftMultiplier * driftingAxis; rearLeftCollider.sidewaysFriction = RLwheelFriction; RRwheelFriction.extremumSlip = RRWextremumSlip * handbrakeDriftMultiplier * driftingAxis; rearRightCollider.sidewaysFriction = RRwheelFriction; Invoke("RecoverTraction", Time.deltaTime); }else if (FLwheelFriction.extremumSlip < FLWextremumSlip){ FLwheelFriction.extremumSlip = FLWextremumSlip; frontLeftCollider.sidewaysFriction = FLwheelFriction; FRwheelFriction.extremumSlip = FRWextremumSlip; frontRightCollider.sidewaysFriction = FRwheelFriction; RLwheelFriction.extremumSlip = RLWextremumSlip; rearLeftCollider.sidewaysFriction = RLwheelFriction; RRwheelFriction.extremumSlip = RRWextremumSlip; rearRightCollider.sidewaysFriction = RRwheelFriction; driftingAxis = 0f; } } }
Editor is loading...
Leave a Comment