Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity-网格生成和平铺邻居,我如何读取它们?_C#_Unity3d_Grid_Neighbours - Fatal编程技术网

C# Unity-网格生成和平铺邻居,我如何读取它们?

C# Unity-网格生成和平铺邻居,我如何读取它们?,c#,unity3d,grid,neighbours,C#,Unity3d,Grid,Neighbours,因此,目前我正在制作一个小游戏,我正在使用细胞自动机生成世界 所以我的问题来了。 我试图找到一种方法来阅读和分配瓷砖的邻居 将创建一个平铺,并将其4个邻居(上面、右边、左边和下面)分配给它,它可以通过代码访问这些平铺。(世界一代所需) 我不想使用Rayscast或Spheres来检测邻居,因为它会降低性能并很快变得混乱 几周来我一直在努力寻找解决问题的方法,但我不明白该如何解决这个问题 这是我给世界一代的代码 public class WorldGenerator : MonoBehaviour

因此,目前我正在制作一个小游戏,我正在使用细胞自动机生成世界

所以我的问题来了。 我试图找到一种方法来阅读和分配瓷砖的邻居

将创建一个平铺,并将其4个邻居(上面、右边、左边和下面)分配给它,它可以通过代码访问这些平铺。(世界一代所需)

我不想使用Rayscast或Spheres来检测邻居,因为它会降低性能并很快变得混乱

几周来我一直在努力寻找解决问题的方法,但我不明白该如何解决这个问题

这是我给世界一代的代码

public class WorldGenerator : MonoBehaviour
{
    public int mapSize;
    public string worldSeed;
    public bool useRandomSeed;

    [Range(0, 100)]
    public int percentOfMapIsLand;
    public GameObject tile;
    public List<GameObject> tiles;

    public int[,] mapFilled;

    // Start is called before the first frame update
    void Start()
    {
        RandomlyFillMap();
        GenerateStartingGrid();
        AssignTileNeighbors();
    }

    void RandomlyFillMap()
    {
        mapFilled = new int[mapSize, mapSize];

        if (useRandomSeed) { worldSeed = Time.time.ToString(); }

        System.Random randomNumber = new System.Random(worldSeed.GetHashCode());

        for (int x = 0; x < mapSize; x++)
        {
            for (int y = 0; y < mapSize; y++)
            {
                mapFilled[x, y] = (randomNumber.Next(0, 100) < percentOfMapIsLand) ? 1 : 0;
            }
        }
    }

    void GenerateStartingGrid() 
    {
        for (int x = 0; x < mapSize; x++)
        {
            for (int y = 0; y < mapSize; y++)
            {
                if( mapFilled[x,y] == 0) 
                {
                    Vector3 tilePosition = new Vector3(-mapSize / 2 + x, 0, -mapSize / 2 + y);

                    GameObject newTile = Instantiate(tile, tilePosition, Quaternion.Euler(Vector3.right * 90f)) as GameObject;
                    newTile.transform.SetParent(transform, false);
                    tiles.Add(newTile);        
                }
                else { continue; }
                
            }
        }
    }

    void AssignTileNeighbors() 
    {
        for (int x = 0; x < mapSize; x++)
        {
            for (int y = 0; y < mapSize; y++)
            {
                //ASIGN NEIGHBOURS HERE//


            }
        }
    }
}

首先,您不仅需要存储
int
值,还需要存储您的分幅,因此我会将值与分幅一起存储

public class Tile : MonoBehaviour
{
    public bool IsLand;

    // What you have you have ;)
    public Vector2Int GridPosition;

    public Tile neighbor_UP;
    public Tile neighbor_RIGHT;
    public Tile neighbor_LEFT;
    public Tile neighbor_DOWN;
}
那么让我们假设网格看起来像

Y
^ 03 13 23 33
| 02 12 22 32
| 01 11 21 31  
| 00 10 20 30
  ----------> X
