diff --git a/nekoyume/Assets/Editor/UberLogger.meta b/nekoyume/Assets/Editor/UberLogger.meta
new file mode 100644
index 00000000000..3d1578f128a
--- /dev/null
+++ b/nekoyume/Assets/Editor/UberLogger.meta
@@ -0,0 +1,6 @@
+fileFormatVersion: 2
+guid: 924e28e7ff79f47cfa66acf89387353d
+folderAsset: yes
+DefaultImporter:
+ userData:
+ assetBundleName:
diff --git a/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs b/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs
new file mode 100644
index 00000000000..bd67cb659a2
--- /dev/null
+++ b/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs
@@ -0,0 +1,983 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+using System;
+using UberLogger;
+using System.Text.RegularExpressions;
+
+///
+/// The console logging frontend.
+/// Pulls data from the UberLoggerEditor backend
+///
+
+public class UberLoggerEditorWindow : EditorWindow, UberLoggerEditor.ILoggerWindow
+{
+ [MenuItem("Window/Show Uber Console")]
+ static public void ShowLogWindow()
+ {
+ Init();
+ }
+
+ static public void Init()
+ {
+ var window = ScriptableObject.CreateInstance();
+ window.Show();
+ window.position = new Rect(200,200,400,300);
+ window.CurrentTopPaneHeight = window.position.height/2;
+ }
+
+ public void OnLogChange(LogInfo logInfo)
+ {
+ Dirty = true;
+ // Repaint();
+ }
+
+
+ void OnInspectorUpdate()
+ {
+ // Debug.Log("Update");
+ if(Dirty)
+ {
+ Repaint();
+ }
+ }
+
+ void OnEnable()
+ {
+ // Connect to or create the backend
+ if(!EditorLogger)
+ {
+ EditorLogger = UberLogger.Logger.GetLogger();
+ if(!EditorLogger)
+ {
+ EditorLogger = UberLoggerEditor.Create();
+ }
+ }
+
+ // UberLogger doesn't allow for duplicate loggers, so this is safe
+ // And, due to Unity serialisation stuff, necessary to do to it here.
+ UberLogger.Logger.AddLogger(EditorLogger);
+ EditorLogger.AddWindow(this);
+
+// _OR_NEWER only became available from 5.3
+#if UNITY_5 || UNITY_5_3_OR_NEWER
+ titleContent.text = "Uber Console";
+#else
+ title = "Uber Console";
+
+#endif
+
+ ClearSelectedMessage();
+
+ SmallErrorIcon = EditorGUIUtility.FindTexture( "d_console.erroricon.sml" ) ;
+ SmallWarningIcon = EditorGUIUtility.FindTexture( "d_console.warnicon.sml" ) ;
+ SmallMessageIcon = EditorGUIUtility.FindTexture( "d_console.infoicon.sml" ) ;
+ ErrorIcon = SmallErrorIcon;
+ WarningIcon = SmallWarningIcon;
+ MessageIcon = SmallMessageIcon;
+ Dirty = true;
+ Repaint();
+
+ }
+
+ ///
+ /// Converts the entire message log to a multiline string
+ ///
+ public string ExtractLogListToString()
+ {
+ string result = "";
+ foreach (CountedLog log in RenderLogs)
+ {
+ UberLogger.LogInfo logInfo = log.Log;
+ result += logInfo.GetRelativeTimeStampAsString() + ": " + logInfo.Severity + ": " + logInfo.Message + "\n";
+ }
+ return result;
+ }
+
+ ///
+ /// Converts the currently-displayed stack to a multiline string
+ ///
+ public string ExtractLogDetailsToString()
+ {
+ string result = "";
+ if (RenderLogs.Count > 0 && SelectedRenderLog >= 0)
+ {
+ var countedLog = RenderLogs[SelectedRenderLog];
+ var log = countedLog.Log;
+
+ for (int c1 = 0; c1 < log.Callstack.Count; c1++)
+ {
+ var frame = log.Callstack[c1];
+ var methodName = frame.GetFormattedMethodName();
+ result += methodName + "\n";
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// Handle "Copy" command; copies log & stacktrace contents to clipboard
+ ///
+ public void HandleCopyToClipboard()
+ {
+ const string copyCommandName = "Copy";
+
+ Event e = Event.current;
+ if (e.type == EventType.ValidateCommand && e.commandName == copyCommandName)
+ {
+ // Respond to "Copy" command
+
+ // Confirm that we will consume the command; this will result in the command being re-issued with type == EventType.ExecuteCommand
+ e.Use();
+ }
+ else if (e.type == EventType.ExecuteCommand && e.commandName == copyCommandName)
+ {
+ // Copy current message log and current stack to the clipboard
+
+ // Convert all messages to a single long string
+ // It would be preferable to only copy one of the two, but that requires UberLogger to have focus handling
+ // between the message log and stack views
+ string result = ExtractLogListToString();
+
+ result += "\n";
+
+ // Convert current callstack to a single long string
+ result += ExtractLogDetailsToString();
+
+ GUIUtility.systemCopyBuffer = result;
+ }
+ }
+
+ Vector2 DrawPos;
+ public void OnGUI()
+ {
+ //Set up the basic style, based on the Unity defaults
+ //A bit hacky, but means we don't have to ship an editor guistyle and can fit in to pro and free skins
+ Color defaultLineColor = GUI.backgroundColor;
+ GUIStyle unityLogLineEven = null;
+ GUIStyle unityLogLineOdd = null;
+ GUIStyle unitySmallLogLine = null;
+
+ foreach(var style in GUI.skin.customStyles)
+ {
+ if (style.name=="CN EntryBackEven") unityLogLineEven = style;
+ else if(style.name=="CN EntryBackOdd") unityLogLineOdd = style;
+ else if(style.name=="CN StatusInfo") unitySmallLogLine = style;
+ }
+
+ EntryStyleBackEven = new GUIStyle(unitySmallLogLine);
+
+ EntryStyleBackEven.normal = unityLogLineEven.normal;
+ EntryStyleBackEven.margin = new RectOffset(0,0,0,0);
+ EntryStyleBackEven.border = new RectOffset(0,0,0,0);
+ EntryStyleBackEven.fixedHeight = 0;
+
+ EntryStyleBackOdd = new GUIStyle(EntryStyleBackEven);
+ EntryStyleBackOdd.normal = unityLogLineOdd.normal;
+ // EntryStyleBackOdd = new GUIStyle(unityLogLine);
+
+
+ SizerLineColour = new Color(defaultLineColor.r*0.5f, defaultLineColor.g*0.5f, defaultLineColor.b*0.5f);
+
+ // GUILayout.BeginVertical(GUILayout.Height(topPanelHeaderHeight), GUILayout.MinHeight(topPanelHeaderHeight));
+ ResizeTopPane();
+ DrawPos = Vector2.zero;
+ DrawToolbar();
+ DrawFilter();
+
+ DrawChannels();
+
+ float logPanelHeight = CurrentTopPaneHeight-DrawPos.y;
+
+ if(Dirty)
+ {
+ CurrentLogList = EditorLogger.CopyLogInfo();
+ }
+ DrawLogList(logPanelHeight);
+
+ DrawPos.y += DividerHeight;
+
+ DrawLogDetails();
+
+ HandleCopyToClipboard();
+
+ //If we're dirty, do a repaint
+ Dirty = false;
+ if(MakeDirty)
+ {
+ Dirty = true;
+ MakeDirty = false;
+ Repaint();
+ }
+ }
+
+ //Some helper functions to draw buttons that are only as big as their text
+ bool ButtonClamped(string text, GUIStyle style, out Vector2 size)
+ {
+ var content = new GUIContent(text);
+ size = style.CalcSize(content);
+ var rect = new Rect(DrawPos, size);
+ return GUI.Button(rect, text, style);
+ }
+
+ bool ToggleClamped(bool state, string text, GUIStyle style, out Vector2 size)
+ {
+ var content = new GUIContent(text);
+ return ToggleClamped(state, content, style, out size);
+ }
+
+ bool ToggleClamped(bool state, GUIContent content, GUIStyle style, out Vector2 size)
+ {
+ size = style.CalcSize(content);
+ Rect drawRect = new Rect(DrawPos, size);
+ return GUI.Toggle(drawRect, state, content, style);
+ }
+
+ void LabelClamped(string text, GUIStyle style, out Vector2 size)
+ {
+ var content = new GUIContent(text);
+ size = style.CalcSize(content);
+
+ Rect drawRect = new Rect(DrawPos, size);
+ GUI.Label(drawRect, text, style);
+ }
+
+ ///
+ /// Draws the thin, Unity-style toolbar showing error counts and toggle buttons
+ ///
+ void DrawToolbar()
+ {
+ var toolbarStyle = EditorStyles.toolbarButton;
+
+ Vector2 elementSize;
+ if(ButtonClamped("Clear", EditorStyles.toolbarButton, out elementSize))
+ {
+ EditorLogger.Clear();
+ }
+ DrawPos.x += elementSize.x;
+ EditorLogger.ClearOnPlay = ToggleClamped(EditorLogger.ClearOnPlay, "Clear On Play", EditorStyles.toolbarButton, out elementSize);
+ DrawPos.x += elementSize.x;
+ EditorLogger.PauseOnError = ToggleClamped(EditorLogger.PauseOnError, "Error Pause", EditorStyles.toolbarButton, out elementSize);
+ DrawPos.x += elementSize.x;
+ var showTimes = ToggleClamped(ShowTimes, "Times", EditorStyles.toolbarButton, out elementSize);
+ if(showTimes!=ShowTimes)
+ {
+ MakeDirty = true;
+ ShowTimes = showTimes;
+ }
+ DrawPos.x += elementSize.x;
+ var showChannels = ToggleClamped(ShowChannels, "Channels", EditorStyles.toolbarButton, out elementSize);
+ if (showChannels != ShowChannels)
+ {
+ MakeDirty = true;
+ ShowChannels = showChannels;
+ }
+ DrawPos.x += elementSize.x;
+ var collapse = ToggleClamped(Collapse, "Collapse", EditorStyles.toolbarButton, out elementSize);
+ if(collapse!=Collapse)
+ {
+ MakeDirty = true;
+ Collapse = collapse;
+ SelectedRenderLog = -1;
+ }
+ DrawPos.x += elementSize.x;
+
+ ScrollFollowMessages = ToggleClamped(ScrollFollowMessages, "Follow", EditorStyles.toolbarButton, out elementSize);
+ DrawPos.x += elementSize.x;
+
+ var errorToggleContent = new GUIContent(EditorLogger.NoErrors.ToString(), SmallErrorIcon);
+ var warningToggleContent = new GUIContent(EditorLogger.NoWarnings.ToString(), SmallWarningIcon);
+ var messageToggleContent = new GUIContent(EditorLogger.NoMessages.ToString(), SmallMessageIcon);
+
+ float totalErrorButtonWidth = toolbarStyle.CalcSize(errorToggleContent).x + toolbarStyle.CalcSize(warningToggleContent).x + toolbarStyle.CalcSize(messageToggleContent).x;
+
+ float errorIconX = position.width-totalErrorButtonWidth;
+ if(errorIconX > DrawPos.x)
+ {
+ DrawPos.x = errorIconX;
+ }
+
+ var showErrors = ToggleClamped(ShowErrors, errorToggleContent, toolbarStyle, out elementSize);
+ DrawPos.x += elementSize.x;
+ var showWarnings = ToggleClamped(ShowWarnings, warningToggleContent, toolbarStyle, out elementSize);
+ DrawPos.x += elementSize.x;
+ var showMessages = ToggleClamped(ShowMessages, messageToggleContent, toolbarStyle, out elementSize);
+ DrawPos.x += elementSize.x;
+
+ DrawPos.y += elementSize.y;
+ DrawPos.x = 0;
+
+ //If the errors/warning to show has changed, clear the selected message
+ if(showErrors!=ShowErrors || showWarnings!=ShowWarnings || showMessages!=ShowMessages)
+ {
+ ClearSelectedMessage();
+ MakeDirty = true;
+ }
+ ShowWarnings = showWarnings;
+ ShowMessages = showMessages;
+ ShowErrors = showErrors;
+ }
+
+ ///
+ /// Draws the channel selector
+ ///
+ void DrawChannels()
+ {
+ var channels = GetChannels();
+ int currentChannelIndex = 0;
+ for(int c1=0; c1
+ /// Based on filter and channel selections, should this log be shown?
+ ///
+ bool ShouldShowLog(System.Text.RegularExpressions.Regex regex, LogInfo log)
+ {
+ if(log.Channel==CurrentChannel || CurrentChannel=="All" || (CurrentChannel=="No Channel" && String.IsNullOrEmpty(log.Channel)))
+ {
+ if((log.Severity==LogSeverity.Message && ShowMessages)
+ || (log.Severity==LogSeverity.Warning && ShowWarnings)
+ || (log.Severity==LogSeverity.Error && ShowErrors))
+ {
+ if(regex==null || regex.IsMatch(log.Message))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// Converts a given log element into a piece of gui content to be displayed
+ ///
+ GUIContent GetLogLineGUIContent(UberLogger.LogInfo log, bool showTimes, bool showChannels)
+ {
+ var showMessage = log.Message;
+
+ //Make all messages single line
+ showMessage = showMessage.Replace(UberLogger.Logger.UnityInternalNewLine, " ");
+
+ // Format the message as follows:
+ // [channel] 0.000 : message <-- Both channel and time shown
+ // 0.000 : message <-- Time shown, channel hidden
+ // [channel] : message <-- Channel shown, time hidden
+ // message <-- Both channel and time hidden
+ var showChannel = showChannels && !string.IsNullOrEmpty(log.Channel);
+ var channelMessage = showChannel ? string.Format("[{0}]", log.Channel) : "";
+ var channelTimeSeparator = (showChannel && showTimes) ? " " : "";
+ var timeMessage = showTimes ? string.Format("{0}", log.GetRelativeTimeStampAsString()) : "";
+ var prefixMessageSeparator = (showChannel || showTimes) ? " : " : "";
+ showMessage = string.Format("{0}{1}{2}{3}{4}",
+ channelMessage,
+ channelTimeSeparator,
+ timeMessage,
+ prefixMessageSeparator,
+ showMessage
+ );
+
+ var content = new GUIContent(showMessage, GetIconForLog(log));
+ return content;
+ }
+
+ ///
+ /// Draws the main log panel
+ ///
+ public void DrawLogList(float height)
+ {
+ var oldColor = GUI.backgroundColor;
+
+
+ float buttonY = 0;
+
+ System.Text.RegularExpressions.Regex filterRegex = null;
+
+ if(!String.IsNullOrEmpty(FilterRegex))
+ {
+ filterRegex = new Regex(FilterRegex);
+ }
+
+ var collapseBadgeStyle = EditorStyles.miniButton;
+ var logLineStyle = EntryStyleBackEven;
+
+ // If we've been marked dirty, we need to recalculate the elements to be displayed
+ if(Dirty)
+ {
+ LogListMaxWidth = 0;
+ LogListLineHeight = 0;
+ CollapseBadgeMaxWidth = 0;
+ RenderLogs.Clear();
+
+ //When collapsed, count up the unique elements and use those to display
+ if(Collapse)
+ {
+ var collapsedLines = new Dictionary();
+ var collapsedLinesList = new List();
+
+ foreach(var log in CurrentLogList)
+ {
+ if(ShouldShowLog(filterRegex, log))
+ {
+ var matchString = log.Message + "!$" + log.Severity + "!$" + log.Channel;
+
+ CountedLog countedLog;
+ if(collapsedLines.TryGetValue(matchString, out countedLog))
+ {
+ countedLog.Count++;
+ }
+ else
+ {
+ countedLog = new CountedLog(log, 1);
+ collapsedLines.Add(matchString, countedLog);
+ collapsedLinesList.Add(countedLog);
+ }
+ }
+ }
+
+ foreach(var countedLog in collapsedLinesList)
+ {
+ var content = GetLogLineGUIContent(countedLog.Log, ShowTimes, ShowChannels);
+ RenderLogs.Add(countedLog);
+ var logLineSize = logLineStyle.CalcSize(content);
+ LogListMaxWidth = Mathf.Max(LogListMaxWidth, logLineSize.x);
+ LogListLineHeight = Mathf.Max(LogListLineHeight, logLineSize.y);
+
+ var collapseBadgeContent = new GUIContent(countedLog.Count.ToString());
+ var collapseBadgeSize = collapseBadgeStyle.CalcSize(collapseBadgeContent);
+ CollapseBadgeMaxWidth = Mathf.Max(CollapseBadgeMaxWidth, collapseBadgeSize.x);
+ }
+ }
+ //If we're not collapsed, display everything in order
+ else
+ {
+ foreach(var log in CurrentLogList)
+ {
+ if(ShouldShowLog(filterRegex, log))
+ {
+ var content = GetLogLineGUIContent(log, ShowTimes, ShowChannels);
+ RenderLogs.Add(new CountedLog(log, 1));
+ var logLineSize = logLineStyle.CalcSize(content);
+ LogListMaxWidth = Mathf.Max(LogListMaxWidth, logLineSize.x);
+ LogListLineHeight = Mathf.Max(LogListLineHeight, logLineSize.y);
+ }
+ }
+ }
+
+ LogListMaxWidth += CollapseBadgeMaxWidth;
+ }
+
+ var scrollRect = new Rect(DrawPos, new Vector2(position.width, height));
+ float lineWidth = Mathf.Max(LogListMaxWidth, scrollRect.width);
+
+ var contentRect = new Rect(0, 0, lineWidth, RenderLogs.Count*LogListLineHeight);
+ Vector2 lastScrollPosition = LogListScrollPosition;
+ LogListScrollPosition = GUI.BeginScrollView(scrollRect, LogListScrollPosition, contentRect);
+
+ //If we're following the messages but the user has moved, cancel following
+ if(ScrollFollowMessages)
+ {
+ if(lastScrollPosition.y - LogListScrollPosition.y > LogListLineHeight)
+ {
+ UberDebug.UnityLog(String.Format("{0} {1}", lastScrollPosition.y, LogListScrollPosition.y));
+ ScrollFollowMessages = false;
+ }
+ }
+
+ float logLineX = CollapseBadgeMaxWidth;
+
+ //Render all the elements
+ int firstRenderLogIndex = (int) (LogListScrollPosition.y/LogListLineHeight);
+ int lastRenderLogIndex = firstRenderLogIndex + (int) (height/LogListLineHeight);
+
+ firstRenderLogIndex = Mathf.Clamp(firstRenderLogIndex, 0, RenderLogs.Count);
+ lastRenderLogIndex = Mathf.Clamp(lastRenderLogIndex, 0, RenderLogs.Count);
+ buttonY = firstRenderLogIndex*LogListLineHeight;
+
+ for(int renderLogIndex=firstRenderLogIndex; renderLogIndex0)
+ {
+ LogListScrollPosition.y = ((RenderLogs.Count+1)*LogListLineHeight)-scrollRect.height;
+ }
+
+ GUI.EndScrollView();
+ DrawPos.y += height;
+ DrawPos.x = 0;
+ GUI.backgroundColor = oldColor;
+ }
+
+
+ ///
+ /// The bottom of the panel - details of the selected log
+ ///
+ public void DrawLogDetails()
+ {
+ var oldColor = GUI.backgroundColor;
+
+ SelectedRenderLog = Mathf.Clamp(SelectedRenderLog, 0, CurrentLogList.Count);
+
+ if(RenderLogs.Count>0 && SelectedRenderLog>=0)
+ {
+ var countedLog = RenderLogs[SelectedRenderLog];
+ var log = countedLog.Log;
+ var logLineStyle = EntryStyleBackEven;
+
+ var sourceStyle = new GUIStyle(GUI.skin.textArea);
+ sourceStyle.richText = true;
+
+ var drawRect = new Rect(DrawPos, new Vector2(position.width-DrawPos.x, position.height-DrawPos.y));
+
+ //Work out the content we need to show, and the sizes
+ var detailLines = new List();
+ float contentHeight = 0;
+ float contentWidth = 0;
+ float lineHeight = 0;
+
+
+ for(int c1=0; c1 GetChannels()
+ {
+ if(Dirty)
+ {
+ CurrentChannels = EditorLogger.CopyChannels();
+ }
+
+ var categories = CurrentChannels;
+
+ var channelList = new List();
+ channelList.Add("All");
+ channelList.Add("No Channel");
+ channelList.AddRange(categories);
+ return channelList;
+ }
+
+ ///
+ /// Handles the split window stuff, somewhat bodgily
+ ///
+ private void ResizeTopPane()
+ {
+ //Set up the resize collision rect
+ CursorChangeRect = new Rect(0, CurrentTopPaneHeight, position.width, DividerHeight);
+
+ var oldColor = GUI.color;
+ GUI.color = SizerLineColour;
+ GUI.DrawTexture(CursorChangeRect, EditorGUIUtility.whiteTexture);
+ GUI.color = oldColor;
+ EditorGUIUtility.AddCursorRect(CursorChangeRect,MouseCursor.ResizeVertical);
+
+ if( Event.current.type == EventType.MouseDown && CursorChangeRect.Contains(Event.current.mousePosition))
+ {
+ Resize = true;
+ }
+
+ //If we've resized, store the new size and force a repaint
+ if(Resize)
+ {
+ CurrentTopPaneHeight = Event.current.mousePosition.y;
+ CursorChangeRect.Set(CursorChangeRect.x,CurrentTopPaneHeight,CursorChangeRect.width,CursorChangeRect.height);
+ Repaint();
+ }
+
+ if(Event.current.type == EventType.MouseUp)
+ Resize = false;
+
+ CurrentTopPaneHeight = Mathf.Clamp(CurrentTopPaneHeight, 100, position.height-100);
+ }
+
+ //Cache for GetSourceForFrame
+ string SourceLines;
+ LogStackFrame SourceLinesFrame;
+
+ ///
+ ///If the frame has a valid filename, get the source string for the code around the frame
+ ///This is cached, so we don't keep getting it.
+ ///
+ string GetSourceForFrame(LogStackFrame frame)
+ {
+ if(SourceLinesFrame==frame)
+ {
+ return SourceLines;
+ }
+
+
+ if(frame.FileName==null)
+ {
+ return "";
+ }
+
+ var osFileName = UberLogger.Logger.ConvertDirectorySeparatorsFromUnityToOS(frame.FileName);
+ var filename = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), osFileName);
+ if (!System.IO.File.Exists(filename))
+ {
+ return "";
+ }
+
+ int lineNumber = frame.LineNumber-1;
+ int linesAround = 3;
+ var lines = System.IO.File.ReadAllLines(filename);
+ var firstLine = Mathf.Max(lineNumber-linesAround, 0);
+ var lastLine = Mathf.Min(lineNumber+linesAround+1, lines.Count());
+
+ SourceLines = "";
+ if(firstLine!=0)
+ {
+ SourceLines += "...\n";
+ }
+ for(int c1=firstLine; c1";
+ }
+ SourceLines += str;
+ }
+ if(lastLine!=lines.Count())
+ {
+ SourceLines += "...\n";
+ }
+
+ SourceLinesFrame = frame;
+ return SourceLines;
+ }
+
+ void ClearSelectedMessage()
+ {
+ SelectedRenderLog = -1;
+ SelectedCallstackFrame = -1;
+ ShowFrameSource = false;
+ }
+
+ Vector2 LogListScrollPosition;
+ Vector2 LogDetailsScrollPosition;
+
+ Texture2D ErrorIcon;
+ Texture2D WarningIcon;
+ Texture2D MessageIcon;
+ Texture2D SmallErrorIcon;
+ Texture2D SmallWarningIcon;
+ Texture2D SmallMessageIcon;
+
+ bool ShowChannels = true;
+ bool ShowTimes = true;
+ bool Collapse = false;
+ bool ScrollFollowMessages = false;
+ float CurrentTopPaneHeight = 200;
+ bool Resize = false;
+ Rect CursorChangeRect;
+ int SelectedRenderLog = -1;
+ bool Dirty=false;
+ bool MakeDirty=false;
+ float DividerHeight = 5;
+
+ double LastMessageClickTime = 0;
+ double LastFrameClickTime = 0;
+
+ const double DoubleClickInterval = 0.3f;
+
+ //Serialise the logger field so that Unity doesn't forget about the logger when you hit Play
+ [UnityEngine.SerializeField]
+ UberLoggerEditor EditorLogger;
+
+ List CurrentLogList = new List();
+ HashSet CurrentChannels = new HashSet();
+
+ //Standard unity pro colours
+ Color SizerLineColour;
+
+ GUIStyle EntryStyleBackEven;
+ GUIStyle EntryStyleBackOdd;
+ string CurrentChannel=null;
+ string FilterRegex = null;
+ bool ShowErrors = true;
+ bool ShowWarnings = true;
+ bool ShowMessages = true;
+ int SelectedCallstackFrame = 0;
+ bool ShowFrameSource = false;
+
+ class CountedLog
+ {
+ public UberLogger.LogInfo Log = null;
+ public Int32 Count=1;
+ public CountedLog(UberLogger.LogInfo log, Int32 count)
+ {
+ Log = log;
+ Count = count;
+ }
+ }
+
+ List RenderLogs = new List();
+ float LogListMaxWidth = 0;
+ float LogListLineHeight = 0;
+ float CollapseBadgeMaxWidth = 0;
+
+}
diff --git a/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs.meta b/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs.meta
new file mode 100644
index 00000000000..560c65f0dbb
--- /dev/null
+++ b/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6ef03148bd3bd4ff99c7296168e907fb
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
diff --git a/nekoyume/Assets/_Scripts/Blockchain/RPCAgent.cs b/nekoyume/Assets/_Scripts/Blockchain/RPCAgent.cs
index 7064544b5a8..33f29c58bca 100644
--- a/nekoyume/Assets/_Scripts/Blockchain/RPCAgent.cs
+++ b/nekoyume/Assets/_Scripts/Blockchain/RPCAgent.cs
@@ -964,8 +964,7 @@ public void OnRenderBlock(byte[] oldTip, byte[] newTip)
BlockTipHashSubject.OnNext(BlockTipHash);
_lastTipChangedAt = DateTimeOffset.UtcNow;
- NcDebug.Log(
- $"[{nameof(RPCAgent)}] Render block: {BlockIndex}, {BlockTipHash.ToString()}");
+ NcDebug.Log($"[{nameof(RPCAgent)}] Render block: {BlockIndex}, {BlockTipHash.ToString()}", channel: "RenderBlock");
BlockRenderer.RenderBlock(null, null);
});
}
diff --git a/nekoyume/Assets/_Scripts/Debugger/NcDebug.cs b/nekoyume/Assets/_Scripts/Debugger/NcDebug.cs
index 788fc9503b2..b156e32014b 100644
--- a/nekoyume/Assets/_Scripts/Debugger/NcDebug.cs
+++ b/nekoyume/Assets/_Scripts/Debugger/NcDebug.cs
@@ -1,26 +1,8 @@
using System;
using JetBrains.Annotations;
-using UnityEngine;
namespace Nekoyume
{
- ///
- /// It overrides UnityEngine.Debug to mute debug messages completely on a platform-specific basis.
- ///
- /// Putting this inside of 'Plugins' foloder is ok.
- ///
- /// Important:
- /// Other preprocessor directives than 'UNITY_EDITOR' does not correctly work.
- ///
- /// Note:
- /// [Conditional] attribute indicates to compilers that a method call or attribute should be
- /// ignored unless a specified conditional compilation symbol is defined.
- ///
- /// See Also:
- /// http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx
- ///
- /// 2012.11. @kimsama
- ///
public static class NcDebug
{
// used for build with 'DEBUG_USE' symbol.
@@ -30,105 +12,108 @@ public static string InsertTimestamp(string message)
return $"[{DateTime.UtcNow:yyyy-M-d HH:mm:ss}] {message}";
}
- public static void Log(object message)
+ public static void Log(object message, string channel = "")
{
#if UNITY_EDITOR
- Debug.Log(message);
+ UberDebug.LogChannel(channel, message.ToString());
#elif DEBUG_USE
- Debug.Log(InsertTimestamp(message.ToString()));
+ UnityEngine.Debug.Log(InsertTimestamp(message.ToString()));
#endif
}
- public static void Log(object message, UnityEngine.Object context)
+ public static void Log(object message, UnityEngine.Object context, string channel = "")
{
#if UNITY_EDITOR
- Debug.Log(message, context);
+ UberDebug.LogChannel(channel, message.ToString(), context);
#elif DEBUG_USE
- Debug.Log(InsertTimestamp(message.ToString()), context);
+ UnityEngine.Debug.Log(InsertTimestamp(message.ToString()), context);
#endif
}
public static void LogFormat(string format, params object[] args)
{
+ var message = string.Format(format, args);
#if UNITY_EDITOR
- Debug.LogFormat(format, args);
+ UberDebug.Log(message);
#elif DEBUG_USE
// LogFormat() in itself expands an array when it takes only one array.
- Debug.Log(InsertTimestamp(string.Format(format, args)));
+ UnityEngine.Debug.Log(InsertTimestamp(message));
#endif
}
- public static void LogWarning(object message)
+ public static void LogWarning(object message, string channel = "")
{
#if UNITY_EDITOR
- Debug.LogWarning(message);
+ UberDebug.LogWarningChannel(channel, message.ToString());
#elif DEBUG_USE
- Debug.LogWarning(InsertTimestamp(message.ToString()));
+ UnityEngine.Debug.LogWarning(InsertTimestamp(message.ToString()));
#endif
}
- public static void LogWarning(object message, UnityEngine.Object context)
+ public static void LogWarning(object message, UnityEngine.Object context, string channel = "")
{
#if UNITY_EDITOR
- Debug.LogWarning(message, context);
+ UberDebug.LogWarningChannel(channel, message.ToString(), context);
#elif DEBUG_USE
- Debug.LogWarning(InsertTimestamp(message.ToString()), context);
+ UnityEngine.Debug.LogWarning(InsertTimestamp(message.ToString()), context);
#endif
}
public static void LogWarningFormat(string format, params object[] args)
{
+ var message = string.Format(format, args);
#if UNITY_EDITOR
- Debug.LogWarningFormat(format, args);
+ UberDebug.LogWarning(message);
#elif DEBUG_USE
// LogWarningFormat() in itself expands an array when it takes only one array.
- Debug.LogWarningFormat(InsertTimestamp(string.Format(format, args)));
+ UnityEngine.Debug.LogWarningFormat(InsertTimestamp(message));
#endif
}
- public static void LogError(object message)
+ public static void LogError(object message, string channel = "")
{
#if UNITY_EDITOR
- Debug.LogError(message);
+ UberDebug.LogErrorChannel(channel, message.ToString());
#elif DEBUG_USE
- Debug.LogError(InsertTimestamp(message.ToString()));
+ UnityEngine.Debug.LogError(InsertTimestamp(message.ToString()));
#endif
}
- public static void LogError(object message, UnityEngine.Object context)
+ public static void LogError(object message, UnityEngine.Object context, string channel = "")
{
#if UNITY_EDITOR
- Debug.LogError(message, context);
+ UberDebug.LogErrorChannel(channel, message.ToString(), context);
#elif DEBUG_USE
- Debug.LogError(InsertTimestamp(message.ToString()), context);
+ UnityEngine.Debug.LogError(InsertTimestamp(message.ToString()), context);
#endif
}
public static void LogErrorFormat(string format, params object[] args)
{
+ var message = string.Format(format, args);
#if UNITY_EDITOR
- Debug.LogErrorFormat(format, args);
+ UberDebug.LogError(message);
#elif DEBUG_USE
// LogErrorFormat() in itself expands an array when it takes only one array.
- Debug.LogErrorFormat(InsertTimestamp(string.Format(format, args)));
+ UnityEngine.Debug.LogErrorFormat(InsertTimestamp(message));
#endif
}
- public static void LogException(Exception exception)
+ public static void LogException(Exception exception, string channel = "")
{
#if UNITY_EDITOR
- Debug.LogError(exception.Message);
+ UberDebug.LogErrorChannel(channel, exception.Message);
#elif DEBUG_USE
- Debug.LogError(InsertTimestamp(exception.Message));
+ UnityEngine.Debug.LogError(InsertTimestamp(exception.Message));
#endif
}
- public static void LogException(Exception exception, UnityEngine.Object context)
+ public static void LogException(Exception exception, UnityEngine.Object context, string channel = "")
{
#if UNITY_EDITOR
- Debug.LogError(exception.Message, context);
+ UberDebug.LogErrorChannel(channel, exception.Message, context);
#elif DEBUG_USE
- Debug.LogError(InsertTimestamp(exception.Message), context);
+ UnityEngine.Debug.LogError(InsertTimestamp(exception.Message), context);
#endif
}
}
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger.meta
new file mode 100644
index 00000000000..13554d22a72
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5d104a850059c7646bca9fc3f9c2381d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art.meta
new file mode 100644
index 00000000000..9b8123b763c
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 08b646709d2a14c419ef4e641ce44797
+folderAsset: yes
+timeCreated: 1437657322
+licenseType: Free
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png
new file mode 100644
index 00000000000..138bac3a33b
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png.meta
new file mode 100644
index 00000000000..dc863ca54a9
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: 2ae9477f7f0774b808aef406d3bf2d3c
+timeCreated: 1437687420
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png
new file mode 100644
index 00000000000..9fcc2146aba
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png.meta
new file mode 100644
index 00000000000..c6b9cf6eb04
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: f752d027f2368431c924c0306e747c4b
+timeCreated: 1437728159
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png
new file mode 100644
index 00000000000..1af20cc9145
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png.meta
new file mode 100644
index 00000000000..b4b604c41b9
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: f5e296e323cd64d619488c517c4692af
+timeCreated: 1437663587
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png
new file mode 100644
index 00000000000..d456d99c804
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png.meta
new file mode 100644
index 00000000000..46c2a163eab
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: 58be81cf6eccb4cabbae417792fd2765
+timeCreated: 1437660139
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png
new file mode 100644
index 00000000000..3dd4b752b05
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png.meta
new file mode 100644
index 00000000000..ca8f95d5a2e
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: 33bd69e44bf8341e5a10577910796fb6
+timeCreated: 1437660139
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png
new file mode 100644
index 00000000000..1cf4942402b
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png.meta
new file mode 100644
index 00000000000..5fbdcb2b673
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: c60b5ba991951418b86ce94a4b97321c
+timeCreated: 1437660139
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png
new file mode 100644
index 00000000000..46d19f8ac4b
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png.meta
new file mode 100644
index 00000000000..4069e255dd8
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: fa976bac27b1e440eb0d8bd71c1caac3
+timeCreated: 1437663836
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png
new file mode 100644
index 00000000000..b368a5d652f
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png.meta
new file mode 100644
index 00000000000..f91b871c3f5
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: 1e3d00b6e3a884febbfd0da496905572
+timeCreated: 1437660139
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png
new file mode 100644
index 00000000000..b9fc1fa8f54
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png.meta
new file mode 100644
index 00000000000..e802694ec67
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: c445efe53c41a452897859c5e65dde5c
+timeCreated: 1437662129
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png
new file mode 100644
index 00000000000..0c463ab22bb
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png.meta
new file mode 100644
index 00000000000..da5095721de
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: bd719bdc497244113bf9f08779f78082
+timeCreated: 1437664533
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin
new file mode 100644
index 00000000000..9d6958b9714
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin
@@ -0,0 +1,1433 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 1
+ m_Script: {fileID: 12001, guid: 0000000000000000e000000000000000, type: 0}
+ m_Name: UberConsoleSkin
+ m_EditorClassIdentifier:
+ m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+ m_box:
+ m_Name: box
+ m_Normal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: .799999952, g: .799999952, b: .799999952, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 6
+ m_Right: 6
+ m_Top: 6
+ m_Bottom: 6
+ m_Margin:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Padding:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 1
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_button:
+ m_Name: button
+ m_Normal:
+ m_Background: {fileID: 11006, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1}
+ m_Hover:
+ m_Background: {fileID: 11003, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Active:
+ m_Background: {fileID: 11002, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 11005, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .90196079, g: .90196079, b: .90196079, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 11004, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 11002, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 6
+ m_Right: 6
+ m_Top: 6
+ m_Bottom: 4
+ m_Margin:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Padding:
+ m_Left: 6
+ m_Right: 6
+ m_Top: 3
+ m_Bottom: 3
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 4
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_toggle:
+ m_Name: toggle
+ m_Normal:
+ m_Background: {fileID: 11018, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .891128957, g: .891128957, b: .891128957, a: 1}
+ m_Hover:
+ m_Background: {fileID: 11014, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Active:
+ m_Background: {fileID: 11013, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 11016, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .890196085, g: .890196085, b: .890196085, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 11015, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 11017, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 14
+ m_Right: 0
+ m_Top: 14
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Padding:
+ m_Left: 15
+ m_Right: 0
+ m_Top: 3
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: -1
+ m_Right: 0
+ m_Top: -4
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_label:
+ m_Name: label
+ m_Normal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 3
+ m_Bottom: 3
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 1
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_textField:
+ m_Name: textfield
+ m_Normal:
+ m_Background: {fileID: 11024, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .799999952, g: .799999952, b: .799999952, a: 1}
+ m_Hover:
+ m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 11025, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Margin:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Padding:
+ m_Left: 3
+ m_Right: 3
+ m_Top: 3
+ m_Bottom: 3
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 0
+ m_TextClipping: 1
+ m_ImagePosition: 3
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_textArea:
+ m_Name: textarea
+ m_Normal:
+ m_Background: {fileID: 11024, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .90196079, g: .90196079, b: .90196079, a: 1}
+ m_Hover:
+ m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: .799999952, g: .799999952, b: .799999952, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 11025, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Margin:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Padding:
+ m_Left: 3
+ m_Right: 3
+ m_Top: 3
+ m_Bottom: 3
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 1
+ m_RichText: 0
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_window:
+ m_Name: window
+ m_Normal:
+ m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Hover:
+ m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Active:
+ m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Focused:
+ m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Border:
+ m_Left: 10
+ m_Right: 9
+ m_Top: 19
+ m_Bottom: 9
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 10
+ m_Right: 10
+ m_Top: 20
+ m_Bottom: 10
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 1
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: -18}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_horizontalSlider:
+ m_Name: horizontalslider
+ m_Normal:
+ m_Background: {fileID: 11009, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 3
+ m_Right: 3
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Padding:
+ m_Left: -1
+ m_Right: -1
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: -2
+ m_Bottom: -3
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 2
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 12
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_horizontalSliderThumb:
+ m_Name: horizontalsliderthumb
+ m_Normal:
+ m_Background: {fileID: 11011, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 11012, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 11010, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 7
+ m_Right: 7
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: -1
+ m_Right: -1
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 2
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 12
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_verticalSlider:
+ m_Name: verticalslider
+ m_Normal:
+ m_Background: {fileID: 11021, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 3
+ m_Bottom: 3
+ m_Margin:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: -1
+ m_Bottom: -1
+ m_Overflow:
+ m_Left: -2
+ m_Right: -3
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 0
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 12
+ m_FixedHeight: 0
+ m_StretchWidth: 0
+ m_StretchHeight: 1
+ m_verticalSliderThumb:
+ m_Name: verticalsliderthumb
+ m_Normal:
+ m_Background: {fileID: 11011, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 11012, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 11010, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 7
+ m_Bottom: 7
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: -1
+ m_Bottom: -1
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 12
+ m_FixedHeight: 0
+ m_StretchWidth: 0
+ m_StretchHeight: 1
+ m_horizontalScrollbar:
+ m_Name: horizontalscrollbar
+ m_Normal:
+ m_Background: {fileID: 11008, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 9
+ m_Right: 9
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 4
+ m_Right: 4
+ m_Top: 1
+ m_Bottom: 4
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 2
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 15
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_horizontalScrollbarThumb:
+ m_Name: horizontalscrollbarthumb
+ m_Normal:
+ m_Background: {fileID: 11007, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 6
+ m_Right: 6
+ m_Top: 6
+ m_Bottom: 6
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 6
+ m_Right: 6
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: -1
+ m_Bottom: 1
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 13
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_horizontalScrollbarLeftButton:
+ m_Name: horizontalscrollbarleftbutton
+ m_Normal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_horizontalScrollbarRightButton:
+ m_Name: horizontalscrollbarrightbutton
+ m_Normal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_verticalScrollbar:
+ m_Name: verticalscrollbar
+ m_Normal:
+ m_Background: {fileID: 11020, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 9
+ m_Bottom: 9
+ m_Margin:
+ m_Left: 1
+ m_Right: 4
+ m_Top: 4
+ m_Bottom: 4
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 1
+ m_Bottom: 1
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 15
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_verticalScrollbarThumb:
+ m_Name: verticalscrollbarthumb
+ m_Normal:
+ m_Background: {fileID: 11019, guid: 0000000000000000e000000000000000, type: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 6
+ m_Right: 6
+ m_Top: 6
+ m_Bottom: 6
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 6
+ m_Bottom: 6
+ m_Overflow:
+ m_Left: -1
+ m_Right: -1
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 2
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 15
+ m_FixedHeight: 0
+ m_StretchWidth: 0
+ m_StretchHeight: 1
+ m_verticalScrollbarUpButton:
+ m_Name: verticalscrollbarupbutton
+ m_Normal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_verticalScrollbarDownButton:
+ m_Name: verticalscrollbardownbutton
+ m_Normal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_ScrollView:
+ m_Name: scrollview
+ m_Normal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Hover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Active:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Focused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 1
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_CustomStyles:
+ - m_Name: LogLine1
+ m_Normal:
+ m_Background: {fileID: 2800000, guid: 58be81cf6eccb4cabbae417792fd2765, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Hover:
+ m_Background: {fileID: 2800000, guid: 58be81cf6eccb4cabbae417792fd2765, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Active:
+ m_Background: {fileID: 2800000, guid: 58be81cf6eccb4cabbae417792fd2765, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Focused:
+ m_Background: {fileID: 2800000, guid: 58be81cf6eccb4cabbae417792fd2765, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 0
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ - m_Name: LogLine2
+ m_Normal:
+ m_Background: {fileID: 2800000, guid: 33bd69e44bf8341e5a10577910796fb6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Hover:
+ m_Background: {fileID: 2800000, guid: 33bd69e44bf8341e5a10577910796fb6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Active:
+ m_Background: {fileID: 2800000, guid: 33bd69e44bf8341e5a10577910796fb6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Focused:
+ m_Background: {fileID: 2800000, guid: 33bd69e44bf8341e5a10577910796fb6, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 0
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ - m_Name: SelectedLogLine
+ m_Normal:
+ m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Hover:
+ m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Active:
+ m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Focused:
+ m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 0, g: 0, b: 0, a: 1}
+ m_Border:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 0
+ m_FontStyle: 0
+ m_Alignment: 0
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 0
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ - m_Name: ToolbarButton
+ m_Normal:
+ m_Background: {fileID: 2800000, guid: 1e3d00b6e3a884febbfd0da496905572, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Hover:
+ m_Background: {fileID: 2800000, guid: 1e3d00b6e3a884febbfd0da496905572, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Active:
+ m_Background: {fileID: 2800000, guid: c445efe53c41a452897859c5e65dde5c, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Focused:
+ m_Background: {fileID: 2800000, guid: 1e3d00b6e3a884febbfd0da496905572, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnNormal:
+ m_Background: {fileID: 2800000, guid: bd719bdc497244113bf9f08779f78082, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnHover:
+ m_Background: {fileID: 0}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnActive:
+ m_Background: {fileID: 2800000, guid: c445efe53c41a452897859c5e65dde5c, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_OnFocused:
+ m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3}
+ m_TextColor: {r: 1, g: 1, b: 1, a: 1}
+ m_Border:
+ m_Left: 1
+ m_Right: 1
+ m_Top: 0
+ m_Bottom: 0
+ m_Margin:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Padding:
+ m_Left: 3
+ m_Right: 3
+ m_Top: 3
+ m_Bottom: 3
+ m_Overflow:
+ m_Left: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_Font: {fileID: 0}
+ m_FontSize: 10
+ m_FontStyle: 0
+ m_Alignment: 4
+ m_WordWrap: 0
+ m_RichText: 1
+ m_TextClipping: 0
+ m_ImagePosition: 0
+ m_ContentOffset: {x: 0, y: 0}
+ m_FixedWidth: 0
+ m_FixedHeight: 0
+ m_StretchWidth: 1
+ m_StretchHeight: 0
+ m_Settings:
+ m_DoubleClickSelectsWord: 1
+ m_TripleClickSelectsLine: 1
+ m_CursorColor: {r: 1, g: 1, b: 1, a: 1}
+ m_CursorFlashSpeed: -1
+ m_SelectionColor: {r: 1, g: .384039074, b: 0, a: .699999988}
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin.meta
new file mode 100644
index 00000000000..40240aec804
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7018997e7c4ba41d8aa5a2338b82d57f
+timeCreated: 1437656589
+licenseType: Free
+NativeFormatImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png
new file mode 100644
index 00000000000..0ad9537f379
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png.meta
new file mode 100644
index 00000000000..9762f65f5ac
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: ecc8f3c040a254019afd50c8bc285b48
+timeCreated: 1437663836
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png
new file mode 100644
index 00000000000..84f7a959fae
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png.meta
new file mode 100644
index 00000000000..7553eee175e
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: 1133c84ccb4d141f1b48c8c137f4b4ea
+timeCreated: 1437657427
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png
new file mode 100644
index 00000000000..cd1240457c5
Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png differ
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png.meta
new file mode 100644
index 00000000000..a6788dd73dd
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png.meta
@@ -0,0 +1,55 @@
+fileFormatVersion: 2
+guid: e4083732964464539b3e141a263f50b6
+timeCreated: 1437658895
+licenseType: Free
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ cubemapConvolution: 0
+ cubemapConvolutionSteps: 8
+ cubemapConvolutionExponent: 1.5
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ rGBM: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE b/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE
new file mode 100644
index 00000000000..c2ebf8e7932
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 bbbscarter
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE.meta
new file mode 100644
index 00000000000..30d3a9b34f2
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f8478442035604d6c9af1c71c9733e99
+timeCreated: 1440268457
+licenseType: Free
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md b/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md
new file mode 100644
index 00000000000..408464ab45d
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md
@@ -0,0 +1,61 @@
+# UberLogger
+UberLogger is a free, modular, opensource replacement for Unity's
+Debug.Log system. It also includes UberConsole, a replacement for
+Unity's editor console, an in game console version of UberConsole, and
+a file logger.
+
+## Core Features
+* Drop in replacement for Unity's Debug.Log() methods. No code changes
+ needed.
+* A threadsafe, modular backend that supports any number of loggers,
+ so Debug.Log can be routed to multiple locations. The supplied file
+ logger should work on mobile devices.
+* Included are a replacement editor console, an in-game console and a
+ file logger.
+* Support for named debug channels - UberDebug.LogChannel("Boot", "Some
+ message") can be filtered based on the channel name.
+* Methods may be marked as excluded from callstacks by tagging them
+ with '[StackTraceIgnore]', to keep your logs tidy.
+
+## UberConsole Features
+* More compact view shows more errors in the same space.
+* Supports debug log channels.
+* Messages can be filtered by regular expressions.
+* Timestamps.
+* Source code can be shown inline with the callstack.
+* An in-game version of UberConsole is also provided.
+
+## Installation
+* Stick the UberLogger folder somewhere under your Unity project
+ Assets folder.
+* To use additional features like channels, use UberDebug instead of
+ Debug - it contains methods like Log, LogChannel, etc.
+* To view the editor UberConsole, go to Window->Show Uber Console.
+* To use UberConsole in your game, drag the UberAppConsole prefab into
+ your scene.
+* Usage examples can be seen in the Examples folder.
+
+## Notes
+* Tested in Unity 5.x, 2017.x, free and Pro.
+* Logging disabled in non-debug builds. To force it on, define
+ ENABLE_UBERLOGGING.
+* Due to file incompatibilities, the in-game console skin doesn't work
+ in Unity 4 and would need to be set up again. Same with the
+ prefab. That said, the code works, and so does the editor
+ UberConsole.
+* Pull requests welcome!
+
+## Extensions
+* [UberLogger-StructuredFile](https://github.com/falldamagestudio/UberLogger-StructuredFile)
+ adds a structured log file format with timestamps, channel names, and control over which
+ log messages are printed with callstacks and which are printed without.
+* [UberLogger-Stackdriver](https://github.com/falldamagestudio/UberLogger-Stackdriver)
+ adds centralized logging. Log messages will be sent from game clients to Google's
+ Stackdriver service. The collected logs can be browsed and searched in the Stackdriver web UI.
+* [UberLogger-LogChannels](https://github.com/falldamagestudio/UberLogger-LogChannels)
+ adds compile-time resolution and muting of log channels. This is useful for very large
+ projects where logging to muted channels causes performance problems.
+
+ * * * *
+
+UberLogger: https://github.com/bbbscarter/UberLogger
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md.meta
new file mode 100644
index 00000000000..43488ee47fc
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 951b1a41f8f1d4c57b6fbcc74ca23057
+timeCreated: 1438190280
+licenseType: Free
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab
new file mode 100644
index 00000000000..944412df980
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab
@@ -0,0 +1,64 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &108080
+GameObject:
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ serializedVersion: 4
+ m_Component:
+ - 4: {fileID: 464206}
+ - 114: {fileID: 11463974}
+ m_Layer: 0
+ m_Name: UberAppConsole
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &464206
+Transform:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 108080}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 22.7158318, y: -1.60936856, z: 6.47446775}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+--- !u!114 &11463974
+MonoBehaviour:
+ m_ObjectHideFlags: 1
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 100100000}
+ m_GameObject: {fileID: 108080}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a0e07a4dd7148412e9649a25c8abcb11, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ Skin: {fileID: 11400000, guid: 7018997e7c4ba41d8aa5a2338b82d57f, type: 2}
+ SmallErrorIcon: {fileID: 2800000, guid: f5e296e323cd64d619488c517c4692af, type: 3}
+ SmallWarningIcon: {fileID: 2800000, guid: ecc8f3c040a254019afd50c8bc285b48, type: 3}
+ SmallMessageIcon: {fileID: 2800000, guid: fa976bac27b1e440eb0d8bd71c1caac3, type: 3}
+ GUIColour: {r: 1, g: 1, b: 1, a: .781000018}
+ FontSize: 0
+ SizerLineColour: {r: .164705887, g: .164705887, b: .164705887, a: 1}
+ SizerStartHeightRatio: .75
+ ButtonTexture: {fileID: 2800000, guid: 2ae9477f7f0774b808aef406d3bf2d3c, type: 3}
+ ErrorButtonTexture: {fileID: 2800000, guid: f752d027f2368431c924c0306e747c4b, type: 3}
+ ButtonPosition: {x: 0, y: 0}
+ ButtonSize: {x: 32, y: 32}
+--- !u!1001 &100100000
+Prefab:
+ m_ObjectHideFlags: 1
+ serializedVersion: 2
+ m_Modification:
+ m_TransformParent: {fileID: 0}
+ m_Modifications: []
+ m_RemovedComponents: []
+ m_ParentPrefab: {fileID: 0}
+ m_RootGameObject: {fileID: 108080}
+ m_IsPrefabParent: 1
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab.meta
new file mode 100644
index 00000000000..fff0c85c62a
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 82c521de7b47a4ce89bb1da3aa96e96f
+timeCreated: 1438191581
+licenseType: Free
+NativeFormatImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs
new file mode 100644
index 00000000000..a464bf98291
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs
@@ -0,0 +1,133 @@
+#if !ENABLE_UBERLOGGING && (DEVELOPMENT_BUILD || DEBUG || UNITY_EDITOR)
+#define ENABLE_UBERLOGGING
+#endif
+
+using UberLogger;
+
+//Helper functions to make logging easier
+public static class UberDebug
+{
+ [StackTraceIgnore]
+ static public void Log(UnityEngine.Object context, string message, params object[] par)
+ {
+ #if ENABLE_UBERLOGGING
+ UberLogger.Logger.Log("", context, LogSeverity.Message, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void Log(string message, params object[] par)
+ {
+ #if ENABLE_UBERLOGGING
+ UberLogger.Logger.Log("", null, LogSeverity.Message, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void LogChannel(UnityEngine.Object context, string channel, string message, params object[] par)
+ {
+ #if ENABLE_UBERLOGGING
+ UberLogger.Logger.Log(channel, context, LogSeverity.Message, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void LogChannel(string channel, string message, params object[] par)
+ {
+ #if ENABLE_UBERLOGGING
+ UberLogger.Logger.Log(channel, null, LogSeverity.Message, message, par);
+ #endif
+ }
+
+
+ [StackTraceIgnore]
+ static public void LogWarning(UnityEngine.Object context, object message, params object[] par)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS)
+ UberLogger.Logger.Log("", context, LogSeverity.Warning, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void LogWarning(object message, params object[] par)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS)
+ UberLogger.Logger.Log("", null, LogSeverity.Warning, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void LogWarningChannel(UnityEngine.Object context, string channel, string message, params object[] par)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS)
+ UberLogger.Logger.Log(channel, context, LogSeverity.Warning, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void LogWarningChannel(string channel, string message, params object[] par)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS)
+ UberLogger.Logger.Log(channel, null, LogSeverity.Warning, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void LogError(UnityEngine.Object context, object message, params object[] par)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS)
+ UberLogger.Logger.Log("", context, LogSeverity.Error, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void LogError(object message, params object[] par)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS)
+ UberLogger.Logger.Log("", null, LogSeverity.Error, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void LogErrorChannel(UnityEngine.Object context, string channel, string message, params object[] par)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS)
+ UberLogger.Logger.Log(channel, context, LogSeverity.Error, message, par);
+ #endif
+ }
+
+ [StackTraceIgnore]
+ static public void LogErrorChannel(string channel, string message, params object[] par)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS)
+ UberLogger.Logger.Log(channel, null, LogSeverity.Error, message, par);
+ #endif
+ }
+
+
+ //Logs that will not be caught by UberLogger
+ //Useful for debugging UberLogger
+ [LogUnityOnly]
+ static public void UnityLog(object message)
+ {
+ #if ENABLE_UBERLOGGING
+ UnityEngine.Debug.Log(message);
+ #endif
+ }
+
+ [LogUnityOnly]
+ static public void UnityLogWarning(object message)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS)
+ UnityEngine.Debug.LogWarning(message);
+ #endif
+ }
+
+ [LogUnityOnly]
+ static public void UnityLogError(object message)
+ {
+ #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS)
+ UnityEngine.Debug.LogError(message);
+ #endif
+ }
+}
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs.meta
new file mode 100644
index 00000000000..57b13df8d65
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 78e53ab1366804822b3fa81f9ea350f7
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs
new file mode 100644
index 00000000000..0e0012b9b96
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs
@@ -0,0 +1,705 @@
+using UnityEngine;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System;
+using System.Reflection;
+using System.Text.RegularExpressions;
+
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+namespace UberLogger
+{
+ //Use this to exclude methods from the stack trace
+ [AttributeUsage(AttributeTargets.Method)]
+ public class StackTraceIgnore : Attribute {}
+
+ //Use this to stop UberLogger handling logs with this in the callstack.
+ [AttributeUsage(AttributeTargets.Method)]
+ public class LogUnityOnly : Attribute {}
+
+ public enum LogSeverity
+ {
+ Message,
+ Warning,
+ Error,
+ }
+
+ ///
+ /// Interface for deriving new logger backends.
+ /// Add a new logger via Logger.AddLogger()
+ ///
+ public interface ILogger
+ {
+ ///
+ /// Logging backend entry point. logInfo contains all the information about the logging request.
+ ///
+ void Log(LogInfo logInfo);
+ }
+
+ ///
+ /// Interface for implementing new log message filter methods.
+ /// Filters will be applied to log messages before they are forwarded to any loggers or Unity itself.
+ ///
+ public interface IFilter
+ {
+ ///
+ /// Apply filter to log message.
+ /// Should return true if the message is to be kept, and false if the message is to be silenced.
+ ///
+ bool ApplyFilter(string channel, UnityEngine.Object source, LogSeverity severity, object message, params object[] par);
+ }
+
+ //Information about a particular frame of a callstack
+ [System.Serializable]
+ public class LogStackFrame
+ {
+ public string MethodName;
+ public string DeclaringType;
+ public string ParameterSig;
+
+ public int LineNumber;
+ public string FileName;
+
+ string FormattedMethodNameWithFileName;
+ string FormattedMethodName;
+ string FormattedFileName;
+
+ ///
+ /// Convert from a .Net stack frame
+ ///
+ public LogStackFrame(StackFrame frame)
+ {
+ var method = frame.GetMethod();
+ MethodName = method.Name;
+ DeclaringType = method.DeclaringType.FullName;
+
+ var pars = method.GetParameters();
+ for (int c1=0; c1
+ /// Convert from a Unity stack frame (for internal Unity errors rather than excpetions)
+ ///
+ public LogStackFrame(string unityStackFrame)
+ {
+ if(Logger.ExtractInfoFromUnityStackInfo(unityStackFrame, ref DeclaringType, ref MethodName, ref FileName, ref LineNumber))
+ {
+ MakeFormattedNames();
+ }
+ else
+ {
+ FormattedMethodNameWithFileName = unityStackFrame;
+ FormattedMethodName = unityStackFrame;
+ FormattedFileName = unityStackFrame;
+ }
+ }
+
+
+ ///
+ /// Basic stack frame info when we have nothing else
+ ///
+ public LogStackFrame(string message, string filename, int lineNumber)
+ {
+ FileName = filename;
+ LineNumber = lineNumber;
+ FormattedMethodNameWithFileName = message;
+ FormattedMethodName = message;
+ FormattedFileName = message;
+ }
+
+
+
+ public string GetFormattedMethodNameWithFileName()
+ {
+ return FormattedMethodNameWithFileName;
+ }
+
+ public string GetFormattedMethodName()
+ {
+ return FormattedMethodName;
+ }
+
+ public string GetFormattedFileName()
+ {
+ return FormattedFileName;
+ }
+
+ ///
+ /// Make a nice string showing the stack information - used by the loggers
+ ///
+ void MakeFormattedNames()
+ {
+ FormattedMethodName = String.Format("{0}.{1}({2})", DeclaringType, MethodName, ParameterSig);
+
+ string filename = FileName;
+ if(!String.IsNullOrEmpty(FileName))
+ {
+ var startSubName = FileName.IndexOf("Assets", StringComparison.OrdinalIgnoreCase);
+
+ if(startSubName>0)
+ {
+ filename = FileName.Substring(startSubName);
+ }
+ }
+ FormattedFileName = String.Format("{0}:{1}", filename, LineNumber);
+
+ FormattedMethodNameWithFileName = String.Format("{0} (at {1})", FormattedMethodName, FormattedFileName);
+ }
+ }
+
+ ///
+ /// A single item of logging information
+ ///
+ [System.Serializable]
+ public class LogInfo
+ {
+ public UnityEngine.Object Source;
+ public string Channel;
+ public LogSeverity Severity;
+ public string Message;
+ public List Callstack;
+ public LogStackFrame OriginatingSourceLocation;
+ public double RelativeTimeStamp;
+ string RelativeTimeStampAsString;
+ public DateTime AbsoluteTimeStamp;
+ string AbsoluteTimeStampAsString;
+
+ public string GetRelativeTimeStampAsString()
+ {
+ return RelativeTimeStampAsString;
+ }
+
+ public string GetAbsoluteTimeStampAsString()
+ {
+ return AbsoluteTimeStampAsString;
+ }
+
+ public LogInfo(UnityEngine.Object source, string channel, LogSeverity severity, List callstack, LogStackFrame originatingSourceLocation, object message, params object[] par)
+ {
+ Source = source;
+ Channel = channel;
+ Severity = severity;
+ Message = "";
+ OriginatingSourceLocation = originatingSourceLocation;
+
+ var messageString = message as String;
+ if(messageString!=null)
+ {
+ if(par.Length>0)
+ {
+ Message = System.String.Format(messageString, par);
+ }
+ else
+ {
+ Message = messageString;
+ }
+ }
+ else
+ {
+ if(message!=null)
+ {
+ Message = message.ToString();
+ }
+ }
+
+ Callstack = callstack;
+ RelativeTimeStamp = Logger.GetRelativeTime();
+ AbsoluteTimeStamp = DateTime.UtcNow;
+ RelativeTimeStampAsString = String.Format("{0:0.0000}", RelativeTimeStamp);
+ AbsoluteTimeStampAsString = AbsoluteTimeStamp.ToString("yyyy-MM-dd HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture);
+ }
+ }
+
+ ///
+ /// The core of UberLogger - the entry point for logging information
+ ///
+ public static class Logger
+ {
+ // Controls how many historical messages to keep to pass into newly registered loggers
+ public static int MaxMessagesToKeep = 1000;
+
+ // If true, any logs sent to UberLogger will be forwarded on to the Unity logger.
+ // Useful if you want to use both systems
+ public static bool ForwardMessages = true;
+
+ // Unity uses \n for line termination in internal multi-line strings. Use this instead of
+ // System.Environment.NewLine when you want to split multi-line strings which are emitted
+ // by Unity's internal APIs.
+ public static string UnityInternalNewLine = "\n";
+
+ // Unity uses forward-slashes as directory separators, regardless of OS.
+ // Convert from this separator to System.IO.Path.DirectorySeparatorChar before passing any Unity-originated
+ // paths to APIs which expect OS-native paths.
+ public static char UnityInternalDirectorySeparator = '/';
+
+ static List Loggers = new List();
+ static LinkedList RecentMessages = new LinkedList();
+ static long StartTick;
+ static bool AlreadyLogging = false;
+ static Regex UnityMessageRegex;
+ static List Filters = new List();
+
+ static Logger()
+ {
+ // Register with Unity's logging system
+// _OR_NEWER only available from 5.3+
+#if UNITY_5 || UNITY_5_3_OR_NEWER
+ Application.logMessageReceivedThreaded += UnityLogHandler;
+#else
+ Application.RegisterLogCallback(UnityLogHandler);
+#endif
+ StartTick = DateTime.Now.Ticks;
+ UnityMessageRegex = new Regex(@"^([^\(]*)\((\d+)[^\)]*\)");
+ }
+
+ ///
+ /// Registered Unity error handler
+ ///
+ [StackTraceIgnore]
+ static void UnityLogHandler(string logString, string stackTrace, UnityEngine.LogType logType)
+ {
+ UnityLogInternal(logString, stackTrace, logType);
+ }
+
+ static public double GetRelativeTime()
+ {
+ long ticks = DateTime.Now.Ticks;
+ return TimeSpan.FromTicks(ticks - StartTick).TotalSeconds;
+ }
+
+ ///
+ /// Registers a new logger backend, which we be told every time there's a new log.
+ /// if populateWithExistingMessages is true, UberLogger will immediately pump the new logger with past messages
+ ///
+ static public void AddLogger(ILogger logger, bool populateWithExistingMessages=true)
+ {
+ lock(Loggers)
+ {
+ if(populateWithExistingMessages)
+ {
+ foreach(var oldLog in RecentMessages)
+ {
+ logger.Log(oldLog);
+ }
+ }
+
+ if(!Loggers.Contains(logger))
+ {
+ Loggers.Add(logger);
+ }
+ }
+ }
+
+ ///
+ /// Registers a new filter mechanism, which will be able to silence any future log messages
+ ///
+ static public void AddFilter(IFilter filter)
+ {
+ lock (Loggers)
+ {
+ Filters.Add(filter);
+ }
+ }
+
+ ///
+ /// Paths provided by Unity will contain forward slashes as directory separators on all OSes.
+ /// This method changes all forward slashes to OS-specific directory separators.
+ ///
+ static public string ConvertDirectorySeparatorsFromUnityToOS(string unityFileName)
+ {
+ return unityFileName.Replace(UnityInternalDirectorySeparator, System.IO.Path.DirectorySeparatorChar);
+ }
+
+ ///
+ /// Tries to extract useful information about the log from a Unity error message.
+ /// Only used when handling a Unity error message and we can't get a useful callstack
+ ///
+ static public bool ExtractInfoFromUnityMessage(string log, ref string filename, ref int lineNumber)
+ {
+ // log = "Assets/Code/Debug.cs(140,21): warning CS0618: 'some error'
+ var firstMatch = UnityMessageRegex.Match(log);
+
+ if (firstMatch.Success)
+ {
+ filename = firstMatch.Groups[1].Value;
+ lineNumber = Convert.ToInt32(firstMatch.Groups[2].Value);
+ return true;
+ }
+ return false;
+ }
+
+
+ ///
+ /// Tries to extract useful information about the log from a Unity stack trace
+ ///
+ static public bool ExtractInfoFromUnityStackInfo(string log, ref string declaringType, ref string methodName, ref string filename, ref int lineNumber)
+ {
+ // log = "DebugLoggerEditorWindow.DrawLogDetails () (at Assets/Code/Editor.cs:298)";
+ var match = System.Text.RegularExpressions.Regex.Matches(log, @"(.*)\.(.*)\s*\(.*\(at (.*):(\d+)");
+
+ if(match.Count>0)
+ {
+ declaringType = match[0].Groups[1].Value;
+ methodName = match[0].Groups[2].Value;
+ filename = match[0].Groups[3].Value;
+ lineNumber = Convert.ToInt32(match[0].Groups[4].Value);
+ return true;
+ }
+ return false;
+ }
+
+
+
+ struct IgnoredUnityMethod
+ {
+ public enum Mode { Show, ShowIfFirstIgnoredMethod, Hide };
+ public string DeclaringTypeName;
+ public string MethodName;
+ public Mode ShowHideMode;
+ }
+
+ // Example callstack when invoking Debug.LogWarning under Unity 5.5:
+ // Application.CallLogCallback
+ // DebugLogHandler.Internal_Log
+ // DebugLogHandler.LogFormat
+ // Logger.Log
+ // Debug.LogWarning
+ //
+
+
+ static IgnoredUnityMethod[] IgnoredUnityMethods = new IgnoredUnityMethod[]
+ {
+ // Internal trampoline, which invokes UberLogger's log callback
+ new IgnoredUnityMethod { DeclaringTypeName = "Application", MethodName = "CallLogCallback", ShowHideMode = IgnoredUnityMethod.Mode.Hide },
+
+ // Internal log-handling methods in Unity
+ new IgnoredUnityMethod { DeclaringTypeName = "DebugLogHandler", MethodName = null, ShowHideMode = IgnoredUnityMethod.Mode.Hide },
+
+ // There are several entry points to Logger. These are primarily called by Unity's own code, but could also be called directly by 3rd party code.
+ // These are helpful to have on the callstack in case source code is not available (they help pinpoint the exact source code location that printed the message),
+ // but remaining ignored methods can safely be hidden
+ new IgnoredUnityMethod { DeclaringTypeName = "Logger", MethodName = null, ShowHideMode = IgnoredUnityMethod.Mode.ShowIfFirstIgnoredMethod },
+
+ // Many of the Debug.* entry points result in log messages being printed
+ // These are helpful to have on the callstack in case source code is not available (they help pinpoint the exact source code location that printed the message),
+ // but remaining ignored methods can safely be hidden
+ new IgnoredUnityMethod { DeclaringTypeName = "Debug", MethodName = null, ShowHideMode = IgnoredUnityMethod.Mode.ShowIfFirstIgnoredMethod },
+
+ // Many of the Assert.* entry points result in log messages being printed
+ // These are not helpful having on the callstack
+ // These are helpful to have on the callstack in case source code is not available (they help pinpoint the exact source code location that printed the message),
+ // but remaining ignored methods can safely be hidden
+ new IgnoredUnityMethod { DeclaringTypeName = "Assert", MethodName = null, ShowHideMode = IgnoredUnityMethod.Mode.ShowIfFirstIgnoredMethod },
+ };
+
+ ///
+ /// Identify a number of Unity methods which we would like to scrub from a stacktrace
+ /// Returns true if the method is part of scrubbing
+ ///
+ static IgnoredUnityMethod.Mode ShowOrHideMethod(MethodBase method)
+ {
+ foreach (IgnoredUnityMethod ignoredUnityMethod in IgnoredUnityMethods)
+ {
+ if ((method.DeclaringType.Name == ignoredUnityMethod.DeclaringTypeName) && ((ignoredUnityMethod.MethodName == null) || (method.Name == ignoredUnityMethod.MethodName)))
+ {
+ return ignoredUnityMethod.ShowHideMode;
+ }
+ }
+
+ return IgnoredUnityMethod.Mode.Show;
+ }
+
+ ///
+ /// Converts the curent stack trace into a list of UberLogger's LogStackFrame.
+ /// Excludes any methods with the StackTraceIgnore attribute
+ /// Excludes all methods (bar the first, sometimes) from a pre-defined list of ignored Unity methods/classes
+ /// Returns false if the stack frame contains any methods flagged as LogUnityOnly
+ ///
+ [StackTraceIgnore]
+ static bool GetCallstack(ref List callstack, out LogStackFrame originatingSourceLocation)
+ {
+ callstack.Clear();
+ StackTrace stackTrace = new StackTrace(true); // get call stack
+ StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
+
+ bool encounteredIgnoredMethodPreviously = false;
+
+ originatingSourceLocation = null;
+
+ // Iterate backwards over stackframes; this enables us to show the "first" ignored Unity method if need be, but hide subsequent ones
+ for (int i = stackFrames.Length - 1; i >= 0; i--)
+ {
+ StackFrame stackFrame = stackFrames[i];
+
+ var method = stackFrame.GetMethod();
+ if(method.IsDefined(typeof(LogUnityOnly), true))
+ {
+ return true;
+ }
+ if(!method.IsDefined(typeof(StackTraceIgnore), true))
+ {
+ IgnoredUnityMethod.Mode showHideMode = ShowOrHideMethod(method);
+
+ bool setOriginatingSourceLocation = (showHideMode == IgnoredUnityMethod.Mode.Show);
+
+ if (showHideMode == IgnoredUnityMethod.Mode.ShowIfFirstIgnoredMethod)
+ {
+ // "show if first ignored" methods are part of the stack trace only if no other ignored methods have been encountered already
+ if (!encounteredIgnoredMethodPreviously)
+ {
+ encounteredIgnoredMethodPreviously = true;
+ showHideMode = IgnoredUnityMethod.Mode.Show;
+ }
+ else
+ showHideMode = IgnoredUnityMethod.Mode.Hide;
+ }
+
+ if (showHideMode == IgnoredUnityMethod.Mode.Show)
+ {
+ var logStackFrame = new LogStackFrame(stackFrame);
+
+ callstack.Add(logStackFrame);
+
+ if (setOriginatingSourceLocation)
+ originatingSourceLocation = logStackFrame;
+ }
+ }
+ }
+
+ // Callstack has been processed backwards -- correct order for presentation
+ callstack.Reverse();
+
+ return false;
+ }
+
+ ///
+ /// Converts a Unity callstack string into a list of UberLogger's LogStackFrame
+ /// Doesn't do any filtering, since this should only be dealing with internal Unity errors rather than client code
+ ///
+ static List GetCallstackFromUnityLog(string unityCallstack, out LogStackFrame originatingSourceLocation)
+ {
+ var lines = System.Text.RegularExpressions.Regex.Split(unityCallstack, UberLogger.Logger.UnityInternalNewLine);
+
+ var stack = new List();
+ foreach(var line in lines)
+ {
+ var frame = new LogStackFrame(line);
+ if(!string.IsNullOrEmpty(frame.GetFormattedMethodNameWithFileName()))
+ {
+ stack.Add(new LogStackFrame(line));
+ }
+ }
+
+ if (stack.Count > 0)
+ originatingSourceLocation = stack[0];
+ else
+ originatingSourceLocation = null;
+
+ return stack;
+ }
+
+ ///
+ /// The core entry point of all logging coming from Unity. Takes a log request, creates the call stack and pumps it to all the backends
+ ///
+ [StackTraceIgnore()]
+ static void UnityLogInternal(string unityMessage, string unityCallStack, UnityEngine.LogType logType)
+ {
+ //Make sure only one thread can do this at a time.
+ //This should mean that most backends don't have to worry about thread safety (unless they do complicated stuff)
+ lock(Loggers)
+ {
+ //Prevent nasty recursion problems
+ if(!AlreadyLogging)
+ {
+ try
+ {
+ AlreadyLogging = true;
+
+ var callstack = new List();
+ LogStackFrame originatingSourceLocation;
+ var unityOnly = GetCallstack(ref callstack, out originatingSourceLocation);
+ if(unityOnly)
+ {
+ return;
+ }
+
+ //If we have no useful callstack, fall back to parsing Unity's callstack
+ if(callstack.Count==0)
+ {
+ callstack = GetCallstackFromUnityLog(unityCallStack, out originatingSourceLocation);
+ }
+
+ LogSeverity severity;
+ switch(logType)
+ {
+ case UnityEngine.LogType.Error: severity = LogSeverity.Error; break;
+ case UnityEngine.LogType.Assert: severity = LogSeverity.Error; break;
+ case UnityEngine.LogType.Exception: severity = LogSeverity.Error; break;
+ case UnityEngine.LogType.Warning: severity = LogSeverity.Warning; break;
+ default: severity = LogSeverity.Message; break;
+ }
+
+ string filename = "";
+ int lineNumber = 0;
+
+ //Finally, parse the error message so we can get basic file and line information
+ if(ExtractInfoFromUnityMessage(unityMessage, ref filename, ref lineNumber))
+ {
+ callstack.Insert(0, new LogStackFrame(unityMessage, filename, lineNumber));
+ }
+
+ var logInfo = new LogInfo(null, "", severity, callstack, originatingSourceLocation, unityMessage);
+
+ //Add this message to our history
+ RecentMessages.AddLast(logInfo);
+
+ //Make sure our history doesn't get too big
+ TrimOldMessages();
+
+ //Delete any dead loggers and pump them with the new log
+ Loggers.RemoveAll(l=>l==null);
+ Loggers.ForEach(l=>l.Log(logInfo));
+ }
+ finally
+ {
+ AlreadyLogging = false;
+ }
+ }
+ }
+ }
+
+
+ ///
+ /// The core entry point of all logging coming from client code.
+ /// Takes a log request, creates the call stack and pumps it to all the backends
+ ///
+ [StackTraceIgnore()]
+ static public void Log(string channel, UnityEngine.Object source, LogSeverity severity, object message, params object[] par)
+ {
+ lock(Loggers)
+ {
+ if(!AlreadyLogging)
+ {
+ try
+ {
+ AlreadyLogging = true;
+
+ foreach (IFilter filter in Filters)
+ {
+ if (!filter.ApplyFilter(channel, source, severity, message, par))
+ return;
+ }
+
+ var callstack = new List();
+ LogStackFrame originatingSourceLocation;
+ var unityOnly = GetCallstack(ref callstack, out originatingSourceLocation);
+ if(unityOnly)
+ {
+ return;
+ }
+
+ var logInfo = new LogInfo(source, channel, severity, callstack, originatingSourceLocation, message, par);
+
+ //Add this message to our history
+ RecentMessages.AddLast(logInfo);
+
+ //Make sure our history doesn't get too big
+ TrimOldMessages();
+
+ //Delete any dead loggers and pump them with the new log
+ Loggers.RemoveAll(l=>l==null);
+ Loggers.ForEach(l=>l.Log(logInfo));
+
+ //If required, pump this message back into Unity
+ if(ForwardMessages)
+ {
+ ForwardToUnity(source, severity, message, par);
+ }
+ }
+ finally
+ {
+ AlreadyLogging = false;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Forwards an UberLogger log to Unity so it's visible in the built-in console
+ ///
+ [LogUnityOnly()]
+ static void ForwardToUnity(UnityEngine.Object source, LogSeverity severity, object message, params object[] par)
+ {
+ object showObject = null;
+ if(message!=null)
+ {
+ var messageAsString = message as string;
+ if(messageAsString!=null)
+ {
+ if(par.Length>0)
+ {
+ showObject = String.Format(messageAsString, par);
+ }
+ else
+ {
+ showObject = message;
+ }
+ }
+ else
+ {
+ showObject = message;
+ }
+ }
+
+ if(source==null)
+ {
+ if(severity==LogSeverity.Message) UnityEngine.Debug.Log(showObject);
+ else if(severity==LogSeverity.Warning) UnityEngine.Debug.LogWarning(showObject);
+ else if(severity==LogSeverity.Error) UnityEngine.Debug.LogError(showObject);
+ }
+ else
+ {
+ if(severity==LogSeverity.Message) UnityEngine.Debug.Log(showObject, source);
+ else if(severity==LogSeverity.Warning) UnityEngine.Debug.LogWarning(showObject, source);
+ else if(severity==LogSeverity.Error) UnityEngine.Debug.LogError(showObject, source);
+ }
+ }
+
+ ///
+ /// Finds a registered logger, if it exists
+ ///
+ static public T GetLogger() where T:class
+ {
+ foreach(var logger in Loggers)
+ {
+ if(logger is T)
+ {
+ return logger as T;
+ }
+ }
+ return null;
+ }
+
+ static void TrimOldMessages()
+ {
+ while(RecentMessages.Count > MaxMessagesToKeep)
+ {
+ RecentMessages.RemoveFirst();
+ }
+ }
+ }
+
+}
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs.meta
new file mode 100644
index 00000000000..b0adbfbc345
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: b82f8d256ff5d4555b51e2cf116640e1
+timeCreated: 1437572839
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs
new file mode 100644
index 00000000000..1f487827f91
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs
@@ -0,0 +1,493 @@
+using UnityEngine;
+using System.Collections.Generic;
+using System;
+using UberLogger;
+
+
+///
+/// The in-app console logging frontend and backend
+///
+public class UberLoggerAppWindow : MonoBehaviour, UberLogger.ILogger
+{
+ public GUISkin Skin;
+ public Texture2D SmallErrorIcon;
+ public Texture2D SmallWarningIcon;
+ public Texture2D SmallMessageIcon;
+ public Color GUIColour = new Color(1, 1, 1, 0.5f);
+
+ //If non-zero, scales the fonts
+ public int FontSize = 0;
+ public Color SizerLineColour = new Color(42.0f/255.0f, 42.0f/255.0f, 42.0f/255.0f);
+ public float SizerStartHeightRatio = 0.75f;
+
+ public void Log(LogInfo logInfo)
+ {
+ LogInfo.Add(logInfo);
+ if(logInfo.Severity==LogSeverity.Error)
+ {
+ NoErrors++;
+ }
+ else if(logInfo.Severity==LogSeverity.Warning)
+ {
+ NoWarnings++;
+ }
+ else
+ {
+ NoMessages++;
+ }
+ if(logInfo.Severity==LogSeverity.Error && PauseOnError)
+ {
+ UnityEngine.Debug.Break();
+ }
+ }
+
+ void Clear()
+ {
+ LogInfo.Clear();
+ NoWarnings = 0;
+ NoErrors = 0;
+ NoMessages = 0;
+ }
+
+ void Start()
+ {
+ DontDestroyOnLoad(gameObject);
+ UberLogger.Logger.AddLogger(this);
+ ClearSelectedMessage();
+ WindowRect = new Rect(0,0, Screen.width/2, Screen.height);
+ CurrentTopPaneHeight = Screen.height*SizerStartHeightRatio;
+ }
+
+ public bool ShowWindow { get; set; }
+ public Texture2D ButtonTexture;
+ public Texture2D ErrorButtonTexture;
+ public Vector2 ButtonPosition;
+ public Vector2 ButtonSize = new Vector2(32, 32);
+
+ ///
+ /// Shows either the activation button or the full UI
+ ///
+ public void OnGUI()
+ {
+ GUI.skin = Skin;
+ if(ShowWindow)
+ {
+ var oldGUIColor = GUI.color;
+ GUI.color = GUIColour;
+ WindowRect = new Rect(0,0, Screen.width/2, Screen.height);
+ //Set up the basic style, based on the Unity defaults
+ LogLineStyle1 = Skin.customStyles[0];
+ LogLineStyle2 = Skin.customStyles[1];
+ SelectedLogLineStyle = Skin.customStyles[2];
+
+
+
+ LogLineStyle1.fontSize = FontSize;
+ LogLineStyle2.fontSize = FontSize;
+ SelectedLogLineStyle.fontSize = FontSize;
+
+ WindowRect = GUILayout.Window(1, WindowRect, DrawWindow, "Uber Console", GUI.skin.window);
+ GUI.color = oldGUIColor;
+ }
+ else
+ {
+ DrawActivationButton();
+ }
+ }
+
+ public void DrawActivationButton()
+ {
+ Texture2D buttonTex = ButtonTexture;
+ if(NoErrors>0)
+ {
+ buttonTex = ErrorButtonTexture;
+ }
+ var buttonPos = ButtonPosition;
+ buttonPos.x*=Screen.width;
+ buttonPos.y*=Screen.height;
+ if(buttonPos.x+ButtonSize.x> Screen.width)
+ {
+ buttonPos.x = Screen.width-ButtonSize.x;
+ }
+ if(buttonPos.y+ButtonSize.y > Screen.height)
+ {
+ buttonPos.y = Screen.height-ButtonSize.y;
+ }
+ var buttonRect = new Rect(buttonPos.x, buttonPos.y, ButtonSize.x, ButtonSize.y);
+ var style = new GUIStyle();
+
+ if(GUI.Button(buttonRect, buttonTex, style))
+ {
+ ShowWindow = !ShowWindow;
+ }
+ }
+
+ ///
+ /// Draws the main window
+ ///
+ void DrawWindow(int windowID)
+ {
+ // GUI.DragWindow(new Rect(0, 0, 10000, 20));
+ var oldGUIColour = GUI.color;
+ GUI.color = GUIColour;
+ GUILayout.BeginVertical(GUILayout.Height(CurrentTopPaneHeight-GUI.skin.window.padding.top), GUILayout.MinHeight(100));
+ DrawToolbar();
+ DrawFilter();
+ DrawChannels();
+ DrawLogList();
+ GUILayout.EndVertical();
+ ResizeTopPane();
+
+ //Create a small gap so the resize handle isn't overwritten
+ GUILayout.Space(10);
+ GUILayout.BeginVertical();
+ DrawLogDetails();
+ GUILayout.EndVertical();
+ GUI.color = oldGUIColour;
+
+ DrawActivationButton();
+ }
+
+ //Some helper functions to draw buttons that are only as big as their text
+ bool ButtonClamped(string text, GUIStyle style)
+ {
+ return GUILayout.Button(text, style, GUILayout.MaxWidth(style.CalcSize(new GUIContent(text)).x));
+ }
+
+ bool ToggleClamped(bool state, string text, GUIStyle style)
+ {
+ return GUILayout.Toggle(state, text, style, GUILayout.MaxWidth(style.CalcSize(new GUIContent(text)).x));
+ }
+
+ bool ToggleClamped(bool state, GUIContent content, GUIStyle style, params GUILayoutOption[] par)
+ {
+ return GUILayout.Toggle(state, content, style, GUILayout.MaxWidth(style.CalcSize(content).x));
+ }
+
+ void LabelClamped(string text, GUIStyle style)
+ {
+ GUILayout.Label(text, style, GUILayout.MaxWidth(style.CalcSize(new GUIContent(text)).x));
+ }
+
+ ///
+ /// Draws the thin, Unity-style toolbar showing error counts and toggle buttons
+ ///
+ void DrawToolbar()
+ {
+ var toolbarStyle = GUI.skin.customStyles[3];
+ GUILayout.BeginHorizontal();
+ if(ButtonClamped("Clear", toolbarStyle))
+ {
+ Clear();
+ }
+ // PauseOnError = ToggleClamped(PauseOnError, "Pause On Error", toolbarStyle);
+ ShowTimes = ToggleClamped(ShowTimes, "Show Times", toolbarStyle);
+
+ var buttonSize = toolbarStyle.CalcSize(new GUIContent("T")).y;
+ GUILayout.FlexibleSpace();
+
+ var showErrors = ToggleClamped(ShowErrors, new GUIContent(NoErrors.ToString(), SmallErrorIcon), toolbarStyle, GUILayout.Height(buttonSize));
+ var showWarnings = ToggleClamped(ShowWarnings, new GUIContent(NoWarnings.ToString(), SmallWarningIcon), toolbarStyle, GUILayout.Height(buttonSize));
+ var showMessages = ToggleClamped(ShowMessages, new GUIContent(NoMessages.ToString(), SmallMessageIcon), toolbarStyle, GUILayout.Height(buttonSize));
+ //If the errors/warning to show has changed, clear the selected message
+ if(showErrors!=ShowErrors || showWarnings!=ShowWarnings || showMessages!=ShowMessages)
+ {
+ ClearSelectedMessage();
+ }
+ ShowWarnings = showWarnings;
+ ShowMessages = showMessages;
+ ShowErrors = showErrors;
+ GUILayout.EndHorizontal();
+ }
+
+ ///
+ /// Draws the channel selector
+ ///
+ void DrawChannels()
+ {
+ var channels = GetChannels();
+ int currentChannelIndex = 0;
+ for(int c1=0; c1
+ /// Based on filter and channel selections, should this log be shown?
+ ///
+ bool ShouldShowLog(System.Text.RegularExpressions.Regex regex, LogInfo log)
+ {
+ if(log.Channel==CurrentChannel || CurrentChannel=="All" || (CurrentChannel=="No Channel" && String.IsNullOrEmpty(log.Channel)))
+ {
+ if((log.Severity==LogSeverity.Message && ShowMessages)
+ || (log.Severity==LogSeverity.Warning && ShowWarnings)
+ || (log.Severity==LogSeverity.Error && ShowErrors))
+ {
+ if(regex==null || regex.IsMatch(log.Message))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// Draws the main log panel
+ ///
+ public void DrawLogList()
+ {
+ var oldColor = GUI.backgroundColor;
+
+ LogListScrollPosition = GUILayout.BeginScrollView(LogListScrollPosition);
+ var maxLogPanelHeight = WindowRect.height;
+
+ float buttonY = 0;
+ float buttonHeight = LogLineStyle1.CalcSize(new GUIContent("Test")).y;
+
+ System.Text.RegularExpressions.Regex filterRegex = null;
+
+ if(!String.IsNullOrEmpty(FilterRegex))
+ {
+ filterRegex = new System.Text.RegularExpressions.Regex(FilterRegex);
+ }
+
+ int drawnButtons = 0;
+ var logLineStyle = LogLineStyle1;
+ for(int c1=0; c1LogListScrollPosition.y && buttonY
+ /// The bottom of the panel - details of the selected log
+ ///
+ public void DrawLogDetails()
+ {
+ var oldColor = GUI.backgroundColor;
+ SelectedMessage = Mathf.Clamp(SelectedMessage, 0, LogInfo.Count);
+ if(LogInfo.Count>0 && SelectedMessage>=0)
+ {
+ LogDetailsScrollPosition = GUILayout.BeginScrollView(LogDetailsScrollPosition);
+ var log = LogInfo[SelectedMessage];
+ var logLineStyle = LogLineStyle1;
+ for(int c1=0; c1 GetChannels()
+ {
+ var categories = new HashSet();
+ foreach(var logInfo in LogInfo)
+ {
+ if(!String.IsNullOrEmpty(logInfo.Channel) && !categories.Contains(logInfo.Channel))
+ {
+ categories.Add(logInfo.Channel);
+ }
+ }
+
+ var channelList = new List();
+ channelList.Add("All");
+ channelList.Add("No Channel");
+ channelList.AddRange(categories);
+ return channelList;
+ }
+
+ bool Resizing = false;
+ private void ResizeTopPane()
+ {
+ //Set up the resize collision rect
+ // float offset = GUI.skin.window.border.bottom;
+ float offset = 0;
+ var resizerRect = new Rect(0, CurrentTopPaneHeight+offset, WindowRect.width, 5f);
+
+ var oldColor = GUI.color;
+ GUI.color = SizerLineColour;
+ GUI.DrawTexture(resizerRect, Texture2D.whiteTexture);
+ GUI.color = oldColor;
+
+ if( Event.current.type == EventType.MouseDown && resizerRect.Contains(Event.current.mousePosition))
+ {
+ Resizing = true;
+ }
+
+ if(Resizing)
+ {
+ CurrentTopPaneHeight = Event.current.mousePosition.y;
+ }
+
+ if(Event.current.type == EventType.MouseUp)
+ {
+ Resizing = false;
+ }
+
+
+ CurrentTopPaneHeight = Mathf.Clamp(CurrentTopPaneHeight, 100, WindowRect.height-100);
+ }
+
+ void ClearSelectedMessage()
+ {
+ SelectedMessage = -1;
+ SelectedCallstackFrame = -1;
+ }
+
+ Vector2 LogListScrollPosition;
+ Vector2 LogDetailsScrollPosition;
+
+
+ bool ShowTimes = true;
+ float CurrentTopPaneHeight;
+ int SelectedMessage = -1;
+
+ double LastMessageClickTime = 0;
+
+ List LogInfo = new List();
+ bool PauseOnError = false;
+ int NoErrors;
+ int NoWarnings;
+ int NoMessages;
+ Rect WindowRect = new Rect(0,0, 100, 100);
+
+
+ GUIStyle LogLineStyle1;
+ GUIStyle LogLineStyle2;
+ GUIStyle SelectedLogLineStyle;
+ string CurrentChannel=null;
+ string FilterRegex = "";
+
+ bool ShowErrors = true;
+ bool ShowWarnings = true;
+ bool ShowMessages = true;
+ int SelectedCallstackFrame = 0;
+}
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs.meta
new file mode 100644
index 00000000000..c2d05c855e2
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs.meta
@@ -0,0 +1,19 @@
+fileFormatVersion: 2
+guid: a0e07a4dd7148412e9649a25c8abcb11
+timeCreated: 1437728182
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences:
+ - Skin: {fileID: 11400000, guid: 7018997e7c4ba41d8aa5a2338b82d57f, type: 2}
+ - ButtonTexture: {fileID: 2800000, guid: 2ae9477f7f0774b808aef406d3bf2d3c, type: 3}
+ - ErrorButtonTexture: {fileID: 2800000, guid: f752d027f2368431c924c0306e747c4b,
+ type: 3}
+ - SmallErrorIcon: {fileID: 2800000, guid: f5e296e323cd64d619488c517c4692af, type: 3}
+ - SmallWarningIcon: {fileID: 2800000, guid: ecc8f3c040a254019afd50c8bc285b48, type: 3}
+ - SmallMessageIcon: {fileID: 2800000, guid: fa976bac27b1e440eb0d8bd71c1caac3, type: 3}
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs
new file mode 100644
index 00000000000..b357a80a00f
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs
@@ -0,0 +1,165 @@
+#if UNITY_EDITOR
+using UnityEngine;
+using System.Collections.Generic;
+using System;
+using UnityEditor;
+using UberLogger;
+
+
+///
+/// The basic editor logger backend
+/// This is seperate from the editor frontend, so we can have multiple frontends active if we wish,
+/// and so that we catch errors even without the frontend active.
+/// Derived from ScriptableObject so it persists across play sessions.
+///
+[System.Serializable]
+public class UberLoggerEditor : ScriptableObject, UberLogger.ILogger
+{
+ List LogInfo = new List();
+ HashSet Channels = new HashSet();
+
+ public bool PauseOnError = false;
+ public bool ClearOnPlay = true;
+ public bool WasPlaying = false;
+ public int NoErrors;
+ public int NoWarnings;
+ public int NoMessages;
+
+ static public UberLoggerEditor Create()
+ {
+ var editorDebug = ScriptableObject.FindObjectOfType();
+
+ if(editorDebug==null)
+ {
+ editorDebug = ScriptableObject.CreateInstance();
+ }
+
+ editorDebug.NoErrors = 0;
+ editorDebug.NoWarnings = 0;
+ editorDebug.NoMessages = 0;
+
+ return editorDebug;
+ }
+
+ public void OnEnable()
+ {
+ EditorApplication.playModeStateChanged += OnPlaymodeStateChanged;
+
+ //Make this scriptable object persist between Play sessions
+ hideFlags = HideFlags.HideAndDontSave;
+ }
+
+ ///
+ /// If we're about to start playing and 'ClearOnPlay' is set, clear the current logs
+ ///
+ public void ProcessOnStartClear()
+ {
+ if(!WasPlaying && EditorApplication.isPlayingOrWillChangePlaymode)
+ {
+ if(ClearOnPlay)
+ {
+ Clear();
+ }
+ }
+ WasPlaying = EditorApplication.isPlayingOrWillChangePlaymode;
+ }
+
+ void OnPlaymodeStateChanged(PlayModeStateChange obj)
+ {
+ ProcessOnStartClear();
+ }
+
+
+ ///
+ /// Interface for deriving new logger backends.
+ /// Add a new logger via Logger.AddLogger()
+ ///
+ public interface ILoggerWindow
+ {
+ ///
+ /// Logging backend entry point. logInfo contains all the information about the logging request.
+ ///
+ void OnLogChange(LogInfo logInfo);
+ }
+ List Windows = new List();
+
+ public void AddWindow(ILoggerWindow window)
+ {
+ if(!Windows.Contains(window))
+ {
+ Windows.Add(window);
+ }
+ }
+
+ public void Log(LogInfo logInfo)
+ {
+ lock(this)
+ {
+ if(!String.IsNullOrEmpty(logInfo.Channel) && !Channels.Contains(logInfo.Channel))
+ {
+ Channels.Add(logInfo.Channel);
+ }
+
+ LogInfo.Add(logInfo);
+ }
+
+ if(logInfo.Severity==LogSeverity.Error)
+ {
+ NoErrors++;
+ }
+ else if(logInfo.Severity==LogSeverity.Warning)
+ {
+ NoWarnings++;
+ }
+ else
+ {
+ NoMessages++;
+ }
+
+ foreach(var window in Windows)
+ {
+ window.OnLogChange(logInfo);
+ }
+
+ if(logInfo.Severity==LogSeverity.Error && PauseOnError)
+ {
+ UnityEngine.Debug.Break();
+ }
+ }
+
+ public void Clear()
+ {
+ lock(this)
+ {
+ LogInfo.Clear();
+ Channels.Clear();
+ NoWarnings = 0;
+ NoErrors = 0;
+ NoMessages = 0;
+
+ foreach(var window in Windows)
+ {
+ window.OnLogChange(null);
+ }
+ }
+ }
+
+ public List CopyLogInfo()
+ {
+ lock(this)
+ {
+ return new List(LogInfo);
+ }
+ }
+
+ public HashSet CopyChannels()
+ {
+ lock(this)
+ {
+ return new HashSet(Channels);
+ }
+ }
+
+}
+
+#endif
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs.meta
new file mode 100644
index 00000000000..2eecee36315
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 171c7ffd53d8144faa6b0cd0cb750235
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs
new file mode 100644
index 00000000000..85ec10e72e2
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs
@@ -0,0 +1,42 @@
+using UberLogger;
+using System.IO;
+using UnityEngine;
+
+///
+/// A basic file logger backend
+///
+public class UberLoggerFile : UberLogger.ILogger
+{
+ private StreamWriter LogFileWriter;
+ private bool IncludeCallStacks;
+
+ ///
+ /// Constructor. Make sure to add it to UberLogger via Logger.AddLogger();
+ /// filename is relative to Application.persistentDataPath
+ /// if includeCallStacks is true it will dump out the full callstack for all logs, at the expense of big log files.
+ ///
+ public UberLoggerFile(string filename, bool includeCallStacks = true)
+ {
+ IncludeCallStacks = includeCallStacks;
+ var fileLogPath = System.IO.Path.Combine(Application.persistentDataPath, filename);
+ Debug.Log("Initialising file logging to " + fileLogPath);
+ LogFileWriter = new StreamWriter(fileLogPath, false);
+ LogFileWriter.AutoFlush = true;
+ }
+
+ public void Log(LogInfo logInfo)
+ {
+ lock(this)
+ {
+ LogFileWriter.WriteLine(logInfo.Message);
+ if(IncludeCallStacks && logInfo.Callstack.Count>0)
+ {
+ foreach(var frame in logInfo.Callstack)
+ {
+ LogFileWriter.WriteLine(frame.GetFormattedMethodNameWithFileName());
+ }
+ LogFileWriter.WriteLine();
+ }
+ }
+ }
+}
diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs.meta
new file mode 100644
index 00000000000..f4b406b3ddd
--- /dev/null
+++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: b5a6acaaa5d694ea0a4f19ef3235bbeb
+timeCreated: 1437774614
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/nekoyume/Assets/_Scripts/UI/Widget/Base/Widget.cs b/nekoyume/Assets/_Scripts/UI/Widget/Base/Widget.cs
index 03750002f99..d2890239f37 100644
--- a/nekoyume/Assets/_Scripts/UI/Widget/Base/Widget.cs
+++ b/nekoyume/Assets/_Scripts/UI/Widget/Base/Widget.cs
@@ -269,7 +269,7 @@ public void Show(System.Action onClose, bool ignoreShowAnimation = false)
public virtual void Show(bool ignoreShowAnimation = false)
{
- NcDebug.Log($"[Widget][{GetType().Name}] Show({ignoreShowAnimation}) invoked.");
+ NcDebug.Log($"[Widget][{GetType().Name}] Show({ignoreShowAnimation}) invoked.", channel: "Widget");
if (_coClose is not null)
{
StopCoroutine(_coClose);
@@ -308,7 +308,7 @@ public void ForceClose(bool ignoreCloseAnimation = false)
public virtual void Close(bool ignoreCloseAnimation = false)
{
- NcDebug.Log($"[Widget][{GetType().Name}] Close({ignoreCloseAnimation}) invoked.");
+ NcDebug.Log($"[Widget][{GetType().Name}] Close({ignoreCloseAnimation}) invoked.", channel: "Widget");
if (WidgetStack.Count > 0 &&
WidgetStack.Peek() == gameObject)
{