Search Unity

Extending Debug.Log to display the name of the variable automatically

Discussion in 'Scripting' started by FeastSC2, Oct 18, 2019.

  1. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    I frequently want to know what's the name of variable and its value:

    Code (CSharp):
    1. Debug.Log("variableName: " + variableName);
    This might output "variableName: true"

    I would like to only have to write something like this instead, as it is faster and if the name of the variable changes it will still display the correct name so I won't have to change this debug line:

    Code (CSharp):
    1. DebugExt.Log(variableName);
    The output would be the same "variableName: true"


    How can I achieve this? I think it's related to reflection but I don't know the subject too well.
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    It would be really tricky to figure out a generic function to do that, because the instant the variable goes into that function, it has a different name. If it's a data type (int, float, string, Vector3) it'll actually be copied and won't even refer to the same object, while if it's a reference type (most objects), it could have multiple references in memory pointing to it, and almost certainly won't know which one you've passed into it, if it even has access to the one you've passed into it at all.

    You can simplify the syntax slightly with string interpolation like this:
    Code (csharp):
    1. Debug.Log($"variableName: {variableName});
    And you could write a Visual Studio extension to output that more easily, but I don't think anything shorter than that would be possible.
     
    MoogleHermit and Monki3 like this.
  3. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,330
    If you want to log the name and current value of a member variable, it can be done using reflection and extension methods. Here's the implementation:

    Code (CSharp):
    1. using System.Reflection;
    2. using JetBrains.Annotations;
    3. using UnityEngine;
    4.  
    5. public static class LogValueExtension
    6. {
    7.     public static void LogValue([NotNull]this object fieldOwner, string fieldName)
    8.     {
    9.         var field = fieldOwner.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    10.         var fieldValue = field.GetValue(fieldOwner);
    11.  
    12.         Debug.Log(fieldName + ": "+(fieldValue == null ? "null" : fieldValue.ToString()));
    13.     }
    14. }
    And here's how you would use it:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class LogValueTest : MonoBehaviour
    4. {
    5.     public int value = 0;
    6.  
    7.     public void OnEnable()
    8.     {
    9.         this.LogValue(nameof(value));
    10.         value++;
    11.         this.LogValue(nameof(value));
    12.         value++;
    13.         this.LogValue(nameof(value));
    14.     }
    15. }
    16.  
    This simple implementation only supports fields, but it could easily be expanded to also support properties.
     
    Last edited: Nov 29, 2019
    douncoding likes this.
  4. LuLusg

    LuLusg

    Joined:
    Oct 16, 2018
    Posts:
    2