其中第一个值是
x
第二个值是
y
mapSize=4
,如您所见,您可以通过这样轻松地浏览磁贴(示例当前磁贴是
21

  • 向上:
    y+1
    ,示例:
    21
    → <代码>22
  • 向下:
    y-1
    ,示例:
    21
    → <代码>20
  • 左:
    x-1
    ,示例:
    21
    → <代码>12
  • 右:
    x+1
    ,示例:
    21
    → <代码>32
那你就可以做了

public class WorldGenerator : MonoBehaviour
{
    public int mapSize;
    public string worldSeed;
    public bool useRandomSeed;

    [Range(0, 100)]
    public int percentOfMapIsLand;
    // Make your prefabs of type Tile instead
    public Tile tile;

    // instead store Tile instances
    public Tile[,] mapFilled;

    void Start()
    {
        RandomlyFillMap();
        AssignTileNeighbors();
    }

    void RandomlyFillMap()
    {
        // In one go cretae the random values and all tile instances
        mapFilled = new Tile[mapSize, mapSize];

        if (useRandomSeed) 
        { 
            worldSeed = Time.time.ToString(); 
        }

        var randomNumber = new System.Random(worldSeed.GetHashCode());

        for (int x = 0; x < mapSize; x++)
        {
            for (int y = 0; y < mapSize; y++)
            {
                // To make things easier I would rather create all the tiles
                // Even though this means a bit more overhead ONCE
                // That's up to you ofcourse .. you could as well just not create them and then 
                // the according values in the neighbors would be not assigned
                var isLand = randomNumber.Next(0, 100) < percentOfMapIsLand;

                var tilePosition = new Vector3(-mapSize / 2 + x, 0, -mapSize / 2 + y);
                var newTile = Instantiate(tile, tilePosition, Quaternion.Euler(Vector3.right * 90f));
                newTile.transform.SetParent(transform, false);
                newTile.IsLand = isLand; 
                newTile.GridPosition = new Vector2Int(x, y);
                
                // Then simply disable the tiles you don't need
                newTile.SetActive(isLand); 
                // And store them in the map
                mapFilled[x, y] = newTile;
            }
        }
    }

    void AssignTileNeighbors() 
    {
        for (int x = 0; x < mapSize; x++)
        {
            for (int y = 0; y < mapSize; y++)
            {
                // And now we just use the rules from before to get the neighbors
                // for the edges the neighbors will stay unassigned
                var tile = mapFilled[x,y];
                // For each assignment we check whether the neighbor would still be within the map bounds
                // if not, that means we are an edge tile and there exists no further neighbor
                tile.neighbor_UP = y < mapSize - 1 ? mapFilled[x, y + 1];
                tile.neighbor_DOWN = y > 0 ? mapFilled[x, y - 1];
                tile.neighbor_LEFT = x > 0 ? mapFilled[x - 1, y];
                tile.neighbor_RIGHT = x < mapSize - 1 ? mapFilled[x + 1, y];
            }
        }
    }
公共类WorldGenerator:MonoBehavior
{
公共int地图大小;
公共种子;
公共bool用户和omseed;
[范围(0,100)]
马匹兰的公共单位百分比;
//将预制件改为瓷砖类型
公共瓷砖;
//而是存储平铺实例
公共瓷砖[,]已填充;
void Start()
{
RandomlyFillMap();
AssignTileNeighbors();
}
void RandomlyFillMap()
{
//一次性创建随机值和所有平铺实例
mapFilled=新磁贴[mapSize,mapSize];
if(useRandomSeed)
{ 
worldSeed=Time.Time.ToString();
}
var randomNumber=new System.Random(worldSeed.GetHashCode());
对于(int x=0;x0?映射填充[x,y-1];
tile.neighbor_LEFT=x>0?映射填充[x-1,y];
tile.neighbor_RIGHT=x
首先,您不仅需要存储
int
值,还需要存储您的磁贴,因此我会将值与磁贴一起存储

public class Tile : MonoBehaviour
{
    public bool IsLand;

    // What you have you have ;)
    public Vector2Int GridPosition;

    public Tile neighbor_UP;
    public Tile neighbor_RIGHT;
    public Tile neighbor_LEFT;
    public Tile neighbor_DOWN;
}
那么让我们假设网格看起来像

Y
^ 03 13 23 33
| 02 12 22 32
| 01 11 21 31  
| 00 10 20 30
  ----------> X
其中第一个值是
x
第二个值是
y
mapSize=4
,如您所见,您可以通过这样轻松地浏览磁贴(示例当前磁贴是
21

  • 向上:
    y+1
    ,示例:
    21
    → <代码>22
  • 向下:
    y-1
    ,示例:
    21
    → <代码>20
  • 左:
    x-1
    ,示例:
    21
    → <代码>12
  • 右:
    x+1
    ,示例:
    21
    → <代码>32
那你就可以做了

public class WorldGenerator : MonoBehaviour
{
    public int mapSize;
    public string worldSeed;
    public bool useRandomSeed;

    [Range(0, 100)]
    public int percentOfMapIsLand;
    // Make your prefabs of type Tile instead
    public Tile tile;

    // instead store Tile instances
    public Tile[,] mapFilled;

    void Start()
    {
        RandomlyFillMap();
        AssignTileNeighbors();
    }

    void RandomlyFillMap()
    {
        // In one go cretae the random values and all tile instances
        mapFilled = new Tile[mapSize, mapSize];

        if (useRandomSeed) 
        { 
            worldSeed = Time.time.ToString(); 
        }

        var randomNumber = new System.Random(worldSeed.GetHashCode());

        for (int x = 0; x < mapSize; x++)
        {
            for (int y = 0; y < mapSize; y++)
            {
                // To make things easier I would rather create all the tiles
                // Even though this means a bit more overhead ONCE
                // That's up to you ofcourse .. you could as well just not create them and then 
                // the according values in the neighbors would be not assigned
                var isLand = randomNumber.Next(0, 100) < percentOfMapIsLand;

                var tilePosition = new Vector3(-mapSize / 2 + x, 0, -mapSize / 2 + y);
                var newTile = Instantiate(tile, tilePosition, Quaternion.Euler(Vector3.right * 90f));
                newTile.transform.SetParent(transform, false);
                newTile.IsLand = isLand; 
                newTile.GridPosition = new Vector2Int(x, y);
                
                // Then simply disable the tiles you don't need
                newTile.SetActive(isLand); 
                // And store them in the map
                mapFilled[x, y] = newTile;
            }
        }
    }

    void AssignTileNeighbors() 
    {
        for (int x = 0; x < mapSize; x++)
        {
            for (int y = 0; y < mapSize; y++)
            {
                // And now we just use the rules from before to get the neighbors
                // for the edges the neighbors will stay unassigned
                var tile = mapFilled[x,y];
                // For each assignment we check whether the neighbor would still be within the map bounds
                // if not, that means we are an edge tile and there exists no further neighbor
                tile.neighbor_UP = y < mapSize - 1 ? mapFilled[x, y + 1];
                tile.neighbor_DOWN = y > 0 ? mapFilled[x, y - 1];
                tile.neighbor_LEFT = x > 0 ? mapFilled[x - 1, y];
                tile.neighbor_RIGHT = x < mapSize - 1 ? mapFilled[x + 1, y];
            }
        }
    }
公共类WorldGenerator:MonoBehavior
{
公共int地图大小;
公共种子;
公共bool用户和omseed;
[范围(0,100)]
马匹兰的公共单位百分比;
//将预制件改为瓷砖类型
公共瓷砖;
//而是存储平铺实例
公共瓷砖[,]已填充;
void Start()
{
RandomlyFillMap();
AssignTileNeighbors();
}
void RandomlyFillMap()
{
//一次性创建随机值和所有平铺实例
mapFilled=新磁贴[mapSize,mapSize];
if(useRandomSeed)
{ 
worldSeed=Time.Time.ToString();
}
var randomNumber=new System.Random(worldSeed.GetHashCode());
对于(int x=0;x