Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by cregox · Apr 10, 2012 at 10:00 PM · editordebugconsole

DebugConsole console clicking

This amazing script will allow us to have a console anywhere outside the Editor. Freaking awesome!

But while in the editor, for all messages it does bring, we can't any longer click on them to bring the file and line, like it still happens on unplanned errors and warnings. That's because instead of using print or debug.log we use it:

 DebugConsole.Log("Hello World");

So the Console will now bring something like this:

 Hello World
 UnityEngine.Debug:Log(Object)
 DebugConsole:Log(String) (at Assets/scripts/Plugin/debugging/DebugConsole.cs:294)
 Test:Start() (at Assets/Test.cs:7)

And, when we click on it, it will open DebugConsole.cs at line 294 instead of Test at line 7, as anyone would wish.

Is there some way to "fix" this?

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image freshingrain · Jun 15, 2015 at 01:32 PM 0
Share

If you want to view logs on devices, I recommend you use this plugin: https://www.assetstore.unity3d.com/#!/content/44935

You can still use Debug.Log(), while you have a debug console on devices.

Screenshot:

alt text

5 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Inhuman Games · Nov 24, 2013 at 06:14 PM

Our editor console replacement asset has this feature, see the second feature discussed in this video:

Console Enhanced

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image cregox · Nov 24, 2013 at 06:23 PM 0
Share

It looks great. And it also looks like it would work with DebugConsole. But, just to make sure... Will it?

avatar image Inhuman Games · Nov 24, 2013 at 07:01 PM 0
Share

If I understand your issue correctly, when you click on a log entry in Unity's console window, you are taken to DebugConsole.cs ins$$anonymous$$d of the true source of the log - in your case, the call to DebugConsole.Log()? If I got you right, then yes, our replacement console will take you to the correct source of the log, just as you saw in the video. You just need to tell our console what wrapper function(s) to ignore. In your case, I think it's DebugConsole.Log, Add$$anonymous$$essage and maybe one or two other functions.

avatar image cregox · Nov 25, 2013 at 11:02 AM 0
Share

Awesome. So, your actual answer to my problem basically is "Don't know if Unity's console do or ever will support that. But you can roll your own panel and make it work. Here's ours implementation.", right? :D

avatar image Inhuman Games · Nov 25, 2013 at 11:34 AM 1
Share

Yeah, that's right. I don't think Unity's console currently supports exactly what you are asking for. It does support something close though. You can hook into calls to UnityEngine.Debug.Log() using Application.RegisterLogCallback(). You'd want to register DebugConsole.Log() or something that calls it. Then, in your app, you'd replace all your calls to DebugConsole.Log() with UnityEngine.Debug.Log(). Perhaps that will work for you. For me, this way did not work well with my project, which is part of why I rolled my own panel.

avatar image DannyLZS · Nov 25, 2013 at 12:30 PM 0
Share

Wrong, check out the comment on my answer

avatar image
2

Answer by devluz · Sep 11, 2014 at 05:54 AM

I got annoyed about this problem as well today. I found an internal method to allow jumps in any file and line in the standard unity log:

 string file = "Asset\MyTestFile.cs";
 int line = 100;
 
 mUnityLog = typeof(UnityEngine.Debug).GetMethod("LogPlayerBuildError", BindingFlags.NonPublic | BindingFlags.Static);
 mUnityLog.Invoke(null, new object[] { message.ToString(), file, line, 0 });

Related problems: only works in the editor and it will be shown as Error like the Debug.LogError method.

