Unity 环境区域网格化

在使用A星算法和物体布局的过程中,常常会使用的网格的概念,即建立在网格的基础上,会使得游戏的相关编程变得简单的多。

格子的代码:

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

[System.Serializable]
public class Node
{
    public Vector3 _worldPos;//格子中心点的位置
    public int _gridX, _gridY;//在网格列表的下标

    public Node(Vector3 Position, int x, int y)
    {
        _worldPos = Position;
        _gridX = x;
        _gridY = y;
    }
}

网格代码:

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

//网格,网格的起点是在左下角,终点是右上角
public class Grid : MonoBehaviour
{
    public static Grid instance;

    private Node[,] grid;//网格
    public Vector2 gridSize;//网格横纵大小
    public float nodeRadius;//格子的半径
    private float nodeDiameter;//格子的直径
    public int gridCntX, gridCntY;//两个方向上的网格数量

    //Test
    public Transform tarTrans;//目标
    public Node tar;
    public float dir;//射程
    //目标区域
    public Node zoneLeftDown;//网格的左下角
    public Node zoneRightUp;//网格的右上角

    Vector3 pos = new Vector3();
    // Start is called before the first frame update
    void Awake()
    {
        instance = this;

        nodeDiameter = nodeRadius * 2;
        gridCntX = Mathf.RoundToInt(gridSize.x / nodeDiameter);
        gridCntY = Mathf.RoundToInt(gridSize.y / nodeDiameter);
        grid = new Node[gridCntX, gridCntY];
        CreateGrid();
    }

    private void Update()
    {
        /*
        //获取到玩家所在的网格点
        tar = GetFromPosition(tarTrans.position);
        //获取射程网格区域
        zoneLeftDown = GetFromPosition(tarTrans.position - new Vector3(dir, dir));
        zoneRightUp = GetFromPosition(tarTrans.position + new Vector3(dir, dir));
        //获取一个随机点
        if (Input.GetKeyDown(KeyCode.Space)) {
            int i = Random.Range(zoneLeftDown._gridX, zoneRightUp._gridX+1);
            int j = Random.Range(zoneLeftDown._gridY, zoneRightUp._gridY+1);

            pos = grid[i, j]._worldPos;
        }
        */
    }

    //创建网格,起始点在左下角
    private void CreateGrid()
    {
        //获得网格的左下角的坐标
        Vector3 startPoint = transform.position - gridSize.x / 2 * Vector3.right - gridSize.y / 2* Vector3.up;
        for (int i = 0; i < gridCntX; i++)
        {
            for (int j = 0; j < gridCntY; j++)
            {
                Vector3 worldPoint = startPoint + Vector3.right * (i * nodeDiameter + nodeRadius) + Vector3.up * (j * nodeDiameter + nodeRadius);
                grid[i, j] = new Node(worldPoint, i, j);
            }
        }
    }

    //获取某个坐标处的格子
    public Node GetFromPosition(Vector3 position)
    {
        //首先获得该坐标相对于网格的宽高的百分比
        float percentX = (position.x + gridSize.x / 2) / gridSize.x;
        float percentY = (position.y + gridSize.y / 2) / gridSize.y;

        //保证百分比值在0到1之间
        percentX = Mathf.Clamp01(percentX);
        percentY = Mathf.Clamp01(percentY);

        int x = Mathf.RoundToInt((gridCntX - 1) * percentX);
        int y = Mathf.RoundToInt((gridCntY - 1) * percentY);

        return grid[x, y];
    }

    //获取一个正方形区域中随机点,length为区域的边长
    public Vector3 GetZoneRandomPos(Vector3 center,float length)
    {
        //射程一定要大于等于0
        //float len = Mathf.Abs(length) / 2;
        //获取射程网格区域
        zoneLeftDown = GetFromPosition(center - new Vector3(length, length));
        zoneRightUp = GetFromPosition(center + new Vector3(length, length));
        //获取并返回射程网格区域中的一个随机点
        int i = Random.Range(zoneLeftDown._gridX, zoneRightUp._gridX);
        int j = Random.Range(zoneLeftDown._gridY, zoneRightUp._gridY);

        return grid[i, j]._worldPos;
    }

    //获取整个区域中的一个随机点
    public Vector3 GetZoneRandomPos()
    {
        int i = Random.Range(0, gridCntX);
        int j = Random.Range(0, gridCntY);
        return grid[i, j]._worldPos;
    }

    private void OnDrawGizmos()
    {
        
        //绘制网格边界线
        Gizmos.DrawWireCube(transform.position, new Vector3(gridSize.x, gridSize.y, 1));
        if (grid == null) return;

        Gizmos.color = new Color(1, 1, 1, 0.2f);
        //绘制网格
        foreach (var node in grid)
        {
            Gizmos.DrawCube(node._worldPos+Vector3.forward, Vector3.one * (nodeDiameter - .1f*nodeDiameter));
        }

        
        /*
        //绘制射程区域
        Gizmos.color = Color.red;
        for (int i = zoneLeftDown._gridX; i <= zoneRightUp._gridX; i++)
            for (int j = zoneLeftDown._gridY; j <= zoneRightUp._gridY; j++)
                Gizmos.DrawCube(grid[i, j]._worldPos + Vector3.forward, Vector3.one * (nodeDiameter - .1f * nodeDiameter));

        //绘制随机点
        Gizmos.color = Color.blue;
        Gizmos.DrawCube(pos + Vector3.forward, Vector3.one * (nodeDiameter - .1f * nodeDiameter));
        /*
        Gizmos.color = Color.red;

        Gizmos.DrawCube(tar._worldPos + Vector3.forward, Vector3.one * (nodeDiameter - .1f * nodeDiameter));
        */
        /*
        //绘制射程区域
        Gizmos.color = Color.red;
        for (int i = 0; i <= 3; i++)
            for (int j = 1; j <= 6; j++)
                Gizmos.DrawCube(grid[i, j]._worldPos + Vector3.forward, Vector3.one * (nodeDiameter - .1f * nodeDiameter));
        */
    }
}

运行结果:

猜你喜欢

转载自www.cnblogs.com/xiaoahui/p/10612463.html
今日推荐