[Unity] 基础寻路算法 - 环境搭建
作者:互联网
本文始发于:https://www.cnblogs.com/wildmelon/p/16148560.html
一、前言
本文只记录搭建工具时碰到的一些问题,并非完善的可视化方案和可实践应用的标准算法。
如果您正在搜索相关的寻路可视化工具,可参考:
- https://qiao.github.io/PathFinding.js/visual/
- https://clementmihailescu.github.io/Pathfinding-Visualizer/
如果您正在搜索寻路算法的入门教程,可参考:
二、背景
原打算利用一些时间了解些常用的寻路算法的基本原理。
本意是使用 Tilemap 来搭建一个简单的寻路过程可视化的工具,作为算法中的路径选择,成本等内容的可视化,大概原型会像这样:
但还是碰到了不少问题:一是 Tilemap 提供的,主要还是关卡环境搭建、表现层面的内容。如果要搭载其他的 UI(数值、高亮)和每个地块的实例数据,还是得单独编写一层数据层(利用官方的 Tilemap Extra 包应该也能实现);二是相关的细节表现,起终点选择,单步前进后退等也需要不少时间优化。
这么一来,所需的开发时间成本就变高了。虽然从工具开发的角度,并不能当作麻烦的内容。但原意是学习算法原理,辅以简洁的UI表现,现在这样就有些背道而驰了。
更重要的是在学习过程中,发现了几个完善的在线寻路可视化工具(参考前言部分)。
目前则打算先搁置多余的可视化部分,仅保留对算法的验证(能跑就行),本文就纯粹记录先前开发中碰到的问题,以作备忘。
三、工具搭建
(一)图片素材
素材来自于:https://cupnooble.itch.io/sprout-lands-asset-pack/
免费版不得使用于商业项目,具体请参考遵循作者的许可协议。
(二)地砖区分
总感觉非常不优雅,不知道能不能直接在 Unity 自带的Tile编辑器里就给设置了。
using UnityEngine;
using UnityEngine.Tilemaps;
#if UNITY_EDITOR
using UnityEditor;
# endif
public class WalkableTile : Tile
{
public WalkableTile()
{
flags = TileFlags.None;
}
}
public class ImwalkableTile : Tile
{
public ImwalkableTile()
{
flags = TileFlags.None;
}
#if UNITY_EDITOR
// 下面是添加菜单项以创建 RoadTile 资源的 helper 函数
[MenuItem("Assets/Create/ImwalkableTile")]
public static void CreateImwalkableTile()
{
string path = EditorUtility.SaveFilePanelInProject("Save ImwalkableTile", "New ImwalkableTile", "Asset", "Save ImwalkableTile", "Assets");
if (path == "")
return;
AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<ImwalkableTile>(), path);
}
# endif
}
(三)地面点击
private void Update()
{
if (!Input.GetMouseButtonDown(0)) return;
// 鼠标点击位置 屏幕空间 -> 世界空间
Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// 鼠标点击位置 世界空间 -> Tilemap格子坐标
Vector3Int cellPos = mTilemap.WorldToCell(mouseWorldPos);
// 格子坐标超出 tilemap 物体边界
if (!mTilemap.cellBounds.Contains(cellPos)) return;
// 点击格子,在水和陆地互换
TileBase tileBase = mTilemap.GetTile(cellPos);
if (!(tileBase is WalkableTile) && !(tileBase is ImwalkableTile)) return;
bool isWalkable = false;
TileBase targetTile = imwalkableTile;
if (tileBase is ImwalkableTile)
{
isWalkable = true;
targetTile = walkableTile;
}
mTilemap.SetTile(cellPos, targetTile);
OnTileCellClick?.Invoke(cellPos);
}
(四)屏幕适配
using UnityEngine;
public class CameraAdjust : MonoBehaviour
{
float width = 1920;
float height = 1200;
void Awake()
{
//屏幕适配
float orthographicSize = this.GetComponent<Camera>().orthographicSize;
print("aa:" + orthographicSize);
float scale = (Screen.height / (float)Screen.width) / (height / width);
orthographicSize *= scale;
print("center:" + scale + "shei" + Screen.height + Screen.width);
print("bb:" + orthographicSize);
this.GetComponent<Camera>().orthographicSize = orthographicSize;
}
}
(五)优先级队列
参考:https://github.com/LiuFeng1011/Test/blob/master/Assets/PriorityQueue/PriorityQueue.cs
四、待扩展的功能
- 自定义场景大小
- 随机地砖/迷宫生成
- 当前成本、预估成本的可视化
- 不同寻路算法选择
- 单步调试,运行时可前进回退寻路过程
标签:算法,ImwalkableTile,Unity,可视化,orthographicSize,https,寻路,public 来源: https://www.cnblogs.com/wildmelon/p/16148560.html