Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Feedback Is it possible to expose Format function that unity use inside `Debug.LogFormat` ?

Discussion in 'Scripting' started by Thaina, Dec 21, 2021.

  1. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,157
    The format function unity used internally for `Debug.LogFormat` is very convenient to log the object into string that we are very familiar with and easy to understand. However sometime we want to debug a very complicate object or collection of objects and so ability to mix our custom string layout with unity object format would be convenient

    So I would like to propose api `string Debug.Format(string format,object obj)` that would return the same string as it would be logged in `Debug.LogFormat` but not really log that string yet and then we can use that string to log or send to analytics later

    for example

    Code (CSharp):
    1. string line0 = Debug.Format(obj0);
    2. string line1 = Debug.Format(obj1);
    3. string line2 = Debug.Format(obj2);
    4.  
    5. Debug.Log("main : " + line0 + "\n sub0 : " + line1 + "\n sub1 : " + line2);
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    I'm not entirely clear on what your proposal would benefit in terms of usability, but a few things to be aware of.

    One, every object in C# has a .ToString() method, and I'm fairly sure this is all Debug.LogFormat uses to format objects into strings. I think this is what your proposed .Format function would be, so you can just:
    Code (csharp):
    1. string line0 = obj0.ToString();
    Two, you can use string.Format(). This is almost certainly what LogFormat uses internally and behaves the same way.
    Code (csharp):
    1. string allLines = string.Format("main : {0}", obj0);
    Three, you can use string interpolation. It's a builtin feature of C# in more recent versions (which all the modern Unity versions use) and it's better than string.Format in both code clarity and memory efficiency. Just need to put a $ in front of your string and you can directly inject values into a string:
    Code (csharp):
    1. string allLines = $"main : {obj0}\n sub0 : {obj1}\n sub1 {obj2}";
    String interpolation is honestly so nice and convenient that Debug.LogFormat is almost unheard of in codebases these days.

    Finally, string concatenation (combining them with plus signs) is ABSURDLY inefficient and you should break the habit of using it entirely, in favor of string interpolation - especially in code that runs in Update. Every single plus sign builds a new string, and then this is discarded as soon as it gets to the next plus sign. So in your example, something like 7 or 8 strings worth of GC allocation is created. This is the sort of thing that causes stuttering in games.
     
    Last edited: Dec 21, 2021
    exiguous likes this.
  3. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,157
    I have made this request because, if I remember it right, there are some object types in unity that the `Debug.Log` did not print out the same string as `tostring()` and that's the reason there was more safe to use `Debug.LogFormat` and unity would format those variable with their internal formatter

    And so I want to utilize that same internal formatter as unity debug class
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    You're probably thinking of Vector3, which when converted to string shows only one decimal of precision, while outputting its float components gives you the full precision of the float. That's nothing to do with Debug.Log though; it's just what Vector3.ToString() outputs, and ToString() is what all of these things are based on.