Loading

[Unity] 基础寻路算法 - 环境搭建

本文始发于:https://www.cnblogs.com/wildmelon/p/16148560.html

一、前言

本文只记录搭建工具时碰到的一些问题,并非完善的可视化方案和可实践应用的标准算法。

如果您正在搜索相关的寻路可视化工具,可参考:

  1. https://qiao.github.io/PathFinding.js/visual/
  2. https://clementmihailescu.github.io/Pathfinding-Visualizer/

如果您正在搜索寻路算法的入门教程,可参考:

  1. https://www.redblobgames.com/pathfinding/a-star/introduction.html (☆ 推荐)

二、背景

原打算利用一些时间了解些常用的寻路算法的基本原理。

本意是使用 Tilemap 来搭建一个简单的寻路过程可视化的工具,作为算法中的路径选择,成本等内容的可视化,大概原型会像这样:
图片1

但还是碰到了不少问题:一是 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

四、待扩展的功能

  1. 自定义场景大小
  2. 随机地砖/迷宫生成
  3. 当前成本、预估成本的可视化
  4. 不同寻路算法选择
  5. 单步调试,运行时可前进回退寻路过程
posted @ 2022-05-03 17:19  野生西瓜  阅读(365)  评论(0编辑  收藏  举报