Author Topic: Add onTooltip to UIEventTrigger  (Read 4419 times)

The-Arrival

  • Newbie
  • *
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 29
    • View Profile
Add onTooltip to UIEventTrigger
« on: February 03, 2016, 05:15:35 AM »
Hey Aren,

is it possible to add onTooltip to the UIEventTrigger?

i want to pass something like the buttonindex to my UI-Class to show the fitting tooltip for each button. I found a workaround to use onHoverOver for this wich works, but to have the onTooltip event available in the class looks like a logical thing to me anyway.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Add onTooltip to UIEventTrigger
« Reply #1 on: February 04, 2016, 09:07:23 PM »
Why use a UIEventTrigger for this? Why not use the more efficient UIEventListener? Event trigger is for stuff you set in inspector. Event listener is a more efficient method of setting it via code.

The-Arrival

  • Newbie
  • *
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 29
    • View Profile
Re: Add onTooltip to UIEventTrigger
« Reply #2 on: February 05, 2016, 06:27:07 AM »
Ok, now i´m confused and i´m not sure i´m understanding the diffrent Methods of using NGUI events and their subscruption. Let me try to restate, how i understand things at the moment:

- every Element wich has a collider/rigidbody and is on the EventMask Layer gets the events from the camera, like onHover or onClick. You can listen to these events, using void OnHover() method in a component on those gameobjects. Since i´m using a UIManager class i´m NOT utilising this.

- since i have 2D UI Elements combined with interactive elements in the 3D world, i use the UICameraScript on the UICamera (EventMask = 2D UI stuff) and the WorldCamera (EventMask = interactive 3D elements).

- by subscribing directly to the UICamera events in my UIManager, i get those events and can use my own callbacks to process the events. All i need is a callback method wich recieves the same arguments as get passed by the event. Every interactive Element will call the event and it´s NOT possible to add custom callsbacks with custom parameters.

- if i need to pass custom arguments to events, i used the UIEventTrigger, since it allows me to setup an EventDelegate like so:
  1. EventDelegate ed = new EventDelegate(this, "GetHoverIndex");
  2. ed.parameters[0].value = 0;
  3. EventDelegate.Set(staticBuild.transform.FindChild("BuildTower1").GetComponent<UIEventTrigger>().onHoverOver, ed);
  4.  
This method needs the EventTrigger component attached to each interactive element, even if i´m using code to subscribe like above.

- The UIEventlistener works like the subscription to UICamera events, only that i can subscribe specific callbacks to specific elements like so:
  1. UIEventListener.Get(staticBuild.transform.FindChild("BuildTower1").gameObject).onTooltip += TestToolTip;
So the advantage is, that i only get callbacks from the elements i want AND i can route them to diffrent callbacks, event they get triggered by the same even. I have not found a way to subscribe an EventDelegate to this though.

So what i want to do is have tooltips on several elments. the tooltip content differes based on the elements for sure. my plan was to give each element an id and have the content found based on the ID. So what i did was,  i used the onHover Event from the Trigger as in the example above to get the hovered button ID and stored it. Then i subscribed to the UICamera.onTooltip Event. When this event was called, i used the stored ID to get the right content in place and showed the tooltip.

I´m not 100% sure how to do something similar with the EventListener. The only thing i can think of is to have for each element a custom callback wich carrys the content (or the ID to call the content).


So is there a way to add additional parameters to UICamera or EventListener events? or even completely customize the EventDelegate like with the EventTrigger?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Add onTooltip to UIEventTrigger
« Reply #3 on: February 07, 2016, 12:15:23 AM »
You can pass parameters easily by using anonymous delegates:
  1. for (int i = 0; i < someList.Length; ++i) // <-- replace with whatever container you're using
  2. {
  3.     UIEventListener.Get(someList[i]).onTooltip = delegate (GameObject g, bool show)
  4.     {
  5.         Debug.Log("Tooltip on " + g.name + ", index " + i + ": " + show);
  6.     });
  7. }

The-Arrival

  • Newbie
  • *
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 29
    • View Profile
