Unity:ログの出力(GUI編)

最終更新日

はじめに

前回は、Debug.Logを使ってログ出力ができる事を確認しました。今回はより実践的に、画面上にログを出して実行時にも確認できるログ出力を実装します。

Unityを知らない方は、ぜひ こちらの記事 をご参照ください。

ログ出力の関連記事

ソースコード

さっそくですが、ソースコードの全文を示したいと思います。

次以降で使い方がありますのでここはコピペで使ってください。

using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

public class DebugGui : MonoBehaviour
{
    public FpsCounter fpsCounter;

    public LogStorage logStorage;

    public DebugGuiStyle style;

    private GUIStyle textStyle;

    void Awake()
    {
        textStyle = GUIStyle.none;
        textStyle.wordWrap = false;
        textStyle.normal.textColor = Color.white;
        textStyle.margin = new RectOffset();
        textStyle.padding = new RectOffset();
    }

    void OnGUI()
    {
        int areaCount = 0;

        if (fpsCounter.enabled)
        {
            fpsCounter.Update();
            areaCount += 1;
        }
        if (logStorage.enabled)
        {
            logStorage.Update();
            areaCount += logStorage.list.Count;
        }

        if (0 < areaCount)
        {
            float margin = style.margin;
            float padding = style.padding;
            int fontSize = style.fontSize;

            // box area
            float width = Screen.width - (margin * 2);
            float height = (areaCount * Mathf.Ceil(fontSize * 1.1f)) + (padding * 2);
            Rect boxArea = new Rect(Screen.width - width - margin, Screen.height - height - margin, width, height);
            GUI.Box(boxArea, "");

            // draw area
            Rect drawArea = new Rect(boxArea.x + padding, boxArea.y + padding, boxArea.width - padding * 2, boxArea.height - padding * 2);

            GUILayout.BeginArea(drawArea);
            {
                textStyle.fontSize = fontSize;

                if (fpsCounter.enabled)
                    GUILayout.Label("FPS:" + fpsCounter.fps.ToString("0.0"), textStyle);

                if (logStorage.enabled)
                    foreach (string str in logStorage.list)
                        GUILayout.Label(str, textStyle);
            }
            GUILayout.EndArea();
        }
    }

    public void Log(string text)
    {
        if (logStorage.enabled == false) return;

        logStorage.Add("I", text);
    }

    public void Log(string format, params object[] paramList)
    {
        if (logStorage.enabled == false) return;

        logStorage.Add("I", format, paramList);
    }

    public void LogError(string text)
    {
        if (logStorage.enabled == false) return;

        logStorage.Add("E", text);
    }

    public void LogError(string format, params object[] paramList)
    {
        if (logStorage.enabled == false) return;

        logStorage.Add("E", format, paramList);
    }

    public void LogWarning(string text)
    {
        if (logStorage.enabled == false) return;

        logStorage.Add("W", text);
    }

    public void LogWarning(string format, params object[] paramList)
    {
        if (logStorage.enabled == false) return;

        logStorage.Add("W", format, paramList);
    }

    #region Inner Class

    [Serializable]
    public class DebugGuiStyle
    {
        public float margin = 10;
        public float padding = 4;
        public int fontSize = 13;
    }

    [Serializable]
    public class FpsCounter
    {
        public bool enabled = true;
        public float interval = 3.0f;

        internal float fps = 0.0f;

        private int frameCount = 0;
        private float prevTime = 0.0f;

        public void Update()
        {
            ++frameCount;
            float time = Time.realtimeSinceStartup - prevTime;

            if (interval <= time)
            {
                fps = frameCount / time;
                frameCount = 0;
                prevTime = Time.realtimeSinceStartup;
            }
        }
    }

    [Serializable]
    public class LogStorage
    {
        public bool enabled = true;
        public int max = 5;
        public int lengthLimit = 150;
        public bool alsoUnityLog = true;

        internal List<string> list = new List<string>();

        public void Update()
        {
            if (max < list.Count)
                list.RemoveRange(0, list.Count - max);
        }

        public void Add(string level, string text)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
            sb.Append(" [");
            sb.Append(level);
            sb.Append("] ");
            sb.Append(text.Substring(0, Math.Min(lengthLimit, text.Length)));

            string output = sb.ToString();
            list.Add(output);

            if (alsoUnityLog)
            {
                if (level == "I") Debug.Log(output);
                if (level == "W") Debug.LogWarning(output);
                if (level == "E") Debug.LogError(output);
            }
        }

        public void Add(string level, string format, params object[] paramList)
        {
            string text = string.Format(format, paramList);
            Add(level, text);
        }
    }

    #endregion
}

使い方

以下に使い方を示します。

オブジェクトの準備

適当なオブジェクト(DebugGui)を作成して、そのオブジェクトに DebugGui.cs のスクリプトをアタッチしてください。パラメータの説明などはこれ以降に説明します。

ソースコード

本スクリプトにログを出力する方法になります。

  • Start() で DebugGui のインスタンスを探します。
  • debugGui.Log / LogWarning / LogError などを使って画面にログを出力します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DebugGuiTest : MonoBehaviour
{
    DebugGui debugGui;

    void Start()
    {
        debugGui = FindObjectOfType<DebugGui>();
    }

    void Update()
    {
        debugGui.Log("Info");
        debugGui.LogWarning("Warning");
        debugGui.LogError("Error");
    }
}

実行結果

以上のように簡単に使えましたね、このスクリプトでは FPS表示/ログ出力/Unityログへも出力が行えます、どうですか意外と高性能ですよね。

パラメータ説明

FPSの表示

以下の部分の表示です。

それぞれのパラメータの意味です。

  • Enabled : 有効/無効
  • Interval : FPSの更新タイミング(秒)

Logの出力

以下の部分の表示になります。

それぞれのパラメータの意味です。

  • Enabled : 有効/無効
  • Max : 表示の最大行数
  • Length Limit : 1行の最大文字数(日時、レベル以外の本文の長さ)
  • Also Unity Log : Unityのコンソールにも出力する

スタイル

以下のログウィンドウのスタイルを定義します。

それぞれのパラメータの意味です。

  • Margin : ログウィンドウの外側の余白
  • Padding : ログウィンドウの内側の余白
  • Font Size : 文字のサイズ

関連リンク

シェアする

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

コメントする