You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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范围的归一化值),确保所有噪声值都能匹配到对应的颜色。
  • 示例配置:
    • 第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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:02:33