1229 lines
36 KiB
C#
1229 lines
36 KiB
C#
|
|
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;
|
||
|
|
}
|
||
|
|
}
|