How to Use an Action

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

// Fired after a successful login attempt was made. Provides the screenname of the user.
public static event Action<string> loginSucceededEvent;
1 Like

Given class

class ExampleClass
{
    public static event Action<string> loginSucceededEvent;
}

You could attach something to it like:

ExampleClass.loginSucceededEvent = delegate (string str)
{
  //
  // Add your code here;
  //
};
2 Likes

Ok, So I tried to implement what you gave me but monodevelop does not recognize Action, only ActionExtensions.

??

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.

1 Like

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…

//in my_MNG
public void btnPressed_login(){
XCX_binding.login();
}

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?

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 +=

Action someAction += someMethod1;
Action someAction += someMethod2:

someAction(); // <-- calls someMethod1 and someMethod2

void someMethod1()
{
     //something happens here
}

void someMethod2()
{
     //something else happens here
}

Hope that helped

11 Likes

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…

void someFunction(){
loginSucceededEvent = delegate(string str){
//WHAT GOES HERE???
};
}

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.

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

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:

class Whatever
{
    public static event Action<string> loginSucceededEvent;

    //subscribe the method to the event
    void Start()
    {
        loginSucceededEvent += doThisWhenLoginSuccessful;
    }

    void doThisWhenLoginSuccessful(string s)
    {
      Debug.Log(s + " calling subscriber: doThisWhenLoginSuccessful");
    }

}

And wherever your code is that determines the login is successful include:

    //make sure the event doesn't try to fire without subscribers
    if (loginSucceededEvent != null)
    {
        loginSucceededEvent("EVENT FIRED!");
    }

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.

5 Likes

ah, beautiful lambdas.

Here you go: http://www.blockypixel.com/2012/09/c-in-unity3d-dynamic-methods-with-lambda-expressions/

2 Likes

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!

You’ll need to subscribe to the action in the third party code. I’d do it like this

void Start () {
    ThirdPartyClass.loginSuceededEvent += LoginSuccess;
}

void LoginSuccess (string s){
    Debug.Log (s + " login worked");
}

I honestly wouldn’t try mess with anonymous functions and lambda sequence just yet.

2 Likes

Ah I see. Claim or access the subscription, via the static, original location of the event.

Nice! I think I got it.

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…

public class SOCIAL_MNG : MonoBehaviour {

public static event System.Action<string>  loginSucceededEvent;

void Start(){
TwitterManager.loginSucceededEvent += tw_loginSucceeded;
}

void tw_loginSucceeded(string str){
}
}

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:

public class SOCIAL_MNG : MonoBehaviour
{
   public static event System.Action<string>  loginSucceededEvent;

   void Start()
   {
      TwitterManager.loginSucceededEvent += tw_loginSucceeded;
   }

   void tw_loginSucceeded()
   {
   }
}

ie, just remove the string parameter from your method declaration.

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)’ parameters

The original declaration of the variable does have a string.

publicstaticevent System.Action<string> loginSucceededEvent;

The error now, is why I originally put it in.
??

Keep this as-is

public static event System.Action<string>  loginSucceededEvent;

make sure this

void tw_loginSucceeded(string str)
{
}

and this

void fb_loginSucceeded(string str)
{
}

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)

Dude, that is exactly what i had.

??

Why do you declare an action in SOCIAL_MNG

public static event System.Action<string> loginSucceededEvent;

It is not being used. What exactly do you want to achieve? What is the overall idea?

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…

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.

1 Like