public void ThrusterDown() { PlayOneShot.PlayShot("ThrusterDown", 1.0f, 1.0f, 200, 100, transform, transform.position, GetComponent <ShipSimulator>().settings.audioEngineStartup); visualLightItensity = 5.0f; }
/// <summary> /// Handles the gravity and hovering for the ship. /// </summary> public void Gravity() { // Reset gravity/magstrip bShipIsGrounded = false; bShipIsOnMagStrip = false; // Increase the rideheight slightly (keeps the ship at the actual wanted height) float rideHeight = GlobalSettings.shipRideHeight * 1.2f; // Pitching if (controller.inputPitch != 0) { shipPitchAmount = Mathf.Lerp(shipPitchAmount, controller.inputPitch * GlobalSettings.shipPitchGroundAmount, Time.deltaTime * GlobalSettings.shipPitchDamping); } else { shipPitchAmount = Mathf.Lerp(shipPitchAmount, 0.0f, Time.deltaTime * GlobalSettings.shipPitchDamping); } shipBody.AddTorque(transform.right * (shipPitchAmount * 10)); // Get the current class and set the gravity multipliers float gravityMul = 0; float trackGrav = 0; float flightGrav = 0; switch (eventSpeedClass) { case GlobalSettings.SpeedClasses.D: // Gravity Multiplier gravityMul = GlobalSettings.airGravityMulD; // Track Gravity trackGrav = GlobalSettings.shipTrackGravityD; // Flight Gravity flightGrav = GlobalSettings.shipFlightGravityD; break; case GlobalSettings.SpeedClasses.C: // Gravity Multiplier gravityMul = GlobalSettings.airGravityMulC; // Track Gravity trackGrav = GlobalSettings.shipTrackGravityC; // Flight Gravity flightGrav = GlobalSettings.shipFlightGravityC; break; case GlobalSettings.SpeedClasses.B: // Gravity Multiplier gravityMul = GlobalSettings.airGravityMulB; // Track Gravity trackGrav = GlobalSettings.shipTrackGravityB; // Flight Gravity flightGrav = GlobalSettings.shipFlightGravityB; break; case GlobalSettings.SpeedClasses.A: // Gravity Multiplier gravityMul = GlobalSettings.airGravityMulA; // Track Gravity trackGrav = GlobalSettings.shipTrackGravityA; // Flight Gravity flightGrav = GlobalSettings.shipFlightGravityA; break; case GlobalSettings.SpeedClasses.AP: // Gravity Multiplier gravityMul = GlobalSettings.airGravityMulAP; // Track Gravity trackGrav = GlobalSettings.shipTrackGravityAP; // Flight Gravity flightGrav = GlobalSettings.shipFlightGravityAP; break; case GlobalSettings.SpeedClasses.APP: // Gravity Multiplier gravityMul = GlobalSettings.airGravityMulAPP; // Track Gravity trackGrav = GlobalSettings.shipTrackGravityAPP; // Flight Gravity flightGrav = GlobalSettings.shipFlightGravityAPP; break; } // Create hover points list List <Vector3> hoverPoints = new List <Vector3>(); // Get a slightly smaller area of the ship size Vector2 hoverArea = new Vector2(settings.physColliderSize.x / 2, settings.physColliderSize.z / 2.05f); // Add hover points hoverPoints.Add(transform.TransformPoint(-hoverArea.x, Mathf.Clamp(shipPitchAmount, 0.0f, 0.5f), hoverArea.y)); // Front Left hoverPoints.Add(transform.TransformPoint(hoverArea.x, Mathf.Clamp(shipPitchAmount, 0.0f, 0.5f), hoverArea.y)); // Front Right hoverPoints.Add(transform.TransformPoint(hoverArea.x, Mathf.Clamp(-shipPitchAmount, 0.0f, 0.7f), -hoverArea.y)); // Back Right hoverPoints.Add(transform.TransformPoint(-hoverArea.x, Mathf.Clamp(-shipPitchAmount, 0.0f, 0.7f), -hoverArea.y)); // Back Left // Run through each hover point and apply hover forces if needed for (int i = 0; i < hoverPoints.Count; i++) { // Bitshift track floor and mag lock layers into a new integer for the ship to only check for those two collision layers int trackFloorMask = 1 << LayerMask.NameToLayer("TrackFloor") | 1 << LayerMask.NameToLayer("Maglock"); // Create raycasthit to store hit data into RaycastHit hoverHit; // Raycast down for track if (Physics.Raycast(hoverPoints[i], -transform.up, out hoverHit, rideHeight, trackFloorMask)) { // Get the distance to the ground float dist = hoverHit.distance; // Normalize the distance into a compression ratio float compressionRatio = ((dist / rideHeight) - 1) * -1; // Get the velocity at the hover point Vector3 hoverVel = shipBody.GetPointVelocity(hoverPoints[i]); // Project the velocity onto the ships up vector Vector3 projForce = Vector3.Project(hoverVel, transform.up); // Check to see if the ship is on a magstrip if (hoverHit.collider.gameObject.layer == LayerMask.NameToLayer("Maglock")) { bShipIsOnMagStrip = true; } /* Calculate force needed to push ship away from track */ // Set a force multiplier float forceMult = 5; // Calcaulate a ratio to multiply the compression ratio by (drasticly increases the hover force as it gets closer to the track) float forceRatio = ((dist / 2) / (rideHeight / 2) - 1) * -forceMult; // Clamp the ratio forceRatio = Mathf.Clamp(forceRatio, 2.0f, 10.0f); // Create the new force float force = 200.0f * (compressionRatio * forceRatio); /* Calculate damping amount to bring the ship to rest quicker */ // Set a damping multiplier float dampMult = 6.5f; // Calculate a ratio to multiply the compression ratio by float dampRatio = ((dist / 2) / (rideHeight / 2) - 1) * -dampMult; // Clamp the ratio dampRatio = Mathf.Clamp(dampRatio, 1.0f, 5.5f); // Clamp the compression ratio, min being the base damp amount float clampedCR = Mathf.Clamp(compressionRatio, 0.5f, 1.0f); // Get the landing rebound to dampen forces straight after a long fall (stops the ship rebounding high off the track) float reboundDamper = Mathf.Clamp(shipReboundLand * 15, 1.0f, Mathf.Infinity); // Create the new damping force float damping = (1 * (clampedCR * dampRatio) * reboundDamper); // If the ship is over a magstrip then we want the ship to act a bit differently if (bShipIsOnMagStrip) { // Calculate how strong the magstrip is based on the ships current angular velocity and speed float magStrength = Mathf.Abs(transform.InverseTransformDirection(shipBody.angularVelocity).x *Time.deltaTime) * Mathf.Abs(transform.InverseTransformDirection(shipBody.velocity).z *Time.deltaTime); // Multiply the strength as the above calculate will result in a terrible lock strength magStrength *= 1000; // Clamp the strength so it can't be too strong magStrength = Mathf.Clamp(magStrength, 0.0f, (transform.InverseTransformDirection(shipBody.velocity).z *Time.deltaTime) * 3.8f); // Set new force and damping multipliers force = (trackGrav * (5.0f + magStrength)); damping = 2f; // Apply the magstrip lock force shipBody.AddForceAtPosition(-transform.up * (trackGrav * (magStrength * 4.0f)), hoverPoints[i], ForceMode.Acceleration); } // Calculate the suspension force Vector3 suspensionForce = transform.up * compressionRatio * force; // Now apply damping Vector3 dampedForce = suspensionForce - (projForce * damping); // Finally, apply the force shipBody.AddForceAtPosition(dampedForce, hoverPoints[i], ForceMode.Acceleration); // Set the grounded boolean to true bShipIsGrounded = true; // Debug line if (bDebugVisualizeHovering) { Debug.DrawLine(hoverPoints[i], hoverHit.point); } // Force feedback if (dist < rideHeight * 0.6f) { vibrationManager.vibLeftMotor = 0.3f; vibrationManager.vibRightMotor = 0.3f; vibrationManager.timerMotor = 1.1f; } } } /* If the ship is grounded then we also want to have the ship be pulled down by gravity * We want to do another raycast for the trackfloor layer only from the centre of the ship * then calculate everything from that. * * Don't worry, we are only casting for one layer over a short distance, this isn't very * expensive to do. */ // Create raycasthit to store hit data into RaycastHit centreHit; // Raycast down if (Physics.Raycast(transform.position, -transform.up, out centreHit, rideHeight, 1 << LayerMask.NameToLayer("TrackFloor"))) { // Use a dot product to find out how much we need to rotate the ship to get it to face down Vector3 trackRot = transform.forward - (Vector3.Dot(transform.forward, centreHit.normal) * centreHit.normal); // Use the track rotation to calculate how much we are going to rotate the ship float rotAmount = (trackRot.x * trackRot.z) * (Mathf.Clamp(Mathf.Abs(trackRot.y), 0.0f, 0.1f) * 10); // Increase the rotation amount as the ship speeds up float rotForce = 20 + (transform.InverseTransformDirection(shipBody.velocity).z *Time.deltaTime) * 1.2f; // Apply the rotation transform.Rotate(Vector3.up * (rotAmount * Time.deltaTime) * rotForce); // Apply gravity force shipBody.AddForce(new Vector3(centreHit.normal.x, 0, centreHit.normal.z) * (Mathf.Abs(trackRot.x)) * 22); } /* We also want to check for pads on the track. We'll do exactly the same as above to do this. * Also we can recycle the centrehit variable! */ // Bitshift pads into integer int padMask = 1 << LayerMask.NameToLayer("SpeedPad") | 1 << LayerMask.NameToLayer("WeaponPad"); // Raycast down if (Physics.Raycast(transform.position, -transform.up, out centreHit, rideHeight + 2, padMask)) { // If the ship hits a speed pad then apply the appropiate force if (centreHit.collider.gameObject.layer == LayerMask.NameToLayer("SpeedPad")) { // Get the pad's forward direction speedPadDirection = centreHit.collider.gameObject.transform.right * GlobalSettings.speedPadAmount; // Set the ships boost timer shipBoostTimer = GlobalSettings.speedPadTime; // Set boosting to true bShipIsBoosting = true; // If we havn't hit this pad already, play the boost sound if (!bShipHitPad) { bShipHitPad = true; // Get sound to play AudioClip boostSFX = Resources.Load("Audio/Ships/BoostSpeedPad") as AudioClip; // Play the sound PlayOneShot.PlayShot("BoostSFX", 1.0f, 1.0f, 50.0f, 500.0f, transform, transform.position, boostSFX); } } } else { // We are not hitting a pad, set the hitting pad boolean to false bShipHitPad = false; } // If the boost timer is over zero then we want to decrease it and apply any boost the ship has if (shipBoostTimer > 0) { // Decrease timer shipBoostTimer -= Time.deltaTime; // Apply pad boost shipBody.AddForce(speedPadDirection, ForceMode.Acceleration); } else { // Make sure that the pad hit boolean is no longer true bShipHitPad = false; // Override boost if the ship has boost power from a barrel rol if (shipBRBoostTimer > 0) { bShipIsBoosting = true; // Apply the barrel roll boost shipBody.AddForce(transform.forward * settings.engineTurbo, ForceMode.Acceleration); } else { // Otherwise the boosting is set to false bShipIsBoosting = false; } } // Allow the turbo pickup to override the boost if (bShipBoostingOverride) { bShipIsBoosting = true; } // Boosting Force Feedback if (bShipIsBoosting) { vibrationManager.timerMotor = 1.1f; vibrationManager.vibLeftMotor = 0.4f; vibrationManager.vibRightMotor = 0.4f; } /* And finally we want to apply gravity, we want to swap out the gravity between two different variables * which allows the ship to feel much lighter on the track, this also makes the hovering feel much better too */ // Check to see if the ship is grounded if (bShipIsGrounded) { // If the ship is on a magstrip then the gravity wants to be heavier if (bShipIsOnMagStrip) { // Set gravity shipGravityForce = -transform.up * (trackGrav * 5); } else { // Set gravity shipGravityForce = -transform.up * trackGrav; } // Set the rebound jump time so the stick force is always maxed when the ship enters flight shipReboundJump = settings.agReboundJumpTime; // Decrease the rebound land shipReboundLand -= Time.deltaTime; } else { // Set the gravity shipGravityForce = Vector3.down * (flightGrav * gravityMul); // Decrease the jump shipReboundJump -= Time.deltaTime; // Apply the stick force if (shipReboundJump > 0) { // Apply the force to keep the ship grounded shipBody.AddForce(Vector3.down * ((10 * GlobalSettings.shipNormalGravity) * settings.agRebound), ForceMode.Acceleration); } // Set rebound to zero if it has gone under zero if (shipReboundLand < 0) { shipReboundLand = 0; } // Increase the rebound land shipReboundLand += Time.deltaTime; // Clamp the rebound land if (shipReboundLand > settings.agReboundLanding) { shipReboundLand = settings.agReboundLanding; } // Slowly rotate the ship forward transform.Rotate(Vector3.right * 0.05f); } // And finally, apply the gravity shipBody.AddForce(shipGravityForce, ForceMode.Acceleration); }
public void ThrusterUp() { PlayOneShot.PlayShot("ThrusterRelease", 1.0f, 1.0f, 200, 100, transform, transform.position, GetComponent <ShipSimulator>().settings.audioEngineCooler); }