Homebound / Scripts / Movement.cs
Movement.cs
Raw
using UnityEngine;
using System;

/// <summary>
/// Controls the movement of the player along with the movement particle and sound effects
/// </summary>
public class Movement : MonoBehaviour
{
    [Header("Player Values")]
    [SerializeField][Tooltip("The higher the value, the faster or more powerful the thrust will be for the player movement")] 
    float thrustPower = 5f;                                         // Thrust speed of the player when moving forward/up
    [SerializeField][Tooltip("The higher the value, the faster the turning will be in either direction")] 
    float rotationSpeed = 3f;                                       // Rotation speed for the player when pressing the side keys

    [Header("Particle Systems")]
    [SerializeField] ParticleSystem thrusterParticleSystem;         // Reference for the particle system when the player presses W, Up Arrow, or Space
    [SerializeField] ParticleSystem leftThrusterParticleSystem;     // Reference for the particle system when the player presses the D or Right Arrow Key
    [SerializeField] ParticleSystem rightThrusterParticleSystem;    // Reference for the particle system when the player presses the A or Left Arrow Key

    [Header("Thruster AudioSources")]
    [SerializeField] AudioSource leftThrusterAudioSource;           // Reference for the audio source on the left side
    [SerializeField] AudioSource rightThrusterAudioSource;          // Reference for the audio source on the right side

    // Components
    Rigidbody myRigidbody;                                          // Reference to the rigidbody attached the player game object
    AudioSource audioSource;                                        // Reference to the audiosource attached to the player game object

    void Start()
    {
        myRigidbody = GetComponent<Rigidbody>(); 
        audioSource = GetComponent<AudioSource>(); 
    }

    void Update()
    {
        Thrust();   // Thrust Check
        Rotation(); // Rotation Check
    }

