【问题标题】:Shuffle array in UnityUnity 中的随机数组
【发布时间】:2016-08-10 16:43:23
【问题描述】:

我想将array 变量中的数字洗牌一次,所以我从Start() 调用了我的Shuffle 方法。

然后我尝试从更新中访问改组后的数组,但我无法这样做。我怎样才能访问它?有没有其他方法可以将我的数组洗牌一次,然后永远使用它?

private System.Random _random = new System.Random();
float sec;
float timecount;
float starttime;
void Start () {
    starttime = Time.time;
    int[] array = { 1, 2, 3, 4, 5, 6, 7, 8};
    Shuffle(array);
    foreach (int value in array)
    {
        Debug.Log(value);
    }
}

void Update () {
    //time
    timecount = Time.time - starttime;
    sec = (timecount % 60f);
    if (Mathf.Round(sec) == 3f) {
        //access shuffled array
        Debug.Log(array[3]);  <=====error here
    }
}

//for shuffle number from array
void Shuffle(int[] array){
    int p = array.Length;
    for (int n = p-1; n > 0 ; n--)
    {
        int r = _random.Next(1, n);
        int t = array[r];
        array[r] = array[n];
        array[n] = t;
    }
}

【问题讨论】:

    标签: c# function unity3d


    【解决方案1】:

    目前,您的数组是在您的Start() 函数中声明的。这意味着它只能从Start() 函数中访问。如果您希望能够从Start()Update() 访问该数组,则需要通过全局声明来扩大其范围。例如:

    private System.Random _random = new System.Random();
    float sec;
    float timecount;
    float starttime;
    
    //declare array globally
    int[] array = { 1, 2, 3, 4, 5, 6, 7, 8};
    
    void Start () 
    {
      starttime = Time.time;
      Shuffle(array);
      foreach (int value in array)
      {
          Debug.Log(value);
      }
    }
    
    void Update () 
    {
        //now you can access array here, because it is declared globally
    }
    

    此外,请查看 this MSDN article 关于 C# 中的范围。

    【讨论】:

    • 但是如果我全局声明它,如果我调用数组[1],例如,显示的值是在洗牌之前,所以它仍然是数组[1]=2
    • 在调用 shuffle 方法之前是否调用了 array[1]?
    • 我在开始时调用了随机播放方法,因为我只想随机播放一次,然后在更新函数中使用随机播放的数字
    • 所以您是说在 Start 中对全局声明的数组调用 shuffle 后,它们不会在 update 中被改组?
    • 哦,我检查过了,它有效,对不起,我粗心了,谢谢 :)
    【解决方案2】:

    int[] array = { 1, 2, 3, 4, 5, 6, 7, 8}; 移到 Start 函数之外。

    private System.Random _random = new System.Random();
    float sec;
    float timecount;
    float starttime;
    
    int[] array = { 1, 2, 3, 4, 5, 6, 7, 8 };
    
    void Start()
    {
        starttime = Time.time;
        Shuffle(array);
        foreach (int value in array)
        {
            Debug.Log(value);
        }
    }
    
    void Update()
    {
        //time
        timecount = Time.time - starttime;
        sec = (timecount % 60f);
        if (Mathf.Round(sec) == 3f)
        {
            //access shuffled array
            Debug.Log(array[3]);
        }
    }
    
    //for shuffle number from array
    void Shuffle(int[] array)
    {
        int p = array.Length;
        for (int n = p - 1; n > 0; n--)
        {
            int r = _random.Next(0, n);
            int t = array[r];
            array[r] = array[n];
            array[n] = t;
        }
    }
    

    编辑与您的问题无关

    您的随机播放功能存在错误。 array[0] 将永远保持 1 并且永远不会改变。要解决此问题,请将 Shuffle 函数中的 int r = _random.Next(1, n); 替换为 int r = _random.Next(0, n);

    【讨论】:

      【解决方案3】:

      这个算法还是有问题的。想象一个值为 0、1、2 的数组 可能的洗牌应该是:

      0 1 2 0 2 1 1 0 2 1 2 0 2 0 1 2 1 0

      并且每种情况的概率应该相同。实现这个修改 int r = _random.Next(0, n+1); 因为Random.Next 的最大值是独占的(见文档)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-29
        • 1970-01-01
        • 1970-01-01
        • 2017-09-07
        • 1970-01-01
        • 2020-11-01
        • 2018-08-09
        • 1970-01-01
        相关资源
        最近更新 更多