C# 程序地形生成尖峰错误
我的地形管理器遇到了一个问题,我得到的是这些奇怪的尖刺柱,而不是普通地形(如果这一代有正常地形),有什么想法吗 图像:C# 程序地形生成尖峰错误,c#,unity3d,unity5,procedural-generation,C#,Unity3d,Unity5,Procedural Generation,我的地形管理器遇到了一个问题,我得到的是这些奇怪的尖刺柱,而不是普通地形(如果这一代有正常地形),有什么想法吗 图像: public class TerrainManager : MonoBehaviour, ICameraObserver { public Terrain mainTerrain; public float terrainChangeRate = 0.0001f; public int brushArea = 20; public static int viewDistanc
public class TerrainManager : MonoBehaviour, ICameraObserver {
public Terrain mainTerrain;
public float terrainChangeRate = 0.0001f;
public int brushArea = 20;
public static int viewDistance = 9;
public static Vector2 VECTOR_WILDCARD = new Vector2(-10000, -10000);
int resolutionX;
int resolutionY;
float[,] heights;
int heightEdit = 1;
//Chunks
List<Vector2> loadedChunks = new List<Vector2>();
Vector2[] visibleChunks = null;
Terrain[] chunkGraphics = new Terrain[viewDistance];
Vector2 curChunkIndex = new Vector2();
int chunkSizeX = 256;
int chunkSizeY = 256;
// Use this for initialization
void Start () {
resolutionX = mainTerrain.terrainData.heightmapWidth;
resolutionY = mainTerrain.terrainData.heightmapHeight;
heights = mainTerrain.terrainData.GetHeights(0, 0, resolutionX, resolutionY);
Camera.main.GetComponent<RTSCamera>().Subscribe(this);
GameObject world = new GameObject();
world.name = "World";
for (int i = 0; i < viewDistance; i++)
{
GameObject go = new GameObject();
go.name = "Chunk_" + i;
go.transform.SetParent(world.transform);
chunkGraphics[i] = go.AddComponent<Terrain>();
chunkGraphics[i].terrainData = new TerrainData();
go.AddComponent<TerrainCollider>().terrainData = chunkGraphics[i].terrainData;
chunkGraphics[i].terrainData.size = new Vector3((int)(chunkSizeX / 4), 600, (int)(chunkSizeY / 4));
chunkGraphics[i].terrainData.heightmapResolution = (int)(chunkSizeX / 2);
}
onCameraMove(Camera.main.transform.position);
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButton(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
editTerrainHeight(hit.point, terrainChangeRate, brushArea);
}
}
}
void editTerrainHeight(Vector3 position, float amount, int diameter)
{
int terrainPosX = (int)((position.x / mainTerrain.terrainData.size.x) * resolutionX);
int terrainPosY = (int)((position.z / mainTerrain.terrainData.size.z) * resolutionY);
float[,] heightChange = new float[diameter, diameter];
int radius = diameter / 2;
if (Input.GetKey(KeyCode.LeftShift))
{
heightEdit = -1;
}
else
{
heightEdit = 1;
}
amount = amount * heightEdit;
for (int x = 0; x < diameter; x++)
{
for (int y = 0; y < diameter; y++)
{
int x2 = x - radius;
int y2 = y - radius;
heightChange[y, x] = heights[terrainPosY + y2, terrainPosX + x2] + amount;
heights[terrainPosY + y2, terrainPosX + x2] = heightChange[y, x];
}
}
mainTerrain.terrainData.SetHeights(terrainPosX - radius, terrainPosY - radius, heightChange);
}
public void onCameraMove(Vector3 newCameraPosition)
{
int chunkIndexX = Mathf.FloorToInt(newCameraPosition.x / chunkSizeX);
int chunkIndexY = Mathf.FloorToInt(newCameraPosition.z / chunkSizeY);
if (curChunkIndex.x == chunkIndexX && curChunkIndex.y == chunkIndexY)
{
return;
}
curChunkIndex.x = chunkIndexX;
curChunkIndex.y = chunkIndexY;
Vector2[] newVisibleChunks = new Vector2[viewDistance];
newVisibleChunks[0] = new Vector2(chunkIndexX - 1, chunkIndexY +1);
newVisibleChunks[1] = new Vector2(chunkIndexX, chunkIndexY +1);
newVisibleChunks[2] = new Vector2(chunkIndexX + 1, chunkIndexY +1);
newVisibleChunks[3] = new Vector2(chunkIndexX -1, chunkIndexY);
newVisibleChunks[4] = new Vector2(chunkIndexX, chunkIndexY);
newVisibleChunks[5] = new Vector2(chunkIndexX + 1, chunkIndexY);
newVisibleChunks[6] = new Vector2(chunkIndexX - 1, chunkIndexY -1);
newVisibleChunks[7] = new Vector2(chunkIndexX, chunkIndexY -1);
newVisibleChunks[8] = new Vector2(chunkIndexX + 1, chunkIndexY -1);
Terrain[] newChunkGraphics = new Terrain[viewDistance];
List<int> freeTerrains = new List<int>();
List<int> loadingIndexes = new List<int>();
for (int i = 0; i < viewDistance; i++)
{
bool found = false;
for (int j = 0; j < viewDistance; j++)
{
if (visibleChunks == null)
{
break;
}
if (newVisibleChunks[i].Equals(visibleChunks[j]))
{
visibleChunks[j] = VECTOR_WILDCARD;
newChunkGraphics[i] = chunkGraphics[j];
found = true;
break;
}
}
if (!found)
{
loadingIndexes.Add(i);
}
}
if (visibleChunks != null)
{
for (int i = 0; i < viewDistance; i++)
{
if (visibleChunks[i] != VECTOR_WILDCARD)
{
freeTerrains.Add(i);
saveChunkToMemory(chunkGraphics[i], visibleChunks[i]);
}
}
}
else
{
for (int i = 0; i < viewDistance; i++)
{
freeTerrains.Add(i);
}
}
for (int i = 0; i < loadingIndexes.Count; i++)
{
loadChunkFromMemory(newVisibleChunks[loadingIndexes[i]], freeTerrains[i]);
newChunkGraphics[loadingIndexes[i]] = chunkGraphics[freeTerrains[i]];
}
visibleChunks = newVisibleChunks;
chunkGraphics = newChunkGraphics;
}
void loadChunkFromMemory(Vector2 cordIndex, int graphicIndex)
{
bool found = false;
foreach (Vector2 v in loadedChunks)
{
if (v == cordIndex)
{
found = true;
break;
}
}
GameObject terrainGO;
if (!found)
{
terrainGO = generateChunk(cordIndex, graphicIndex);
}
else
{
//Load Chunk from Memory
Debug.Log("Loading Chunk(" + cordIndex.x + "," + cordIndex.y + ")");
terrainGO = chunkGraphics[graphicIndex].gameObject;
}
terrainGO.transform.position = new Vector3(chunkSizeX * cordIndex.x, 0, chunkSizeY * cordIndex.y);
}
GameObject generateChunk(Vector2 cordIndex, int graphicIndex)
{
GameObject terrainGO = chunkGraphics[graphicIndex].gameObject;
loadedChunks.Add(cordIndex);
setTerrainHeightMap(terrainGO.GetComponent<Terrain>(), cordIndex);
return terrainGO;
}
void setTerrainHeightMap(Terrain terrain, Vector2 cordIndex)
{
float[,] heights = new float[terrain.terrainData.heightmapHeight, terrain.terrainData.heightmapWidth];
heights[0, 0] = 0.5f;
heights[terrain.terrainData.heightmapWidth - 1, 0] = 0.5f;
heights[0, terrain.terrainData.heightmapHeight - 1] = 0.5f;
heights[terrain.terrainData.heightmapWidth - 1, terrain.terrainData.heightmapHeight - 1] = 0.5f;
heights = diamondSquare(heights, 0, 0, terrain.terrainData.heightmapWidth - 1, 0);
terrain.terrainData.SetHeights(0, 0, heights);
}
float[,] getTerrainHeightMap(Vector2 cordIndex)
{
return null;
}
float[,] diamondSquare(float[,] heights, int offSetX, int offSetY, int squareSize, int depth)
{
if (squareSize == 1)
{
return heights;
}
float topLeft = heights[offSetY, offSetX];
float topRight = heights[offSetY, offSetX + squareSize];
float bottomLeft = heights[offSetY + squareSize, offSetX];
float bottomRight = heights[offSetY + squareSize, offSetX + squareSize];
int size = squareSize / 2;
if (topLeft == 0 || topRight == 0 || bottomLeft == 0 || bottomRight == 0)
{
Debug.LogError("One or more Corner Seeds have not been set..");
}
if (heights[offSetY + size, offSetX + size] == 0)
{
heights[offSetY + size, offSetX + size] = getRandomHeight(depth + (int)averagePoints(topLeft, topRight, bottomLeft, bottomRight));
}
float centrePoint = heights[offSetY + size, offSetX + size];
//left Diamond
float runningAverage = averagePoints(topLeft, centrePoint, bottomLeft);
if (offSetX - size > 0 && heights[offSetY + size, offSetX - size] != 0)
{
runningAverage = averagePoints(topLeft, centrePoint, bottomLeft, heights[offSetY + size, offSetX - size]);
}
if (heights[offSetY + size, offSetX] == 0)
{
heights[offSetY + size, offSetX] = runningAverage + getRandomHeight(depth);
}
//right Diamond
runningAverage = averagePoints(topRight, centrePoint, bottomRight);
if (offSetX + (squareSize * 1.5f) < heights.GetLength(1) && heights[offSetY + size, offSetX + (int)(squareSize * 1.5f)] != 0)
{
runningAverage = averagePoints(topRight, centrePoint, bottomRight, heights[offSetY + size, offSetX + (int)(squareSize * 1.5f)]);
}
if (heights[offSetY + size, offSetX + squareSize] == 0)
{
heights[offSetY + size, offSetX + squareSize] = runningAverage + getRandomHeight(depth);
}
//top Diamond
runningAverage = averagePoints(topLeft, centrePoint, topRight);
if (offSetY - size > 0 && heights[offSetY - size, offSetX + size] != 0)
{
runningAverage = averagePoints(topLeft, centrePoint, topRight, heights[offSetY - size, offSetX + size]);
}
if (heights[offSetY, offSetX + size] == 0)
{
heights[offSetY, offSetX + size] = runningAverage + getRandomHeight(depth);
}
//bottom Diamond
runningAverage = averagePoints(bottomRight, centrePoint, bottomLeft);
if (offSetY + (squareSize * 1.5f) < heights.GetLength(0) && heights[offSetY + (int)(squareSize * 1.5f), offSetX + size] != 0)
{
runningAverage = averagePoints(bottomRight, centrePoint, topRight, heights[offSetY + (int)(squareSize * 1.5f), offSetX + size]);
}
if (heights[offSetY + squareSize, offSetX + size] == 0)
{
heights[offSetY + squareSize, offSetX + size] = runningAverage + getRandomHeight(depth);
}
heights = diamondSquare(heights, offSetX, offSetY, size, depth + 1);
heights = diamondSquare(heights, offSetX + size, offSetY, size, depth + 1);
heights = diamondSquare(heights, offSetX, offSetY + size, size, depth + 1);
heights = diamondSquare(heights, offSetX + size, offSetY + size, size, depth + 1);
return heights;
}
float averagePoints(float p1, float p2, float p3, float p4)
{
return (p1 + p2 + p3 + p4) * 0.25f;
}
float averagePoints(float p1, float p2, float p3)
{
return (p1 + p2 + p3) * 0.3333f;
}
float getRandomHeight(int depth)
{
return Random.Range(-0.1f, 0.0f) / Mathf.Pow(2, depth);
}
void saveChunkToMemory(Terrain chunk, Vector2 index)
{
Debug.Log("Unloading Chunk(" + index.x + "," + index.y + ")");
}
}
代码:
public class TerrainManager : MonoBehaviour, ICameraObserver {
public Terrain mainTerrain;
public float terrainChangeRate = 0.0001f;
public int brushArea = 20;
public static int viewDistance = 9;
public static Vector2 VECTOR_WILDCARD = new Vector2(-10000, -10000);
int resolutionX;
int resolutionY;
float[,] heights;
int heightEdit = 1;
//Chunks
List<Vector2> loadedChunks = new List<Vector2>();
Vector2[] visibleChunks = null;
Terrain[] chunkGraphics = new Terrain[viewDistance];
Vector2 curChunkIndex = new Vector2();
int chunkSizeX = 256;
int chunkSizeY = 256;
// Use this for initialization
void Start () {
resolutionX = mainTerrain.terrainData.heightmapWidth;
resolutionY = mainTerrain.terrainData.heightmapHeight;
heights = mainTerrain.terrainData.GetHeights(0, 0, resolutionX, resolutionY);
Camera.main.GetComponent<RTSCamera>().Subscribe(this);
GameObject world = new GameObject();
world.name = "World";
for (int i = 0; i < viewDistance; i++)
{
GameObject go = new GameObject();
go.name = "Chunk_" + i;
go.transform.SetParent(world.transform);
chunkGraphics[i] = go.AddComponent<Terrain>();
chunkGraphics[i].terrainData = new TerrainData();
go.AddComponent<TerrainCollider>().terrainData = chunkGraphics[i].terrainData;
chunkGraphics[i].terrainData.size = new Vector3((int)(chunkSizeX / 4), 600, (int)(chunkSizeY / 4));
chunkGraphics[i].terrainData.heightmapResolution = (int)(chunkSizeX / 2);
}
onCameraMove(Camera.main.transform.position);
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButton(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
editTerrainHeight(hit.point, terrainChangeRate, brushArea);
}
}
}
void editTerrainHeight(Vector3 position, float amount, int diameter)
{
int terrainPosX = (int)((position.x / mainTerrain.terrainData.size.x) * resolutionX);
int terrainPosY = (int)((position.z / mainTerrain.terrainData.size.z) * resolutionY);
float[,] heightChange = new float[diameter, diameter];
int radius = diameter / 2;
if (Input.GetKey(KeyCode.LeftShift))
{
heightEdit = -1;
}
else
{
heightEdit = 1;
}
amount = amount * heightEdit;
for (int x = 0; x < diameter; x++)
{
for (int y = 0; y < diameter; y++)
{
int x2 = x - radius;
int y2 = y - radius;
heightChange[y, x] = heights[terrainPosY + y2, terrainPosX + x2] + amount;
heights[terrainPosY + y2, terrainPosX + x2] = heightChange[y, x];
}
}
mainTerrain.terrainData.SetHeights(terrainPosX - radius, terrainPosY - radius, heightChange);
}
public void onCameraMove(Vector3 newCameraPosition)
{
int chunkIndexX = Mathf.FloorToInt(newCameraPosition.x / chunkSizeX);
int chunkIndexY = Mathf.FloorToInt(newCameraPosition.z / chunkSizeY);
if (curChunkIndex.x == chunkIndexX && curChunkIndex.y == chunkIndexY)
{
return;
}
curChunkIndex.x = chunkIndexX;
curChunkIndex.y = chunkIndexY;
Vector2[] newVisibleChunks = new Vector2[viewDistance];
newVisibleChunks[0] = new Vector2(chunkIndexX - 1, chunkIndexY +1);
newVisibleChunks[1] = new Vector2(chunkIndexX, chunkIndexY +1);
newVisibleChunks[2] = new Vector2(chunkIndexX + 1, chunkIndexY +1);
newVisibleChunks[3] = new Vector2(chunkIndexX -1, chunkIndexY);
newVisibleChunks[4] = new Vector2(chunkIndexX, chunkIndexY);
newVisibleChunks[5] = new Vector2(chunkIndexX + 1, chunkIndexY);
newVisibleChunks[6] = new Vector2(chunkIndexX - 1, chunkIndexY -1);
newVisibleChunks[7] = new Vector2(chunkIndexX, chunkIndexY -1);
newVisibleChunks[8] = new Vector2(chunkIndexX + 1, chunkIndexY -1);
Terrain[] newChunkGraphics = new Terrain[viewDistance];
List<int> freeTerrains = new List<int>();
List<int> loadingIndexes = new List<int>();
for (int i = 0; i < viewDistance; i++)
{
bool found = false;
for (int j = 0; j < viewDistance; j++)
{
if (visibleChunks == null)
{
break;
}
if (newVisibleChunks[i].Equals(visibleChunks[j]))
{
visibleChunks[j] = VECTOR_WILDCARD;
newChunkGraphics[i] = chunkGraphics[j];
found = true;
break;
}
}
if (!found)
{
loadingIndexes.Add(i);
}
}
if (visibleChunks != null)
{
for (int i = 0; i < viewDistance; i++)
{
if (visibleChunks[i] != VECTOR_WILDCARD)
{
freeTerrains.Add(i);
saveChunkToMemory(chunkGraphics[i], visibleChunks[i]);
}
}
}
else
{
for (int i = 0; i < viewDistance; i++)
{
freeTerrains.Add(i);
}
}
for (int i = 0; i < loadingIndexes.Count; i++)
{
loadChunkFromMemory(newVisibleChunks[loadingIndexes[i]], freeTerrains[i]);
newChunkGraphics[loadingIndexes[i]] = chunkGraphics[freeTerrains[i]];
}
visibleChunks = newVisibleChunks;
chunkGraphics = newChunkGraphics;
}
void loadChunkFromMemory(Vector2 cordIndex, int graphicIndex)
{
bool found = false;
foreach (Vector2 v in loadedChunks)
{
if (v == cordIndex)
{
found = true;
break;
}
}
GameObject terrainGO;
if (!found)
{
terrainGO = generateChunk(cordIndex, graphicIndex);
}
else
{
//Load Chunk from Memory
Debug.Log("Loading Chunk(" + cordIndex.x + "," + cordIndex.y + ")");
terrainGO = chunkGraphics[graphicIndex].gameObject;
}
terrainGO.transform.position = new Vector3(chunkSizeX * cordIndex.x, 0, chunkSizeY * cordIndex.y);
}
GameObject generateChunk(Vector2 cordIndex, int graphicIndex)
{
GameObject terrainGO = chunkGraphics[graphicIndex].gameObject;
loadedChunks.Add(cordIndex);
setTerrainHeightMap(terrainGO.GetComponent<Terrain>(), cordIndex);
return terrainGO;
}
void setTerrainHeightMap(Terrain terrain, Vector2 cordIndex)
{
float[,] heights = new float[terrain.terrainData.heightmapHeight, terrain.terrainData.heightmapWidth];
heights[0, 0] = 0.5f;
heights[terrain.terrainData.heightmapWidth - 1, 0] = 0.5f;
heights[0, terrain.terrainData.heightmapHeight - 1] = 0.5f;
heights[terrain.terrainData.heightmapWidth - 1, terrain.terrainData.heightmapHeight - 1] = 0.5f;
heights = diamondSquare(heights, 0, 0, terrain.terrainData.heightmapWidth - 1, 0);
terrain.terrainData.SetHeights(0, 0, heights);
}
float[,] getTerrainHeightMap(Vector2 cordIndex)
{
return null;
}
float[,] diamondSquare(float[,] heights, int offSetX, int offSetY, int squareSize, int depth)
{
if (squareSize == 1)
{
return heights;
}
float topLeft = heights[offSetY, offSetX];
float topRight = heights[offSetY, offSetX + squareSize];
float bottomLeft = heights[offSetY + squareSize, offSetX];
float bottomRight = heights[offSetY + squareSize, offSetX + squareSize];
int size = squareSize / 2;
if (topLeft == 0 || topRight == 0 || bottomLeft == 0 || bottomRight == 0)
{
Debug.LogError("One or more Corner Seeds have not been set..");
}
if (heights[offSetY + size, offSetX + size] == 0)
{
heights[offSetY + size, offSetX + size] = getRandomHeight(depth + (int)averagePoints(topLeft, topRight, bottomLeft, bottomRight));
}
float centrePoint = heights[offSetY + size, offSetX + size];
//left Diamond
float runningAverage = averagePoints(topLeft, centrePoint, bottomLeft);
if (offSetX - size > 0 && heights[offSetY + size, offSetX - size] != 0)
{
runningAverage = averagePoints(topLeft, centrePoint, bottomLeft, heights[offSetY + size, offSetX - size]);
}
if (heights[offSetY + size, offSetX] == 0)
{
heights[offSetY + size, offSetX] = runningAverage + getRandomHeight(depth);
}
//right Diamond
runningAverage = averagePoints(topRight, centrePoint, bottomRight);
if (offSetX + (squareSize * 1.5f) < heights.GetLength(1) && heights[offSetY + size, offSetX + (int)(squareSize * 1.5f)] != 0)
{
runningAverage = averagePoints(topRight, centrePoint, bottomRight, heights[offSetY + size, offSetX + (int)(squareSize * 1.5f)]);
}
if (heights[offSetY + size, offSetX + squareSize] == 0)
{
heights[offSetY + size, offSetX + squareSize] = runningAverage + getRandomHeight(depth);
}
//top Diamond
runningAverage = averagePoints(topLeft, centrePoint, topRight);
if (offSetY - size > 0 && heights[offSetY - size, offSetX + size] != 0)
{
runningAverage = averagePoints(topLeft, centrePoint, topRight, heights[offSetY - size, offSetX + size]);
}
if (heights[offSetY, offSetX + size] == 0)
{
heights[offSetY, offSetX + size] = runningAverage + getRandomHeight(depth);
}
//bottom Diamond
runningAverage = averagePoints(bottomRight, centrePoint, bottomLeft);
if (offSetY + (squareSize * 1.5f) < heights.GetLength(0) && heights[offSetY + (int)(squareSize * 1.5f), offSetX + size] != 0)
{
runningAverage = averagePoints(bottomRight, centrePoint, topRight, heights[offSetY + (int)(squareSize * 1.5f), offSetX + size]);
}
if (heights[offSetY + squareSize, offSetX + size] == 0)
{
heights[offSetY + squareSize, offSetX + size] = runningAverage + getRandomHeight(depth);
}
heights = diamondSquare(heights, offSetX, offSetY, size, depth + 1);
heights = diamondSquare(heights, offSetX + size, offSetY, size, depth + 1);
heights = diamondSquare(heights, offSetX, offSetY + size, size, depth + 1);
heights = diamondSquare(heights, offSetX + size, offSetY + size, size, depth + 1);
return heights;
}
float averagePoints(float p1, float p2, float p3, float p4)
{
return (p1 + p2 + p3 + p4) * 0.25f;
}
float averagePoints(float p1, float p2, float p3)
{
return (p1 + p2 + p3) * 0.3333f;
}
float getRandomHeight(int depth)
{
return Random.Range(-0.1f, 0.0f) / Mathf.Pow(2, depth);
}
void saveChunkToMemory(Terrain chunk, Vector2 index)
{
Debug.Log("Unloading Chunk(" + index.x + "," + index.y + ")");
}
}
公共类TerrainManager:MonoBehavior,iCameraoObserver{
公共地形;
公共浮动地形变化率=0.0001f;
公共区域=20;
公共静态int视距=9;
公共静态向量2 VECTOR_通配符=新向量2(-10000,-10000);
内分辨率X;
内分辨率;
浮动高度;
int-heightEdit=1;
//大块
List loadedChunks=新列表();
Vector2[]visibleChunks=null;
Terrain[]chunkGraphics=新地形[视距];
Vector2 curChunkIndex=新Vector2();
int chunkSizeX=256;
int chunkSizeY=256;
//用于初始化
无效开始(){
resolutionX=Main Terrain.terrainData.heightmapWidth;
分辨率=Main Terrain.terrainData.heightmapHeight;
高度=主地形.terrainData.GetHeights(0,0,分辨率x,分辨率y);
Camera.main.GetComponent().Subscribe(这个);
游戏对象世界=新游戏对象();
world.name=“world”;
对于(int i=0;i<视距;i++)
{
GameObject go=新建GameObject();
go.name=“Chunk_”+i;
go.transform.SetParent(world.transform);
chunkGraphics[i]=go.AddComponent();
chunkGraphics[i].terrainData=新的terrainData();
go.AddComponent().terrainData=chunkGraphics[i].terrainData;
chunkGraphics[i].terrainData.size=新向量3((int)(chunkSizeX/4),600,(int)(chunkSizeY/4));
chunkGraphics[i].terrainData.heightmapResolution=(int)(chunkSizeX/2);
}
onCameraMove(Camera.main.transform.position);
}
//每帧调用一次更新
无效更新(){
if(输入。GetMouseButton(0))
{
雷卡斯特击中;
Ray-Ray=Camera.main.screenpointoray(输入.鼠标位置);
如果(物理.光线投射(光线,出击))
{
编辑地形高度(生命点、地形变化率、灌木丛面积);
}
}
}
void editTerrainHeight(矢量3位置、浮动量、整数直径)
{
int terrainPosX=(int)((position.x/maintrain.terrainData.size.x)*分辨率x);
int terrainPosY=(int)((position.z/maintrain.terrainData.size.z)*分辨率);
浮动[,]高度变化=新浮动[直径,直径];
int半径=直径/2;
if(Input.GetKey(KeyCode.LeftShift))
{
heightEdit=-1;
}
其他的
{
heightEdit=1;
}
金额=金额*高度编辑;
对于(int x=0;x