using UnityEngine; public class ShipControls : MonoBehaviour { public Camera aim; public Timing timing; Rigidbody rigidBody; Vector3 initialPosition; Vector3 initialForce; Quaternion initialAim; Vector3 thrust; Vector3 strafe; float strafeMag; float thrustMag; float stabliseMag; ForceMode forceMode; // Camera Controls float mouseSenseY = 1.0f; float mouseSenseX = 1.0f; float camPitch; float camYaw; void Start() { Cursor.lockState = CursorLockMode.Locked; rigidBody = GetComponent(); // just stop the body from being affected by rotation for now // until the 3p camera is in to explain why rigidBody.freezeRotation = true; initialPosition = rigidBody.transform.position; initialAim = aim.transform.rotation; initialForce = Vector3.forward; thrust = Vector3.zero; strafe = Vector3.zero; thrustMag = 50.0f; strafeMag = 25.0f; stabliseMag = 75.0f; camPitch = initialAim.eulerAngles.x; camYaw = initialAim.eulerAngles.y; forceMode = ForceMode.Acceleration; } void Update() { // update the movement vectors every frame thrust = getThrust(); strafe = getStrafe(); // do everything else input related on every frame too processInput(); } void FixedUpdate() { // when you hit the trigger... // GO // needs to be done here in fixedUpdate because otherwise the input is checked on every frame // so they will have already hit the button before this tick bool shouldStartTimer = !timing.timerEnabled && (thrust != Vector3.zero || strafe != Vector3.zero); if (shouldStartTimer) timing.StartTimer(); // the ship being propelled forward rigidBody.AddForce(thrust, forceMode); // moving side to side rigidBody.AddRelativeForce(strafe, forceMode); // rotating towards the camera's orientation // not being done by a force because of strange behaviour // needs investigation float step = stabliseMag * Time.fixedDeltaTime; rigidBody.rotation = Quaternion.RotateTowards(transform.rotation, aim.transform.rotation, step); } Vector3 getThrust() { // thrust in the direction of the camera if (Input.GetMouseButton(0)) // transform from the camera's forward vector into world space return aim.transform.TransformDirection(Vector3.forward) * thrustMag; // brake just decelerates the ship against the direction it is moving if (Input.GetMouseButton(1)) { // the velocity is already in world space so we just invert it return rigidBody.velocity.normalized * -1f * thrustMag; } return Vector3.zero; } // 2D strafing // we combine all the vectors so you can move in 2 dimensions at once // thrust is added as a relative force so we don't need to convert to worldspace Vector3 getStrafe() { Vector3 strafe = new Vector3(0.0f, 0.0f, 0.0f); if (Input.GetKey(KeyCode.W)) strafe += strafeMag * Vector3.up; if (Input.GetKey(KeyCode.S)) strafe += strafeMag * Vector3.down; if (Input.GetKey(KeyCode.A)) strafe += strafeMag * Vector3.left; if (Input.GetKey(KeyCode.D)) strafe += strafeMag * Vector3.right; return strafe; } void processInput() { updateCamera(); // don't just spam respawn if (Input.GetKeyDown(KeyCode.Space)) Respawn(); if (Input.GetKey(KeyCode.F10)) Application.Quit(); } public void Respawn() { // IMPORTANT // stop the timer before we move the ship or anything // otherwise it might generate a checkpoint time // for the final sector timing.StopTimer(); thrust = new Vector3(0.0f, 0.0f, 0.0f); transform.position = initialPosition; rigidBody.transform.forward = initialForce; rigidBody.velocity = new Vector3(0f, 0f, 0f); rigidBody.angularVelocity = new Vector3(0f, 0f, 0f); aim.transform.rotation = initialAim; camPitch = initialAim.eulerAngles.x; camYaw = initialAim.eulerAngles.y; } void updateCamera() { camPitch -= mouseSenseY * Input.GetAxis("Mouse Y"); camYaw += mouseSenseX * Input.GetAxis("Mouse X"); aim.transform.eulerAngles = new Vector3(camPitch, camYaw, 0.0f); } void OnDrawGizmosSelected() { if (Application.isPlaying == false) return; Gizmos.color = Color.red; Vector3 right = aim.transform.TransformDirection(Vector3.right) * 10; Gizmos.DrawRay(transform.position, right); Gizmos.color = Color.green; Vector3 direction = aim.transform.TransformDirection(Vector3.up) * 10; Gizmos.DrawRay(transform.position, direction); Gizmos.color = Color.blue; Vector3 forward = aim.transform.TransformDirection(Vector3.forward) * 10; Gizmos.DrawRay(transform.position, forward); Gizmos.color = Color.yellow; Vector3 velocity = rigidBody.velocity; Gizmos.DrawRay(transform.position, velocity); Gizmos.color = Color.cyan; Gizmos.DrawRay(transform.position, thrust); } public float Speed() { return rigidBody.velocity.magnitude; } }