1,前言

给定一个场景:

  • 有两个点:A和B
  • 若干个辅助点
  • 一些障碍物(层级为WallLayer,标签为Wall)

在辅助点的帮助下,将A和B用线连起来,同时画出来的线不能穿过墙壁。求怎么画才能画出最短的路线

2,脚本实现

  • person代表A点
  • target代表B点
  • secondaryParent代表所有辅助点的父物体
  • 所有的障碍物,其层级为WallLayer,且障碍物的标签为Wall
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 根据Floyd算法画出最短路线
/// </summary>
public class AutoFindRoadByFloyd : MonoBehaviour
{//人物public Transform person;//辅助点集合public Transform secondaryParent;//目标物体public Transform target;//所有点的集合private List<Transform> list = new List<Transform>();//射线监测碰到的层【若不设置这个,就有概率发生 当射线穿过辅助点再穿过墙壁 。//              因为射线检测碰撞墙壁会检测第一个碰到的物体,当先穿过辅助点,就会被认为这条射线是合理的,即便后续它会穿过墙壁//              注意:这里的辅助点是默认为Cube,是否添加这个,视具体情况而定】private int targetLayerMask;//距离矩阵,Floyd算法核心之一private float[,] dis;//路径矩阵,FLoyd算法核心之一private int[,] path;//所有点的数量private int length;//当得出最短路径有哪些点之后,将其添加到这里,统一画图private List<Transform> result = new List<Transform>();//线的宽度public float lineWidth;// Start is called before the first frame updatevoid Start(){//初始化射线检测的层targetLayerMask = LayerMask.GetMask("WallLayer");//初始化所有点的先渲染其设置InitAllPoints();}// Update is called once per framevoid Update(){//寻找最短路径,并画线FloydWrap();}/// <summary>/// Floyd的包装方法,在这里进行画线前的参数初始化,并进行画线/// </summary>public void FloydWrap(){//初始化矩阵InitMatrix();//重置所有点的线,防止路径改变后,某些点还在画线ResetAllPoints();//重置路径数组result = new List<Transform>();//Floyd算法,得出最短路径Floyd();//将最短路径加入结果数组中,FindFloydPath有可能发生异常,因为当不形成通路时,会报数组下标越界try{result.Add(person);FindFloydPath(0, length - 1);result.Add(target);}catch (Exception e){//若无法形成通路,在这里输出,或者执行相应的方法Debug.Log("当前没有无法形成通路,请重新再试");}//执行画线的方法DrawLine();}/// <summary>/// 初始化矩阵/// </summary>public void InitMatrix(){//获取所有点的数量length = list.Count;//根据点的数量,创建一个【距离矩阵】,每个矩阵点的数值有三种情况===》// 0:代表自身到自身//  float.MaxValue:代表两个点之间无法相连(中间有墙壁阻隔)// 其他情况:代表两个点可以相连,数值为距离dis = new float[length, length];//创建一个【路径矩阵】,这个矩阵代表着从A点到B点要经过哪些点path = new int[length, length];//初始化【距离矩阵】和【路径矩阵】for (int i = 0; i < length; i++){for (int j = 0; j < length; j++){//路径矩阵 每个点初始化为-1path[i, j] = -1;//当点到自身的时候,值为0if (i == j){dis[i, j] = 0;continue;}//判断两点之间是否隔着墙if (CheckCollideWall(list[i], list[j])){//若没有隔墙,则将两点距离进行赋值dis[i, j] = Vector3.Distance(list[i].position, list[j].position);}else{//若隔着墙,则赋予 float.MaxValuedis[i, j] = float.MaxValue;}}}}/// <summary>/// 执行Floyd算法,修改dis和path矩阵/// </summary>public void Floyd(){for (int k = 0; k < length; k++){for (int i = 0; i < length; i++){for (int j = 0; j < length; j++){if (dis[i, j] > dis[i, k] + dis[k, j]){dis[i, j] = dis[i, k] + dis[k, j];path[i, j] = k;}}}}}/// <summary>/// 通过【路径矩阵】获取最短路径///  path矩阵///     (0) (1) (2) (3) (4)/// (0) -1   2  -1   2   3   /// (1) -1  -1  -1  -1   3/// (2) -1  -1  -1   1   3/// (3) -1  -1  -1  -1  -1/// (4) -1  -1  -1  -1  -1 ///      ///     以找 0-4 之间的最短路径为例:///         先找path[0,4],其值为3,代表0与4之间存在一个中间节点3///             接下来就分为两部分:【0-3】 与 【3-4】,查看这两部分之间是否存在中间节点///                 找path[0,3],其值为2,代表存在一个中间节点 2///                     接下来分为两部分:【0-2】 与 【2-3】,查看这两部分之间是否存在中间节点///                         找path[0,2],其值为-1,代表不存在中间节点///                         找path[2.3],其值为1,代表存在一个中间节点1///                             接下来分为两部分:【2,1】 与 【1,3】,查看这两部分之间是否存在中间节点///                                 找path[2,1],其值为-1,代表不存在中间节点///                                 找path[1,3],其值为-1.代表不存在中间节点///                 找path[3,4],其值为-1,代表不存在中间节点///     综上所述,可以得出0-4之间的最短路径序列为:///         0-》2-》1-》3-》4/// </summary>/// <param name="st"></param>/// <param name="ed"></param>void FindPath(int st, int ed){if (dis[st, ed] < float.MaxValue && path[st, ed] == (-1)){result.Add(list[ed]);// Debug.Log("->>" + list[ed].name);}else{int mid = path[st, ed];FindPath(st, mid);FindPath(mid, ed);}}/// <summary>/// FindPath的包装方法,可以通过这,递归调用FindPath()/// </summary>/// <param name="st"></param>/// <param name="ed"></param>void FindFloydPath(int st, int ed){// Debug.Log("最短路径" + st + "-" + ed + "-" + st);FindPath(st, ed);}/// <summary>/// 根据结果数组进行画线/// </summary>public void DrawLine(){LineRenderer component;for (int i = 0; i < result.Count - 1; i++){component = result[i].GetComponent<LineRenderer>();component.SetPosition(0, result[i].position);component.SetPosition(1, result[i + 1].position);}}public void InitAllPoints(){LineRenderer component;//初始化所有点集合,并添加线渲染器person.gameObject.AddComponent<LineRenderer>();component = person.GetComponent<LineRenderer>();component.startWidth = lineWidth;component.endWidth = lineWidth;component.material = lineMaterial;component.textureMode = LineTextureMode.Tile;list.Add(person);foreach (Transform o in secondaryParent){o.gameObject.AddComponent<LineRenderer>();component = o.GetComponent<LineRenderer>();component.startWidth = lineWidth;component.endWidth = lineWidth;component.material = lineMaterial;component.textureMode = LineTextureMode.Tile;list.Add(o);}target.gameObject.AddComponent<LineRenderer>();component = target.GetComponent<LineRenderer>();component.startWidth = lineWidth;component.endWidth = lineWidth;component.material = lineMaterial;component.textureMode = LineTextureMode.Tile;list.Add(target);}/// <summary>/// 重置所有点的线渲染器的位置数据,以达到删除线的效果/// </summary>public void ResetAllPoints(){foreach (Transform o in list){LineRenderer lineRenderer = o.GetComponent<LineRenderer>();lineRenderer.SetPosition(0, o.position);lineRenderer.SetPosition(1, o.position);}}/// <summary>/// 判断是否撞墙了/// </summary>/// <param name="from"></param>/// <param name="to"></param>/// <returns></returns>public bool CheckCollideWall(Transform from, Transform to){//初始化射线设置Ray ray = new Ray(@from.position, (to.position - @from.position).normalized);RaycastHit hit;//射线只会与 targetLayerMask指定的Layer发生碰撞检测if (Physics.Raycast(ray, out hit, Vector3.Distance(from.position, to.position), targetLayerMask)){//碰到墙if (hit.transform.tag.Equals("Wall")){return false;}}//未碰到墙return true;}}

Unity--Floyd画出最短的路径相关推荐

