基于A*的寻路路径点生成,这里只做之后的显示以及曲线平滑

这里主要是Catmull-Rom的应用,最终选用的是Centripetal Catmull–Rom spline

起初想要通过贝塞尔曲线去平滑路径,但是很快便发现路径平滑后它不穿过中途点。

贝塞尔曲线

Catmoll-Rom

参考


由最少4个点进行差值计算,差值结果在p1-p2之间

曲柄是由P’(0) = τ(Pi - Pi-2), P’(1) = τ(Pi + 1 - Pi - 1)



Chordal与Uniform样条曲线的最大区别是对每一个τ都进行了计算实际间隔长度

Centripetal 则是对这个τ部分又进行了一个幂次方,当幂是0则为Uniform,为1则是Chordal,而0.25-0.5则是Centripetal


这张图解释了不选用默认样条的原因

//获取lilneRenderer组件并初始化
void GetLineRenderer(){if (_lr == null){Debug.Log($"{this.transform.name}: line renderer 获取失败");return;}if (lineMat == null){Debug.Log("line renderer材质不能为空");return;}//line renderer 设置;_lr.materials = lineMat;_lr.useWorldSpace = true;//颜色渐变,linerenderer会赋值给顶点色_lr.colorGradient = gradient;_lr.shadowCastingMode = ShadowCastingMode.Off;_lr.lightProbeUsage = LightProbeUsage.Off;_lr.reflectionProbeUsage = ReflectionProbeUsage.Off;_lr.textureMode = LineTextureMode.RepeatPerSegment;_lr.alignment = LineAlignment.TransformZ;_lr.widthCurve = width;_lr.useWorldSpace = true;}//这步可省略,可以在inspector里手动设置private Gradient GetColorGradient(){var g = new Gradient();   // Populate the color keys at the relative time 0 and 1 (0 and 100%)var colorKey = new GradientColorKey[4];colorKey[0].color = Color.black;colorKey[0].time = 0.1f;colorKey[1].color = Color.white;colorKey[1].time = 0.2f;    colorKey[2].color = Color.white;colorKey[2].time = 0.8f;  colorKey[3].color = Color.black;colorKey[3].time = 0.9f;var alphaKey = new GradientAlphaKey[1];alphaKey[0].alpha = 1.0f;alphaKey[0].time = 0.0f;g.SetKeys(colorKey, alphaKey);return g;}private void SetPath(){transform.localRotation = Quaternion.Euler(new Vector3(0,0,0));//高度控制for (int i = 0; i < _pathArray.Count; i++){_pathArray[i] += Vector3.up * height;}_lr.enabled = true;//将传入的寻路点输入,生成平滑点,smooth越高,差值出的平滑点越多_pathArray = GetCurve(_pathArray, smooth);_lr.positionCount = _pathArray.Count;for (int i = 0; i < _pathArray.Count; i++){_lr.SetPosition(i, _pathArray[i]);}//需要将立面旋转为平面transform.localRotation = Quaternion.Euler(new Vector3(90,0,0));}//根据输入点重新分布并平滑曲线点List<Vector3> GetCurve( List<Vector3> pathArray, int smooth = 4){if (pathArray.Count < 3){return pathArray;}List<Vector3> pathss = new List<Vector3>();CatmullRomCurve curve;Vector3 pt, p0, p1, p2, p3;for (int i = 0; i <= pathArray.Count - 2; i++){p1 = pathArray[i];p0 = i == 0 ? p1 : pathArray[i - 1];p2 = pathArray[i + 1];p3 = i == pathArray.Count - 2 ? p2 : pathArray[i + 2];curve = new CatmullRomCurve(p0, p1, p2, p3, 0.5f);int detail = smooth;for( int j = 1; j < detail; j++ ) {float t = j / ( detail - 1f );pt = curve.GetPoint( t );pathss.Add(pt);}}return pathss;}//https://en.wikipedia.org/wiki/Centripetal_Catmull–Rom_splinepublic struct CatmullRomCurve {public Vector3 p0, p1, p2, p3;public float alpha;public CatmullRomCurve( Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float alpha ) {( this.p0, this.p1, this.p2, this.p3 ) = ( p0, p1, p2, p3 );this.alpha = alpha;}// Evaluates a point at the given t-value from 0 to 1public Vector3 GetPoint( float t ) {// calculate knotsconst float k0 = 0;float k1 = GetKnotInterval( p0, p1 );float k2 = GetKnotInterval( p1, p2 ) + k1;float k3 = GetKnotInterval( p2, p3 ) + k2;// evaluate the pointfloat u = Mathf.LerpUnclamped( k1, k2, t );Vector3 A1 = Remap( k0, k1, p0, p1, u );Vector3 A2 = Remap( k1, k2, p1, p2, u );Vector3 A3 = Remap( k2, k3, p2, p3, u );Vector3 B1 = Remap( k0, k2, A1, A2, u );Vector3 B2 = Remap( k1, k3, A2, A3, u );return Remap( k1, k2, B1, B2, u );}static Vector3 Remap( float a, float b, Vector3 c, Vector3 d, float u ) {return Vector3.LerpUnclamped( c, d, ( u - a ) / ( b - a ) );}float GetKnotInterval( Vector3 a, Vector3 b ) {return Mathf.Pow( Vector3.SqrMagnitude( a - b ), 0.5f * alpha );}}//移除角色身后的路径点void PlayerMovingForward(){if (playerPos == null || _lr == null || _lr.positionCount == 0 || _pathArray.Count == 0) return;Vector3 p1 = _lr.GetPosition(0);Vector3 p2 = playerPos.position;Vector3 dir = Vector3.Normalize(p1 - p2);var cross = Vector3.Cross(playerPos.right, dir);//>0 p1 在 p2 后面, <0 p1 在 p2 前面,移除身后点if (cross.y > 0){if (_pathArray.Count == 0){//0点后不再进行删除return;}_pathArray.RemoveAt(0);_lr.positionCount = _pathArray.Count;for (int i = 0; i < _pathArray.Count; i++){_lr.SetPosition(i, _pathArray[i]);}}}

Unity中利用LineRenderer绘制寻路路径相关推荐

  1. Unity中利用NOPI读取Excel

    Unity中利用NOPI读取Excel ---0v0--- 前言 ---0_0--- NPOI的相关.dll网盘下载链接 一.解析Excel的类 二.测试代码 -0v0- 前言 最近工作遇到解析.xl ...

  2. python神奇时钟项目_怎么在Python项目中利用Pygame绘制一个时钟

    怎么在Python项目中利用Pygame绘制一个时钟 发布时间:2020-11-30 14:24:30 来源:亿速云 阅读:54 作者:Leah 怎么在Python项目中利用Pygame绘制一个时钟? ...

  3. Unity中利用材质自发光实现物体闪烁效果

    Unity中利用材质自发光实现物体闪烁效果 补充:这种方法有一点问题,在测试(Windows平台)的时候发现,要想在Build出来的游戏中实现闪烁效果,就必须在 Project 窗口中将源材质的自发光 ...

  4. 小功能⭐️Unity中利用材质自发光实现物体闪烁效果

    文章目录 本文基于VDer的文章<Unity中利用材质自发光实现物体闪烁效果>延伸开发 在实现了具有一个Material的物体闪烁发光之后,延伸开发了具有多个Material的自闪烁效果, ...

  5. Unity中 利用Line Renderer || Trail Renderer制作飘烟拖尾

    在Unity中粒子特效就可以制作飘烟拖尾,但是如果运动过快难免会有不自然的断开.虽然粒子中加入了Trail,但是我让拖尾转角圆滑比较困难(这方面还得请教特效同学).当然如果对转角没有要求,粒子还是最简 ...

  6. Unity中利用C#开发泡泡龙游戏

    泡泡龙是一款非常经典的游戏,版本有很多,如百度的<彩色泡泡>等.游戏开始时,泡泡应该出现m行:如果连续n次发射泡泡没有出现同色泡泡相消的情况,在屏幕上方自动加上一行泡泡:如果屏幕中泡泡全部 ...

  7. 【Unity Shader】Unity中利用GrabPass实现玻璃效果

    <入门精要>中模拟玻璃是用了Unity里的一个特殊的Pass来实现的,这个Pass就是GrabPass,比起上一篇博客实现镜子的方法,这个方法我认为相对复杂,因此在实现之前需要对GrabP ...

  8. unity editor android 黑屏_如何在Unity中利用nReal制作AR应用

    来源:新浪VR nReal眼镜是今年最有趣的增强现实小工具之一.它们已经在CES上展示过了,几个月前笔者在北京亲自试用过,在我的评测中,我强调了它们不仅非常轻.时尚,而且还能提供非常明亮的全息视图. ...

  9. UNITY中利用点乘和叉乘判断方向 2D

    void DirectionJudge(){Vector3 dir = mousePositionInWorld - transform.position;dir.z = 0f;var magiDir ...

最新文章

  1. 特斯拉fsd全自动驾驶与华为自动驾驶
  2. 圣才电子书怎么提取pdf_总结10个免费网站,助你解决PDF所有问题!
  3. 他为何能够领跑互联网与AI时代?李彦宏讲述成功之道
  4. Servlet的Filter的使用
  5. 踢毽也能治胃病,适当的运动带来健康,健康带来快乐
  6. JSP-03-实现数据传递
  7. 广州的11个辖区_避开人潮,广州7月展览指南,有11个免费
  8. TDSQL 全时态数据库系统-理念与愿景
  9. 2017.8.23创业项目方向
  10. 如何用VMware搭建HA和DRS环境(第一篇;序)
  11. 阿里RDS开发专家解析MySQL各版本并行复制
  12. 策略的静态与动态报表——绝对值得收藏的策略资料(文尾视频)
  13. Kotlin 输出“Hello World”
  14. 群体智能优化算法之和声搜索(Harmony Search,HS)-附源码
  15. 按键精灵易语言c,易语言插件按键精灵调用方法
  16. Android studio断点调试源码
  17. android_97_TouchSlop
  18. HDU 1874 畅通工程续 Floyd
  19. 解决Laragon的nginx/apache重启后网站配置文件被修改的问题 - This file has been modified by another program - 文件auto.conf
  20. Android 蓝牙 A2dp音频数据通过L2cap 发往Controller -- 代码详解

热门文章

  1. chrome + IDM + 油猴插件 实现百度网盘大文件的高速下载
  2. 【Asp.net入门01】动态网站基础知识
  3. ABAQUS学习之路
  4. 介绍部电影“Sicko”,迈克尔摩尔拍摄的抨击美国医疗体制的纪录片
  5. Windows远程桌面服务漏洞(CVE-2019-0708)复现测试
  6. 【状语从句练习题】连词 + 过去分词
  7. 机器学习入门(二) 准备工作
  8. 做SEO优化第六步:设置Title、keywords和Description
  9. 通过jmeter进行用户并发(vu/s)测试
  10. Vitamio使用篇,打造强悍的视频播放器