Unity 2D基于NoiseMap的地形Colormap不显示问题求助
Unity 2D噪声地图转颜色地图显示空白问题排查
实现Unity 2D基于噪声地图的地形颜色地图显示功能时,噪声地图可正常显示,但切换至颜色地图时仅显示背景,切回噪声地图则恢复正常。参考Sebastian Lague的程序化地形生成教程自行编写2D版本,相关代码及调试日志如下:
MapDisplay.cs 代码
using UnityEngine; public class MapDisplay : MonoBehaviour { public enum DrawMode { NoiseMap, ColorMap } public DrawMode drawMode; [Header("Map Settings")] public int mapLength = 256; public int mapWidth = 256; public float noiseScale = 20f; public Vector2 offset; public bool autoUpdate; [Header("Noise Settings")] public int octaves = 4; [Range(0, 1)] public float persistence = 0.5f; public float lacunarity = 2f; public int seed; [Header("Terrain Settings")] public TerrainType[] regions; private MapCreator mapCreator; private SpriteRenderer spriteRenderer; void Start() { mapCreator = gameObject.AddComponent<MapCreator>(); spriteRenderer = gameObject.AddComponent<SpriteRenderer>(); GenerateAndDisplayMap(); } public void GenerateAndDisplayMap() { mapLength = Mathf.Max(1, mapLength); mapWidth = Mathf.Max(1, mapWidth); octaves = Mathf.Max(0, octaves); lacunarity = Mathf.Max(1f, lacunarity); persistence = Mathf.Clamp(persistence, 0f, 1f); float[,] noiseMap = mapCreator.GenerateMap(mapLength, mapWidth, noiseScale, offset, octaves, lacunarity, persistence, seed); DisplayMap(noiseMap); } public void DisplayMap(float[,] noiseMap) { Texture2D texture; if (drawMode == DrawMode.NoiseMap) { texture = TextureGenerator.TextureFromHeightMap(noiseMap); } else // ColorMap { texture = GenerateTextureFromColourMap(noiseMap); } spriteRenderer.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); spriteRenderer.transform.localScale = new Vector3(mapWidth, mapLength, 1); } private Texture2D GenerateTextureFromColourMap(float[,] noiseMap) { int width = noiseMap.GetLength(0); int height = noiseMap.GetLength(1); Color[] colourMap = new Color[width * height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float currentHeight = noiseMap[x, y]; for (int i = 0; i < regions.Length; i++) { if (currentHeight <= regions[i].height) { colourMap[y * width + x] = regions[i].color; break; } } } } return TextureGenerator.TextureFromColourMap(colourMap, width, height); } }
TextureGenerator.cs 代码
using UnityEngine; public static class TextureGenerator { public static Texture2D TextureFromColourMap(Color[] colourMap, int width, int height) { Texture2D texture = new Texture2D(width, height); texture.filterMode = FilterMode.Point; texture.wrapMode = TextureWrapMode.Clamp; texture.SetPixels(colourMap); texture.Apply(); return texture; } public static Texture2D TextureFromHeightMap(float[,] heightMap) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); Color[] colourMap = new Color[width * height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { colourMap[y * width + x] = Color.Lerp(Color.black, Color.white, heightMap[x, y]); } } return TextureFromColourMap(colourMap, width, height); } }
生成颜色地图时的调试日志
MapDisplay: Start - Components added, generating and displaying map. UnityEngine.Debug:Log (object) MapDisplay:Start () (at Assets/MapDisplay.cs:32) MapDisplay: GenerateAndDisplayMap - Parameters adjusted: UnityEngine.Debug:Log (object) MapDisplay:GenerateAndDisplayMap () (at Assets/MapDisplay.cs:44) MapDisplay:Start () (at Assets/MapDisplay.cs:33) mapLength: 256, mapWidth: 256, octaves: 4, lacunarity: 2, persistence: 0.5 UnityEngine.Debug:Log (object) MapDisplay:GenerateAndDisplayMap () (at Assets/MapDisplay.cs:45) MapDisplay:Start () (at Assets/MapDisplay.cs:33) MapDisplay: GenerateAndDisplayMap - Noise map generated. UnityEngine.Debug:Log (object) MapDisplay:GenerateAndDisplayMap () (at Assets/MapDisplay.cs:48) MapDisplay:Start () (at Assets/MapDisplay.cs:33) MapDisplay: DisplayMap - Drawing color map. UnityEngine.Debug:Log (object) MapDisplay:DisplayMap (single[,]) (at Assets/MapDisplay.cs:63) MapDisplay:GenerateAndDisplayMap () (at Assets/MapDisplay.cs:49) MapDisplayEditor:OnInspectorGUI () (at Assets/Editor/MapDisplayEditor.cs:15) UnityEditor.EditorGUI/PopupCallbackInfo:SetEnumValueDelegate (object,string[],int) MapDisplay: GenerateTextureFromColourMap - Generating color map. UnityEngine.Debug:Log (object) MapDisplay:GenerateTextureFromColourMap (single[,]) (at Assets/MapDisplay.cs:78) MapDisplay:DisplayMap (single[,]) (at Assets/MapDisplay.cs:64) MapDisplay:GenerateAndDisplayMap () (at Assets/MapDisplay.cs:49) MapDisplayEditor:OnInspectorGUI () (at Assets/Editor/MapDisplayEditor.cs:15) UnityEditor.EditorGUI/PopupCallbackInfo:SetEnumValueDelegate (object,string[],int) MapDisplay: GenerateTextureFromColourMap - Color map generated. UnityEngine.Debug:Log (object) MapDisplay:GenerateTextureFromColourMap (single[,]) (at Assets/MapDisplay.cs:96) MapDisplay:DisplayMap (single[,]) (at Assets/MapDisplay.cs:64) MapDisplay:GenerateAndDisplayMap () (at Assets/MapDisplay.cs:49) MapDisplayEditor:OnInspectorGUI () (at Assets/Editor/MapDisplayEditor.cs:15) UnityEditor.EditorGUI/PopupCallbackInfo:SetEnumValueDelegate (object,string[],int) MapDisplay: DisplayMap - Texture applied to sprite renderer. UnityEngine.Debug:Log (object) MapDisplay:DisplayMap (single[,]) (at Assets/MapDisplay.cs:69) MapDisplay:GenerateAndDisplayMap () (at Assets/MapDisplay.cs:49) MapDisplayEditor:OnInspectorGUI () (at Assets/Editor/MapDisplayEditor.cs:15) UnityEditor.EditorGUI/PopupCallbackInfo:SetEnumValueDelegate (object,string[],int)
排查方向与修复建议
1. 地形区域配置错误
- 核心问题:若
regions数组未正确配置,会导致颜色数组colourMap未被赋值(默认Color.clear,完全透明),最终显示背景。 - 检查点:
- 确认Inspector中
regions数组不为空,且按高度从小到大排序。 - 最后一个区域的
height值需设置为1.0f(噪声地图通常输出0-1范围的归一化值),确保所有噪声值都能匹配到对应的颜色。
- 确认Inspector中
- 示例配置:
- 第1个区域:height=0.2,颜色=深海洋蓝
- 第2个区域:height=0.4,颜色=浅蓝
- 第3个区域:height=0.6,颜色=绿色草地
- 第4个区域:height=1.0,颜色=灰色山地
2. 噪声值范围未归一化
- 核心问题:若
MapCreator.GenerateMap生成的噪声值超出0-1范围,会导致所有值无法匹配regions的阈值,颜色数组无有效赋值。 - 排查方法:在
GenerateTextureFromColourMap中添加日志,打印噪声值范围:float currentHeight = noiseMap[x, y]; if(x == 0 && y == 0) Debug.Log("Noise value at (0,0): " + currentHeight); - 修复:若噪声值未归一化,需在
MapCreator.GenerateMap中对结果做归一化处理,将值压缩到0-1区间。
3. 添加默认颜色兜底
- 优化建议:在颜色匹配循环后添加兜底逻辑,标记未匹配到区域的噪声值,便于排查:
float currentHeight = noiseMap[x, y]; bool matched = false; for (int i = 0; i < regions.Length; i++) { if (currentHeight <= regions[i].height) { colourMap[y * width + x] = regions[i].color; matched = true; break; } } // 未匹配到任何区域时设置显眼颜色 if (!matched) { colourMap[y * width + x] = Color.magenta; }
4. 确认TerrainType定义
- 检查点:确保
TerrainType类已正确定义,包含height和color字段且可在Inspector中编辑:[System.Serializable] public class TerrainType { public float height; public Color color; }
内容的提问来源于stack exchange,提问作者Zewen Senpai
相关产品推荐
相关产品推荐