  1. 用python画雪花 科赫曲线递归_【TCE的编程小讲堂】【Python】【第三期】如何画出科赫雪花?(下)...

    大家还记得上期讲的科赫雪花吗?我们上次讲过画出一条边的方法,大家看看代码复习一下 import turtle#包含turtle库 def koch(l): turtle.forward(l / 4)# ...

  2. 【机器学习】【条件随机场CRF-3】条件随机场的参数化形式详解 + 画出对应的状态路径图 + 给出对应的矩阵表示...

    1.条件随机场概念 CRF,Conditional Random Field,是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模式,其特点是假设输出随机变量构成马尔可夫随机场. 条件随机场 ...

  3. 通通玩blend美工(8)——动态绘制路径动画,画出个萌妹子~

    通通玩blend美工(8)--动态绘制路径动画,画出个萌妹子~ 原文:通通玩blend美工(8)--动态绘制路径动画,画出个萌妹子~ 2年前我在玩Flex的时候就一直有一个疑问,就是如何来实现一个蚊香 ...

  4. Android studio编译跑步运动app一个安卓的跑步软件实时记录速度,画出跑步路径, 管理跑步数据履历,查看数据详细等

    Android studio编译跑步运动app一个安卓的跑步软件实时记录速度,画出跑步路径, 管理跑步数据履历,查看数据详细等 效果图: 效果视频: 安卓运动跑步APP android studio编 ...

