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

如何通过脚本设置对象纹理?类Minecraft地形生成器纹理失效求助

Minecraft风格地形生成的方块纹理设置问题解决

我做了一个类似Minecraft的地形生成系统,想通过脚本给不同高度的方块设置对应纹理,但方块始终显示空白。尝试过用Cube预制体替代CreatePrimitive创建的方块(但预制体设置后无效),也试过把Block脚本的逻辑移到Chunk脚本里,都没解决问题。

Chunk 脚本

private Vector3 position;
private int chunkSize;
private Material blockMaterial;
public float noiseScale = 0.1f;
public float amplitude = 5.0f;

public void Initialize(Vector3 position, int chunkSize, Material blockMaterial)
{
    this.position = position;
    this.chunkSize = chunkSize;
    this.blockMaterial = blockMaterial;
    GenerateTerrain();
}

void GenerateTerrain()
{
    for (int x = 0; x < chunkSize; x++)
    {
        for (int z = 0; z < chunkSize; z++)
        {
            float perlinValue = Mathf.PerlinNoise((x + position.x) * noiseScale, (z + position.z) * noiseScale);
            float y = perlinValue * amplitude; // 增加地形高度随机性

            for (int yBlock = 0; yBlock < y; yBlock++)
            {
                Vector3 blockPosition = new Vector3(x, yBlock, z);
                GameObject block = GameObject.CreatePrimitive(PrimitiveType.Cube);
                block.transform.parent = transform;
                block.transform.position = blockPosition + position;

                Block blockScript = block.AddComponent<Block>();
            }
        }
    }
}

Block 脚本

public string blockType; // 方块名称或标识符
public Texture grass;
public Texture dirt;
public Texture stone;

void Start()
{
    Renderer renderer = this.GetComponent<Renderer>();
    SetTextures();
}

void SetTextures()
{
    float yPos = transform.position.y;

    if (yPos > 5)
    {
        GetComponent<Renderer>().material.mainTexture = grass;
        blockType = "grass";
    }

    if (yPos <= 0)
    {
        GetComponent<Renderer>().material.mainTexture = stone;
        blockType = "stone";
    }
    
    if (yPos > 0)
    {
        GetComponent<Renderer>().material.mainTexture = dirt;
        blockType = "dirt";
    }
}

问题原因及修复方案

1. 条件判断逻辑错误

当前SetTextures里的三个独立if会导致覆盖:当yPos > 5时,先设置grass纹理,但随后yPos > 0的条件也成立,会把纹理改成dirt,导致草方块永远显示为泥土。

修复:改用else if链式判断,确保每个高度区间只触发一次:

void SetTextures()
{
    float yPos = transform.position.y;
    Renderer renderer = GetComponent<Renderer>();

    if (yPos > 5)
    {
        renderer.material.mainTexture = grass;
        blockType = "grass";
    }
    else if (yPos > 0) // 仅当yPos <=5时才进入这里
    {
        renderer.material.mainTexture = dirt;
        blockType = "dirt";
    }
    else // yPos <=0
    {
        renderer.material.mainTexture = stone;
        blockType = "stone";
    }
}

2. Texture变量未赋值

grass、dirt、stone是public变量,但未在Inspector面板给Block组件拖入对应的纹理资源,导致变量为null,设置纹理后显示空白。

修复:

  • 手动赋值:选中场景中任意Block对象,在Inspector的Block组件里,把对应纹理拖入grass、dirt、stone字段。
  • 动态加载:如果是批量生成的Block,可在Chunk脚本中从Resources文件夹加载纹理并赋值:
// 在Chunk的GenerateTerrain方法中,添加Block组件后赋值
Block blockScript = block.AddComponent<Block>();
blockScript.grass = Resources.Load<Texture>("Textures/grass");
blockScript.dirt = Resources.Load<Texture>("Textures/dirt");
blockScript.stone = Resources.Load<Texture>("Textures/stone");

(需将纹理放在Assets/Resources/Textures目录下)

3. 材质使用问题

CreatePrimitive创建的Cube默认使用内置Standard材质,直接修改mainTexture可能因材质渲染设置不生效;且每个方块创建材质实例会浪费性能,建议复用传入的blockMaterial。

修复:生成方块时给Renderer赋值传入的材质(创建实例避免修改共享材质):

GameObject block = GameObject.CreatePrimitive(PrimitiveType.Cube);
block.transform.parent = transform;
block.transform.position = blockPosition + position;
// 复用传入的材质,创建实例避免影响其他方块
block.GetComponent<Renderer>().material = new Material(blockMaterial);
Block blockScript = block.AddComponent<Block>();

4. 预制体无效问题

预制体为空大概率是因为未正确配置:

修复:

  1. 创建一个Cube对象,添加Block组件并拖入纹理资源,设置好材质。
  2. 将该Cube拖到Project窗口创建预制体。
  3. 在Chunk脚本中用Instantiate替代CreatePrimitive:
// 在Chunk脚本中添加预制体字段
public GameObject blockPrefab;

// 在GenerateTerrain中替换创建逻辑
GameObject block = Instantiate(blockPrefab, blockPosition + position, Quaternion.identity);
block.transform.parent = transform;

最后在Inspector中给Chunk组件的blockPrefab拖入你的预制体。

内容的提问来源于stack exchange,提问作者jollyname

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 09:25:58