public static void LogException(this ManualLogSource logger, Exception exception, UnityEngineObject context, string message = null) { var msgBuilder = Common.RequestStringBuilder(); try { var currentException = exception; var level = 0; void StartLine() { for (var i = 0; i < level; i++) { msgBuilder.Append("> "); } } while (currentException != null) { StartLine(); msgBuilder.Append(currentException.GetPrettyTypeFullName()).Append(": "); if (!string.IsNullOrEmpty(message)) { msgBuilder.Append(message).Append(": "); } msgBuilder.Append(currentException.Message); if (level == 0) { logger.LogWarning(msgBuilder.ToString()); } msgBuilder.AppendLine(":"); if (level == 0 && context) { StartLine(); msgBuilder.Append(" Context: ").Append(context).Append(" (") .Append(context.GetPrettyTypeFullName()).AppendLine(")"); } var stackTrace = new StackTrace(currentException, true); var frames = stackTrace.GetFrames(); if (frames != null) { foreach (var frame in frames) { StartLine(); msgBuilder.Append(" at ").Append(frame.GetMethod()); var filename = frame.GetFileName(); if (!string.IsNullOrEmpty(filename)) { msgBuilder.Append(" in ").Append(frame.GetFileName()); var line = frame.GetFileLineNumber(); if (line > 1) { msgBuilder.Append(": line").Append(line); } } msgBuilder.AppendLine(); } } level++; currentException = currentException.InnerException; if (currentException == null) { break; } StartLine(); msgBuilder.AppendLine("Inner exception:"); } Logger.LogDebug(msgBuilder.ToString()); } finally { Common.ReleaseStringBuilder(msgBuilder); } }