Author Topic: Allowing the Notify feature to send arguments?  (Read 4138 times)

bac9

  • Full Member
  • ***
  • Thank You
  • -Given: 2
  • -Receive: 4
  • Posts: 113
    • View Profile
Allowing the Notify feature to send arguments?
« on: November 27, 2013, 07:47:35 AM »
Notify function is available with almost every single NGUI element and is immensely useful. Still, there is something that will make it much more versatile.

Right now, as far as I understand, Notify window populates the Method list strictly with public voids that contain no arguments whatsoever. Adding an argument stops the void method from appearing in the list. It would be nice if methods requiring arguments will be listed too, as they allow to simplify the code surrounding some stuff immensely.

For example, I have a complex encyclopedia style app with multiple screens containing various interfaces and 3d models on them, with animated transitions between those screens. As of right now, I have to make a transition manager script containing methods like:

  • public void L1_To_L2 ()
  • public void L1_To_L2_Reverse ()
  • public void L2_To_L3 ()
  • public void L2_To_L3_Reverse ()
  • public void L3_To_L41 ()
  • public void L3_To_L41_Reverse ()
  • public void L3_To_L42 ()
  • public void L3_To_L42_Reverse ()
  • public void L3_To_L43 ()
  • public void L3_To_L43_Reverse ()
  • public void L3_To_L44 ()
  • public void L3_To_L44_Reverse ()
  • public void L41_To_L43 ()
  • and so on

Each of them looking like this (or containing something additional like animation playback if I don't want to use Play Animation components on buttons):

  1.         public void L43_To_L53A1 () {
  2.                 L43Equipment.gameObject.SetActive (false);
  3.                 L53A1Generator.gameObject.SetActive (true);
  4.         }

One of those methods is then added into the Notify slot of a button triggering the appropriate transition (e.g. "Back" button on screen L3 runs the L2_To_L3_Reverse method). Of course, each GameObject variable has to be manually populated by the user in the scene manager component too.

As you can imagine, it's not exactly the most pleasant setup to work with. It's manageable if, like in my case, screen count is under a dozen or two, but it quickly becomes inconvenient. So, I've been looking to replace it with something more efficient. Like this:

  1. public void LA_To_LB (GameObject LevelA, GameObject LevelB) {
  2.                 StartCoroutine(LA_To_LB_IE(LevelA, LevelB)); }
  3.  
  4. IEnumerator LA_To_LB_IE(GameObject LevelA, GameObject LevelB){
  5.                         LevelB.gameObject.SetActive (true);
  6.                         LevelA.gameObject.animation.Play (exitAnimationName);
  7.                         LevelB.gameObject.animation.Play (entryAnimationName);
  8.                         yield return new WaitForSeconds(LevelA.gameObject.animation[exitAnimationName].length);
  9.                         LevelA.gameObject.SetActive (false);
  10.                 }

Then, a Notify list on a "Next Screen" button will show the LA_To_LB method, and upon selecting it, you'll see additional fields created in the Inspector window under the method name: them being two GameObject slots where current screen and target screen will be inserted into.

Or maybe (a man can dream, right?), even listing public IEnumerators in the Notify list, with the Notify method starting the coroutine by itself if one of them is selected.

So, how can that become a reality? Can the argument support be added by myself (if so, which scripts have to be modified and how?) or, perhaps, is it planned for future releases of NGUI?
« Last Edit: November 27, 2013, 08:05:50 AM by bac9 »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Allowing the Notify feature to send arguments?
« Reply #1 on: November 27, 2013, 10:22:13 AM »
Where would you specify those extra parameters in the inspector though? How would you set their values? Keep in mind you can always use the 'current' approach, like UIButton.current to determine who called the button notification. Other classes also have 'current'.

bac9

  • Full Member
  • ***
  • Thank You
  • -Given: 2
  • -Receive: 4
  • Posts: 113
    • View Profile
Re: Allowing the Notify feature to send arguments?
« Reply #2 on: November 27, 2013, 10:37:40 AM »
Where would you specify those extra parameters in the inspector though? How would you set their values?

Just like the Method parameter appears after a Notify slot is filled, I guess.

New public variables can be created and displayed under it. There is an argument for the selected method, and it's of GameObject type? Public GameObject variable is added to the Notify block, slot for a GameObject appears there (if I'm not mistaken, Unity handles that automatically for any public variable), you drag whatever object you want into that slot, and the value of that variable is used in a corresponding argument when Notify of that NGUI object is called during the game.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Allowing the Notify feature to send arguments?
« Reply #3 on: November 27, 2013, 11:25:46 AM »
Some platforms don't support reflection correctly (like Win8 RT), so the only way to trigger functions there is by using Unity's SendMessage, and you can't have arbitrary parameters with that.

Simply create a custom "data holder" script attached to your buttons. Specify the data you need on that holder script. In the notification function do UIButton.current.GetComponent<DataHolder>(), and do what you wish.

bac9

  • Full Member
  • ***
  • Thank You
  • -Given: 2
  • -Receive: 4
  • Posts: 113
    • View Profile
Re: Allowing the Notify feature to send arguments?
« Reply #4 on: November 27, 2013, 04:43:25 PM »
Some platforms don't support reflection correctly (like Win8 RT), so the only way to trigger functions there is by using Unity's SendMessage, and you can't have arbitrary parameters with that.

Simply create a custom "data holder" script attached to your buttons. Specify the data you need on that holder script. In the notification function do UIButton.current.GetComponent<DataHolder>(), and do what you wish.

Shame to hear that, hopefully Unity folks will look into improving the situation in the future. As far as I understand, though, SendMessage supports arguments, but only one and only as a number. That could be useful in some cases (like for a set of buttons notifying damage, camera zoom, brush thickness or other similarly written methods with a different magnitude of effect), but I guess it's a bit niche area that can be always handled with a bit of additional code, without a value slot cluttering the Notify window in the Inspector.

Yeah, the idea of using a separate per-button script sounds good, certainly better than using dozens of methods in some sort of a scene manager script handling all transitions in a level. I'll try doing that, thanks! I have initially set up the scene manager thing to avoid remembering and duplicating complex transition setups involving Play Animation/Play Tween/Play Sound/WaitForSeconds for each button, but you are right, using one small component on each button to condense all transition activities sounds like more elegant way of doing it.
« Last Edit: November 27, 2013, 04:57:21 PM by bac9 »