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

Unity 3D Tilemap.GetInstantiatedObject在Update中返回null问题

问题产生原因
  • 核心触发原因是鼠标坐标转世界坐标的传参错误:直接调用Camera.main.ScreenToWorldPoint(Input.mousePosition)时,传入参数的z分量默认是0,对应相机本地坐标系下与相机自身位置重合的平面,转换出的世界坐标不在Tilemap所在平面上,后续WorldToCell算出的格子坐标和实际放置Tile的(0,0,0)坐标不匹配,对应位置无生成的Tile实例,GetInstantiatedObject就会返回null。
  • 缺少必要的合法性校验:代码硬编码将转换后坐标的z值设为0,若点击位置算出的x/y坐标本身没有放置Tile,调用方法时也会直接返回null触发空引用。
  • Start方法中能正常拿到实例,说明Tile的生成、初始设置逻辑没有问题,故障完全出在Update环节的坐标转换逻辑上。
修复方法
  1. 修正屏幕坐标转世界坐标的逻辑,传入正确的深度值:深度值取相机到Tilemap所在平面的距离,2D项目中可直接计算相机Z坐标和Tilemap Z坐标的差值得到。
  2. 调用GetInstantiatedObject前先校验对应位置是否存在Tile、返回的实例是否为空,避免空引用报错。
  3. 不要手动修改WorldToCell返回的坐标z值,六边形Tilemap根据Grid配置不同,坐标z值可能非0,硬编码重置为0反而会造成坐标错位。

修复后的Update代码如下:

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        // 计算相机到Tilemap平面的正确深度
        float cameraDepth = Mathf.Abs(Camera.main.transform.position.z - Board_Tilemap.transform.position.z);
        // 构造带正确深度的鼠标屏幕坐标
        Vector3 mouseScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, cameraDepth);
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(mouseScreenPos);
        
        Vector3Int tilePos = Board_Tilemap.WorldToCell(worldPos);
        // 先校验位置是否存在Tile
        if (Board_Tilemap.HasTile(tilePos))
        {
            GameObject tileInstance = Board_Tilemap.GetInstantiatedObject(tilePos);
            if (tileInstance != null)
            {
                tileInstance.transform.Rotate(90, 0, 0);
            }
        }
    }
}

额外排查点:如果Grid组件(Tilemap的父对象)设置了非默认的Cell Swizzle轴向,直接使用WorldToCell返回的原始坐标查询即可,不要手动修改任意坐标分量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:54:36