【Unity】端末でも確認出来るAssertウインドウ
Unity 標準で使えるDebug.Assertは論理エラーを弾くのにとても便利なものです。
【Unity】Assertを活用してデバッグ効率を上げよう | KAZUPON研究室
以前こちらでお話しましたが、僕がプロジェクトでAssert を仕込む時は少し拡張したものを使っています。
目次
ソースコード
using UnityEngine;
using UnityEngine.Events;
namespace mira
{
class AssertWindow : MonoBehaviour
{
public enum MenuEvent
{
Continue,
ReStart,
Report,
}
[System.Serializable]
public class OnPressMenu : UnityEvent<MenuEvent> { }
/// <summary>
/// UI Event
/// </summary>
[SerializeField]
private OnPressMenu m_OnPressMenu = new OnPressMenu();
public OnPressMenu onPressMenu
{
get { return m_OnPressMenu; }
}
private string m_message = string.Empty;
private Vector2 scrollPosition = Vector2.zero;
private void Init(string _message)
{
m_message = _message;
}
private void OnContinue()
{
onPressMenu.Invoke(MenuEvent.Continue);
GameObject.Destroy(this.gameObject);
}
private void OnRestart()
{
onPressMenu.Invoke(MenuEvent.ReStart);
}
private void OnReport()
{
onPressMenu.Invoke(MenuEvent.Report);
}
public static AssertWindow Create( string _message )
{
var prefab = new GameObject("AssertWindow", typeof(AssertWindow));
var instance = Instantiate(prefab);
AssertWindow component = instance.GetComponent<AssertWindow>();
component.Init(_message);
return component;
}
private void OnGUI ()
{
float scale = (Screen.width > Screen.height) ? Screen.width / 720f : Screen.height / 720f;
GUIUtility.ScaleAroundPivot(new Vector2(scale, scale), Vector2.zero);
var centeredStyle = new GUIStyle(GUI.skin.label);
centeredStyle.alignment = TextAnchor.UpperCenter;
GUILayout.BeginArea(new Rect(0, 0, Screen.width / scale, Screen.height / scale));
GUILayout.BeginVertical (GUI.skin.box);
{
GUILayout.Label ("Assert");
GUILayout.BeginHorizontal (GUI.skin.box);
{
if( GUILayout.Button("Continue") )
{
OnContinue();
}
if( GUILayout.Button("Restart") )
{
OnRestart();
}
if( GUILayout.Button("report") )
{
OnReport();
}
}
GUILayout.EndHorizontal ();
scrollPosition = GUILayout.BeginScrollView (scrollPosition);
GUILayout.Label ( $"{m_message}" );
GUILayout.EndScrollView ();
}
GUILayout.EndVertical ();
GUILayout.EndArea();
GUI.matrix = Matrix4x4.identity;
}
}
}
using UnityEngine;
using UnityEngine.Events;
using System.Diagnostics;
namespace mira
{
/// <summary>
/// 例外検知機能。
/// </summary>
public static class Assert
{
static AssertWindow s_assertWindow_ = null;
[Conditional("UNITY_EDITOR"), Conditional("DEVELOPMENT_BUILD")]
public static void Check(object obj, string _message)
{
Check(obj != null, _message);
}
[Conditional("UNITY_EDITOR"), Conditional("DEVELOPMENT_BUILD")]
public static void Check(bool isComparison, string _message)
{
if (!isComparison)
{
UnityEngine.Debug.Assert(isComparison, _message);
}
}
public static void LogMessageCallBack(
string condition,
string stackTrace,
LogType type,
UnityAction _onContinue = null,
UnityAction _onRestart = null,
UnityAction _onReport = null)
{
switch (type)
{
case LogType.Assert:
case LogType.Exception:
if(s_assertWindow_ == null)
{
s_assertWindow_ = AssertWindow.Create(condition + "\n" + stackTrace);
s_assertWindow_.onPressMenu.AddListener((_t)=>
{
switch (_t)
{
case AssertWindow.MenuEvent.Continue:
{
_onContinue.Invoke();
break;
}
case AssertWindow.MenuEvent.ReStart:
{
_onRestart.Invoke();
break;
}
case AssertWindow.MenuEvent.Report:
{
_onReport.Invoke();
break;
}
}
});
}
break;
}
}
}
}
使い方
using UnityEngine;
public class Example : MonoBehaviour
{
void Start()
{
mira.Assert.Check(false, "アサートテスト!!!!!!!");
}
#if DEVELOPMENT_BUILD || UNITY_EDITOR
public static void LogMessageCallBack(
string _condition,
string _stackTrace,
LogType _type)
{
mira.Assert.LogMessageCallBack(
_condition,
_stackTrace,
_type,
_onContinue:()=>
{
// コンティニュー
},
_onRestart: () =>
{
// 再起動
},
_onReport: () =>
{
// エラーレポート送信など
}
);
}
private void OnEnable()
{
Application.logMessageReceived += LogMessageCallBack;
}
private void OnDisable()
{
Application.logMessageReceived -= LogMessageCallBack;
}
#endif
}
結果
通常のAssert ではコンソールウインドウに表示されるだけですが、こちらはゲーム画面に表示されます。こちらですと実機でエラーを確認することが容易なため「実機でエラー発生したけど、発生場所が分からない」の様な面倒な出来事も回避できるためおすすめです。