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

自制Tilemap光照系统仅多次循环生效的问题排查与优化

类Terraria游戏Tilemap光照系统问题排查与优化求助

项目背景与光照系统逻辑

我正在开发一款类Terraria游戏,因未找到基于Tilemap实现同类光照的常规方案,自行开发了一套光照系统:

  • 用二维int数组lighting存储每个方块的光照等级
  • 初始化阶段:将所有空气块的光照等级设为15(最大光照值)
  • 实体块光照计算:取上下左右四个相邻块的最大光照值减3,通过Mathf.Clamp将结果限制在0-15区间,以此作为当前实体块的光照等级,再根据该值计算并设置Tile的显示颜色

当前遇到的问题

  • 光照渲染异常:只有连续调用4次Right()方法时,光照显示才正常;仅调用1次时,光照衰减不连贯,明暗过渡异常
  • 更新卡顿:每次放置或破坏方块后更新光照,会出现严重的性能卡顿

代码实现

public class Lighting : MonoBehaviour
{
    public static int[,] lighting;
    [SerializeField] Tilemap tp;
    private void Start()
    {
        Lighting.lighting = new int[tp.cellBounds.max.x, tp.cellBounds.max.y];
    }
 
    public static IEnumerator UpdateLighting(Tilemap tp) //Ran at the start of the scene
    {
        for (int y = tp.cellBounds.min.y; y < tp.cellBounds.max.y; y++)
        {
            for (int x = tp.cellBounds.min.x; x < tp.cellBounds.max.x; x++)
            {
                if (tp.GetTile(new Vector3Int(x, y, 0)) == null)
                {
                    Lighting.lighting[x, y] = 15; //placing max lighting in air blocks
                }
            }
        }
        Right();
        Right();
        Right();
        Right();
        IEnumerator Right()
        {
            for (int y = tp.cellBounds.min.y; y < tp.cellBounds.max.y; y++)
            {
                for (int x = tp.cellBounds.min.x; x < tp.cellBounds.max.x; x++)
                {
                    if (tp.GetTile(new Vector3Int(x, y, 0)) != null)
                    {
                        int maxlight = 0;
                        if (((y + 1) < tp.cellBounds.max.y) && (lighting[x, y + 1] > maxlight))
                        {
                            maxlight = Lighting.lighting[x, y + 1]; //Up position from block
                        }
                        if (((x + 1) < tp.cellBounds.max.x) && (lighting[x + 1, y] > maxlight))
                        {
                            maxlight = Lighting.lighting[x + 1, y]; //Right position from block
                        }
                        if (((x - 1) > tp.cellBounds.min.x) && (Lighting.lighting[x - 1, y] > maxlight))
                        {
                            maxlight = lighting[x - 1, y]; //Left position from block
                        }
                        if (((y - 1) > tp.cellBounds.min.y) && (lighting[x, y - 1] > maxlight))
                        {
                            maxlight = lighting[x, y - 1]; //Down position from block
                        }
                        lighting[x, y] = Mathf.Clamp(maxlight - 3, 0, 15);
                        float tc = lighting[x, y] / 15f; //calculating the color of the light(because 1 is white and 0 is black)
                        tp.SetColor(new Vector3Int(x, y, 0), new Color(tc, tc, tc, 1)); //setting the color of the tile
                    }
                }
            }
            return null;
        }
        return null;
    }
}

效果对比

  • 正常效果:光照在实体块间自然衰减,形成连续的明暗过渡,符合类Terraria的预期光照表现
  • 仅调用1次Right()的异常效果:光照衰减不连贯,部分区域明暗突变,没有自然的过渡层次

求助需求

  1. 排查为何仅调用1次Right()会导致光照异常,以及连续调用4次才能正常工作的原因
  2. 针对放置/破坏方块后更新光照的卡顿问题,提供可行的优化方案

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 17:42:00