C# 设计一个显示消息、返回自定义对象并等待用户响应的对话框

C# 设计一个显示消息、返回自定义对象并等待用户响应的对话框,c#,unity3d,coroutine,C#,Unity3d,Coroutine,我试图在unity中为所有平台上的运行时设计一个自定义对话框(以Android和webplayer为例) 我已经成功地显示了一个对话框,获得了用户响应并更新了此响应。但是,当从其他方法/类外部使用对话框时,我不知道如何调用display对话框并等待它返回值 这是显示对话框的代码: public void ShowDialogBox(string title, string message, DialogBoxButtons buttons) {

我试图在unity中为所有平台上的运行时设计一个自定义对话框(以Android和webplayer为例)

我已经成功地显示了一个对话框,获得了用户响应并更新了此响应。但是,当从其他方法/类外部使用对话框时,我不知道如何调用display对话框并等待它返回值

这是显示对话框的代码:

            public void ShowDialogBox(string title, string message, DialogBoxButtons buttons)
            {
                StartCoroutine(ShowDialogBoxHelper(title, message, buttons));
            }

            public void ShowDialogBox(string title, string message)
            {
                StartCoroutine(ShowDialogBoxHelper(title, message, DialogBoxButtons.OK));
            }

            public IEnumerator ShowDialogBoxHelper (string title, string message, DialogBoxButtons buttons)
            {
                Response = DialogResponse.NONE;

                Title.text = title;
                Message.text = message;

                ButtonSet = buttons;
                HandleButtonSet(ButtonSet);

                _canvasGroup.alpha = 1;
                _canvasGroup.interactable = true;
                transform.SetAsLastSibling();

                _apprearenceMode = ApprearenceMode.Shown;

                 yield return StartCoroutine(WaitForButtonResponse());

                Debug.Log("user response : " + Response);

            }
协同程序“WaitForButtonResponse()”声明如下:

IEnumerator WaitForButtonResponse()
            {
                Debug.Log("waiting in the enumerator, responded: " + Response);

                yield return new waitForUserAction(() => Response != DialogResponse.NONE);

                Debug.Log("done waiting in the enumerator, responded: " + Response);

            }
“waitForUserAction()”协同程序是一个自定义的,继承自

用法如下:

 if (ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL) == DialogResponse.YES)
                {
                    //do something
                }
现在的问题是,“return Response;”不会等待“start例程(ShowDialogBoxHelper(标题、消息、按钮));”更新用户的选择并返回响应的旧值,而不是用户当前选择的值

提前感谢您在这方面提供的任何帮助

干杯


Ani

如果没有立即评估结果,您需要实际等待,并告诉例程在有响应时该怎么做

我会使用
操作
来处理类似的问题:

// Here you can actually use an overload with optional parameter
// If you don't pass in the "buttons" it simply has the default value `OK`
// And additionally pass in the action to invoke once a response was given
// If you don't pass it then simply nothing happens ;) 
public void ShowDialogBox(string title, string message, DialogBoxButtons buttons = DialogBoxButtons.OK, Action<DialogResponse> onResponse = null)
{
    StartCoroutine(ShowDialogBoxHelper(title, message, buttons, onResponse));
}

public IEnumerator ShowDialogBoxHelper (string title, string message, DialogBoxButtons buttons, Action<DialogResponse> onResponse)
{
    Response = DialogResponse.NONE;

    Title.text = title;
    Message.text = message;

    ButtonSet = buttons;
    HandleButtonSet(ButtonSet);

    _canvasGroup.alpha = 1;
    _canvasGroup.interactable = true;
    transform.SetAsLastSibling();

    _apprearenceMode = ApprearenceMode.Shown;

    // Here rather use the Unity built-in
    yield return new WaitWhile(() => Response == DialogResponse.NONE);

    Debug.Log("user response : " + Response);

    onResponse?.Invoke(Response);
}
或者相同,但是有一个方法

ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL, HandleResponse);

private void HandleResponse(DialogResponse response)
{
    if(response == DialogResponse.YES)
    {
        // Do something
    }
}

hi@derHugo,这是我实现它的一种方式,通过一个unity操作,该操作将在响应时调用,但我试图获得类似的行为。有没有其他方法可以让代码执行暂停,直到用户单击后返回响应?@the_nandavar嗯,你肯定不会喜欢这样做,因为它会阻止Unity主线程,因此你甚至无法再与按钮交互;)好吧公平的我将继续接受你提供的答案。如果您稍后发现,请确实建议任何其他方法来实现我尝试的目标:)
// Here you can actually use an overload with optional parameter
// If you don't pass in the "buttons" it simply has the default value `OK`
// And additionally pass in the action to invoke once a response was given
// If you don't pass it then simply nothing happens ;) 
public void ShowDialogBox(string title, string message, DialogBoxButtons buttons = DialogBoxButtons.OK, Action<DialogResponse> onResponse = null)
{
    StartCoroutine(ShowDialogBoxHelper(title, message, buttons, onResponse));
}

public IEnumerator ShowDialogBoxHelper (string title, string message, DialogBoxButtons buttons, Action<DialogResponse> onResponse)
{
    Response = DialogResponse.NONE;

    Title.text = title;
    Message.text = message;

    ButtonSet = buttons;
    HandleButtonSet(ButtonSet);

    _canvasGroup.alpha = 1;
    _canvasGroup.interactable = true;
    transform.SetAsLastSibling();

    _apprearenceMode = ApprearenceMode.Shown;

    // Here rather use the Unity built-in
    yield return new WaitWhile(() => Response == DialogResponse.NONE);

    Debug.Log("user response : " + Response);

    onResponse?.Invoke(Response);
}
ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL, response => 
    {
        if(response == DialogResponse.YES)
        {
            // Do something
        }
    });
ShowDialogBox("test", "testing dialog box behaviour", DialogBoxButtons.YES_NO_CANCEL, HandleResponse);

private void HandleResponse(DialogResponse response)
{
    if(response == DialogResponse.YES)
    {
        // Do something
    }
}