Files
FueraDeEscala/Assets/Game Kit Controller/Scripts/Vehicles/Vehicle Controllers/motorBikeController.cs

1229 lines
36 KiB
C#
Raw Normal View History

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using GameKitController.Audio;
public class motorBikeController : vehicleController
{
[Header ("Custom Settings")]
[Space]
public List<Wheels> wheelsList = new List<Wheels> ();
public List<Gears> gearsList = new List<Gears> ();
public OtherCarParts otherCarParts;
public motorBikeSettings settings;
public float stabilitySpeed = 220;
public float stabilityForce = 36;
public int currentGear;
public float currentRPM = 0;
[Space]
[Header ("IK and Animation Settings")]
[Space]
public bool placeDriverFeetOnGroundOnLowSpeed;
public float lowSpeedChassisRotationAmount = 20;
public float minimumLowSpeed = 5;
public float chassisRotationSpeed = 1;
public Transform rightRaycastPositionToFeet;
public Transform leftRaycastPositionToFeet;
public Vector3 footOnGroundPositionOffset;
public float adjustFeetToGroundSpeed = 4;
public Transform rightFootTransform;
public Transform lefFootTransform;
public Transform originalRightFootPosition;
public Transform originalLeftFootPosition;
public Transform footPositionOnGroundParent;
public Transform footPositionOnGround;
public bool useStandAnimation;
public string standAnimationName;
public Animation mainAnimation;
[Space]
[Header ("Debug")]
[Space]
public bool anyOnGround;
public bool reversing;
[Space]
[Header ("Components")]
[Space]
public skidsManager skidMarksManager;
bool useRightFootForGround;
Vector3 raycastPositionFoundForFeet;
bool lowSpeedDetected;
bool previoslyLowSpeedDetected;
bool adjustChassisLean = true;
List<ParticleSystem> boostingParticles = new List<ParticleSystem> ();
int i;
int collisionForceLimit = 10;
float horizontalLean = 0;
float verticalLean = 0;
float steerInput = 0;
float defSteerAngle = 0;
float originalJumpPower;
Wheels frontWheel;
Wheels rearWheel;
RaycastHit hit;
Vector3 ColliderCenterPoint;
WheelCollider currentWheelCollider;
Transform currentWheelTransform;
Transform currentWheelMeshTransform;
WheelHit wheelGroundHit;
Quaternion newRotation;
float normalizedLeanAngle;
Vector3 currentAngularVelocity;
WheelHit wheelGroundHitFront;
WheelHit wheelGroundHitRear;
int totalWheelsOnAir;
bool checkVehicleTurnedOn;
float speedMultiplier;
Vector3 predictedUp;
Vector3 torqueVector;
float currentSkidsVolume;
Wheels currentWheel;
int wheelsListCount;
int gearListCount;
ParticleSystem currentParticleSystem;
bool engineStartAudioLocated;
protected override void InitializeAudioElements ()
{
otherCarParts.InitializeAudioElements ();
foreach (var gear in gearsList) {
gear.InitializeAudioElements ();
if (otherCarParts.gearShiftingSound != null) {
gear.gearShiftingAudioElement.audioSource = otherCarParts.gearShiftingSound;
}
}
}
public override void Awake ()
{
base.Awake ();
}
public override void Start ()
{
base.Start ();
//set every wheel slip smoke particles and get the front and the rear wheel
wheelsListCount = wheelsList.Count;
gearListCount = gearsList.Count;
for (i = 0; i < wheelsListCount; i++) {
currentWheel = wheelsList [i];
if (currentWheel.wheelSide == wheelType.front) {
frontWheel = currentWheel;
}
if (currentWheel.wheelSide == wheelType.rear) {
rearWheel = currentWheel;
}
currentWheel.hasMudGuard = currentWheel.mudGuard != null;
currentWheel.hasSuspension = currentWheel.suspension != null;
currentWheel.hasParticles = currentWheel.wheelParticleSystem != null;
}
engineStartAudioLocated = otherCarParts.engineStartAudio != null;
if (useStandAnimation) {
if (mainAnimation == null) {
useStandAnimation = false;
}
}
//set the sound components
setAudioState (otherCarParts.engineAudioElement, 5, 0, true, false, false);
setAudioState (otherCarParts.skidAudioElement, 5, 0, true, false, false);
setAudioState (otherCarParts.engineStartAudioElement, 5, 0.7f, false, false, false);
mainRigidbody.centerOfMass = new Vector3 (otherCarParts.COM.localPosition.x * transform.localScale.x,
otherCarParts.COM.localPosition.y * transform.localScale.y,
otherCarParts.COM.localPosition.z * transform.localScale.z);
mainRigidbody.maxAngularVelocity = 2;
//store the max steer angle
defSteerAngle = settings.steerAngleLimit;
//get the boost particles inside the vehicle
if (otherCarParts.boostParticles != null) {
Component[] boostParticlesComponents = otherCarParts.boostParticles.GetComponentsInChildren (typeof(ParticleSystem));
foreach (ParticleSystem child in boostParticlesComponents) {
boostingParticles.Add (child);
child.gameObject.SetActive (false);
}
}
originalJumpPower = vehicleControllerSettings.jumpPower;
}
public override void vehicleUpdate ()
{
base.vehicleUpdate ();
//change gear
if (!changingGear && !usingGravityControl) {
if (currentGear + 1 < gearListCount) {
if (currentSpeed >= gearsList [currentGear].gearSpeed && rearWheel.wheelCollider.rpm >= 0) {
StartCoroutine (changeGear (currentGear + 1));
}
}
if (currentGear - 1 >= 0) {
if (currentSpeed < gearsList [currentGear - 1].gearSpeed) {
StartCoroutine (changeGear (currentGear - 1));
}
}
//set the current gear to 0 if the velocity is too low
if (currentSpeed < 5 && currentGear > 1) {
StartCoroutine (changeGear (0));
}
}
float currentDeltatime = Time.deltaTime;
//check every wheel collider of the vehicle, to move it and apply rotation to it correctly using raycast
for (i = 0; i < wheelsListCount; i++) {
currentWheel = wheelsList [i];
currentWheelCollider = currentWheel.wheelCollider;
currentWheelTransform = currentWheelCollider.transform;
currentWheelMeshTransform = currentWheel.wheelMesh.transform;
//get the center position of the wheel
ColliderCenterPoint = currentWheelTransform.TransformPoint (currentWheelCollider.center);
//use a raycast in the ground direction
currentWheelCollider.GetGroundHit (out wheelGroundHit);
//if the wheel is close enough to the ground, then
if (Physics.Raycast (ColliderCenterPoint, -currentWheelTransform.up, out hit,
(currentWheelCollider.suspensionDistance + currentWheelCollider.radius) * transform.localScale.y, settings.layer)) {
//set the wheel mesh position according to the values of the wheel collider
currentWheelMeshTransform.position = hit.point + (currentWheelCollider.radius * transform.localScale.y) * currentWheelTransform.up;
}
//the wheel is in the air
else {
//set the wheel mesh position according to the values of the wheel collider
currentWheelMeshTransform.position = ColliderCenterPoint - (currentWheelCollider.suspensionDistance * transform.localScale.y) * currentWheelTransform.up;
}
//if the current wheel is the front one,rotate the steering handlebar according to the wheel collider steerAngle
if (currentWheel.wheelSide == wheelType.front) {
otherCarParts.steeringHandlebar.transform.rotation = currentWheelTransform.rotation * Quaternion.Euler (0, currentWheelCollider.steerAngle, currentWheelTransform.rotation.z);
}
//if the wheel has a mudguard
if (currentWheel.hasMudGuard) {
//rotate the mudguard according to that rotation
currentWheel.mudGuard.transform.position = currentWheelMeshTransform.position;
}
//if the wheel has suspension, set its rotation according to the wheel position
if (currentWheel.hasSuspension) {
newRotation = Quaternion.LookRotation (currentWheel.suspension.transform.position - currentWheelMeshTransform.position, currentWheel.suspension.transform.up);
currentWheel.suspension.transform.rotation = newRotation;
}
//set the rotation value in the wheel collider
currentWheel.rotationValue += currentWheelCollider.rpm * (6) * currentDeltatime;
//rotate the wheel mesh only according to the current speed
currentWheelMeshTransform.rotation = currentWheelTransform.rotation * Quaternion.Euler (currentWheel.rotationValue, currentWheelCollider.steerAngle, currentWheelTransform.rotation.z);
}
currentAngularVelocity = mainRigidbody.angularVelocity;
//rotate the vehicle chassis when the gear is being changed
//get the vertical lean value
verticalLean =
Mathf.Clamp (Mathf.Lerp (verticalLean, transform.InverseTransformDirection (currentAngularVelocity).x * settings.chassisLean.y,
currentDeltatime * 5), -settings.chassisLeanLimit.y, settings.chassisLeanLimit.y);
frontWheel.wheelCollider.GetGroundHit (out wheelGroundHit);
normalizedLeanAngle = Mathf.Clamp (wheelGroundHit.sidewaysSlip, -1, 1);
if (transform.InverseTransformDirection (mainRigidbody.linearVelocity).z > 0) {
normalizedLeanAngle = -1;
} else {
normalizedLeanAngle = 1;
}
if (placeDriverFeetOnGroundOnLowSpeed) {
if (currentSpeed < minimumLowSpeed && anyOnGround) {
adjustChassisLean = false;
lowSpeedDetected = true;
} else {
lowSpeedDetected = false;
}
if (usingHoverBoardWaypoint) {
lowSpeedDetected = false;
}
checkDriverFootPosition ();
} else {
adjustChassisLean = true;
}
//get the horizontal lean value
horizontalLean =
Mathf.Clamp (Mathf.Lerp (horizontalLean, (transform.InverseTransformDirection (currentAngularVelocity).y * normalizedLeanAngle) *
settings.chassisLean.x, currentDeltatime * 3), -settings.chassisLeanLimit.x, settings.chassisLeanLimit.x);
Quaternion target = Quaternion.Euler (verticalLean, otherCarParts.chassis.transform.localRotation.y + (currentAngularVelocity.z), horizontalLean);
if (adjustChassisLean) {
//set the lean rotation value in the chassis transform
otherCarParts.chassis.transform.localRotation = target;
}
//set the vehicle mass center
mainRigidbody.centerOfMass = new Vector3 ((otherCarParts.COM.localPosition.x) * transform.lossyScale.x,
(otherCarParts.COM.localPosition.y) * transform.lossyScale.y,
(otherCarParts.COM.localPosition.z) * transform.localScale.z);
}
void FixedUpdate ()
{
//get the current speed value
currentSpeed = mainRigidbody.linearVelocity.magnitude * 3.6f;
if (usingHoverBoardWaypoint) {
return;
}
float currentDeltatime = Time.deltaTime;
//allows vehicle to remain roughly pointing in the direction of travel
if (!anyOnGround && settings.preserveDirectionWhileInAir && currentSpeed > 5) {
float velocityDirection = Vector3.Dot (mainRigidbody.linearVelocity, currentNormal);
if (velocityDirection > -20) {
float angleX = Mathf.Asin (transform.InverseTransformDirection (Vector3.Cross (currentNormal.normalized, transform.up)).x) * Mathf.Rad2Deg;
transform.eulerAngles -= (angleX * currentDeltatime) * transform.InverseTransformDirection (transform.right);
}
}
steerInput = Mathf.Lerp (steerInput, horizontalAxis, currentDeltatime * settings.steerInputSpeed);
//set the steer limit
settings.steerAngleLimit = Mathf.Lerp (defSteerAngle, settings.highSpeedSteerAngle, (currentSpeed / settings.highSpeedSteerAngleAtSpeed));
//set the steer angle in the fron wheel
frontWheel.wheelCollider.steerAngle = settings.steerAngleLimit * steerInput;
//set the current RPM
currentRPM =
Mathf.Clamp ((((Mathf.Abs ((frontWheel.wheelCollider.rpm + rearWheel.wheelCollider.rpm)) * settings.gearShiftRate) + settings.minRPM)) /
(currentGear + 1), settings.minRPM, settings.maxRPM);
//check if the vehicle is moving forwards or backwards
if (motorInput < 0) {
reversing = true;
} else {
reversing = false;
}
//set the engine audio volume and pitch according to input and current RPM
if (!vehicleDestroyed) {
otherCarParts.engineAudio.volume = Mathf.Lerp (otherCarParts.engineAudio.volume, Mathf.Clamp (motorInput, 0.35f, 0.85f), currentDeltatime * 5);
otherCarParts.engineAudio.pitch =
Mathf.Lerp (otherCarParts.engineAudio.pitch, Mathf.Lerp (1, 2, (currentRPM - (settings.minRPM / 1.5f)) / (settings.maxRPM + settings.minRPM)), currentDeltatime * 5);
}
if (engineStartAudioLocated) {
if (otherCarParts.engineStartAudio.volume > 0) {
otherCarParts.engineStartAudio.volume -= currentDeltatime / 5;
}
}
//if the current speed is higher that the max speed, stop apply motor torque to the powered wheel
if (currentSpeed > vehicleControllerSettings.maxForwardSpeed || usingGravityControl) {
rearWheel.wheelCollider.motorTorque = 0;
}
//else if the vehicle is moving in fowards direction, apply motor torque to the powered wheel using the gear animation curve
else if (!reversing && !changingGear) {
speedMultiplier = 1;
if (settings.useCurves) {
speedMultiplier = gearsList [currentGear].engineTorqueCurve.Evaluate (currentSpeed);
}
rearWheel.wheelCollider.motorTorque = settings.engineTorque * Mathf.Clamp (motorInput, 0, 1) * boostInput * speedMultiplier;
}
//if the vehicle is moving backwards, apply motor torque to every powered wheel
if (reversing) {
//if the current speed is lower than the maxBackWardSpeed, apply motor torque
if (currentSpeed < settings.maxBackwardSpeed && Mathf.Abs (rearWheel.wheelCollider.rpm / 2) < 3000) {
rearWheel.wheelCollider.motorTorque = settings.engineTorque * motorInput;
}
//else, stop adding motor torque
else {
rearWheel.wheelCollider.motorTorque = 0;
}
}
bool brakeActive = (braking || isBrakeActive ());
//if the handbrake is pressed, set the brake torque value in every wheel
for (i = 0; i < wheelsListCount; i++) {
currentWheel = wheelsList [i];
if (brakeActive) {
if (currentWheel.wheelSide == wheelType.front) {
currentWheel.wheelCollider.brakeTorque = settings.brake * 5;
}
if (currentWheel.wheelSide == wheelType.rear) {
currentWheel.wheelCollider.brakeTorque = settings.brake * 25;
}
} else {
//else, check if the vehicle input is in forward or in backward direction
//the vehicle is decelerating
if (Mathf.Abs (motorInput) <= 0.05f && !changingGear) {
currentWheel.wheelCollider.brakeTorque = settings.brake / 25;
}
//the vehicle is braking
else if (motorInput < 0 && !reversing) {
if (currentWheel.wheelSide == wheelType.front) {
currentWheel.wheelCollider.brakeTorque = settings.brake * (Mathf.Abs (motorInput) / 5);
}
if (currentWheel.wheelSide == wheelType.rear) {
currentWheel.wheelCollider.brakeTorque = settings.brake * (Mathf.Abs (motorInput));
}
} else {
currentWheel.wheelCollider.brakeTorque = 0;
}
}
}
//check the right front and right rear wheel to play the skid audio according to their state
frontWheel.wheelCollider.GetGroundHit (out wheelGroundHitFront);
rearWheel.wheelCollider.GetGroundHit (out wheelGroundHitRear);
currentSkidsVolume = otherCarParts.skidAudio.volume;
if (anyOnGround) {
//if the values in the wheel hit are higher that
if (Mathf.Abs (wheelGroundHitFront.sidewaysSlip) > 0.25f || Mathf.Abs (wheelGroundHitRear.forwardSlip) > 0.5f || Mathf.Abs (wheelGroundHitFront.forwardSlip) > 0.5f) {
//and the vehicle is moving, then
if (mainRigidbody.linearVelocity.magnitude > 1) {
//set the skid volume value according to the vehicle skid
currentSkidsVolume = Mathf.Abs (wheelGroundHitFront.sidewaysSlip) + ((Mathf.Abs (wheelGroundHitFront.forwardSlip) + Mathf.Abs (wheelGroundHitRear.forwardSlip)) / 4);
} else {
//set the skid volume value to 0
currentSkidsVolume -= currentDeltatime;
}
} else {
//set the skid volume value to 0
currentSkidsVolume -= currentDeltatime;
}
} else {
currentSkidsVolume -= currentDeltatime * 10;
}
otherCarParts.skidAudio.volume = currentSkidsVolume;
anyOnGround = true;
totalWheelsOnAir = 0;
//set the smoke skid particles in every wheel
for (i = 0; i < wheelsListCount; i++) {
currentWheel = wheelsList [i];
currentWheel.wheelCollider.GetGroundHit (out wheelGroundHit);
//set the skid marks under every wheel
currentWheel.wheelSlipAmountSideways = Mathf.Abs (wheelGroundHit.sidewaysSlip);
currentWheel.wheelSlipAmountForward = Mathf.Abs (wheelGroundHit.forwardSlip);
if (currentWheel.wheelSlipAmountSideways > 0.25f || wheelsList [i].wheelSlipAmountForward > 0.5f) {
Vector3 skidPoint = wheelGroundHit.point + (2 * currentDeltatime) * (mainRigidbody.linearVelocity);
if (mainRigidbody.linearVelocity.magnitude > 1) {
currentWheel.lastSkidmark = skidMarksManager.AddSkidMark (skidPoint, wheelGroundHit.normal,
(currentWheel.wheelSlipAmountSideways / 2) + (currentWheel.wheelSlipAmountForward / 2.5f), currentWheel.lastSkidmark);
} else {
currentWheel.lastSkidmark = -1;
}
} else {
currentWheel.lastSkidmark = -1;
}
if (currentWheel.hasParticles) {
currentParticleSystem = currentWheel.wheelParticleSystem;
if (Mathf.Abs (wheelGroundHit.sidewaysSlip) > 0.25f || Mathf.Abs (wheelGroundHit.forwardSlip) > 0.5f) {
if (!currentParticleSystem.isPlaying) {
currentParticleSystem.Play ();
}
} else {
if (currentParticleSystem.isPlaying) {
currentParticleSystem.Stop ();
}
}
}
//check if the car is in the ground or not
if (!currentWheel.wheelCollider.isGrounded) {
//if the current wheel is in the air, increase the number of wheels in the air
totalWheelsOnAir++;
}
}
if (isTurnedOn) {
checkVehicleTurnedOn = true;
//set the exhaust particles state
int normalExhaustCount = otherCarParts.normalExhaust.Count;
for (i = 0; i < normalExhaustCount; i++) {
currentParticleSystem = otherCarParts.normalExhaust [i];
if (isTurnedOn && currentSpeed < 20) {
if (!currentParticleSystem.isPlaying) {
currentParticleSystem.Play ();
}
} else {
if (currentParticleSystem.isPlaying) {
currentParticleSystem.Stop ();
}
}
}
int heavyExhaustCount = otherCarParts.heavyExhaust.Count;
for (i = 0; i < heavyExhaustCount; i++) {
currentParticleSystem = otherCarParts.heavyExhaust [i];
if (isTurnedOn && currentSpeed > 20 && motorInput > 0.5f) {
if (!currentParticleSystem.isPlaying) {
currentParticleSystem.Play ();
}
} else {
if (currentParticleSystem.isPlaying) {
currentParticleSystem.Stop ();
}
}
}
} else {
if (checkVehicleTurnedOn) {
stopVehicleParticles ();
checkVehicleTurnedOn = false;
}
}
//if the total amount of wheels in the air is equal to the number of wheel sin the vehicle, anyOnGround is false
if (totalWheelsOnAir == wheelsListCount && anyOnGround) {
anyOnGround = false;
}
//if any wheel is in the ground rear, then
if (anyOnGround) {
//check if the jump input has been presses
if (jumpInputPressed) {
//apply force in the up direction
mainRigidbody.AddForce ((mainRigidbody.mass * vehicleControllerSettings.jumpPower) * transform.up);
jumpInputPressed = false;
}
}
//stabilize the vehicle in its forward direction
predictedUp = Quaternion.AngleAxis (mainRigidbody.angularVelocity.magnitude * Mathf.Rad2Deg * stabilityForce / stabilitySpeed, mainRigidbody.angularVelocity) * transform.up;
torqueVector = Vector3.Cross (predictedUp, mainVehicleCameraController.transform.up);
torqueVector = transform.InverseTransformDirection (torqueVector).z * transform.forward;
mainRigidbody.AddTorque ((stabilitySpeed * stabilitySpeed) * torqueVector);
}
public void checkDriverFootPosition ()
{
if (lowSpeedDetected != previoslyLowSpeedDetected) {
previoslyLowSpeedDetected = lowSpeedDetected;
if (lowSpeedDetected) {
Vector3 currentNormal = getCurrentNormal ();
float chassisAngle = Vector3.SignedAngle (transform.up, currentNormal, transform.forward);
useRightFootForGround = true;
if (chassisAngle > 0) {
useRightFootForGround = false;
}
Vector3 raycastPositionTransformPosition = Vector3.zero;
if (useRightFootForGround) {
raycastPositionTransformPosition = rightRaycastPositionToFeet.position;
} else {
raycastPositionTransformPosition = leftRaycastPositionToFeet.position;
}
if (Physics.Raycast (raycastPositionTransformPosition, -currentNormal, out hit, 20, settings.layer)) {
raycastPositionFoundForFeet = hit.point;
raycastPositionFoundForFeet +=
footOnGroundPositionOffset.x * transform.right +
footOnGroundPositionOffset.y * hit.normal +
footOnGroundPositionOffset.z * transform.forward;
footPositionOnGround.position = raycastPositionFoundForFeet;
footPositionOnGround.SetParent (footPositionOnGroundParent);
footPositionOnGround.localRotation = Quaternion.identity;
if (useRightFootForGround) {
setChassisRotation (new Vector3 (0, 0, -lowSpeedChassisRotationAmount));
} else {
setChassisRotation (new Vector3 (0, 0, lowSpeedChassisRotationAmount));
}
adjustFeetToGround (true);
}
} else {
setChassisRotation (new Vector3 (0, 0, 0));
adjustFeetToGround (false);
}
}
}
public void playStandAnimation (bool playForward)
{
if (useStandAnimation) {
if (playForward) {
mainAnimation [standAnimationName].speed = 1;
} else {
mainAnimation [standAnimationName].speed = -1;
mainAnimation [standAnimationName].time = mainAnimation [standAnimationName].length;
}
mainAnimation.Play (standAnimationName);
}
}
public override bool isDrivingActive ()
{
return driving;
}
public override void setEngineOnOrOffState ()
{
base.setEngineOnOrOffState ();
}
public override void pressHorn ()
{
base.pressHorn ();
setAudioState (otherCarParts.hornAudioElement, 5, 1, false, true, false);
}
//if the vehicle is using the gravity control, set the state in this component
public override void changeGravityControlUse (bool state)
{
base.changeGravityControlUse (state);
if (usingGravityControl) {
StartCoroutine (changeGear (0));
}
}
//the player is getting on or off from the vehicle, so
public override void changeVehicleState ()
{
base.changeVehicleState ();
playStandAnimation (driving);
}
public override void setTurnOnState ()
{
setAudioState (otherCarParts.engineAudioElement, 5, 0, true, true, false);
setAudioState (otherCarParts.skidAudioElement, 5, 0, true, true, false);
setAudioState (otherCarParts.engineStartAudioElement, 5, 0.7f, false, true, false);
}
public override void setTurnOffState (bool previouslyTurnedOn)
{
base.setTurnOffState (previouslyTurnedOn);
if (previouslyTurnedOn) {
setAudioState (otherCarParts.engineAudioElement, 5, 0, false, false, true);
setAudioState (otherCarParts.engineEndAudioElement, 5, 1, false, true, false);
}
steerInput = 0;
}
public override void turnOnOrOff (bool state, bool previouslyTurnedOn)
{
base.turnOnOrOff (state, previouslyTurnedOn);
}
//the vehicle has been destroyed, so disabled every component in it
public override void disableVehicle ()
{
//stop the audio sources
setAudioState (otherCarParts.engineAudioElement, 5, 0, false, false, false);
setAudioState (otherCarParts.skidAudioElement, 5, 0, false, false, false);
setAudioState (otherCarParts.engineStartAudioElement, 5, 0.7f, false, false, false);
skidMarksManager.setSkidsEnabledState (false);
vehicleDestroyed = true;
setTurnOffState (false);
//disable the skid particles
stopVehicleParticles ();
//disable the controller
this.enabled = false;
}
public void stopVehicleParticles ()
{
for (i = 0; i < wheelsListCount; i++) {
wheelsList [i].wheelParticleSystem.Stop ();
}
//disable the exhausts particles
for (i = 0; i < otherCarParts.normalExhaust.Count; i++) {
otherCarParts.normalExhaust [i].Stop ();
}
for (i = 0; i < otherCarParts.heavyExhaust.Count; i++) {
otherCarParts.heavyExhaust [i].Stop ();
}
}
//change the gear in the vehicle
IEnumerator changeGear (int gear)
{
changingGear = true;
setAudioState (gearsList [gear].gearShiftingAudioElement, 5, 0.3f, false, true, false);
WaitForSeconds delay = new WaitForSeconds (0.5f);
yield return delay;
changingGear = false;
currentGear = gear;
}
//if the vehicle is using the boost, set the boost particles
public override void usingBoosting ()
{
base.usingBoosting ();
if (otherCarParts.boostParticles) {
for (int i = 0; i < boostingParticles.Count; i++) {
if (usingBoost) {
if (!boostingParticles [i].isPlaying) {
boostingParticles [i].gameObject.SetActive (true);
boostingParticles [i].Play ();
var boostingParticlesMain = boostingParticles [i].main;
boostingParticlesMain.loop = true;
}
} else {
if (boostingParticles [i].isPlaying) {
var boostingParticlesMain = boostingParticles [i].main;
boostingParticlesMain.loop = false;
}
}
}
}
}
//use a jump platform
public void useVehicleJumpPlatform (Vector3 direction)
{
mainRigidbody.AddForce (mainRigidbody.mass * direction, ForceMode.Impulse);
}
public void useJumpPlatformParable (Vector3 direction)
{
mainRigidbody.AddForce (direction, ForceMode.VelocityChange);
}
public void setNewJumpPower (float newJumpPower)
{
vehicleControllerSettings.jumpPower = newJumpPower * 100;
}
public void setOriginalJumpPower ()
{
vehicleControllerSettings.jumpPower = originalJumpPower;
}
Coroutine chassisRotationCoroutine;
public void setChassisRotation (Vector3 rotationAmount)
{
stopSetChassisRotationCoroutine ();
chassisRotationCoroutine = StartCoroutine (setChassisRotationCoroutine (rotationAmount));
}
public void stopSetChassisRotationCoroutine ()
{
if (chassisRotationCoroutine != null) {
StopCoroutine (chassisRotationCoroutine);
}
}
IEnumerator setChassisRotationCoroutine (Vector3 rotationAmount)
{
float t = 0;
float normalAngle = 0;
bool targetReached = false;
float coroutineTimer = 0;
while (!targetReached) {
t += Time.deltaTime * chassisRotationSpeed;
normalAngle = Quaternion.Angle (otherCarParts.chassis.transform.localRotation, Quaternion.Euler (rotationAmount));
otherCarParts.chassis.transform.localRotation = Quaternion.Slerp (otherCarParts.chassis.transform.localRotation, Quaternion.Euler (rotationAmount), t);
coroutineTimer += Time.deltaTime;
if (normalAngle < 0.1f || coroutineTimer > 2) {
targetReached = true;
if (rotationAmount == Vector3.zero) {
adjustChassisLean = true;
}
}
yield return null;
}
}
Coroutine adjustFeetCoroutine;
public void adjustFeetToGround (bool adjustToGround)
{
stopAdjustHoldOnLedgeCoroutine ();
adjustFeetCoroutine = StartCoroutine (adjustFeetToGroundCoroutine (adjustToGround));
}
public void stopAdjustHoldOnLedgeCoroutine ()
{
if (adjustFeetCoroutine != null) {
StopCoroutine (adjustFeetCoroutine);
}
}
IEnumerator adjustFeetToGroundCoroutine (bool adjustToGround)
{
Transform currentFootTransform = rightFootTransform;
Vector3 targetPosition = raycastPositionFoundForFeet;
Quaternion targetRotation = footPositionOnGround.localRotation;
Transform currentTargetRotationTransform = footPositionOnGround;
footPositionOnGround.SetParent (mainVehicleCameraController.transform);
footPositionOnGround.localEulerAngles = new Vector3 (0, footPositionOnGround.localEulerAngles.y, 0);
footPositionOnGround.SetParent (null);
if (!adjustToGround) {
targetPosition = originalRightFootPosition.localPosition;
targetRotation = originalRightFootPosition.localRotation;
currentTargetRotationTransform = originalRightFootPosition;
}
if (!useRightFootForGround) {
currentFootTransform = lefFootTransform;
if (!adjustToGround) {
targetPosition = originalLeftFootPosition.localPosition;
targetRotation = originalLeftFootPosition.localRotation;
currentTargetRotationTransform = originalLeftFootPosition;
}
}
if (adjustToGround) {
targetPosition = footPositionOnGround.position;
targetRotation = footPositionOnGround.rotation;
}
float dist = 0;
if (adjustToGround) {
dist = GKC_Utils.distance (currentFootTransform.position, targetPosition);
} else {
dist = GKC_Utils.distance (currentFootTransform.localPosition, targetPosition);
}
float duration = dist / adjustFeetToGroundSpeed;
float translateTimer = 0;
float rotateTimer = 0;
float adjustmentTimer = 0;
float normalAngle = 0;
bool targetReached = false;
while (!targetReached) {
translateTimer += Time.deltaTime / duration;
if (adjustToGround) {
currentFootTransform.position = Vector3.Lerp (currentFootTransform.position, targetPosition, translateTimer);
} else {
currentFootTransform.localPosition = Vector3.Lerp (currentFootTransform.localPosition, targetPosition, translateTimer);
}
rotateTimer += Time.deltaTime * adjustFeetToGroundSpeed;
if (adjustToGround) {
currentFootTransform.rotation = Quaternion.Lerp (currentFootTransform.rotation, targetRotation, rotateTimer);
} else {
currentFootTransform.localRotation = Quaternion.Lerp (currentFootTransform.localRotation, targetRotation, rotateTimer);
}
adjustmentTimer += Time.deltaTime;
normalAngle = Vector3.Angle (currentFootTransform.up, currentTargetRotationTransform.up);
if (adjustToGround) {
if ((GKC_Utils.distance (currentFootTransform.position, targetPosition) < 0.01f && normalAngle < 0.1f) || adjustmentTimer > (duration + 2f)) {
targetReached = true;
}
} else {
if ((GKC_Utils.distance (currentFootTransform.localPosition, targetPosition) < 0.01f && normalAngle < 0.1f) || adjustmentTimer > (duration + 2f)) {
targetReached = true;
}
}
yield return null;
}
}
public void setCanJumpState (bool state)
{
vehicleControllerSettings.canJump = state;
}
//OVERRIDE FUNCTIONS FOR VEHICLE CONTROLLER
//if any collider in the vehicle collides, then
public override void setCollisionDetected (Collision currentCollision)
{
//check that the collision is not with the player
if (!currentCollision.gameObject.CompareTag ("Player")) {
//if the velocity of the collision is higher that the limit
if (currentCollision.relativeVelocity.magnitude > collisionForceLimit) {
//set the collision audio with a random collision clip
if (otherCarParts.crashAudioElements.Length > 0) {
setAudioState (otherCarParts.crashAudioElements [UnityEngine.Random.Range (0, otherCarParts.crashAudioElements.Length)], 5, 1, false, true, false);
}
}
}
}
public override void startBrakeVehicleToStopCompletely ()
{
braking = true;
}
public override void endBrakeVehicleToStopCompletely ()
{
braking = false;
}
public override float getCurrentSpeed ()
{
return currentSpeed;
}
//CALL INPUT FUNCTIONS
public override void inputJump ()
{
if (driving && !usingGravityControl && isTurnedOn && vehicleControllerSettings.canJump) {
if (usingHoverBoardWaypoint) {
pickOrReleaseHoverboardVehicle (false, false);
Vector3 totalJumpForce = mainRigidbody.mass * hoverboardJumpForce * (currentNormal + transform.forward);
if (useHoverboardJumpClamp) {
totalJumpForce = Vector3.ClampMagnitude (totalJumpForce, hoverboardJumpClamp);
}
mainRigidbody.AddForce (totalJumpForce, ForceMode.Impulse);
return;
}
jumpInputPressed = true;
}
}
public override void inputHoldOrReleaseTurbo (bool holdingButton)
{
if (driving && !usingGravityControl && isTurnedOn && !usingHoverBoardWaypoint) {
//boost input
if (holdingButton) {
if (vehicleControllerSettings.canUseBoost) {
usingBoost = true;
//set the camera move away action
mainVehicleCameraController.usingBoost (true, vehicleControllerSettings.boostCameraShakeStateName,
vehicleControllerSettings.useBoostCameraShake, vehicleControllerSettings.moveCameraAwayOnBoost);
}
} else {
//stop boost
usingBoost = false;
//disable the camera move away action
mainVehicleCameraController.usingBoost (false, vehicleControllerSettings.boostCameraShakeStateName,
vehicleControllerSettings.useBoostCameraShake, vehicleControllerSettings.moveCameraAwayOnBoost);
//disable the boost particles
usingBoosting ();
boostInput = 1;
}
}
}
public override void inputSetTurnOnState ()
{
if (driving && !usingGravityControl) {
if (mainVehicleHUDManager.canSetTurnOnState) {
setEngineOnOrOffState ();
}
}
}
public override void inputHorn ()
{
if (driving) {
pressHorn ();
}
}
public override void inputHoldOrReleaseBrake (bool holdingButton)
{
if (driving && !usingGravityControl) {
braking = holdingButton;
}
}
[System.Serializable]
public class Wheels
{
public string Name;
public WheelCollider wheelCollider;
public GameObject wheelMesh;
public GameObject mudGuard;
public GameObject suspension;
public wheelType wheelSide;
public ParticleSystem wheelParticleSystem;
[HideInInspector] public bool hasMudGuard;
[HideInInspector] public bool hasSuspension;
[HideInInspector] public bool hasParticles;
[HideInInspector] public float suspensionSpringPos;
[HideInInspector] public float rotationValue;
[HideInInspector] public float wheelSlipAmountSideways;
[HideInInspector] public float wheelSlipAmountForward;
[HideInInspector] public int lastSkidmark = -1;
}
public enum wheelType
{
front,
rear,
}
[System.Serializable]
public class OtherCarParts
{
public Transform steeringHandlebar;
public Transform COM;
public GameObject wheelSlipPrefab;
public GameObject chassis;
public AudioClip engineStartClip;
public AudioElement engineStartAudioElement;
public AudioClip engineClip;
public AudioElement engineAudioElement;
public AudioClip engineEndClip;
public AudioElement engineEndAudioElement;
public AudioClip skidClip;
public AudioElement skidAudioElement;
public AudioClip[] crashClips;
public AudioElement[] crashAudioElements;
public AudioClip hornClip;
public AudioElement hornAudioElement;
public List<ParticleSystem> normalExhaust = new List<ParticleSystem> ();
public List<ParticleSystem> heavyExhaust = new List<ParticleSystem> ();
public AudioSource engineStartAudio;
public AudioSource engineAudio;
public AudioSource skidAudio;
public AudioSource crashAudio;
public AudioSource gearShiftingSound;
public AudioSource hornAudio;
public GameObject boostParticles;
public void InitializeAudioElements ()
{
if (engineStartClip != null) {
engineStartAudioElement.clip = engineStartClip;
}
if (engineClip != null) {
engineAudioElement.clip = engineClip;
}
if (engineEndClip != null) {
engineEndAudioElement.clip = engineEndClip;
}
if (skidClip != null) {
skidAudioElement.clip = skidClip;
}
if (crashClips != null && crashClips.Length > 0) {
crashAudioElements = new AudioElement[crashClips.Length];
for (var i = 0; i < crashClips.Length; i++) {
crashAudioElements [i] = new AudioElement { clip = crashClips [i] };
}
}
if (hornClip != null) {
hornAudioElement.clip = hornClip;
}
if (engineStartAudio != null) {
engineStartAudioElement.audioSource = engineStartAudio;
}
if (engineAudio != null) {
engineAudioElement.audioSource = engineAudio;
engineEndAudioElement.audioSource = engineAudio;
}
if (skidAudio != null) {
skidAudioElement.audioSource = skidAudio;
}
if (crashAudio != null) {
foreach (var audioElement in crashAudioElements) {
audioElement.audioSource = crashAudio;
}
}
if (hornAudio != null) {
hornAudioElement.audioSource = hornAudio;
}
}
}
[System.Serializable]
public class Gears
{
public string Name;
public AnimationCurve engineTorqueCurve;
public float gearSpeed;
public AudioClip gearShiftingClip;
public AudioElement gearShiftingAudioElement;
public void InitializeAudioElements ()
{
if (gearShiftingClip != null) {
gearShiftingAudioElement.clip = gearShiftingClip;
}
}
}
[System.Serializable]
public class motorBikeSettings
{
public LayerMask layer;
public float engineTorque = 1500;
public float maxRPM = 6000;
public float minRPM = 1000;
public float steerInputSpeed = 10;
public float steerAngleLimit;
public float highSpeedSteerAngle = 5;
public float highSpeedSteerAngleAtSpeed = 80;
public float brake;
public float maxBackwardSpeed;
public float gearShiftRate = 10;
public Vector2 chassisLean;
public Vector2 chassisLeanLimit;
public bool preserveDirectionWhileInAir;
public bool useCurves;
}
}