c# - unity randomizer 生成导致非随机梯度
问题描述
我正在使用 Sebastian Lague 的教程系列“制作游戏”中的代码,到目前为止,一切都已轻松适应新版本的统一。然而,在第 9 集,我已经变得不合时宜了。我已经修改了地图生成器的代码,以使其在我的统一版本中编译,2019.3.11f1
. 然而,随机地图生成似乎偏向于地图的最低协调。
我的一代结果:
它应该是什么样子:
[
这段代码是地图生成器脚本,它被放置在世界中的一个空地上,并添加了立方体作为障碍物,并提供了一些预制件。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapGenerator : MonoBehaviour
{
public Transform tilePrefab;
public Vector2 mapSize;
public int seed = 10;
public Transform obstaclePrefab;
public int obstacleCount = 10;
[Range(0, 1)]
public float outlinePercent; // Cotrols scale of tiles
List<Coord> allTileCoords;
Queue<Coord> shuffledTileCoords;
private void Start()
{
GenerateMap();
}
public void GenerateMap()
{
allTileCoords = new List<Coord>();
for (int x = 0; x < mapSize.x; x++)
{
for (int y = 0; y < mapSize.y; y++)
{
allTileCoords.Add(new Coord(x, y)); //iterate through mapSize adding tiles
}
}
shuffledTileCoords = new Queue<Coord>(Utility.ShuffleArray(allTileCoords.ToArray(), seed)); //shuffled array of tiles coords
string holderName = "Generated Map"; //Added for the editor script
if (GameObject.Find(holderName)) //Added for the editor script
{ //Added for the editor script
DestroyImmediate(GameObject.Find(holderName)); //Added for the editor script
} //Added for the editor script
Transform mapHolder = new GameObject(holderName).transform; //This is only neccessary because of the editor script
mapHolder.parent = transform; //This is only neccessary because of the editor script
for (int x = 0; x < mapSize.x; x++)
{
for (int y = 0; y < mapSize.y; y++)
{
Vector3 tilePosition = relativeToSpacial(x, y); //converts grid x,y data to real spatial coords
Transform newTile = Instantiate(tilePrefab, tilePosition, Quaternion.Euler(Vector3.right * 90)) as Transform; //instantiates tile in loctaion from rel to spatial func with 90 rotation
newTile.localScale = Vector3.one * (1 - outlinePercent); //scales down tiles to leave a outline
newTile.parent = mapHolder;
}
}
for (int i = 0; i < obstacleCount; i++)
{
Coord randomCoord = GetRandomCoord();
Vector3 obstaclePosition = relativeToSpacial(randomCoord.x, randomCoord.y);
Transform newObstacle = Instantiate(obstaclePrefab, obstaclePosition + Vector3.up * .5f, Quaternion.identity) as Transform;
newObstacle.parent = mapHolder;
}
}
Vector3 relativeToSpacial(int x, int y)
{
return new Vector3(-mapSize.x / 2 + .5f + x, 0, -mapSize.y / 2 + .5f + y);
}
public Coord GetRandomCoord()
{
Coord randomCoord = shuffledTileCoords.Dequeue();
shuffledTileCoords.Enqueue(randomCoord);
//print("|| " + randomCoord.x + " || " + randomCoord.y + " ||");
return randomCoord;
}
public struct Coord
{
public int x;
public int y;
public Coord(int _x, int _y)
{
x = _x;
y = _y;
}
}
}
Utility.ShuffleArray
这是我用于改组数组的自定义函数的代码。
using System.Collections;
using System.Collections.Generic;
public static class Utility
{
public static T[] ShuffleArray<T>(T[] array, int seed)
{
System.Random prng = new System.Random(seed);
for (int i =0; i < array.Length -1; i++)
{
int randomIndex = prng.Next(i, array.Length);
T tempItem = array[randomIndex];
array[randomIndex] = array[i];
}
return array;
}
}
任何帮助表示赞赏。
解决方案
int randomIndex = prng.Next(i, array.Length);
您在 for 循环的这一行中增加了 rng 上的钳位,因此它越来越偏向数组的末尾,我还添加了代码来交换位置而不是重复位置尝试这样的事情
int randomIndex = prng.Next(0, array.Length);
T tempItem = array[randomIndex];
T tempItemTwo = array[i];
array[randomIndex] = array[i];
array[i] = tempItemTWo;
如果这不起作用,请尝试:
int randomIndex = prng.Next(i, array.Length);
T tempItem = array[randomIndex];
T tempItemTwo = array[i];
array[randomIndex] = array[i];
array[i] = tempItemTWo;
推荐阅读
- spring-boot - ConnectionClosedException:使用 apache hhtpclient 4.5.5 的块编码消息正文过早结束
- loops - 如何同时循环并继续运行脚本(自动热键)
- postgresql - 使用 typeorm 进行跨模式连接
- sql - 这个带有别名表的可疑 SQL 更新语法是否正确?
- php - htaccess - 重定向 GET 参数
- chartify - 如何在 Chartify 图中添加网格线?
- google-sheets - 谷歌表,SUMIF 函数给出:“参数必须是一个范围”错误,如果我使用 ADDRESS 函数作为范围的第二个参数
- r - 从数据框中选择值
- laravel - 带有 VueJS 的 JQUERY 数据表
- perl - Per:子程序的变量对其子程序的可见性