Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

How to Use an Action

Discussion in 'Scripting' started by renman3000, Jul 10, 2015.

  1. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
    Hi,
    I am new to Actions. I am using an API plugin, and they have a list of Actions which generally seem to be called upon completing an event. ex, on succesful login, action, confirm login.

    However, I am not so sure as to how to implement this in script.

    I have attached an action class example, and am hoping someone can show me how I can implement this into a script.

    Thank you

    Code (csharp):
    1.  
    2. // Fired after a successful login attempt was made. Provides the screenname of the user.
    3. public static event Action<string> loginSucceededEvent;
     
    Lex4art likes this.
  2. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Given class

    Code (csharp):
    1. class ExampleClass
    2. {
    3.     public static event Action<string> loginSucceededEvent;
    4. }
    You could attach something to it like:

    Code (csharp):
    1. ExampleClass.loginSucceededEvent = delegate (string str)
    2. {
    3.   //
    4.   // Add your code here;
    5.   //
    6. };
    7.  
     
    shekalo and Ouro17 like this.
  3. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
    Ok, So I tried to implement what you gave me but monodevelop does not recognize Action, only ActionExtensions.

    ??
     
  4. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Action is in the System namespace, so either add a:

    #import System;

    To the top of the file, or use:

    System.Action<string>

    Everywhere instead of the unqualified name.
     
    SuuuB likes this.
  5. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
    Thanks.
    Quick question tho.

    Where i am cunfused is, I am using Plugin XCX, this is where the event, Action, loginSucceddedEvent is part of this.

    My script, my_MNG calls basic functions from the XCX plugin, via XCX_binding. So...
    Code (csharp):
    1.  
    2. //in my_MNG
    3. public void btnPressed_login(){
    4. XCX_binding.login();
    5. }
    Now, in your response you listed everything under example class. What I am wondering is, the Action noted, am I using XCX_bindning.loginSucceededEvent();?

    My issue is, I can not sort out how XCX will callback to my_MNG on a succesful login. Would I not need to subscribe to this event?
     
  6. SkillBased

    SkillBased

    Joined:
    Aug 11, 2014
    Posts:
    141
    In the first reply he showed one possible way to assign a method to the Action.

    An Action is basically an interface for any method which has no return and no input parameters, that's it.

    So you can assign to your Action variable an anonymous method (like in the first reply), any other exposed method in your scripts that meets the signature requirements of void/empty parameters.

    Since delegates in C# inherit from multicast delegates you can treat them like events. So you can assign multiple methods to your Action variable with +=

    Code (CSharp):
    1. Action someAction += someMethod1;
    2. Action someAction += someMethod2:
    3.  
    4. someAction(); // <-- calls someMethod1 and someMethod2
    5.  
    6. void someMethod1()
    7. {
    8.      //something happens here
    9. }
    10.  
    11. void someMethod2()
    12. {
    13.      //something else happens here
    14. }
    15.  
    Hope that helped
     
  7. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
    Hi, thanks.

    I am still having trouble sorting this out.

    The only way I can get error free code in regards to setting up a delegate is...
    Code (csharp):
    1.  
    2. void someFunction(){
    3. loginSucceededEvent = delegate(string str){
    4. //WHAT GOES HERE???
    5. };
    6. }
    7.  
    However, this seems backwards to me. Meaning, I need to know when a succesful log in has occured. Since this can happen at any moment in time, someFunction() is useless.

    I have tried many variations of this over the past hour thinking I could "Strike it rich", but no such luck yet.

    Thanks

    ps. I also tried subscriptions, but they are proven error riddled, the way I am doing them as well.
     
  8. SkillBased

    SkillBased

    Joined:
    Aug 11, 2014
    Posts:
    141
    Oh, well basically it sounds like whenever the login occurs it should fire an event. An event being some method (or collection of methods) that do something in response to the login occuring.

    It sounds to me like your event called loginSucceededEvent should subscribe to whatever methods you want to fire in response to the login occuring.

    Looking closely at the event

    Code (CSharp):
    1. public static event Action<string> loginSucceededEvent;
    You see its actually an Action<> that that allows any method with no return, and an input parameter of type string.

    Here's a simple implementation to hopefully get it working:

    Code (CSharp):
    1. class Whatever
    2. {
    3.     public static event Action<string> loginSucceededEvent;
    4.  
    5.     //subscribe the method to the event
    6.     void Start()
    7.     {
    8.         loginSucceededEvent += doThisWhenLoginSuccessful;
    9.     }
    10.  
    11.     void doThisWhenLoginSuccessful(string s)
    12.     {
    13.       Debug.Log(s + " calling subscriber: doThisWhenLoginSuccessful");
    14.     }
    15.  
    16. }
    And wherever your code is that determines the login is successful include:

    Code (CSharp):
    1.     //make sure the event doesn't try to fire without subscribers
    2.     if (loginSucceededEvent != null)
    3.     {
    4.         loginSucceededEvent("EVENT FIRED!");
    5.     }
    of course, you need to modify the references to make it work properly relative to your class names/instances, etc.

    NOTE: forgot to mention that you should be sure to put that last code block (where event-firing part) within the class that contains the event (in this case the nonsense class "Whatever"). You can't raise/trigger the event in a class outside of which it was declared. So be sure the event is in the class that actually determines the login was successful.
     
    Last edited: Jul 10, 2015
  9. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
  10. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
    Awesomeballs.
    Will try out.


    So basically, I declare the action as an event in my script. I then subscribe to it. This subscription method is called when that event occurs.

    Just so I understand the mechanics of it, the action, is static. However, it lyes in my script, not the plug ins. Is this irrelevant? What I am getting at is this action, must access all scripts (or ones with the same action declared).

    Hmmm. Maybe over thinking thinfpgs as susual, but just seeing how things relate.
    Cheers!
     
  11. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    You'll need to subscribe to the action in the third party code. I'd do it like this

    Code (CSharp):
    1. void Start () {
    2.     ThirdPartyClass.loginSuceededEvent += LoginSuccess;
    3. }
    4.  
    5. void LoginSuccess (string s){
    6.     Debug.Log (s + " login worked");
    7. }
    I honestly wouldn't try mess with anonymous functions and lambda sequence just yet.
     
    DianaCode3 and iLyxa3D like this.
  12. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
    Ah I see. Claim or access the subscription, via the static, original location of the event.

    Nice! I think I got it.
     
  13. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
    Hi Guys so I am in the mix, but I am getting an error.

    Assets/Scripts/SOCIAL_MNG.cs(37,33): error CS0123: A method or delegate `SOCIAL_MNG.fb_loginSucceeded(string)' parameters do not match delegate `System.Action()' parameters


    Here is my code...
    Code (csharp):
    1.  
    2. public class SOCIAL_MNG : MonoBehaviour {
    3.  
    4. public static event System.Action<string>  loginSucceededEvent;
    5.  
    6. void Start(){
    7. TwitterManager.loginSucceededEvent += tw_loginSucceeded;
    8. }
    9.  
    10. void tw_loginSucceeded(string str){
    11. }
    12. }
     
  14. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    As the error indicates TwitterManager.loginSucceededEvent is defined as System.Action() (not System.Action<string>()) as such it needs a reference to a method that matches the Action() signature like:

    Code (csharp):
    1.  
    2. public class SOCIAL_MNG : MonoBehaviour
    3. {
    4.    public static event System.Action<string>  loginSucceededEvent;
    5.  
    6.    void Start()
    7.    {
    8.       TwitterManager.loginSucceededEvent += tw_loginSucceeded;
    9.    }
    10.  
    11.    void tw_loginSucceeded()
    12.    {
    13.    }
    14. }
    ie, just remove the string parameter from your method declaration.
     
  15. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
    Hi,
    If I remove the argument I get this error...

    Assets/Scripts/SOCIAL_MNG.cs(29,32): error CS0123: A method or delegate `SOCIAL_MNG.tw_loginSucceeded()' parameters do not match delegate `System.Action<string>(string)' parameters



    The original declaration of the variable does have a string.
    Code (csharp):
    1.  
    2. publicstaticevent System.Action<string> loginSucceededEvent;
    The error now, is why I originally put it in.
    ??
     
  16. SkillBased

    SkillBased

    Joined:
    Aug 11, 2014
    Posts:
    141
    Keep this as-is

    Code (CSharp):
    1. public static event System.Action<string>  loginSucceededEvent;
    make sure this
    Code (CSharp):
    1. void tw_loginSucceeded(string str)
    2. {
    3. }
    and this
    Code (CSharp):
    1. void fb_loginSucceeded(string str)
    2. {
    3. }
    contain the parameter (string str). That way they both match the event signature (both are methods with no return type, that take a single string input parameter)
     
  17. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
  18. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Why do you declare an action in SOCIAL_MNG
    Code (csharp):
    1. public static event System.Action<string> loginSucceededEvent;
    It is not being used. What exactly do you want to achieve? What is the overall idea?
     
  19. SkillBased

    SkillBased

    Joined:
    Aug 11, 2014
    Posts:
    141
    Part of the problem is your original mention of the error was:

    SOCIAL_MNG.fb_loginSucceeded(string)' parameters do not match delegate `System.Action()' parameters

    Notice that refers to the fb_loginSucceeded() method, of which you never showed what it looked like in your script.

    So I had to assume that you kept messing about with your delegate signatures parameters and method parameters. If you are sure that your methods meet the signature requirements of the delegate, then the only thing I can conclude is that fb_loginSucceeded has to be tied into a different event, one that does NOT take a string.

    In other words, facebook login should fire a different event than twitter login... This is implied by the error messages referring to two different delegate signatures (one takes in a string, the other doesn't).

    That's the best advice I can give because otherwise it doesn't seem like it should be a complex problem. If there is a vendor for the code you are referencing maybe its best to ask them directly...
     
  20. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702

    Ok, I got rid of me declaring the action in my script, as this makes sense. This is something that exists elsewhere. Also, one uses a string for an argument, the other does not.

    So, all in all, I have cleared all errors.

    Thank you for your help.
     
  21. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    The definition/declaration of TwitterManager.loginSucceededEvent is the thing that is declared as System.Action().

    Is the TwitterManager your class also?

    Can you show the relevant bits.
     
  22. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,702
    I have not tested on an iOS device, but for now, in unity, there are no errors.

    My thinking is this...
    In Start() I subscribe a function to the static event.
    I create that function.

    Unicorns appear.