为什么该方法在返回随机值时返回相同的值两次?

时间:2016-04-04 07:55:29

标签: c# arrays random unity3d return-value

我正在制作一个“建塔”游戏。在我的游戏中,我随机地将立方体边纹理化,因此每个新立方体的每一面都有随机纹理。新的多维数据集由附加到“gamemanager”空游戏对象的脚本创建。这个游戏管理器将“TextureController”脚本附加到每个新的多维数据集。此脚本负责创建纹理图集并为多维数据集的每一侧拾取UV。纹理被加载并存储在“TextureContainer”脚本(也附加到“gamemanager”)中,该脚本具有返回随机纹理数组的方法。这很有效,除了一件事,按计划进行。第一个(基础)多维数据集不是由脚本创建的,而是由我设置的。它有一个不同的脚本(我们称之为“baseCubeTextures”),它必须从“gamemanager”获取数组,创建自己的textureatlas并将UV设置到多维数据集的两侧。但问题是基本多维数据集的纹理总是与脚本第一次创建的多维数据集相同。为了使它更清晰:

GameManager有一个脚本GameManagerScript,其方法为CreateNextCube(),其中有一行:

playerCube.AddComponent<TextureController>().atlasTextures = GetComponent<TextureContainer>().getTextures(TextureSize.Ten);

它还附加了TextureContainer脚本。

TextureContainer有一个返回随机纹理数组的方法:

public Texture2D[] getTextures(TextureSize textureSize)
{

    switch (textureSize)
    {
        case TextureSize.Ten:
            textures[0] = textures10x6[Random.Range(0, textures10x6.Length)];
            textures[2] = textures10x6[Random.Range(0, textures10x6.Length)];
            textures[4] = textures10x6[Random.Range(0, textures10x6.Length)];
            textures[5] = textures10x6[Random.Range(0, textures10x6.Length)];

            break;
        case TextureSize.Eight:
            break;
        case TextureSize.Six:
            break;
        case TextureSize.Four:
            break;
        case TextureSize.Two:
            break;
        case TextureSize.One:
            break;
        default:
            break;
    }

    textures[1] = topBottomtextures[Random.Range(0, topBottomtextures.Length)];
    textures[3] = topBottomtextures[Random.Range(0, topBottomtextures.Length)];

    return textures;
}

基础多维数据集的脚本或多或少看起来像这样:

public GameObject gameController;
private Texture2D[] atlasTextures = new Texture2D[7];
private Texture2D atlas;

Mesh mesh;
Vector2[] originalUVs;
private Rect[] atlasUVs;
// Use this for initialization
void Start()
{
    atlasTextures = gameController.GetComponent<TextureContainer>().getTextures(TextureSize.Ten);
// code for setting UVs
}

那么为什么我从getTextures()方法获得相同的纹理?是因为我几乎同时调用这个方法(在两个脚本的Start()中调用方法)?我读到随机数生成器可能会发生这种情况。可以在某种程度上避免这里吗?

2 个答案:

答案 0 :(得分:1)

我需要完整的代码才能确定,但​​我认为这里的问题是附加在GameManagerScript上的TextureContainer脚本总是返回相同的数组指针“textures”。

你在函数的开头缺少一个“Texture2D [] textures = new Texture2D []”。

答案 1 :(得分:1)

我知道这已经得到了解答,但我决定提供我的答案,因为我已经在研究这个问题,当前的解决方案无法使随机数不是重复。所以你可能会有两面具有相同的纹理。

如果在2秒内无法生成随机数,则使用计时器停止以下功能。你总是可以改变它。 Unity也有一个针对Random类的错误,它有时会在函数中使用while循环返回相同的数字。即使您使用System.Random类,Unity中也存在此错误。

这两个函数应该使纹理的随机数不重复。

/// FOR textures10x6
    public List<int> newRandtextures10x6List = new List<int>();
    private void newRandtextures10x6Func(int arrayAmount)
    {
        System.Random a = new System.Random();
        int MyNumber = 0;

        //Reset
        newRandtextures10x6List.Clear();

        //2 seconds Timer. If it blocks exit 2 seconds exit
        System.DateTime startTime = System.DateTime.UtcNow;
        System.TimeSpan exitTime = System.TimeSpan.FromSeconds(2);

        bool quitRand = false;

        for (int i = 0; i < arrayAmount; i++)
        {
            do
            {
                if (System.DateTime.UtcNow - startTime > exitTime)
                {
                    quitRand = true;
                    Debug.Log("Time out Reached! ...Assigning 0 to it");
                    newRandtextures10x6List.Add(0);
                    break;
                }
                MyNumber = a.Next(0, arrayAmount);
            } while (newRandtextures10x6List.Contains(MyNumber));
            newRandtextures10x6List.Add(MyNumber);

            /* OPTIONAL. WILL QUIT THE WHOLE FUNCTION INSTEAD OF JUST THE WHILE LOOP
            if (quitRand)
            {
                break;
            }*/
        }
    }

    /// FOR topBottomtextures
    public List<int> newRandTopBottomtexturesList = new List<int>();
    private void newRandTopBottomtexturesFunc(int arrayAmount)
    {
        System.Random a = new System.Random();
        int MyNumber = 0;

        //Reset
        newRandTopBottomtexturesList.Clear();

        //2 seconds Timer. If it blocks exit 2 seconds exit
        System.DateTime startTime = System.DateTime.UtcNow;
        System.TimeSpan exitTime = System.TimeSpan.FromSeconds(2);

        bool quitRand = false;

        for (int i = 0; i < arrayAmount; i++)
        {
            do
            {
                if (System.DateTime.UtcNow - startTime > exitTime)
                {
                    quitRand = true;
                    Debug.Log("Time out Reached! ...Assigning 0 to it");
                    newRandTopBottomtexturesList.Add(0);
                    break;
                }
                MyNumber = a.Next(0, arrayAmount);
            } while (newRandTopBottomtexturesList.Contains(MyNumber));
            newRandTopBottomtexturesList.Add(MyNumber);

            /* OPTIONAL. WILL QUIT THE WHOLE FUNCTION INSTEAD OF JUST THE WHILE LOOP
            if (quitRand)
            {
                break;
            }*/
        }
    }

要测试您可以使用的newRandtextures10x6Func()功能:

 newRandtextures10x6Func(6);

for (int i = 0; i < newRandtextures10x6List.Count; i++)
{
    Debug.Log(newRandtextures10x6List[i]);
}

它将生成6个不同的数字,它们将永远不会相同。

以下是您问题的其余代码。

public Texture2D[] getTextures(TextureSize textureSize)
    {

        switch (textureSize)
        {
            case TextureSize.Ten:

                //Generate the random numbers here with no repeated values
                newRandtextures10x6Func(textures10x6.Length);
                textures[0] = textures10x6[newRandtextures10x6List[0]];
                textures[2] = textures10x6[newRandtextures10x6List[2]];
                textures[4] = textures10x6[newRandtextures10x6List[4]];
                textures[5] = textures10x6[newRandtextures10x6List[5]];

                break;
            case TextureSize.Eight:
                break;
            case TextureSize.Six:
                break;
            case TextureSize.Four:
                break;
            case TextureSize.Two:
                break;
            case TextureSize.One:
                break;
            default:
                break;
        }

        //Generate the random numbers here with no repeated values
        newRandTopBottomtexturesFunc(topBottomtextures.Length);
        textures[1] = topBottomtextures[newRandTopBottomtexturesList[0]];
        textures[3] = topBottomtextures[newRandTopBottomtexturesList[1]];

        return textures;
    }