【发布时间】:2015-07-18 14:16:33
【问题描述】:
编辑:在尝试了一些事情后重写了我的问题并使其更具体。
您好,我正在创建一个带有程序生成地图的移动 RTS 游戏。我已经研究了如何创建一个带有基本 perlin 噪声的地形,并尝试将https://gamedev.stackexchange.com/questions/54276/a-simple-method-to-create-island-map-mask 方法集成到程序上创建一个岛。这是目前的结果:
http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/ 的下图显示了我所追求的地形类型。那里的教程很棒,但是太密集了,因此是帖子。
我想要一个带有 Perlin 噪声的随机形状岛屿,陆地被水包围。
编辑:基本的 Perlin 地形生成现在工作 =)
这是我的代码。一个附加到 null 的脚本,带有一个用于激活 Begin() 的按钮:
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class Gen_Perlin : MonoBehaviour {
public float Tiling = 0.5f;
private bool active = false;
public int mapHeight = 10;
public void Begin()
{
if (active == false) {
TerrainData terrainData = new TerrainData ();
const int size = 513;
terrainData.heightmapResolution = size;
terrainData.size = new Vector3 (2000, mapHeight, 2000);
terrainData.heightmapResolution = 513;
terrainData.baseMapResolution = 1024;
terrainData.SetDetailResolution (1024, 1024);
Terrain.CreateTerrainGameObject (terrainData);
GameObject obj = GameObject.Find ("Terrain");
obj.transform.parent = this.transform;
if (obj.GetComponent<Terrain> ()) {
GenerateHeights (obj.GetComponent<Terrain> (), Tiling);
}
} else {
GameObject obj = GameObject.Find ("Terrain");
if (obj.GetComponent<Terrain> ()) {
GenerateHeights (obj.GetComponent<Terrain> (), Tiling);
}
}
}
public void GenerateHeights(Terrain terrain, float tileSize)
{
Debug.Log ("Start_Height_Gen");
float[,] heights = new float[terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight];
for (int i = 0; i < terrain.terrainData.heightmapWidth; i++)
{
for (int k = 0; k < terrain.terrainData.heightmapHeight; k++)
{
heights[i, k] = 0.25f + Mathf.PerlinNoise(((float)i / (float)terrain.terrainData.heightmapWidth) * tileSize, ((float)k / (float)terrain.terrainData.heightmapHeight) * tileSize);
heights[i, k] *= makeMask( terrain.terrainData.heightmapWidth, terrain.terrainData.heightmapHeight, i, k, heights[i, k] );
}
}
terrain.terrainData.SetHeights(0, 0, heights);
}
public static float makeMask( int width, int height, int posX, int posY, float oldValue ) {
int minVal = ( ( ( height + width ) / 2 ) / 100 * 2 );
int maxVal = ( ( ( height + width ) / 2 ) / 100 * 10 );
if( getDistanceToEdge( posX, posY, width, height ) <= minVal ) {
return 0;
} else if( getDistanceToEdge( posX, posY, width, height ) >= maxVal ) {
return oldValue;
} else {
float factor = getFactor( getDistanceToEdge( posX, posY, width, height ), minVal, maxVal );
return oldValue * factor;
}
}
private static float getFactor( int val, int min, int max ) {
int full = max - min;
int part = val - min;
float factor = (float)part / (float)full;
return factor;
}
public static int getDistanceToEdge( int x, int y, int width, int height ) {
int[] distances = new int[]{ y, x, ( width - x ), ( height - y ) };
int min = distances[ 0 ];
foreach( var val in distances ) {
if( val < min ) {
min = val;
}
}
return min;
}
}
【问题讨论】:
-
很高兴让它工作!下一步我建议用具有良好 2D 单纯形实现的导入库替换 Mathf.PerlinNoise。 Perlin 噪声具有非常网格对齐的问题。您可以导入
Unity.Mathematics.noise.snoise(float2)或使用this。后者可能会更快,因为您没有使用优化 Unity.Mathematics 噪声的 Burst 作业。 -
哦,哇,我没看到这篇文章有多老!我认为它出现在我最新排序的搜索结果中,因为有一个最近的回复。希望我的评论对某人有用!
标签: c# unity3d terrain perlin-noise procedural-generation