DebugConsole.cs 4.57 KB
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;

[assembly: System.Reflection.AssemblyVersion("1.0.*")]
public class DebugConsole : MonoBehaviour
{
    // Use this event to reset junk in your game to their initial states.
    public static event System.Action OnReset;
    public static int fps { get; private set; }

    [Header("Spawning")]
    [SerializeField]
    private CanvasGroup _container;
    [SerializeField]
    private KeyCode toggleKey = KeyCode.D;
    [SerializeField]
    private int _tapsToSpawn = 3;
    [SerializeField]
    private float _totalTapTime = 1;
    [Header("Info")]
    [SerializeField]
    private Text _appInfo;
    [SerializeField]
    private Text _fpsCounter;
    [SerializeField]
    private float _fpsUpdateFrequency = 0.5f;
    [SerializeField]
    private Text _debugTextNode;

    private static DebugConsole _inst = null;

    void Awake()
    {
        if (_inst != null)
        {
            Destroy(gameObject);
            return;
        }

        _inst = this;
        DontDestroyOnLoad(this);
    }

    private void Start () 
    {
        if (Application.isMobilePlatform)
            GetComponent<CanvasScaler>().scaleFactor = 3;

	    Application.logMessageReceived += OnLogMessageReceived;
        _debugTextNode.text = "Debug Console Window";
        _debugTextNode.color = Color.cyan;

        Hide();

        string[] appInfo = new string[]
        {
            Application.companyName,
            Application.productName,
			Application.version
        };
        _appInfo.text = string.Format("{0} {1} - v{2}", appInfo);

        StartCoroutine(FPS());
    }

    private IEnumerator FPS()
    {
        while (true)
        {
            int lastFrameCount = Time.frameCount;
            float lastTime = Time.realtimeSinceStartup;
            yield return new WaitForSeconds(_fpsUpdateFrequency);
            float timeSpan = Time.realtimeSinceStartup - lastTime;
            int frameCount = Time.frameCount - lastFrameCount;
            
            fps = Mathf.RoundToInt(frameCount / timeSpan);
            _fpsCounter.text = fps.ToString() + " fps";
        }
    }

    private List<Text> _logItems = new List<Text>();
    private const int _maxLogItems = 50;

    private void OnLogMessageReceived(string condition, string stackTrace, LogType type)
    {
        Text newText = Instantiate(_debugTextNode) as Text;
        newText.transform.SetParent(_debugTextNode.transform.parent);
        newText.transform.localScale = _debugTextNode.transform.localScale;
        newText.text = string.Format("{0}\n{1}", condition, stackTrace);

        switch (type)
        {
            case LogType.Log:
                newText.color = Color.white;
                break;
            case LogType.Warning:
                newText.color = Color.yellow;
                break;
            case LogType.Exception:
                newText.color = Color.red;
                break;
            case LogType.Error:
                newText.color = Color.red;
                break;
        }

        _logItems.Add(newText);

        if (_logItems.Count > _maxLogItems)
        {
            Destroy(_logItems[0].gameObject);
            _logItems.RemoveAt(0);
        }
    }

    public void DebugTap()
    {
        if (_container.gameObject.activeSelf)
            Hide();
        else
            _tapCount++;
    }

    private int _tapCount;
    private float _currentTapTime;

    private void Update()
    {
        if (Input.GetKeyDown(toggleKey))
            Toggle();

        if (_tapCount == 0) return;

        _currentTapTime += Time.deltaTime;

        if (_currentTapTime >= _totalTapTime)
        {
            _currentTapTime = 0;
            _tapCount = 0;
        }
        else if (_tapCount >= _tapsToSpawn)
        {
            _tapCount = 0;
            _currentTapTime = 0;
            Toggle();
        }
    }

    public void Toggle()
    {
        if (_container.gameObject.activeSelf)
            Hide();
        else
            Show();
    }

    public void Hide()
    {
        _container.gameObject.SetActive(false);
        _container.interactable = false;
        _container.blocksRaycasts = false;
    }

    public void Show()
    {
        _container.gameObject.SetActive(true);
        _container.interactable = true;
        _container.blocksRaycasts = true;
    }

    public void ResetApp()
    {
        if (OnReset != null) OnReset();

        UnityEngine.SceneManagement.SceneManager.LoadScene(0);
    }

    private void OnDestroy()
    {
        Application.logMessageReceived -= OnLogMessageReceived;
    }
}