  5. Unity使用LineRenderer组件画出菱形,长度,角度可任意调节

    首先说下我的思路: 开始想的比较简单,就是先建两个空物体分别挂上脚本,一个在X轴画直线,一个与X轴成angle夹角,通过计算得出坐标,这样就能画出一个菱形的角度,下面是实例图: 最后再写个脚本通过循环 ...

  6. python:基于matplotlib在坐标轴上画出车辆路径规划示意图(箭头、中文图例)

    车辆路径规划问题的研究一般较常遇到需要画出车辆路径示意图,已知有每辆车的真实坐标序列,那么如何利用在一个空白的坐标轴上画出路径呢? 1.准备 1.1 matplotlib引入 一般情况下只引入plt就 ...

  7. 利用easyX图形库画迷宫问题的路径

    文章目录 前言 1.迷宫问题 1.1 问题描述: 1.2 实验目的: 2.函数原型及功能 3.关键内容 3.1 如何记录bfs算法访问各个路径中点的横纵坐标 3.2 如何用VC6.0输出最短路径图 3 ...

  8. 如何画出优秀的架构图?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | 三画 来源 | 公众号「阿里巴巴云原生」 导读:技术传播 ...

  9. pyhton 画出音频文件的波形图和频谱图

    pyhton 画出音频文件的波形图和频谱图 # -*- coding:utf-8 -*- import wave import struct import numpy as np import mat ...

最新文章

  1. chrome浏览器不能录音:Uncaught TypeError: Cannot read property ‘getUserMedia‘ of undefined解决方法
  2. java实现网页保存_详解Java两种方式简单实现:爬取网页并且保存
  3. 分享20个Android游戏源代码。以后看看。
  4. python3.4新特性_Python3中的新特性(1)——新的语言特性
  5. 小鹏汽车4月交付量5147台 同比增长285%
  6. 从零开始学习ASP.NET MVC1.O (第一章)
  7. python的jieba分词
  8. 51CTO博客改版日记(目录) 2006年 by小废
  9. 【读书笔记《Bootstrap 实战》】4.企业网站
  10. JAVA程序设计(学堂在线-清华大学) 课后练习题 已更新完毕
  11. 不理解 Java Steam?一步步梳理其工作方式
  12. 【Git】查看改动文件清单
  13. matlab kmeans 质心,KMeans_SPD_Matrices
  14. 操作MySQL出错提示“BLOB/TEXT column used in key specification without a key length”解决办法
  15. 查询某个网址的服务器IP
  16. dxdiag windows硬件检测
  17. Android - 一个似神器而非神器之Palette探索与实践
  18. 革文B2B行业洞察:中国气凝胶市场分析、竞争格局和发展趋势
  19. String的inturn()的运用
  20. Hi3559AV100/Hi3559CV100 DDR4参数配置说明

热门文章

  1. jmeter并发测试教程_jmeter怎么进行并发测试
  2. 小米6 WiFi验证门户中的RCE漏洞
  3. oracle数据库查询过后显示所受影响的行数
  4. 京东开源项目之列表解决方案Drip-Table
  5. 51单片机DS18B20测温数码管显示例程(Proteus仿真+程序)
  6. 宋浩_1_函数映射, 满射/双射/单射/逆映射, 定义域,值域
  7. 520 钻石争霸赛 2023
  8. 计算两个时间戳型的时间差
  9. 化工中用到的计算机知识,计算机在化工中的应用课件.ppt
  10. 病理图像相关内容整理