Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Maxter · Sep 10, 2015 at 06:35 PM · uibuttoneventonclickevent-listener

Move Button OnClick listeners to another button

What I want to achieve: Create a component (MonoBehaviour) (which requires Button component on the same object) that will show confirmation dialog ("Do you really want to blah blah blah?" "Yes"/"No") on button click. If "Yes" button is pressed, it does whatever the original Button should have done. If "No" - nothing.

The problem: I can't find any examples on moving event handlers from one button to another. I'm not very experienced with all those delegates, UnityActions and stuff... Googling failed. Documentation is... umm... scarce.

My component should grab original OnClick handlers and stuff them into its "Yes" button. After that it should replace original OnClick with its own handler that shows the confirmation dialog. Replacing one handler with another is clear. The real problem is moving arbitrary handlers to another button.

So, how can I do these shenanigans?

EDIT:

I want to have an easily reusable component which I can just drop onto button and it works. I remove it and nothing breaks. I don't want to fiddle around with "rewiring" event handlers manually. It seems like something that component can do for itself.

Also, I am using data binding library and the action that button executes is set by another component, so I don't have direct control over the handler.

My fallback plan is to extend component that binds an action to have in-built functionality to show confirmation dialog, but I really want to avoid that. I want decoupled (as much as possible) functional components.

If moving arbitrary event handlers from one button to another is impossible, I will stick to my fallback plan.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by Maxter · Sep 12, 2015 at 05:49 PM

I have achieved the desired behavior! Woohoo!

ThisButton - original button component

YesButton, NoButton - buttons in the confirmation dialog

             YesButton.onClick = ThisButton.onClick;
             YesButton.onClick.AddListener(HideDialog);
             NoButton.onClick.AddListener(HideDialog);
 
             ThisButton.onClick = new Button.ButtonClickedEvent(); // <-- IMPORTANT
             ThisButton.onClick.AddListener(ShowDialog);

The trick is to NOT use ThisButton.onClick.RemoveAllListeners(), because it would clear all the listeners on YesButton too (they share the same onClick instance). Instead I just replace onClick instance of the original button with a new object.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NchucreZ · Apr 13 at 11:37 AM 0
Share

Simple and eficcient. Thanks, you save me just now

avatar image
0

Answer by tyoc213 · Sep 11, 2015 at 05:38 AM

Why not have 2 prefabs, one for your first screen and one for the next, so you instantiate one and delete the other, no need to "update" handlers.

In any case if you really want to point to new handlers you have another option, same handler with a click count, so you could know if it clicked the button for first time or second time and reset.

If still you need to replace the see AddListener and RemoveListener http://docs.unity3d.com/ScriptReference/UI.Button.ButtonClickedEvent.html and if you want a little hing (also note how to capture a value there) http://answers.unity3d.com/questions/791573/46-ui-how-to-apply-onclick-handler-for-button-gene.html

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by cjdev · Sep 10, 2015 at 08:59 PM

There are a few ways of doing something like this although I don't think you want to necessarily 'take' the handlers from the original buttons and move them over so much as have the original buttons assign the right function to any given Yes button. You could do that by storing the function you want to run with the next pressed Yes button into a delegate, basically a variable that holds a function, and then adding that delegate as the listener of the Yes button when it is Instantiated. It would look something like this:

 private GameObject buttonCanvas;
 private GameObject confirmCanvResource;
 //Separate the reference to the prefab and the GO you destroy
 private GameObject confirmationCanvas;

 //Create a delegate of a custom type to hold the function called by the next 'Yes' click
 private delegate void Handler();
 private Handler currentHandler;

 void Start()
 {
     buttonCanvas = GameObject.Find("ButtonCanvas");
     confirmCanvResource = Resources.Load("ConfirmationCanvas") as GameObject;
 }

 //Called by the buttons preceding Yes/No to set the Yes button with the right handler
 public void OnButtonClick()
 {
     currentHandler = IntendedFunction;
     Destroy(buttonCanvas);
     confirmationCanvas = Instantiate(confirmCanvResource);
     Button[] buttons = confirmationCanvas.GetComponentsInChildren<Button>();
     for (int i = 0; i < buttons.Length; i++)
         if (buttons[i].name == "Yes")
             buttons[i].onClick.AddListener(delegate { currentHandler(); });
     //You'll also need to add logic for your other buttons
 }

 public void IntendedFunction()
 {
     //Do stuff after 'Yes' is clicked
 }

There's a few details here worth mentioning, like creating multiple GameObjects for the confirmation canvas. If you were to create just one reference to the Resource then when you went to Destroy it you would be trying to destroy the prefab itself rather than an instance of it. The delegate is defined, you can think of it like defining a function with no contents except by putting the delegate keyword in there you're creating a type (like int or string) instead of an actual function. Then after that you create an instance of that delegate type named currentHandler that stores the function that will get called on the next Yes button click. Finally, when one of the normal buttons is clicked it destroys it's canvas, instantiates the Yes/No canvas, and adds the delegate handler to the Yes button.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Maxter · Sep 11, 2015 at 09:14 AM 0
Share

Thank you for detailed reply but this solution doesn't really provide the outcome I desire. I provided more info in the first post.

However, your solution might fit into my fallback plan.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

How to access the OnClick event via Script 1 Answer

List of Buttons: Adding a listener passes Last element? 2 Answers

Event system or UI Button ? 0 Answers

Functions aren't appearing in the onClick editor..... 1 Answer

Assigning a function with a parameter to buttons in for loop with a temp variable 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges