TapTapTap!!!(30)~背景とボタンの見た目を変更する~ では Unity の Asset Store 背景及びボタンをダウンロードして「TapTapTap!!!」に反映した。その後、実機で内部テストを行ったところ時間が経過してもライフが回復しない不具合を発見した。設定を確認しても問題は無いように見えるので今回は、ログ出力クラスを作成し原因の調査を行う。
クラスとは簡単に説明すると1個のスクリプトファイルのことである。細かく説明するともっと複雑なのだが今回はわかりやすさを重視してこのような説明としている。
1.出力するデータを考える
ログ出力クラスを作るにあたってまずはじめに考えなければならないことは、どのようなデータをログとして出力したいのかということだろう。さしあたって考えられるのは以下の通り。
- 時刻
- クラス
- 関数名
- 関数の実行開始
- 関数の実行完了
- 更新データ
この当りが無難なところであろう。また、ログレベルというのも設定しておいたほうが良い。ログレベルというのは、どこの情報までログを出力するかということである。例えば、 Unity の クラス内で Update() というものがあるが、これを毎回出力していてはとてつもない情報量となってしまい重要な情報を見逃す可能性がある。そこで今回は以下のログレベルでログを出力していく。
- Error:アプリが強制終了するほどの異常
- Worning:アプリが強制終了することはない異常
- Info:関数の開始/終了やユーザーの操作など
- Debug:開発中に確認したい内容
- Trace:ループ内の局所的に確認したい内容
このような分類で分けて考えていく。
2.出力するフォーマットを考える
ログ出力をするデータについては決まったが、一律の形式で見えたほうがわかりやすくて良いと思われる。出力する順序が異なると 5W1H がわからなくなってしまう。そこで、今回は以下のようにフォーマットを整えていきたいと思う。
[ログレベル] 時間 : クラス名 :: 関数名 - 情報
3.出力するクラスを作成する
ログ出力クラスは [Project] > [Script] で右クリックを行い、[Create] > [C# Script] から作成する。この当りはいつもどおりなので省略する。スクリプトの内容としては以下の通り。古典的な手法を用いているので、誰か良い方法があれば教えてほしいくらいだ。
MyLogger スクリプトの内容
[cce_csharp]using System; using UnityEngine; public class MyLogger : MonoBehaviour { /// <summary> /// エラーログレベル /// </summary> private static byte ERROR = 0; /// <summary> /// 警告ログレベル /// </summary> private static byte WORNING = 1; /// <summary> /// 情報ログレベル /// </summary> private static byte INFO = 2; /// <summary> /// デバッグログレベル /// </summary> private static byte DEBUG = 3; /// <summary> /// トレースログレベル /// </summary> private static byte TRACE = 4; /// <summary> /// ログレベル配列 /// </summary> private static string[] LEVEL = new string[] { "Error", "Worning", "Info", "Debug", "Trace" }; /// <summary> /// 出力するログレベル /// </summary> [SerializeField] private byte LOG_LEVEL = INFO; /// <summary> /// 開始ログ /// </summary> /// <param name="className">クラス名</param> /// <param name="methodName">関数名</param> public void StartLog(string className, string methodName) { if (LOG_LEVEL < INFO) { return; } Log(LEVEL[INFO], className, methodName, "Start"); } /// <summary> /// 終了ログ /// </summary> /// <param name="className">クラス名</param> /// <param name="methodName">関数名</param> public void EndLog(string className, string methodName) { if (LOG_LEVEL < INFO) { return; } Log(LEVEL[INFO], className, methodName, "End"); } /// <summary> /// エラーログ /// </summary> /// <param name="className">クラス名</param> /// <param name="methodName">関数名</param> /// <param name="msg">メッセージ</param> public void ErrorLog(string className, string methodName, string msg) { if (LOG_LEVEL < ERROR) { return; } Log(LEVEL[ERROR], className, methodName, msg); } /// <summary> /// 警告ログ /// </summary> /// <param name="className">クラス名</param> /// <param name="methodName">関数名</param> /// <param name="msg">メッセージ</param> public void WorningLog(string className, string methodName, string msg) { if (LOG_LEVEL < WORNING) { return; } Log(LEVEL[WORNING], className, methodName, msg); } /// <summary> /// 情報ログ /// </summary> /// <param name="className">クラス名</param> /// <param name="methodName">関数名</param> /// <param name="msg">メッセージ</param> public void InfoLog(string className, string methodName, string msg) { if (LOG_LEVEL < INFO) { return; } Log(LEVEL[INFO], className, methodName, msg); } /// <summary> /// デバッグログ /// </summary> /// <param name="className">クラス名</param> /// <param name="methodName">関数名</param> /// <param name="msg">メッセージ</param> public void DebugLog(string className, string methodName, string msg) { if (LOG_LEVEL < DEBUG) { return; } Log(LEVEL[DEBUG], className, methodName, msg); } /// <summary> /// トレースログ /// </summary> /// <param name="className">クラス名</param> /// <param name="methodName">関数名</param> /// <param name="msg">メッセージ</param> public void TraceLog(string className, string methodName, string msg) { if (LOG_LEVEL < TRACE) { return; } Log(LEVEL[TRACE], className, methodName, msg); } /// <summary> /// ログ出力 /// </summary> /// <param name="level">ログレベル</param> /// <param name="className">クラス名</param> /// <param name="methodName">関数名</param> /// <param name="msg">メッセージ</param> private void Log(string level, string className, string methodName, string msg) { Debug.Log("[" + level + "]" + DateTime.Now + " : " + className + "::" + methodName + " - " + msg); } }[/cce_csharp]
これを各処理の中に組み込んでいく。はじめからやっていれば苦労しなかったのだが・・・。今回の反省を生かして次のものを作っていく。