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

Question can invoke visualscript in C#

Discussion in 'Visual Scripting' started by wang37921, Jun 30, 2021.

  1. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
    using visual script like a function, with input and output,
    in C#, invoke a function in visual script, pass in input data and got the output.
     
  2. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,304
    FunctionNode.jpg
    I just tried, it's messy, because visual scripting doesn't handle regular delegates or generics at this time, and it's also not type safe, and a lot of stuff is done with "magic strings" and Objects, so you can expect runtime errors if you get anything wrong, which is a lot less convenient than compile time errors.


    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using Unity.VisualScripting;
    6. using System;
    7.  
    8. public class Greeting : MonoBehaviour
    9. {
    10.     // Start is called before the first frame update
    11.  
    12.     private Action<string> GreetingCallback;
    13.     void Start()
    14.     {
    15.         string name = "Wang";
    16.         GreetingCallback = PrintGreeting;
    17.         CustomEvent.Trigger(gameObject, "HelloGeneratorEvent", new object[] { name, GreetingCallback });
    18.     }
    19.  
    20.     public void PrintGreeting(string greeting)
    21.     {
    22.         Debug.Log(greeting);
    23.     }
    24. }
    25.  
    26.  

    I ended up using a dedicated function to invoke an action, and you would need 1 of these for every function signature that you want to support, which is painful. Creating your own eventargs sounds just as painful.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.VisualScripting;
    5. using System;
    6.  
    7. [IncludeInSettings(true)]
    8. [Inspectable]
    9. public class ActionUtility
    10. {
    11.     public static void InvokeActionString(Action<string> action, string stringArg)
    12.     {
    13.         action?.Invoke(stringArg);
    14.     }
    15. }
    16.  

    I'd probably look into custom nodes for this kind of thing, unless someone has any better ideas.
     
    Last edited: Jul 2, 2021
  3. MasterSubby

    MasterSubby

    Joined:
    Sep 5, 2012
    Posts:
    252
    Edit: Totally had a brain fart and gave information that you didn't need when posting before. But I think Return Events in the Community Add-ons does exactly what your asking. It's intended to work almost identical to custom events, except you can return, and trigger in C# and return a value to an assigned callback in the trigger.

    Code (CSharp):
    1. public static void Trigger(GameObject target, string name, Action<object> callback = null, bool global = false, params object[] args)
    2.  
    This will allow you to use an action that does something with the return value once it's hit. It's not an immediate return, so the callback is necessary. Return events allow for Coroutines before returning.

    Not perfect in the context of C# return methods, but it's the closest without going too deep into riskier APIs.

    example.png

    https://github.com/RealityStop/Bolt.Addons.Community

    Git URL:
    https://github.com/RealityStop/Bolt.Addons.Community.git#UVSsupport-Dev

    As far as the mention on delegates, we now support Delegates as well. Compile a delegate to a wrapper using our new assets, fill out the generics if their is any, and It will be searchable and auto populated with the new compiled types. Like this:

    Unity_2021-06-30_13-10-55.png

    You could theoretically assign the delegate to a variable and invoke it that way. This is 100% the way to go if you want to be close to 100% C# like methods. I'll make another post to clarify this further.
     
    Last edited: Jul 2, 2021
    Hikiko66 likes this.
  4. MasterSubby

    MasterSubby

    Joined:
    Sep 5, 2012
    Posts:
    252
    Okay, so the other options if you do not go straight script, or use the above return events is the delegates. You can make one in the graph with the addons by creating the asset and compiling.

    Unity_2021-07-01_21-30-29.png

    Unity_2021-07-01_21-17-29.png

    Then you can now add that delegate using the units developed for the wrapper. Using the variables system, you can use them just like methods. Pull the delegate initializes it so we assign the instance on enable.

    Unity_2021-07-01_21-29-51.png

    Then call the variable in C#.

    Code (CSharp):
    1. int playerHealth = Variables.Object(gameObject).Get<Funcintint>("Damage").callback(10);
    Since its compiled, the callback is a type safe delegate. You will have both the parameters and return types via intellisense and UVS search.
     
    Last edited: Jul 2, 2021
    Hikiko66 likes this.