Home > database >  Unity function stepping out of execution and debugging when I search for gameobject
Unity function stepping out of execution and debugging when I search for gameobject

Time:10-12

Ok, so this is something that never happened to me. I'm working on a audio-based game, and need things to happen whenever a given midi note is played. No problem getting the note event and details, but once I call the actual function that's supposed to do something with it, something weird happens. (I'm using DryWetMidi to listen for midi NoteOn events, if that is relevant to the issue) I'm trying to find a specific gameobject and change something within it. As soon as I search for it, the function simply stops execution without any error, exception or feedback of any kind. If I debug the code, it reaches that line fine, stops if I set a breakpoint on it, but if I click "step over" to go through the code, it simply continues execution and "steps out of the debug break" (not sure how to call this, hope it makes sense).

Here's the code

public void PlayNote(int note, int velocity)
{
    Debug.Log("Playing note "   note   " at velocity "   velocity); // this logs the message fine
    GameObject key = GameObject.Find(note.toString()); // execution reaches this line

    // nothing is executed from this point on
    if (key != null)
        key.GetComponent<ObjectSetup>().SetPressed(true);

    Debug.Log("Done"); // never logs anything
}

The gameobject in question is already created, as it is visible in-game, and the function works if I call it from somewhere else (let's say: from Start function of the current script). I'm stumped, as I can't even understand why it's "jumping ship" mid-execution... If I try to search for another gameobject, or simply create a new one, it does exactly the same thing.

CodePudding user response:

The first thing I see with your code is toString() instead of ‘ToString()`.

I also hazard a guess that you’re not seeing any error message because you might have unselected the error category in the console. That’s the red icon in the top right of the Console window. If that’s not selected, you won’t see any errors in the console.

enter image description here

You can read up about the switches at the Unity documentation.

CodePudding user response:

Since you are listening to events from some external library: Are you sure these are involved on the Unity main thread?

Most of the Unity API can only be used on the main thread! I suspect this to be the issue here as it reaches the line containing GameObject.Find but nothing beyond.

You would basically need to dispatch the calls back into the Unity main thread. A pattern often used for this could look like

public class MainThreadDispatcher : MonoBehaviour
{
    private static MainThreadDispatcher _instance;
    public static MainThreadDispatcher Instance => _instance;

    private readonly ConcurrentQueue<Action> _actions = new ();

    private void Awake ()
    {
        if(_instance && _instance != this)
        {
            Destroy(gameObject);
            return;
        }

        _instance = this;
        // optionally
        DontDestroyOnLoad(gameObject);
    }

    private void Update()
    {
        while(_actions.TryDequeue(out var action))
        {
            action?.Invoke();
        }
    }

    public void DoInNextUpdate(Action action)
    {
        _actions.Enqueue(action);
    }
}



public void PlayNote(int note, int velocity)
{
    Debug.Log("Playing note "   note   " at velocity "   velocity); // this logs the message fine
    GameObject key = GameObject.Find(note.toString()); // execution reaches this line

    // nothing is executed from this point on
    if (key != null)
        key.GetComponent<ObjectSetup>().SetPressed(true);

    Debug.Log("Done"); // never logs anything
}

And then you do

public void PlayNote(int note, int velocity)
{
    MainThreadDispatcher.Instance.DoInNextUpdate(() =>
    {
        Debug.Log("Playing note "   note   " at velocity "   velocity); // this logs the message fine
        GameObject key = GameObject.Find(note.ToString());
 
        if (key && key.TryGetComponent<ObjectSetup>(out var setup))
            setup.SetPressed(true);

        Debug.Log("Done");
    });
}
  • Related