Author Topic: UIButtonMessage Guidance Please  (Read 11632 times)

rhart

  • Guest
UIButtonMessage Guidance Please
« on: May 08, 2012, 01:55:21 PM »
Hello,

I've been using NGUI for about 2 weeks now and I've been quite happy with the results so far!

I'm would like to have a button in my panel call a method on my GameManager object when the button is clicked.

My thought was to make use of UIButtonMessage to send a message to the GameManager. I placed the  UIButtonMessage script onto the button and referenced the GameManager as the Target and the method Hello as the function name. I set the trigger to be OnClick.

My GameManager has a script attached to it, which is where I put my Hello method. Not sure how NGUI will reference the script component of the GameManager component to call the method, which could possible be the problem?

I think I must be missing a step or leaving something out, because when I fire things up and click the button, my Hello method is not being called.

void Hello(){
   Debug.Log ("Hello Message!!!!");
}

Any advice or guidance you can give as to what I may be missing would be greatly appreciated.

Cheers!

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIButtonMessage Guidance Please
« Reply #1 on: May 08, 2012, 02:15:16 PM »
UIButtonMessage uses SendMessage, which calls the function you specified on all the components attached to your target object. For performance reasons, I recommend using the delegate approach instead:
  1. UIEventListener.Get(buttonGameObject).onClick += HelloFunction;
But regardless, from your description you've set it up correctly and it should be working.

rhart

  • Guest
Re: UIButtonMessage Guidance Please
« Reply #2 on: May 08, 2012, 02:34:53 PM »
Working now.

So 2 different approaches people can take:

1. Use the UIButtonMesssage and specify the target game object and function name

or

2. Instead of using UIButtonMessage at at, use a delate instead and subscribe to the button event on the button you are interested in.

Thanks!

Razieln64

  • Guest
Re: UIButtonMessage Guidance Please
« Reply #3 on: May 23, 2012, 12:20:03 PM »
Any way to send data specific to the button when attaching the delegate? In your example, you're calling a method that has no parameter, what if I need to send data specific to this button I clicked (let's say the reference to the button). Should I just code my own button class?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIButtonMessage Guidance Please
« Reply #4 on: May 23, 2012, 01:31:37 PM »
The delegates used by NGUI always have a parameter -- the game object that triggered the event.

Razieln64

  • Guest
Re: UIButtonMessage Guidance Please
« Reply #5 on: May 23, 2012, 01:58:28 PM »
So I'd have to guess the type of component that called the event since I only get the reference to the game object, right?

The thing is that I don't want to resort to using Unity's send message and I want to send specific data when a button is clicked.
« Last Edit: May 23, 2012, 02:02:04 PM by Razieln64 »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIButtonMessage Guidance Please
« Reply #6 on: May 23, 2012, 02:44:30 PM »
Since you're the one who registers the button delegates, you should also know which function they will call (you're the one assigning it after all!). You should obviously only have one function per action, not one function to handle all 10 buttons with a giant "if" statement inside.

Razieln64

  • Guest
Re: UIButtonMessage Guidance Please
« Reply #7 on: May 23, 2012, 03:05:00 PM »
I'm not that kind of coder, but I use GetComponent() as a last resort. It's a waste of code getting the component if initially I can hook up with the component reference directly without having to go through a gameObject.

Ok then, do you have something to get the index of the button that was clicked in a UIGrid contained in a scrollable panel?

Then the delegate (or single function) would only get the active index and set some specific text in a label based on the received index.
« Last Edit: May 23, 2012, 03:18:59 PM by Razieln64 »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIButtonMessage Guidance Please
« Reply #8 on: May 23, 2012, 03:08:33 PM »
Why would you want to anyway? Delegates don't need to be static functions. They can be functions that are already a part of your component, and this component of yours can already contain all the data you need -- references to other scripts, prefabs, settings, what have you.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIButtonMessage Guidance Please
« Reply #9 on: May 23, 2012, 03:17:14 PM »
Consider looking at it from the opposite side. Create a script attached to your button that has a public variable (index you need), and uses NGUITools.FindInParents inside OnClick() to find your manager script that's attached to one of the parent objects. Your script can then call some function on the manager script, passing the index.

It's clean, the parent doesn't know anything about what's calling it, and the only thing you have to do is set the index when instantiating your grid items.

Razieln64

  • Guest
Re: UIButtonMessage Guidance Please
« Reply #10 on: May 23, 2012, 03:24:24 PM »
Thanks. I'll just go with hooking to a specific delegate that calls a main delegate in a manager.

sintua

  • Jr. Member
  • **
  • Thank You
  • -Given: 7
  • -Receive: 0
  • Posts: 63
    • View Profile
Re: UIButtonMessage Guidance Please
« Reply #11 on: March 09, 2013, 09:22:54 PM »
Consider looking at it from the opposite side. Create a script attached to your button that has a public variable (index you need), and uses NGUITools.FindInParents inside OnClick() to find your manager script that's attached to one of the parent objects. Your script can then call some function on the manager script, passing the index.

It's clean, the parent doesn't know anything about what's calling it, and the only thing you have to do is set the index when instantiating your grid items.

Sorry to revive an old thread, but can you give an example of this? I'm not quite sure what you're suggesting here.

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: UIButtonMessage Guidance Please
« Reply #12 on: March 09, 2013, 10:23:49 PM »
Put a custom script on the actual button.

This custom script contains an int (or an enum if you want to be fancy).

Use UIEventListener to attach a delegate to the button object from a different place (where you want to handle the button logic).

There's an example in the UIEventListener.cs file that shows how.

When the button logic is run it will be something like this

  1. void MyButtonCode(GameObject sender)
  2. {
  3.   MyCustomScript customScript = sender.GetComponent<MyCustomScript>();
  4.   if (customScript != null)
  5.   {
  6.     //read int/enum
  7.     // do stuff
  8.   }
  9. }
  10.  

sintua

  • Jr. Member
  • **
  • Thank You
  • -Given: 7
  • -Receive: 0
  • Posts: 63
    • View Profile
Re: UIButtonMessage Guidance Please
« Reply #13 on: March 09, 2013, 11:44:14 PM »
EDIT: Just realized you meant MyButtonCode to be the thing in the CoreLogic, not the script on the button. Yes, I think that's what I needed! Thank you.

sintua

  • Jr. Member
  • **
  • Thank You
  • -Given: 7
  • -Receive: 0
  • Posts: 63
    • View Profile
Re: UIButtonMessage Guidance Please
« Reply #14 on: March 09, 2013, 11:52:09 PM »
But what if you wanted to do the part where you added the method to the listener elsewhere? like:


  1.         void Start ()
  2.         {
  3.                 AddButton("Manage Circles", ManageCirclesMenu(), ThingToAdd);
  4.         }
  5.  
  6.         public void AddButton (string name, ????? methodToCall, GameObject thingToAdd)//how to send in the method?
  7.         {
  8.                 //make newButton
  9.                 UIEventListener.Get(newButton).onClick += methodToCall;
  10.                 //add thingToAdd to button
  11.         }