I have a method that needs to wait for a signal and use the parameter carried by the signal. From my searching it looks like it is pretty simple in GDScript e.g. var x = await signal(), but I can't find a way to do it in c#.
Example code:

async void MyFunction() {
    // do something
    // hang until a unit is selected
    Unit unitSelected = await ToSignal(Events.events, "UnitClicked"); // UnitClicked carries the Unit that was clicked
    // do something with unitSelected
}

I'm fairly new to Godot but I have moderate experience with Unity, and in Unity I would use a coroutine but Godot seems to prefer async methods.
Thanks

  • Jesusemora replied to this.
  • Qwertytops ok, I found something that might help:

    https://stackoverflow.com/questions/77749279/godot-4-tosignal-string-parameter-in-c-sharp-for-await
    https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#awaiting-for-signals-or-coroutines

    Qwertytops I updated the question with an example which I hope clarifies it.

    Qwertytops ```
    async void MyFunction() {
    // do something
    // hang until a unit is selected
    Unit unitSelected = await ToSignal(Events.events, "UnitClicked"); // UnitClicked carries the Unit that was clicked
    // do something with unitSelected
    }

    the way await works in gdscript, it pauses execution of the code until it receives a signal, the signal then resumes the code.
    what you are trying to do is run a function and wait for a return value.
    Maybe your approach to this problem is wrong. I would store the "return value" in a reference or in a singleton, and emit the signal when the unit has been selected, resuming execution, then I would use the value stored in the singleton or reference.

    so I would have a singleton with a reference unitSelected.
    then, when a unit is selected it would override unitSelected with self and emit the signal unit_clicked (also in the singleton):

    mysingleton.unitSelected = self
    mysingleton.unit_clicked.emit()

    your paused code would then receive the signal and resume execution:

    func myfunction:
         await mysingleton.unit_clicked
         #mysingleton.unitSelected

    Jesusemora Looks like I spent a lot more time reading the docs than you did reading the question. I know how to await a signal, but I can't find a C# way to store the parameter carried by the signal that is being awaited in the function that is waiting. In GDScript you can do it apparently as in the example I gave.

      Qwertytops In GDScript you can do it apparently as in the example I gave.

      await is a C# operator, it has special conditions:
      https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/await

      signals in godot C# are events. I can't test this for you because I don't use C# these days, but nothing about this is godot specific, it's all presented in C# ways.

      Qwertytops a C# way to store the parameter carried by the signal that is being awaited in the function that is waiting.

      the parameter or the return?

      if you need to store the return, you could use a reference as parameter and use it to get the result?

      private void myfunction(int x, int ref ret)
      {
           var a = x + 2;
           ret = a;
      }

        Jesusemora I updated the question with an example which I hope clarifies it.
        So is there no way to do this kind of thing in C# that Godot provides? If not I'll just check the C# docs and see if I can figure it out.

          Qwertytops ok, I found something that might help:

          https://stackoverflow.com/questions/77749279/godot-4-tosignal-string-parameter-in-c-sharp-for-await
          https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#awaiting-for-signals-or-coroutines

          Qwertytops I updated the question with an example which I hope clarifies it.

          Qwertytops ```
          async void MyFunction() {
          // do something
          // hang until a unit is selected
          Unit unitSelected = await ToSignal(Events.events, "UnitClicked"); // UnitClicked carries the Unit that was clicked
          // do something with unitSelected
          }

          the way await works in gdscript, it pauses execution of the code until it receives a signal, the signal then resumes the code.
          what you are trying to do is run a function and wait for a return value.
          Maybe your approach to this problem is wrong. I would store the "return value" in a reference or in a singleton, and emit the signal when the unit has been selected, resuming execution, then I would use the value stored in the singleton or reference.

          so I would have a singleton with a reference unitSelected.
          then, when a unit is selected it would override unitSelected with self and emit the signal unit_clicked (also in the singleton):

          mysingleton.unitSelected = self
          mysingleton.unit_clicked.emit()

          your paused code would then receive the signal and resume execution:

          func myfunction:
               await mysingleton.unit_clicked
               #mysingleton.unitSelected
            13 days later