【Unity】2D场景绘制瓦片地图的网格线

本解决方案的代码基于此文章所提供的代码所进行的修改调整:http://t.csdnimg.cn/zoKa2

绘制网格线是通过UnityEngine.GL库来实现

cs 复制代码
using UnityEngine;
using UnityEngine.Tilemaps;

/// <summary>
/// 挂在主摄像机上
/// </summary>
public class MapGridDraw : MonoBehaviour
{
    /// <summary>
    /// 线的材质
    /// 创建一个Unlit-Color材质就可以拿来用
    /// </summary>
    public Material lineMat;
 
    /// <summary>
    /// 线的颜色
    /// </summary>
    public Color lineColor = new Color(1, 1, 1, 0.5f);
 
 
    public Camera _camera; //相机
 
    public Tilemap tilemap; //瓦片地图


    /// <summary>
    ///  OnPostRender函数是Unity自带函数
    ///  与摄像机有关,因此该脚本必须挂在
    ///  主摄像机上
    /// </summary>
    void OnPostRender()
    { 
        DrawGrid();
    }


 
    /// <summary>
    /// 绘制网格
    /// </summary>
    void DrawGrid()
    {
        if (lineMat == null)
        {
            return;
        }
        Vector2 cameraPos = _camera.transform.position;
 
        //相机的宽高
        int width = _camera.pixelWidth;
        int height = _camera.pixelHeight;

        //视口在世界空间的四个点
        Vector2 leftUp = _camera.ScreenToWorldPoint(new Vector2(0, height));
        Vector2 rightUp = _camera.ScreenToWorldPoint(new Vector2(width, height));
        Vector2 leftDown = _camera.ScreenToWorldPoint(new Vector2(0, 0));
        Vector2 rightDown = _camera.ScreenToWorldPoint(new Vector2(width, 0));

        Vector3Int leftUp_Tile = tilemap.WorldToCell(leftUp);
        Vector3Int rightUp_Tile = tilemap.WorldToCell(rightUp);
        Vector3Int leftDown_Tile = tilemap.WorldToCell(leftDown);
        Vector3Int rightDown_Tile = tilemap.WorldToCell(rightDown);

        //转成基于瓦片地图坐标的世界坐标
        leftUp = tilemap.CellToWorld(leftUp_Tile);
        rightUp = tilemap.CellToWorld(rightUp_Tile);
        leftDown = tilemap.CellToWorld(leftDown_Tile);
        rightDown = tilemap.CellToWorld(rightDown_Tile);

        //相机视口在世界坐标中的宽高
        float viewWidth = rightUp.x - leftDown.x;
        float viewHeight = rightUp.y - leftDown.y;

        //cell在横轴和纵轴上的个数
        int x = (int) viewWidth + 1;
        int y = (int) viewHeight + 1;
 
        //x y变为奇数
        x = x / 2 * 2 + 1;
        y = y / 2 * 2 + 1;
 
        //中间的方块位置
        float centerX = x / 2+0.5f;
        float centerY = y / 2+0.5f;
        // float centerX = x / 2 + 1;
        // float centerY = y / 2 + 1;
 
        // //偏移
        float offsetX = cameraPos.x % 1;
        float offsetY = cameraPos.y % 1;
 
        //竖线
        for (int i = 0; i <= x; i++)
        {
            //初始位置
            float posX = i - centerX + 0.5f;
            //线跟随摄像机移动
            posX += cameraPos.x;
            //产生偏移
            posX -= offsetX;
 
            DrawLine(new Vector2(posX, leftUp.y), new Vector2(posX, leftDown.y), lineColor);
        }
        //横线
        for (int j = 1; j <= y; j++)
        {
            //线跟随摄像机移动
            float posY = j - centerY + 0.5f;
            //线跟随摄像机移动
            posY += cameraPos.y;
            //产生偏移
            posY -= offsetY;
 
            DrawLine(new Vector2(leftUp.x, posY), new Vector2(rightUp.x, posY), lineColor);
        }
    }
 
 
    /// <summary>
    /// 画一条线 世界坐标
    /// </summary>
    /// <param name="posA"></param>
    /// <param name="posB"></param>
    /// /// <param name="color"></param>
    void DrawLine(Vector2 posA, Vector2 posB,Color color)
    {
        GL.Begin(GL.LINES);
        lineMat.SetPass(0);
        GL.Color(color);
        GL.Vertex3(posA.x, posA.y, 0);
        GL.Vertex3(posB.x, posB.y, 0);
        GL.End();
    }
 
  

    
}

但是经过我在实际项目中测试发现,该方案存在一个待解决的问题,那就是如果场景中存在UI对象,那么这些网格线的部分线条会遮挡UI,因此请慎用。(如果有朋友解决了这个问题,还请在评论中提供一下解决办法,谢谢!)

相关推荐
dengzhenyue11 小时前
C# 初级编程
开发语言·c#
怣疯knight12 小时前
unity实现2D人物从上面踩踏敌人,敌人减血的简易方法(类似马里奥的攻击手段)
unity·游戏引擎
AA陈超15 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P06-16 属性菜单 - 构建
c++·游戏·ue5·游戏引擎·虚幻
津津有味道18 小时前
ISO18000-6C协议UHF6C超高频RFID读写C#源码
c#·uhf6c·超高频·iso18000-6c
白雪公主的后妈19 小时前
Auto CAD二次开发——创建圆弧对象
c#·cad二次开发·创建圆弧对象
weixin_307779131 天前
C#程序实现将MySQL的存储过程转换为Azure Synapse Dedicated SQL Pool的T-SQL存储过程
c#·自动化·云计算·运维开发·azure
"菠萝"1 天前
C#知识学习-018(方法参数传递)
学习·c#·1024程序员节
CiLerLinux1 天前
第三章 FreeRTOS 任务相关 API 函数
开发语言·单片机·物联网·c#
.NET修仙日记1 天前
C#/.NET 微服务架构:从入门到精通的完整学习路线
微服务·c#·.net·.net core·分布式架构·技术进阶
歪歪1001 天前
在C#中详细介绍一下Visual Studio中如何使用数据可视化工具
开发语言·前端·c#·visual studio code·visual studio·1024程序员节