基于位置的一致随机数(不是基于噪声)

时间:2018-09-20 20:21:55

标签: c# unity3d

我正在寻找一种在特定地图坐标处的两个范围之间选择一个随机数的好方法,该坐标始终基于该坐标返回相同的数字。

在上下文中,我有一个地图生成器,该地图生成器使用perlin噪声进行构建,放置水,草,岩石等,效果很好,但是每个图块可以具有其他纹理,例如,草图块可能具有5个其他纹理它可以使用。我希望能够完全随机地生成其中之一,但是在每次播放中都需要保持一致,并且不使用Perlin噪声,因为这通常会产生流动(一种纹理中的一些紧随其后的一些下一纹理中的等等

值得注意的是,我不能为此设置随机种子,因为世界的这一部分可以随时生成,而不是按特定顺序生成。

我尝试了以下操作:

public static int PerlinNoiseCalcInt(float x, float y, float size, float power, int min, int max) {
        int f = Mathf.RoundToInt(Mathf.PerlinNoise(x / size * power, y / size * power) * max + min);
        return f < max ? f : max--;
    }

这种类型的作品,但是正如您可能期望的那样,它提供了一堆纹理,然后又是一堆纹理,我真的希望它看起来非常随机,但是每次在那个地图位置每次都一样

3 个答案:

答案 0 :(得分:1)

我不确定我是否正确理解您要寻找的内容,但是您是否尝试查看Voronoi Diagrams?该算法将是这样的:

  • 获取一堆称为种子或生成器的随机点,并为它们应用随机纹理(种子越多,获得的区域就越多)
  • 对于每个点,找到最近的种子并将其应用于相同的纹理

如果只跟踪种子,则每次都可以以相同的外观进行再生。如果您想更多地生成一种纹理而不是另一种纹理,则还可以发挥几率。

答案 1 :(得分:1)

  

值得注意的是,我不能为此设置随机种子,因为世界的这一部分可以随时生成,而不是按特定顺序生成。

使用坐标哈希作为种子,为每个坐标创建一个新的System.Random。

// this would be your coordinate
var coord = Vector3.one;

var rng = new System.Random(coord.GetHashCode());

// the below will always be the same (as long as coord doesn't change)
var rand1 = rng.Next();
var rand2 = rng.Next();
var rand3 = rng.Next();

答案 2 :(得分:1)

当您说“一致”时,您是说“确定性”吗?

有很多方法可以做到这一点。您可以使用任何随机数函数,其中参数是坐标的某种组合。

例如:

public int GetTileInt(int x, int y, int seed, int numberOfOptions)
{
     return SomeRandomFunction(x^2*y + 2*y^2*x + seed)%numberOfOptions;
}

这将为坐标和种子的每种组合产生一个唯一的值,但每次都相同。您也可以研究Hashing事物,但这并不是我真正的风格。

另一种选择是将随机int应用于每个图块,而与任何坐标无关。然后,对于每个图块,纹理索引将为可能的纹理数量的模数,然后在该索引处分配纹理。