类成员被意外更改

时间:2018-10-22 19:38:11

标签: c# unity3d random

我正在用C#制作《乌尔皇家游戏》的骰子。它需要4个4面金字塔,而在4个峰中有2个是白色。这意味着单个骰子有50/50的可能性为0或1。

现在看一下这段代码,并告诉我为什么有时它会给我5和6。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ButtonScript : MonoBehaviour {
    public Button rollButton;
    public int result;

    void Start()
    {
        rollButton.onClick.AddListener(onClick);
    }

    void resultReset()
    {
        Debug.Log("Setting result from " + result + " to 0");
        result = 0;
    }

    public int Calculate()
    {        
        for (int i = 0; i < 4; i++)
        {
            int num = Random.Range(0,2); // Either 1 or 0.

            result = result + num; // num is added to total result
            if (result > 4)
            {
                Debug.Log("Rolling " + result + " not possible!!");
            }
        }
        return result;
    }

    void onClick()
    {
        resultReset();

        int iRolled = Calculate();
        Debug.Log("I rolled " + iRolled); // Sometimes gives 5+ and skips the for loop (like, goes 1-2 times and gives out an impossible number)
    }

}

2 个答案:

答案 0 :(得分:3)

我无法重现这一点,但我最大的猜测是onClick方法是否与同时被触发的两个不同对象相关联?或者,事件处理程序可能会以某种方式多次添加到单个对象中。谁都可以解释为什么将其发射两次。您可能有一个竞争条件,其中两个对象都重置[共享]结果,然后两个对象都同时开始添加到它。尝试对非共享局部变量运行循环,如下所示:

public int Calculate()
{
    int thisRoll = 0;       // only accessible from inside the method

    for (int i = 0; i < 4; i++)
    {
        int num = Random.Range(0,2); // Either 1 or 0.

        thisRoll = thisRoll + num; // num is added to total result
        if (thisRoll > 4)
        {
            Debug.Log("Rolling " + thisRoll + " not possible!!");
        }
    }
    return thisRoll;
}

void onClick()
{
    //resultReset();        // not necessary anymore

    int iRolled = Calculate();
    Debug.Log("I rolled " + iRolled); // Sometimes gives 5+ and skips the for loop (like, goes 1-2 times and gives out an impossible number)

    // set result here if you actually need it in addition to iRolled:
    result = iRolled;
}

答案 1 :(得分:0)

OnClickCalculate中的至少一个被调用了两次。

当Unity在AddListener上调用Start()时,对ButtonScript的调用占了一次。点击任何其他电话都会创建竞争条件,从而可能产生意外的输出。

在运行场景之前,请确保检查器中On Click事件的按钮列表中都不包含这些方法。