Search Unity

Disable interactivity of button for 3 seconds after its successful OnClock

Discussion in 'Scripting' started by vit_the, Feb 16, 2018.

  1. vit_the

    vit_the

    Joined:
    Feb 3, 2018
    Posts:
    13
    Hello,

    Scenario:
    I have a button that causes a few other things to happen. Its working fine.

    Problem:
    However if the button is tapped rapidly things get screwed up.

    Targeted Solution:
    Turn the button into a does-nothing-in-logic button for 3 seconds after it is used.


    I have spent a few hours trying to do this to no avail.

    I figured there is a property in Unity's button design called "Interactible", so I would just give the button script like this for OnClick:


    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6.  
    7. public class EndTurnButtonDisabler : MonoBehaviour
    8. {
    9.  
    10.     public Button endTurnButton;
    11.  
    12.  
    13.  
    14.  
    15.     public IEnumerator TimeoutEndTurnButton()
    16.     {
    17.  
    18.         endTurnButton.interactable = false;
    19.         yield return new WaitForSeconds(2f);
    20.         endTurnButton.interactable = true;
    21.     }
    22.  
    23. }
    24.  
    But I can't figure out how to get the script and the Button to actually know what eachother are. I placed this script on the Button in question and linked the button in the editor. I also tried adding in another OnClick() field, connecting this script, and looking to use the drop down and select the TimeoutEndTurnButton coroutine, but it doesn't appear.

    I have this button already working with an OnClick () that sends TurnManager.EndTurn information to a script TurnManager.cs on another gameObject called TurnManager.

    If it is a better solution to put a line in TurnManager's Endturn() that references a script containing the button-disabling-script, I am open to that too, because I'd like to be able to use my TurnManager game object's Inspector field to change the length of time the button is disabled while I tweak things.

    I need a good tutorial on how to get scripts to talk to one another and gameobjects to be targeted by a method's influence if you have one handy please refer me to it.

    I tried a bunch of stuff and got nowhere so it is a waste to try and communicate my attempts. The problem seems very simple.. Please refer to the targeted solution and lend me your aid.
     
    Last edited: Feb 16, 2018
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    You can't tie an IEnumerator into the onClick.

    So setup a normal public method and tie that method into the onclick and have it do a startcoroutine call. Or, use Invoke instead.

    Code (CSharp):
    1. public class EndTurnButtonDisabler : MonoBehaviour
    2. {
    3.     public Button endTurnButton;
    4.  
    5.     public void StartTimer() //Call this from OnClick
    6.     {
    7.         StartCoroutine(TimeoutEndTurnButton());
    8.     }
    9.     IEnumerator TimeoutEndTurnButton()
    10.     {
    11.         endTurnButton.interactable = false;
    12.         yield return new WaitForSeconds(2f);
    13.         endTurnButton.interactable = true;
    14.     }
    15. }
    Code (CSharp):
    1. public class EndTurnButtonDisabler : MonoBehaviour
    2. {
    3.  
    4.     public Button endTurnButton;
    5.  
    6.     public void StartTimer() //Call this from OnClick
    7.     {
    8.         endTurnButton.SetActive(false);
    9.         Invoke("EndTimer", 2f);
    10.     }
    11.  
    12.     private void EndTimer()
    13.    {
    14.        endTurnButton.SetActive(true);
    15.    }
    16.  
    17. }
    Excuse typos as I typed it right in the forum real quick.
     
    vit_the likes this.
  3. ihgyug

    ihgyug

    Joined:
    Aug 5, 2017
    Posts:
    194
    So basically, your function on click should make the button non interactable and start a coroutine.
    This coroutine, after a set amount of time, will turn the button interactable.
    You could have a variable seconds so that you can change the seconds from inspector as you prefer, and you would put that variable instead of the actual time like this : yield return new WaitForSeconds(seconds).
    Coroutines are really important, once you learn about them a lot of possibilities will open.
    Another way to do this is with Invoke as Brathnann suggested.
    There are other ways to achieve what you need but Coroutine/Invoke should be the best and simplest ways for what you need.
     
    vit_the likes this.
  4. vit_the

    vit_the

    Joined:
    Feb 3, 2018
    Posts:
    13
    I appreciate the tips and code. The StartTimer() function is not appearing in OnClick, what's going on?

     
  5. ihgyug

    ihgyug

    Joined:
    Aug 5, 2017
    Posts:
    194
    Are you sure you set it the function to public? Also, you made sure you dragged in the field the object with the script attached and not only the script alone right?
     
    vit_the likes this.
  6. vit_the

    vit_the

    Joined:
    Feb 3, 2018
    Posts:
    13
    The OnClick and it all seems to be working fine now -- I placed the actual Button object with its script attached from the Hierarchy into the Button(Script)'s On Click () field where in the above screenshot I had placed the script I thought it was going to grab the method from.
     
    ihgyug likes this.