我想要的效果是:我在Unity,版本2020.3.31。里写了一个缩放地图,我希望在Unity检查器里改动一个值,就可以缩放整个地图(包括地板、障碍物、)
我做出来的效果:如图


改动值:tilesize(默认为1),缩放的仅仅只是障碍物的大小,而且障碍物重叠了,这不是我想要的效果,而且地图大小整体没变化。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapGenerator : MonoBehaviour
{
public float tilesize = 1;//建立可外控地图缩放(初始位1)
public Transform Quad;
public int seed;
public Transform mapPoint;
public Vector2 mapSize;
public Transform tilePresf;//建立瓦片(单个网格)
public Transform obsPresf;//建立障碍物的预制体
[Range(0, 1)]
public float obsPercent;
List<Coord> coordsList;
[Range(0, 1)]
public float outinePercent;
Queue<Coord> coordQueue;
Coord mapCenter;//地图中心点,用于玩家生成
public Vector2 mapMaxSize;//最大地图大小(使其可以在外面设置)
public void GenerateMap()
{
coordsList = new List<Coord>();
if (mapPoint != null)
{
DestroyImmediate(mapPoint.gameObject);//每帧删除(大概)
mapPoint = new GameObject().transform;
mapPoint.parent = transform;
}
mapCenter = new Coord((int)mapSize.x / 2, (int)mapSize.y / 2);
for (int x = 0; x < mapSize.x; x++)//生成瓦片
{
for (int y = 0;y<mapSize.y;y++)
{
Transform newTile = Instantiate(tilePresf);
newTile.position = new Vector3(-mapSize.x/2+0.5f + x, 0, -mapSize.y/2+y + 0.5f);
newTile.parent = mapPoint;
newTile.localScale *= outinePercent * tilesize;//缩放1在这里!!!-----------------------------------------------------------
coordsList.Add(new Coord(x, y));//把每个瓦片的位置信息传入list用于随机生成障碍物
}
}
int currentOvstacleCount = 0;
coordQueue = new Queue<Coord>(Utilities.Shuffle<Coord>(coordsList.ToArray(), seed));//这一步的意义是打乱list里的元素
int obstacleCount = (int)(mapSize.x * mapSize.y * obsPercent);//假设的障碍物数量
Debug.Log(obstacleCount);
bool[,] obstacleMap = new bool[(int)mapSize.x, (int)mapSize.y];//这个布尔是用来记录生成障碍物可否的;
for (int i = 0;i<obstacleCount;i++)
{
currentOvstacleCount++;//假设这里可以生成障碍物
Coord tile = GetRandomCoord();//得到一个经过打乱的元素
obstacleMap[tile.x, tile.y] = true;//假设这里不可通行
if(tile != mapCenter && MapIsFullyAccessble(obstacleMap,currentOvstacleCount))
{
Transform newObs = Instantiate(obsPresf);//实例化障碍物
newObs.position = new Vector3(-mapSize.x / 2 + 0.5f + tile.x, 0, -mapSize.y / 2 + tile.y + 0.5f);
newObs.parent = mapPoint;
newObs.localScale *= outinePercent * tilesize;//缩放2在这里!!!-----------------------------------------------------------------------------------------------
newObs.localScale = new Vector3(newObs.localScale.x, 1, newObs.localScale.z);
}
else
{
currentOvstacleCount--;//假设这里可以生成障碍物
obstacleMap[tile.x, tile.y] = false;//假设这里不可通行
}
}
Quad.localScale = new Vector3(mapMaxSize.x, mapMaxSize.y, 1) * tilesize;//缩放3在这里!!!-------------------------------------------------------------------------------------------
}
Coord GetRandomCoord()
{
Coord coord = coordQueue.Dequeue();
coordQueue.Enqueue(coord);
return coord;
}
bool MapIsFullyAccessble(bool[,] obstaqleMap,int currentObstacleCount)
{
bool[,] mapLogs = new bool[obstaqleMap. GetLength(0), obstaqleMap.GetLength(1)];
mapLogs[mapCenter.x, mapCenter.y] = true;//一开始就把中心点标记为已经检测过了
int accessibleTileCount = 1;//可通行区域 +1
Queue<Coord> queue = new Queue<Coord>();//用于记录遍历所有的瓦片
queue.Enqueue(new Coord(mapCenter.x, mapCenter.y));
while(queue.Count > 0)
{
Coord coord = queue.Dequeue();
for(int x = -1; x < 2; x++)
{
for (int y = -1; y < 2; y++)
{
int neiighourX = coord.x + x;
int neiighourY = coord.y + y;
if (x == 0 || y == 0)//判断四边
{
if (neiighourX >= 0 && neiighourX < mapSize.x && neiighourY >= 0 && neiighourY < mapSize.y)//判断地图边界,保障障碍物不会超出索引范围
{
if (!mapLogs[neiighourX, neiighourY] && !obstaqleMap[neiighourX, neiighourY])//判断是否已经检测过了
{
queue.Enqueue(new Coord(neiighourX, neiighourY));//加入队列开始下一轮遍历
mapLogs[neiighourX, neiighourY] = true;//标记为已经检测过的
accessibleTileCount++;//可通行区域++
}
}
}
}
}
}
int s = (int)(mapSize.x * mapSize.y) - currentObstacleCount;//得到的实际的可通行区域的数量
return accessibleTileCount == s;//把洪水填充算法得到的可通行区域和实际可通行区域的数量进行比较
}
//private void Start()
//{
//GenerateMap();
//}
}
public struct Coord
{
public int x;//意同下
public int y;//这两个值是用来记录地图的
public Coord(int x,int y)
{
this.x = x;
this.y = y;
}
public static bool operator != (Coord c1,Coord c2)
{
return !(c1 == c2);
}
public static bool operator ==(Coord c1, Coord c2)
{
return c1.x == c2.x && c1.y == c2.y;
}
}
想要改动地图缩放值改动,障碍物大小和障碍物间距一起缩放,还有地板(瓦片)大小与间距,该怎么办?