A*寻路网格烘焙

本文介绍了在2D游戏中使用A*算法进行寻路的方法,而非使用NavMesh。作者分享了如何将地图数据烘焙成图片来标识行走区域,并简化为点对点寻路,用哈希结构存储墙体信息。地图信息通过编辑器工具生成并序列化为二进制文件,以减少IO开销。最后展示了地图信息采集和烘焙的效果。
摘要由CSDN通过智能技术生成

A*寻路可以说是老生常谈的内容了,我这里要讲的是项目里碰到一个关于如何给A*做地图烘焙,到如何做算法结构调整优化。算法是另一个程序写的,我只是进行了一些补充和筛选,后续优化还会继续更新。

先说一下功能的背景和需求,我们制作的是一款(……以下省略1W字介绍,我拉点关键信息出来)。

2D游戏,要做一个点击移动的功能,类似于大地图寻路,2D游戏我们没有选择网格烘焙(NavMesh),而是选择了把地图数据洪培成一张图片,标识可行走区域和不可行走区域来做A*算法进行寻路。

先来看一下地图样式,

同事推荐的国外的一个论坛:

https://www.redblobgames.com/grids/hexagons/?tdsourcetag=s_pcqq_aiomsg

我当时一看我去!惊了!我们要做六边形寻路这种高端大气上档次的东西吗? 废话不多说,折腾了几天后发现很复杂,而且算法复杂度极高,难以优化,最终改成了点对点的寻路,即所有的坐标定义成一个结构体,墙体由一个哈希结构存储(取数据时间复杂度低)。

地图采集由编辑器工具生成(实时生成开销较大),

废话不多说,上代码:

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

namespace Client
{
    public static class AStarHelper
    {
        /// <summary>
        /// 采集换算倍率
        /// </summary>
        public const float samplingNum = 5f;

        /// <summary>
        /// 数据中心点放大倍率
        /// </summary>
        public const float CenterScaling = 1000f;
        public const string AStarBytesPath = "/Resources/AstarData/Bytes";
    
        public static AStarData GetAStarData()
        {
            return BytesConvertHelper.LoadFromFile<AStarData>("AstarData/aStar");
        }
        public static Location GetLocation(Vector3 worldPos, AstarData aStar, Texture2D texture)
        {
            return new Location
                (

                (int)((worldPos.x - aStar.CenterX / CenterScaling) * samplingNum + texture.width / 2)
                ,
                (int)((worldPos.y - aStar.CenterY / CenterScaling) * samplingNum + texture.height / 2)

                );
        }
        public static SquareGrid SetNewGrid(int style, int id, out Texture2D texture)
        {
            texture = Resources.Load<Texture2D>("AstarData/" + style + "/" + id); 
            if (texture == null)
                return null;
            SquareGrid grid = new SquareGrid(texture.width, texture.height);
            for (int i = 0; i < texture.width; i++)
            {
                for (int j = 0; j < texture.height; j++)
                {
                    if (texture.GetPixel(i, j) != Color.blue)
                    {
                        grid.walls.Add(new Location(i, j));
                    }
                }
            }
            return grid;
        }

        public static Vector3 GetPos(Location location, Texture2D 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值