Unity UI Button不断双击,该如何解决?

我在互动小说游戏中设置了两个按钮,每次按都会调用一行新的文本。问题是,每当我按下按钮时,都会收到两条记录的调试消息,通知我单击,游戏将移动两部分文本。

我尝试了许多不同的方法来解决此问题,包括尝试更改项目设置和许多不同代码形式中的提交输入。任何帮助将不胜感激。

这是我当前的代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AdventureGame : MonoBehaviour
{
    [SerializeField]
    private Text _textComponent;
    [SerializeField]
    private State _startingState;

    private State state;

    [SerializeField]
    private Button _input0Button;
    [SerializeField]
    private Button _input1Button;

    [SerializeField]
    private Text _choices1;
    [SerializeField]
    private Text _choices2;

    private bool _buttonOnepressed;
    private bool _buttonTwopressed;

    void Start()
    {
        state = _startingState;
        _textComponent.text = state.GetStateStory();
        _input0Button.onClick.AddListener(Input0Button);
        _input1Button.onClick.AddListener(Input1Button);
        _buttonOnepressed = false;
        _buttonTwopressed = false;


    }
    void Update()
    {
        ManageState();
    }
    private void ManageState()
    {
        if (state._choice == true)
        {
            _choices1.text = state.getchoiceone();
            _choices2.text = state.getchoiceTwo();
            _textComponent.text = state.GetStateStory();
            _input0Button.gameObject.Setactive(true);
            _input1Button.gameObject.Setactive(true);
            if(_buttonOnepressed == true)
            {
                StartCoroutine(WaitForItOne());
            }
            else if(_buttonTwopressed == true)
            {
                StartCoroutine(WaitForItTwo());
            }
        }
        else if (state._choice == false)
        {
            _choices1.text = state.getchoiceone();
            _choices2.text = state.getchoiceTwo();
            _textComponent.text = state.GetStateStory();
            _input0Button.gameObject.Setactive(true);
            _input1Button.gameObject.Setactive(false);
            if(_buttonOnepressed == true)
            {
                StartCoroutine(WaitForItOne());
            }
        }

    }
    private void ManageChoiceone()
    {
            _buttonOnepressed = false;
            State[] _newState = state.GetNextStatesArray();
            state = _newState[0];
    }
    private void ManageChoiceTwo()
    {
            _buttonTwopressed = false;
            State[] _newState = state.GetNextStatesArray();
            state = _newState[1];
    }

    public void Input0Button()
    {
        Debug.Log("Input 0 pressed");
        _buttonOnepressed = true;
    }
    public void Input1Button()
    {
        Debug.Log("Input 1 pressed");
        _buttonTwopressed = true;
    }
    IEnumerator WaitForItOne()
    {
        yield return new WaitForSeconds(3.0f);
        ManageChoiceone();
    }
    IEnumerator WaitForItTwo()
    {
        yield return new WaitForSeconds(3.0f);
        ManageChoiceTwo();
    }

}
shangcangcun 回答:Unity UI Button不断双击,该如何解决?

  • 首先,每帧您都要不断启动新的协程,例如_buttonOnePressed == true ..您等待3秒钟,才最终取消设置此标志!

  • 然后进行两次调用,确保在检查器中也未配置回调!好像您在Inspector中拥有了一次,并在您的Start方法中添加了它们,所以它们被称为两次

    请注意,您不会在运行时在Inspector中看到添加的回调!

  • 您为什么还要在这里使用Update?轮询状态和布尔值并在每个帧中不断检查和处理它们的状态是非常多余的。我宁愿简单地在button方法本身中启动例程,而是改为驱动整个代码事件!

  • (可选)为给用户更好的反馈,我将同时在3秒钟内使按钮不可交互..保持按钮处于活动状态但不可单击:

// Remove state;
// Remove _buttonOnePressed
// Remove _buttonTwoPressed

private void Start()
{
    // Either remove this two lines or the callbacks set in the Inspector
    _input0Button.onClick.AddListener(Input0Button);
    _input1Button.onClick.AddListener(Input1Button);

    ManageState(_startingState);
}

// Remove Update

// This will be called only when actually needed
// since the state is passed in as parameter you don't need the private field
private void ManageState(State state)
{
    // These happen in both cases anyway
    _choices1.text = state.GetChoiceOne();
    _choices2.text = state.GetChoiceTwo();
    _textComponent.text = state.GetStateStory();
    _input0Button.gameObject.SetActive(true);

    // Here directly use the state flag
    // since the button is disabled when needed
    // there is no need for having different "states"
    // since anyway only the according button(s) is(are) available
    _input1Button.gameObject.SetActive(state._choice);
}

// (optional) Flag for avoiding concurrent routines
// Should be impossible since buttons get disabled but you never know
private bool alreadyHandlingButton;

private IEnumerator ManageChoice(bool isButtonOne)
{
    // (optional) Skip if another routine running
    if(alreadyHandlingButton) yield break;

    // (optional) Block other routines just in cade
    alreadyHandlingButton = true;

    // Disable interactions
    _input0Button.interactable = false;
    _input1Button.interactable = false;

    // This is the same for both buttons
    yield return new WaitForSeconds(3f);

    State[] _newState = state.GetNextStatesArray();

    var state = _newState[isButtonOne ? 0 : 1];

    // Only call ManageState when the state is actually changing
    ManageState(state);

    // (optional) Allow a new routine
    alreadyHandlingButton = false;

    // Enable interactions
    _input0Button.interactable = true;
    _input1Button.interactable = true;
}

public void Input0Button()
{
    // (optional) Ignore if other button is already handled
    if(alreadyHandlingButton) return;

    Debug.Log("Input 0 pressed");
    StartCoroutine(ManageChoice(true));
}

public void Input1Button()
{
    // (optional) Ignore if other button is already handled
    if(alreadyHandlingButton) return;

    Debug.Log("Input 1 pressed");
    StartCoroutine(ManageChoice(false));
}
本文链接:https://www.f2er.com/3162039.html

大家都在问