I use it like this in my logger:

 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
 using System.Reflection;
 using System.Runtime.CompilerServices;
 using System.Text;
 using UnityEngine;
 
 public class TLog
 {
     public static readonly string TAG_ERROR = "error";
     public static readonly string TAG_WARNING = "warning";
     public static readonly string TAG_INFO = "info";
 
     public static readonly bool doLog = true;
     public static readonly bool doFilter = true;
     public static readonly String[] visibleTags = new String[] { TAG_ERROR, TAG_WARNING, TAG_INFO};
 
     public static readonly bool showParameters = true;
 
 
     private static MethodBase mUnityLog;
 
     static TLog()
     {
         mUnityLog = typeof(UnityEngine.Debug).GetMethod("LogPlayerBuildError", BindingFlags.NonPublic | BindingFlags.Static);
                 
     }
 
 
     public static void Log(string msg, params string[] tags)
     {
         LogArray(msg, tags);
     }
     public static void LogArray(string msg, string[] tags)
     {
         //quit if no log is required
         if (doLog == false)
             return;
         //filter needed? if yes -> check if one of the tags is in our filter list
         if (doFilter && visibleTags.Intersect(tags).Any() == false)
             return;
         if (mUnityLog == null)
         {
             //this happens outside of the editor mode
             //log the normal way and ignore everything that isn't an error
             if (tags != null && tags.Contains(TAG_ERROR))
             {
                 UnityEngine.Debug.LogError(msg);
             }
             return;
         }
 
         StringBuilder message = new StringBuilder();
 
         StackTrace stackTrace = new StackTrace(true);
         StackFrame[] stackFrames = stackTrace.GetFrames();
         int line = 0;
         string file = "";
         int col = 0;
 
         //no tags? just print plain
         if (tags == null || tags.Length == 0)
         {
             message.Append(msg);
         }
         else
         {
             //print tags
             message.Append("<color=green><size=7>");
             for (int k = 0; k < tags.Length; k++)
             {
                 message.Append(tags[k]);
                 if(k + 1 < tags.Length)
                     message.Append("|");
             }
             message.Append("</size></color>");
 
             //print the color tag dependend
             if (tags.Contains(TAG_ERROR))
             {
                 message.Append("<color=red>");
                 message.Append(msg);
                 message.Append("</color>");
             }
             else if (tags.Contains(TAG_WARNING))
             {
                 message.Append("<b><color=yellow>");
                 message.Append(msg);
                 message.Append("</color></b>");
             }
             else
             {
                 message.Append(msg);
             }
         }
         message.Append("\n");
 
         bool foundStart = false;
         //look for the first method call in the stack that isn't from this class.
         //save the first one to jump into it later and add all further lines to the log
         for (int i = 0; i < stackFrames.Length; i++)
         {
             MethodBase mb = stackFrames[i].GetMethod();
             if (foundStart == false && mb.DeclaringType != typeof(TLog))
             {
                 file = FormatFileName(stackFrames[i].GetFileName());
                 line = stackFrames[i].GetFileLineNumber();
                 col = stackFrames[i].GetFileColumnNumber();
                 foundStart = true;
             }
                 
                 
             if(foundStart)
             {
                 message.Append("<color=blue>");
                 message.Append(mb.DeclaringType.FullName);
                 message.Append(":");
                 message.Append(mb.Name);
                 message.Append("(");
                 if (showParameters)
                 {
                     ParameterInfo[] paramters = mb.GetParameters();
                     for (int k = 0; k < paramters.Length; k++)
                     {
                         message.Append(paramters[k].ParameterType.Name);
                         if (k + 1 < paramters.Length)
                             message.Append(", ");
                     }
                 }
                     
                 message.Append(")");
                 message.Append("</color>");
 
 
                 message.Append(" (at ");
                 //the first stack message is found now we add the other stack frames to the log
                 message.Append(FormatFileName(stackFrames[i].GetFileName()));
                 message.Append(":");
                 message.Append(stackFrames[i].GetFileLineNumber());
                 message.Append(")");
                 message.Append("\n");
             }
         }
         mUnityLog.Invoke(null, new object[] { message.ToString(), file, line, col });
     }
 
     private static string FormatFileName(String file)
     {
         //remove everything of the absolute path that is before the Assetfolder
         //using the destination of the Assetfolder to get the right length (not ideal)
         return file.Remove(0, Application.dataPath.Length - "Assets".Length);
     }
 }

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image kreso · Dec 09, 2017 at 07:18 AM 0
Share

I logged in so I can say - Wow. This code actually parses stackTrace, and instructs Unity's built in console which file/line to open. No DLL necessary, no custom console window necessary. $$anonymous$$udos to you sir. Not sure how this will go for my project (since it shows up as error only), but it's nice to see it possible even though hacky ;-)

avatar image
1

Answer by ianjosephfischer · Jan 12, 2013 at 09:28 AM

I've been working on something like this. I can open the external editor at the correct spot, but I am searching for something that will let me set the console double click goto position.

Here is my code for that which gets called by my internal debugging system. If you found out how let me know or if any one else has any tips.

     private static void OpenFile()
     {
         Assembly assembly = Assembly.GetAssembly(typeof(UnityEditor.SceneView));
         System.Type type = assembly.GetType("UnityEditorInternal.InternalEditorUtility");
         if(type == null)
         {
             Debug.Log("Failed to open source file");
             return;
         }

         string[] stackFrames = System.Environment.StackTrace.Split(new char[] {'\n' });
         string callingFrame = stackFrames[4];

         string[] splitLog = callingFrame.Split(':');
         char drive = splitLog[0][splitLog[0].Length-1];
         string filePath = splitLog[1];
         splitLog[2] = StringManipulation.TrimStartString(
             splitLog[2], "line ");
         int lineNumber = int.Parse(StringManipulation.GetBeforeNextChar(
             splitLog[2], '\n'));


         string fullDrive = drive + ":" + filePath;

         //Debug.Log(@fullDrive + " line #" + lineNumber );
         MethodInfo method = type.GetMethod("OpenFileAtLineExternal");
         method.Invoke(method, new object[] { @fullDrive, lineNumber });
     }

