Генерация рандомизатора Unity приводит к неслучайному градиенту - PullRequest
0 голосов
/ 06 мая 2020

Я использую код из серии руководств «Сделай игру» Себастьяна Лага, и до сих пор все было легко адаптировано к новым версиям unity. Однако в Эпизоде ​​9 я застрял. Я адаптировал код генератора карт, чтобы он скомпилировался в моей версии unity, 2019.3.11f1. Тем не менее, генерация случайной карты, похоже, смещена в сторону наименее скоординированной карты.

Результаты My Gen:

My Gen

Что должно выглядит так:

[target[2]

Этот код представляет собой скрипт генератора карты, он помещается в пустое пространство в мире и добавляет кубики в качестве препятствий, снабженных некоторыми префабами.

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;
    }
}

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 06 мая 2020
int randomIndex = prng.Next(i, array.Length);

Вы увеличиваете зажим на вашем rng в этой строке в вашем for l oop, поэтому он становится все более смещенным к концу массива, также я добавил код для обмена позициями, а не дублирования позиции попробуйте что-то вроде этого

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;
...