Re: Add onTooltip to UIEventTrigger
« Reply #4 on: February 07, 2016, 08:17:38 PM »
Thanks for the tip... i didn´t knew that technique!
Your example was a bit confusing though, but i figured it out. In case somebody else stumbles upon this question, i´ll repost the more straight forward answer, wich works for me:

  1.    
  2. for (int i = 0; i < someList.Length; ++i) // <-- replace with whatever container you're using
  3.     {
  4.         UIEventListener.Get(someList[i]).onTooltip = delegate (GameObject g, bool show)
  5.         {
  6.             MyCallbackMethod(gm show, i)
  7.         });
  8.     }
  9.  
  10. public void MyCallbackMethod(GameObject g, bool show, int index)
  11.     {
  12.         Debug.Log("Tooltip on " + g.name + ", index " + index + ": " + show);  
  13.     }
  14.  

The-Arrival

  • Newbie
  • *
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 29
    • View Profile
Re: Add onTooltip to UIEventTrigger
« Reply #5 on: February 08, 2016, 09:00:19 PM »
Well, unfortunally what i posted seems NOT to work as expected. I can print your Debug Message as you did, but the subscription to the delegate doesn´t work with the index.

I´m setting up 3 Buttons like this (with subscribe = true):

  1. private void SubOnTooltip(bool subscribe)
  2.     {
  3.         for (int i = 0; i < staticBuild.transform.childCount; i++)
  4.         {
  5.             if (subscribe)
  6.             {
  7.                
  8.                 GameObject btn = staticBuild.transform.GetChild(i).GetComponent<UIButton>().gameObject;
  9.                 Debug.Log("Index: " + i);
  10.                 UIEventListener.Get(btn).onTooltip = delegate(GameObject go, bool show) { ShowToolTip(go, show, i); };
  11.             }
  12.             else
  13.             {
  14.                 GameObject btn = staticBuild.transform.GetChild(i).GetComponent<UIButton>().gameObject;
  15.                 UIEventListener.Get(btn).onTooltip -= delegate(GameObject go, bool show) { ShowToolTip(go, show, i); };
  16.             }
  17.         }
  18.     }
  19.  

First of all, the subscribe = false case is not working out yet. Can you help me with that?

Besides this the subscription works, i get the i´s from 0-2. But when i recieve the events, all index from all buttons are 3?

  1. public void ShowToolTip(GameObject go, bool state, int index)
  2.     {
  3.        Debug.Log("index: " + index);
  4.      }
  5.  

I bet it´s something supersimple but i can´t make sense of the index 3 which i recieve
« Last Edit: February 08, 2016, 09:33:02 PM by The-Arrival »

The-Arrival

  • Newbie
  • *
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 29
    • View Profile
Re: Add onTooltip to UIEventTrigger
« Reply #6 on: February 08, 2016, 10:02:19 PM »
Sorry for the Spam, but i figured it out for the Index. i had to copy the iterator to a new in, otherwise all delegates hold the reference to tzhe iterator which indeed goes one step further then the loop :)

Leaves me still with the question on how to unsubscribe those anonymous delegates. Obviously it´s not recommended to use them if you wanna do so:

Quote
It is important to notice that you cannot easily unsubscribe from an event if you used an anonymous function to subscribe to it. To unsubscribe in this scenario, it is necessary to go back to the code where you subscribe to the event, store the anonymous method in a delegate variable, and then add the delegate to the event. In general, we recommend that you do not use anonymous functions to subscribe to events if you will have to unsubscribe from the event at some later point in your code. For more information about anonymous functions, see Anonymous Functions (C# Programming Guide).
"Solution" so far looks like this now:

  1. private void SubOnTooltip(bool subscribe)
  2.     {
  3.         for (int i = 0; i < staticBuild.transform.childCount; i++)
  4.         {
  5.             if (subscribe)
  6.             {
  7.                 int copy = i;
  8.                 GameObject btn = staticBuild.transform.GetChild(i).GetComponent<UIButton>().gameObject;
  9.                 Debug.Log("Button: " + btn + ", Index: " + i);
  10.                 UIEventListener.Get(btn).onTooltip += delegate(GameObject go, bool show) { ShowToolTip(go, show, copy); };
  11.             }
  12.             else
  13.             {
  14.                 int copy = i;
  15.                 GameObject btn = staticBuild.transform.GetChild(i).GetComponent<UIButton>().gameObject;
  16.                 UIEventListener.Get(btn).onTooltip -= delegate(GameObject go, bool show) { ShowToolTip(go, show, copy); };
  17.             }
  18.         }
  19.     }
  20.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Add onTooltip to UIEventTrigger
« Reply #7 on: February 09, 2016, 02:57:01 AM »
You can't unsubscribe anonymous delegates unless you keep a reference to them locally. But remember... you can simply clear the onTooltip. Just set it to null.