(Here is that "StringManipulation" method I use which I am sure you could have figured out if you are reading this question.

 public static string GetBeforeNextChar(string sourceString, char trimed)
 {
     string[] splits = sourceString.Split(trimed);
     return splits[0];
 }
 public static string TrimStartCharacter(string sourceString, char trimed)
 {
     sourceString = sourceString.TrimStart(trimed);
     return sourceString;
 }
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image cregox · Jan 14, 2013 at 11:25 AM 0
Share

So you can simulate the double click with scripting only. That's quite interesting, but maybe the solution to the question wouldn't even require this much scripting. Either way, I'm still clueless. :P

avatar image Jake-L · Jun 20, 2013 at 08:43 PM 0
Share

You don't need Reflection to call InternalEditorUtility.OpenFileAtLineExternal, just call it directly...

avatar image ianjosephfischer · Jun 20, 2013 at 08:46 PM 0
Share

It was private back then, they must have changed it.

avatar image cregox · Jun 21, 2013 at 04:51 PM 1
Share

What I meant in my previous comment is that I'm still clueless on how to use your solution... By the way, if by "set the console double click goto position" you mean context, I don't know when this was implemented but it's there already. Take a look.

avatar image
0

Answer by DannyLZS · Nov 25, 2013 at 11:20 AM

Why don't you just override the normal Debug.Log and make it do both you're console log and the normal unity one at the same time. Then stick it in a DLL so that it goes to the correct line

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image cregox · Nov 25, 2013 at 11:26 AM 0
Share

Yeah... I don't think it's as simple as you imply here. Debug is a sealed class so it can't be overridden, to begin with. And DLL? Since when "sticking a DLL" is something simple? I don't even know what you mean there. The DebugConsole is mostly trying to do what you said already. $$anonymous$$aybe it would help if you could elaborate a lot more here.

avatar image DannyLZS · Nov 25, 2013 at 12:27 PM 0
Share

I think you will find if you do this ...

 public static class Debug
 {
         public static void Log(object message)
     {
               .... code here
         }
 }

You will in all intents and purposes be over-writing Debug.Log

Whenever you call Debug.Log from now on it will actually point to your own class.

Now if you log something and double click it it will go to this NEW class you have made. BUT ... if you build it out as a DLL it will bypass this and go to the correct file and line who sent it to this guy.

Just trying to point you in the right direction

avatar image cregox · Nov 25, 2013 at 12:40 PM 0
Share

Ok, so we can roll our own "Debug" implementation (which DebugConsole already do). The new bits you bring here are "do it with the same name, so you have the risk of getting duplicated definition if you ever use same namespaces" (which, again, is precisely what DebugConsole do, except without namespace issues) and "build it out as a DLL", which I got no clue how to do or why it would be helpful. If "build a DLL" is the right direction, I'd like to see more pointers, please! (Other than http://docs.unity3d.com/Documentation/$$anonymous$$anual/UsingDLL.html )

avatar image codestage · Jan 19, 2014 at 05:58 PM 0
Share

Why override? We have Application.LogCallback() (http://docs.unity3d.com/Documentation/ScriptReference/Application.LogCallback.html)!

avatar image
0

Answer by iwHiteRabbiT · Mar 12, 2015 at 01:00 PM

I had the same problem, then I just made a simple DLL (with Mono) with this unique static class :

 using System;
 using UnityEngine;
 
 namespace [MyNameSpace]
 {
     public static class MyDebug
     {
         public static string TAG = "MyUnity";
 
         public static string CurrentClass
         {
             get {
                 var st = new System.Diagnostics.StackTrace();
 
                 var index = Mathf.Min(st.FrameCount - 1, 2);
 
                 if (index < 0)
                     return "{NoClass}";
 
                 return "{" + st.GetFrame(index).GetMethod().DeclaringType.Name + "}";
             }
         }
 
         public static void Log(string Msg)
         {
             if (Debug.isDebugBuild)
                 Debug.Log(string.Format("{0}:{1}:{2}", TAG, CurrentClass, Msg));
         }
 
         public static void LogWarning(string Msg)
         {
             Debug.LogWarning(string.Format("{0}:{1}:{2}", TAG, CurrentClass, Msg));
         }
 
         public static void LogError(string Msg)
         {
             Debug.LogError(string.Format("{0}:{1}:{2}", TAG, CurrentClass, Msg));
         }
     }
 }


Then, back in Unity you just have to past your plugin.dll in your asset folder and in the code side:

 using [MyNameSpace];
 
 // In method
 MyDebug.Log("My message log");

In the console you will see: "MyUnity:{ClassName}:My message log" And if you dbl click on it you will open the ClassName file at the right line!

It works like a charm!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

14 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Double click on Console Window 1 Answer

Editor Console window message no longer wraps... Help? Please? 1 Answer

No line numbers in stack trace 1 Answer

How to clear a specific error/warning in the console output window? 0 Answers

Input Button is not setup Error 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges