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

Unity使用SetTile方法随机填充Tilemap无报错不生效问题求解

问题原因与修复方案

核心错误点

  • 坐标转换逻辑错误:Tilemap.SetTile() 要求传入的是瓦片网格的本地单元格坐标(Vector3Int),你当前的代码存储的是CellToWorld转换后的世界坐标,再用Vector3Int.FloorToInt转世界坐标得到的结果和原始单元格坐标完全不匹配,尤其是当Tilemap存在缩放、位置偏移的时候,必然会定位到错误的单元格甚至完全定位不到。
  • 随机逻辑不符合预期:你设置的随机数范围是0.1f ~ 1.0f,天然缺失了0~0.1的区间,而且大于0.6f的区间(占总概率的40%)会直接把瓦片设为null,会导致你预先绘制的tileNull区域有近一半被清空,看起来就像没生效一样。
  • 冗余的坐标转换开销:不需要额外把单元格坐标转成世界坐标存储,直接存原始的Vector3Int单元格坐标即可,避免后续转换误差。

修复后代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;

public class PopulateMap : MonoBehaviour
{
    public Tilemap map; //需要填充的Tilemap
    public Tile tile1; //用于填充的瓦片
    public Tile tile2;
    public Tile tile3;
    public Tile tile4;
    public Tile tile5;
    public Tile tileNull; //预先绘制的空白瓦片,标记需要生效的区域
    List<Vector3Int> tileLocations; //直接存储单元格坐标,避免转换误差

    // Start is called before the first frame update
    void Start()
    {
        tileLocations = new List<Vector3Int>();
    
        //遍历所有单元格,记录有瓦片的位置(也就是你预先绘制tileNull的区域)
        foreach (var pos in map.cellBounds.allPositionsWithin) 
        {
            Vector3Int localPlace = new Vector3Int(pos.x, pos.y, pos.z);
            if (map.HasTile(localPlace))
            {
                tileLocations.Add(localPlace); //直接存单元格坐标
            }
        }

        FillMap();
    }

    void FillMap()
    {
        foreach (Vector3Int cellPos in tileLocations)
        {
            //随机范围改为0~1,覆盖全部概率区间
            float f = Random.Range(0f, 1.0f);
        
            if (f < 0.2f)
            {
                map.SetTile(cellPos, tile1);
            } 
            else if (f < 0.3f)
            {
                map.SetTile(cellPos, tile2);
            } 
            else if (f < 0.4f)
            {
                map.SetTile(cellPos, tile3);
            } 
            else if (f < 0.5f)
            {
                map.SetTile(cellPos, tile4);
            } 
            else if (f < 0.6f)
            {
                map.SetTile(cellPos, tile5);
            } 
            else
            {
                //如果不需要清空区域,这里保留tileNull即可维持原始空白效果
                map.SetTile(cellPos, tileNull);
            }
        }
    }   
}

额外注意点

  • 检查Inspector面板中map、tile1~tile5、tileNull的引用是否都已经正确赋值,空引用也会导致设置不生效
  • 如果需要调整各瓦片的生成概率,直接修改if判断的阈值即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:00:01