    /// <summary>
    /// Processes the thrust for the player based on if the player presses any of the three keys given, otherwise 
    /// the sound and particle effects will cease
    /// </summary>
    void Thrust()
    {
        // If player presses W, the Up Arrow, or Space then they will accelerate forwards in the direction they are pointing
        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.Space))
        {
            PlayThrustSound();      // Plays thruster sounds attached to the audio source
            StartThrusterEffects(); // Plays the thruster effects in thrusterParticleSystem

            // The game object is then pushed upwards based on the launchSpeed set in the serialized field, time, and the base vector of Vector3.up
            myRigidbody.AddRelativeForce(thrustPower * Time.deltaTime * Vector3.up); 
        }
        else
        {
            StopThrustSound();      // Stops all thruster sounds
            StopThrusterEffects();  // Stops all of the thruster effects
        }
    }

    /// <summary>
    /// Loops the sound attached to the audio source when the player is pressing the thrust key
    /// </summary>
    void PlayThrustSound()
    {
        if (!audioSource.isPlaying) audioSource.Play();
    }

    /// <summary>
    /// Starts the thrusters particle system attached to the player prefab
    /// </summary>
    void StartThrusterEffects()
    {
        if (!thrusterParticleSystem.isPlaying) thrusterParticleSystem.Play();
    }

    /// <summary>
    /// Stops the thrusting sound when the player is no longer pressing the thrust key
    /// </summary>
    void StopThrustSound() => audioSource.Stop();

    /// <summary>
    /// Stops the thruster particle system attached to the player prefab
    /// </summary>
    void StopThrusterEffects() => thrusterParticleSystem.Stop();

    /// <summary>
    /// The player game object will rotate based on the key pressed from the list given, then particles and sounds will play from the source
    /// opposite of the key pressed to give the illusion of force being applied
    /// </summary>
    void Rotation()
    {
        // If the user preses A or Left Arrow then the player will rotate in the left direction (i.e. right thruster activates)
        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
        {
            RotationDirection(Vector3.forward);     // Inputs +1

            // Proceed with activating the right particle effects
            ProcessParticlesAndSound(Vector3.forward);
        }
        // If the user preses D or Right Arrow then the player will rotate in the right direction (i.e. left thruster activates)
        else if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
        {
            RotationDirection(Vector3.back);        // Inputs -1

            // Proceed with activating the left paricle effects
            ProcessParticlesAndSound(Vector3.back);
        }
        else
            StopSideThrusterParticlesAndSounds(); // Stops all sounds and particle systems if none of the rotation buttons are pressed
    }

    /// <summary>
    /// Direction of rotation is processed based on which key direction is pressed.
    /// </summary>
    /// <param name="direction">Should either be Vector3.back or Vector3.forward, other parameters may cause strange behaviour</param>    
    void RotationDirection(Vector3 direction)
    {
        myRigidbody.freezeRotation = true;  // Freezes rotation for manual rotation
        transform.Rotate(rotationSpeed * Time.deltaTime * direction);
        myRigidbody.freezeRotation = false; // Unfreezes rotation for physics system to take back control
    }

    /// <summary>
    /// Method processes the direction passed through the parameter for either the left or right thruster particle system and audio system to play
    /// </summary>
    /// <param name="direction">Should be Vector3.forward or Vector3.back, other values will throw exception</param>
    /// <exception cref="ArgumentException">Direction is an unexpected value that is not Vector3.forward or Vector3.back</exception>
    void ProcessParticlesAndSound(Vector3 direction)
    {
        if (direction == Vector3.forward)       // Plays the right sound effects and particle systems
        {
            RightThrusterPlaySound();
            RightThrusterPlayParticles();
        }
        else if (direction == Vector3.back)     // Plays the left sound effects and particles systems
        {
            LeftThrusterPlaySound();
            LeftThrusterPlayParticles();
        }
        else
            throw new ArgumentException("Direction must be Vector3.forward or Vector3.back, current Direction ---> " + direction.ToString());
    }

    /// <summary>
    /// Plays right thruster audio source
    /// </summary>
    void RightThrusterPlaySound()
    {
        if (!rightThrusterAudioSource.isPlaying) rightThrusterAudioSource.Play();
    }
    /// <summary>
    /// Plays left thruster audio source
    /// </summary>
    void LeftThrusterPlaySound()
    {
        if (!leftThrusterAudioSource.isPlaying) leftThrusterAudioSource.Play();
    }
    /// <summary>
    /// Plays right thruster particles
    /// </summary>
    void RightThrusterPlayParticles()
    {
        if (!rightThrusterParticleSystem.isPlaying) rightThrusterParticleSystem.Play();
    }
    /// <summary>
    /// Plays left thruster particles
    /// </summary>
    void LeftThrusterPlayParticles()
    {
        if (!leftThrusterParticleSystem.isPlaying) leftThrusterParticleSystem.Play();
    }
    /// <summary>
    /// Stops the audio sources and particle systems on both thrusters if neither are being activated
    /// </summary>
    void StopSideThrusterParticlesAndSounds()
    {
        // Stop audio sources
        StopLeftThrusterAudioSource();
        StopRightThrusterAudioSource();

        // Stop particle systems
        StopLeftThrusterParticleSystem();
        StopRightThrusterParticleSystem();
    }
    /// <summary>
    /// Stops all particles and sound effects on the movement basis on the player's game object
    /// </summary>
    public void StopAllParticlesAndSounds()
    {
        // Stops main thruster sources
        StopThrusterEffects();
        StopThrustSound();

        // Stops the side thruster sources
        StopSideThrusterParticlesAndSounds();
    }
    /// <summary>
    /// Stops left thruster audio
    /// </summary>
    void StopLeftThrusterAudioSource() => leftThrusterAudioSource.Stop();
    /// <summary>
    /// Stops right thruster audio
    /// </summary>
    void StopRightThrusterAudioSource() => rightThrusterAudioSource.Stop();
    /// <summary>
    /// Stops left thruster particles
    /// </summary>
    void StopLeftThrusterParticleSystem() => leftThrusterParticleSystem.Stop();
    /// <summary>
    /// Stops right thruster particles
    /// </summary>
    void StopRightThrusterParticleSystem() => rightThrusterParticleSystem.Stop();
}