A*寻路算法——多人寻路、实时碰撞寻路、最近目的地

本文介绍了如何在多人寻路场景中应用A*算法,包括在路径不可达时如何寻找离目的地最近的点,以及如何处理实时碰撞检测。在遇到碰撞时,算法会重新调用A*进行寻路,确保路径的无障碍。通过提供的工程文件,读者可以进一步了解其实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A* 路算法原理可以参考这个文章,已经写的很详细了http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx

这篇文章主要写写多人寻路的实时碰撞

先说说无法寻路的情况下,如何移动的离目的地最近的点

其实所有能到达的点都在"关闭列表中",当“开启列表”中所有的点都遍历完后,如果还未找到终点,则视为路径不通

这时候遍历“关闭列表”,找出其中离终点直线距离最短的点即可,见下面代码中findNearPointFromList函数


多人碰撞的大体思路就是

1、用A*找出一条路径

2、按该路径走,没移动一格检测是否发生碰撞

3、如果碰撞,调用A*重新寻路

4、如果未碰撞,按原来路径继续走

5、到目的地停止


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace testAstar
{
    public class AstarNode
    {
        private AstarNode parent = null;
        private int g;
        private int h;
        private int x;
        private int y;

        public AstarNode Parent
        {
            get
            {
                return parent;
            }
            set
            {
                parent = value;
            }
        }

        public int G
        {
            get
            {
                return g;
            }
            set
            {
                g = value;
            }
        }

        public int H
        {
            get
            {
                return h;
            }
            set
            {
                h = value;
            }
        }

        public int F
        {
            get
            {
                return g + h;
            }
        }

        public int X
        {
            get
            {
                return x;
            }
            set
            {
                x = value;
            }
        }

        public int Y
        {
            get
            {
                return y;
            }
            set
            {
                y = value;
            }
        }

        public AstarNode(int _x, int _y)
        {
            this.x = _x;
            this.y = _y;
            this.parent = null;
            this.g = 0;
            this.h = 0;
        }
    }

    public class Astar
    {
        private List<AstarNode> openList = new List<AstarNode>();
        private List<AstarNode> closeList = new List<AstarNode>();
        private bool[,] mapData = null;
        private int pixelFormat = 16;
        private int mapWidth = 0;
        private int mapHeight = 0;
        private int endX = 0;
        private int endY = 0;

        public bool[,] MapData
        {
            get
            {
                return mapData;
            }
        }

        public int PixelFormat
        {
            get
            {
                return pixelFormat;
            }
        }

        public int MapWidth
        {
            get
            {
                return mapWidth;
            }
        }

        public int MapHeight
        {
            get
            {
                return mapHeight;
            }
        }

        public Astar()
        {
        }

        private bool isValid(int x, int y)
        {
            if (x < 0 || x >= mapWidth)
            {
                return false;
            }

            if (y < 0 || y >= mapHeight)
            {
                return false;
            }

            return true;
        }

        private bool inList(List<AstarNode> list, int x, int y)
        {
            foreach (AstarNode node in list)
            {
                if (node.X == x && node.Y == y)
                {
                 
### Unity 内置渲染管线与 URP (Universal Render Pipeline) 的区别 #### 渲染架构差异 Unity 内置渲染管线采用较为传统的单通道或通道延迟渲染方式,其灵活性较低。相比之下,URP 是基于 Scriptable Render Pipeline(SRP),允许开发者自定义渲染流程中的各个阶段[^1]。 #### 性能优化特性 对于移动设备和其他资源受限平台而言,URP 提供了更高效的性能表现。这是因为 URP 支持更低级别的硬件访问控制以及更好的批处理能力,从而减少了绘制调用次数并提高了帧率稳定性[^4]。 #### Shader 和材质支持 在内置渲染管线中使用的着色器主要依赖于 Surface Shaders 或者 Handwritten Vertex/Pixel Shaders 。然而,在 URP 下则完全迁移到 HLSL 并引入了新的 Material Properties ,这不仅简化了开发过程还增强了跨平台兼容性。 #### 特殊效果实现 当涉及到复杂视觉特效如屏幕空间环境光遮蔽(Ambient Occlusion)时,两者都提供了相应的解决方案。但在具体实现上有所区别;例如,在 URP 中可以通过编写自定义 Passes 来增强此类功能的效果质量[^3]。 ```csharp // 示例:如何在一个简单的 URP shader 中添加 AO 效果 Shader "Custom/AOExample" { SubShader { Tags { "RenderType"="Opaque" } Pass { Name "AO" HLSLPROGRAM #pragma vertex vert #pragma fragment frag struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; }; struct Varyings { float4 posHCS : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _MainTex; Varyings vert(Attributes input) { Varyings output; output.posHCS = TransformObjectToHClip(input.positionOS); output.uv = input.uv; return output; } half4 frag(Varyings input) : SV_Target { // 假设我们已经有了一个可以获取 SSAO 数据的方法 GetScreenSpaceAmbientOcclusion() half aoValue = GetScreenSpaceAmbientOcclusion(input.uv); // 应用 AO 到最终颜色输出 half4 color = tex2D(_MainTex, input.uv); color.rgb *= lerp(1.0, aoValue, 0.75); return color; } ENDHLSL } } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值