Unity: Скрипт GameController.cs для обучающего проекта Space Shooter tutorial

Страница обучающего курса: Space Shooter tutorial
Курс написан для Unity 4.x, поэтому для Unity 5.x пришлось переписывать почти все скрипты. Кое-что я добавил свое (например поддержку игрового контроллера и «режим бога», чтобы легче было отлаживать). Режим отладки включается только чекбоксом из Unity Editor, при этом в консоль выводятся данные через Debug.Log. Помимо этого в игре реализована Пауза. Отдельное замечу, что все исправленные скрипты работают с расширенной версией урока, поэтому скорее всего не подойдут для первых уроков, где еще нет некоторых элементов типа вражеских кораблей, подвижного фона и т.п.

Скрипт GameController.cs:

// <Start> + <Fire1> - God Mode
// <Start> + <Select> - Restart level

using UnityEngine;
using System.Collections;
using System;
using UnityEngine.SceneManagement;

public class GameController : MonoBehaviour
{
    public bool godMode;
    public bool debugMode;

    public GameObject[] hazards;
    public Vector3 spawnValues;
    public int hazardCount;
    public float spawnWait;
    public float startWait;
    public float waveWait;
    
    public GUIText scoreText;
    public GUIText restartText;
    public GUIText gameOverText;
    
    private bool gameOver;
    private int score;

    private bool isSelectAvailable;
    private bool isStartAvailable;

    private bool paused;

    private float timer;
    private float delta;


    bool IsButtonAvailable(string btnName)
    {
        try
        {
            Input.GetButton(btnName);
            return true;
        }
        catch (ArgumentException)
        {
            return false;
        }
    }

    void Restart()
    {
        if (debugMode)
        {
            Debug.Log("User request for Restart.");
        }


        paused = false;
        timer = 1f;
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);

    }

    void GamePause()
    {
        paused = !paused;
        if (paused && timer <= 0f)
        {
            Time.timeScale = 0;
        }
        else
        {
            Time.timeScale = 1;
        }

        if (debugMode)
        {
            Debug.Log("Paused is " + paused);
        }
    }


    void Start ()
    {
        
        // Проверяем, инициализирована ли кнопка 'Select', если нет, то она проверятся не будет. Если бы такой проверки не было, и не было бы такой кнопки, то в дебаг-лог сыпалось бы куча ошибок!
        isSelectAvailable = IsButtonAvailable("Select");
        isStartAvailable = IsButtonAvailable("Start");
        if (debugMode)
        {
            Debug.Log("Select=" + isSelectAvailable + "\n\rStart=" + isStartAvailable);
        }

        paused = false;
        gameOver = false;
        if (godMode)
        {
            restartText.text = "God Mode is ON";
        }
        else
        {
            restartText.text = "";
        }
        gameOverText.text = "";
        score = 0;
        timer = 1f; // Примерно на 1 секунду будет игнорироваться Пауза, это сделано, чтобы случайно не включилась пауза при перезапуске
        delta = 0.02f;

        UpdateScore ();
        StartCoroutine (SpawnWaves ());
    }
    
    void Update ()
    {
        if (timer > 0f)
        {
            timer -= delta;
        }

        //Test for Joypad keys
        if (debugMode)
        {
            for (int i = 0; i < 20; i++)
            {
                if (Input.GetKeyDown("joystick button " + i))
                {
                    Debug.Log("Button " + i + " was pressed!");
                }
            }
        }

        if (Input.GetKeyDown(KeyCode.R))
        {
            Restart();
        }
        // GetButtonDown отображает состояние кнопки только на первый фрейм, на втором фрейме она уже будет показывать FALSE, 
        // поэтому если нужно отслеживать нажатие и удержание кнопки, нужно использовать функцию GetButton!
        if (isSelectAvailable && Input.GetButton("Select") && isStartAvailable && Input.GetButton("Start")) 
        {
            Restart();
        }

        if (isStartAvailable && Input.GetButtonDown("Start") || Input.GetKeyDown(KeyCode.P))
        {
            Debug.Log("Pause: Button Start pressed");
            GamePause();
        }


        if (isStartAvailable && Input.GetButton("Start") && Input.GetButton("Fire1"))
        {
            if (gameOver)
            {
                return;
            }

            godMode = !godMode;
            if (godMode)
            {
                restartText.text = "God Mode is ON";
            }
            else
            {
                restartText.text = "";
            }


            if (debugMode)
            {
                Debug.Log("GodMode is " + godMode);
            }
        }

    }

    IEnumerator SpawnWaves ()
    {
        yield return new WaitForSeconds (startWait);
        while (true)
        {
            for (int i = 0; i < hazardCount; i++)
            {
                GameObject hazard = hazards [UnityEngine.Random.Range (0, hazards.Length)];
                Vector3 spawnPosition = new Vector3 (UnityEngine.Random.Range (-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
                Quaternion spawnRotation = Quaternion.identity;
                Instantiate (hazard, spawnPosition, spawnRotation);
                yield return new WaitForSeconds (spawnWait);
            }
            yield return new WaitForSeconds (waveWait);
            
            if (gameOver)
            {
                restartText.text = "Press 'R' for Restart";
                break;
            }
        }
    }
    
    public void AddScore (int newScoreValue)
    {
        score += newScoreValue;
        UpdateScore ();
    }
    
    void UpdateScore ()
    {
        scoreText.text = "Score: " + score;
    }
    
    public void GameOver ()
    {
        gameOverText.text = "Game Over!";
        gameOver = true;
    }
}