基于Spline的测距功能插件

一、功能分析

这里首先分析一下整个插件的功能部件

  • SplineActor—基于Spline的线条显示模块

  • Ranging—对整个插件功能的整体控制

  • DistancePanel—距离显示UI

  • Point—线上的点,集成DistancePanel

  • FunLib—高复用函数集合

    资产状况:

由于使用屏幕坐标转世界坐标的方式实现测距功能可能及其复杂,所以这里使用比较直观简便的三维Spline来实现测距功能。

二、制作线上的点Point

1.Point的结构分析

Point是一个拥有StaticMesh和WedgitComponent组件的Actor,StaticMesh我这里使用Shape,Materials是自己做的一个发光材质。

2.MeshMeterial材质

Materials蓝图:

3.Point核心函数实现

Point主要实现一个函数两个事件

  • 函数ShowDistance—负责距离显示
  • 事件InitFontInfo—负责获取初始字体信息
  • 事件ShowText—控制距离是否显示

在构造函数需要记录DistancePanel的初始位置信息和初始字体信息。

ConstructScript:记录DistancePanel的初始位置信息和初始字体信息

InitFontInfo:记录字体的初始信息

ShowText:设置显示字体的大小。

Tick函数:SetActorRotation设置点上的文字跟随摄像机旋转使之始终面向摄像机,GetMouseLocation->SetActorLocation->ShowText当SureLocation为false时即未确定点的位置时设置点跟随鼠标移动,当点跟随鼠标移动时不显示距离。

  • FontInfo:是一个SlateFontInfoStructure结构体用于设置距离显示的字体样式。
  • SureLocation:bool变量,确认点是否已经确定了位置坐标,当点没有确定位置坐标时,点将跟随鼠标移动。
  • InitScale3D:Vector变量,保存DistancePanel的初始大小。
  • SureAdsorb:bool变量,控制闭环吸附,当为true时,起点具有吸附功能,可以将终点吸附到起点位置实现闭环。

ShowDistance:将输入的距离信息显示出来。

至此点的设计完毕。

三、用于显示的Widget

创建一个UserWidget命名为DistancePanel,DistancePanel比较简单,CanvasPanel下就一个Text即可,只有一个函数UpdateTextScale,然后在EventConstruct中记录Text的初始大小。

EventConstruct:

UpdateTextScale:更新Text的大小,使Text跟随摄像机距离地板的远近变大变小,以保证Text的大小在视野中保持不变。

三、使用Spline制作线段

1.SplineActor结构分析

Spline是UE4的样条线组件,Spline是一组点和线的集合,但是Spline的点和线只有在编辑模式下可见,在运行模式下不可见,Spline可以通过选中其中的点按下Alt键并拖动鼠标来添加新的点。

我们需要一个Actor作为Spline的载体,创建一个Actor命名为Spline。Spline的组件结构为:

  • StaticMesh:使用Shape和自定义的材质,这个Mesh作为起点使用。
  • Spline:样条线组件,此Actor的核心组件。
  • Sphere:球型触发器,用于起点吸附。

2.在编辑模式下实现Spline编辑

在编辑模式下实现样条线的编辑需要在构造函数中实现下面的逻辑:

核心函数分析:

  • AddSplineMeshComponent:这是一个自定义的封装函数,作用就是提高复用率,

StaticMesh决定线的样式,Meterial决定线的颜色;

  • AttachToMeshComponent:将添加的SplineMeshComponent组件设置StaticMesh为父节点;

  • Set Start and End:函数根据Get LocationandTangentatSplinePoint函数获取的起点和终点的位置和切角,将生成的SplineMeshComponent组件附着在上面。

这样我们的Spline样条线就被设置成了我们设定的模样,并且在运行时可见。

3.运行时动态添加Spline的点

由于在运行模式下无法像在编辑模式下通过Alt键拖动点来添加Spline的点,所以我们需要通过蓝图来实现。这项功能封装在AddPoint函数中。

AddPoint函数通过输入的坐标位置动态生成Spline的点

  • AddSplinePoint:向Spline中添加新的点;
  • SpawnActorPoint:目的是在Spline的生成的新点的位置处生成一个具象化的Point;
  • Sequence的的Then0分支作用是当生成一个新的Point时,确定上一个Point的位置坐标;
  • PointArray是一个Point类型的数组,用于存储生成的Point的引用,SplineMeshComponentArray是一个SplineMeshComponent类型的数组,用于存储生成的SplineMeshComponent组件的引用,两个数组的作用是方便之后对Point和SplineMeshComponent的操作。
  • AddSplineMeshComponent、AttachToComponent和SetSartandEnd函数作用和构造函数中一样;
  • UpddateTotaldistance函数用于更新距离显示,具体实现在后面介绍。

AddPoint函数在AddPointEvent事件中调用。

  • GetMouseLocation是FunLib库中的一个函数负责获取鼠标坐在的屏幕坐标转换成空间坐标。

4.实时更新样条线

实时更新样条线的功能封装在UpdateCurrentSplinePoint函数中。

UpdateCurrentSplinePoint函数在SplineActor的Tick函数中调用,每帧删除前一个Spline的点,在新的坐标位置下添加一个新的Spline的点,由于Point是跟随鼠标移动的,所以通过这个操作在宏观上的表现就是Spline的点在跟随鼠标一点,之所以使用这种方式,是因为Spline中的点似乎没办法直接修改位置。

每帧设置好位置之后再重新渲染一遍Mesh组件,就达到如下效果了:

这样在运行状态下编辑Spline样条线就制作完成了。

四、实时更新距离

实时更新距离的功能封装在UpdateTotalDistance函数下。

  • Ranging变量就是Ranging类型,存储Ranging的引用,在重新计算总距离前先将存储中距离的变量TotalDistance清零;
  • 然后一次取PointArray中的Point来计算Point与Point之间的距离,0号索引的Point较为特殊需要与其他索引的Point分开计算,因为0号索引的Point需要与SplineActor的位置计算距离;
  • ShowDistance函数封装在Point类中,负责将输入的距离显示出来。

显示总距离专门创建了一个DistancePanel来显示。

  • HiddenTotalDistance控制总距离是否显示。

到这里基本的功能就基本实现了,下面实现一些必要的附加功能。

五、封装Ranging类

由于SplineActor类是插件的核心类,不宜对外开放调用接口,且SplineActor类自身拥有Mesh,直接拖入场景中会显示Mesh,效果不佳,所以在SplineActor之外再封装一成没有Mesh的Ranging是十分必要的,有Ranging类提供对外调用的接口。

Ranging类的封装函数和变量:

  • SetupRanging:启动测距,在鼠标所在位置生成SplineActor;

  • AddPoint:封装SplineActor中的AddPointEvent事件;

  • EndRanging:结束测距,封装ActorSpline的DeleteLastPoint函数,函数的具体实现在之后介绍;

  • Remove:删除所有的点线,封装SplineActor的RemoveAllPoint函数,函数的具体实现在之后介绍;

  • SplineActor:存储SplineActor的引用;

  • TotalDistance:存储总距离的值;

  • DistanceUint:显示总距离时的单位;

  • K:存储SplineActor中DistancePanel随相机距离变化大小的变化倍率;我这里设定的值为0.0002。

文字随相机距离变化的函数实现封装在Ranging的UpdeteDistancePanelScale事件中,事件在Ranging的Tick函数中调用。

六、保持Point的DistancePanel组件的大小不变

为了保证观感效果,Point的显示距离的DistancePanel组件的大小应该跟随相机的远近保持保持一定的大小,以保证相机贴近地面时,文字不会过大,相机原理地面时文字不过过小而看不见。

实现原理就在Ranging的UpdateDistancePanelScale事件中。

七、返回上一步功能

当我们确定点的位置时会出现位置确定错误的情况,所以返回上一步的功能也是十分必要的,具体实现在SplineActor的DeleteLastPoint函数中。

原理是移除上一个Spline的点和其匹配的Point、SplineMeshComponent并删除数组中对应的元素,然后更新一次距离,如果剩下最后一个点时,再撤回就直接将SplineActor删除并把显示总距离的DistancePanel移除,防止再创建SplineActor时再生成一个DiatancePanel而出现两个DistancePanel。

八、移除所有的点

当测距完成后需要清除所有的点,所以此功能也是必要的,具体实现在SplineActor的RemoveAllPoint中。

九、起点吸附功能

起点吸附是为了实现闭环。具体实现在SplineActor的EventActorBeginOverlap事件中。

原理就是当SplineActor的Sphere触发器检测到Point时将此Point的坐标设置到起点的坐标处。

九、整体效果预览

【UE4】基于Spline的测距功能相关推荐

  1. fmcw matlab仿真,基于SIMULINK的FMCW雷达测距功能仿真.pdf

    基于SIMULINK的FMCW雷达测距功能仿真.pdf 全国空气动力测控技术交流会论文集 基于SlMUUNK的FMCW雷达测距功能仿真 也esimulation function ofFMCW dis ...

  2. ThreeJS 测距功能

    文章目录 选点绘线 绘制标签 1.使用 TextGeometry 创建标签文字 2. 使用 CSS2DObject 创建标签 动态绘制点.线和标签 绘制辅助线 撤销操作   测距功能,也就是选择两点, ...

  3. 高德地图JSAPI测距功能优化

    文章目录 前言 测距实现思路 使用测距插件 开启测距 关闭测距 前言 高德提供了一个距离测量插件可直接使用,但是没有完全满足需求.在测距过程中只会显示新增节点到起始点的总长度,而不会在鼠标移动过程中显 ...

  4. 基于单片机的TLC稳压电源系统设计-基于单片机大脑运算能力智力测试仪-基于单片机超声波测距系统仿真设计(报告 PCB 原理图)-基于单片机超高精度电参数测试设计-基于单片机变电站变压器运行参数监测仿真

    1316基于单片机的TLC稳压电源系统设计-毕设课设仿真资料 三极管射极电压是稳压电源的输出电压,可以接用电器或负载,这个电压值通过TLC549(A/D,同TLC548)数据转换后,送往单片机处理并显 ...

  5. 百度地图 测距功能 DistanceTool 在不同浏览器下标注不一致的解决办法,打开新地图测距不生效的解决办法

    1. 在项目中用到百度地图的测距功能,在主页面的地图中用没问题,如果从主页的地图跳转到详情页的地图,在返回到主页,打开地图的测距功能,测距一直不显示.下面是解决办法 将测距功能的工具类函数下载到本地, ...

  6. 多路测量实时同步工作原理_TOF测距功能的原理及使用方法

    摘要:该方法属于双向测距技术,利用数据信号在一对收发机之间往返的飞行时间来测量两点间的距离.将发射端发出数据信号和接收到接收端应答信号的时间间隔记为Tt,接收端收到发射端的数据信号和发出应答信号的时间 ...

  7. TOF测距功能的原理及使用方法

    一.飞行时间测距法TOF(time-of-flight)测距方法 该方法属于双向测距技术,利用数据信号在一对收发机之间往返的飞行时间来测量两点间的距离.将发射端发出数据信号和接收到接收端应答信号的时间 ...

  8. think php ajax分页,thinkPHP5框架实现基于ajax的分页功能示例

    本文实例讲述了thinkPHP5框架实现基于ajax的分页功能.分享给大家供大家参考,具体如下: 最近一个页面的选项卡又牵扯到ajax分页,所以研究了一下tp5的ajax分页使用方法 首先看一下tp5 ...

  9. (jQuery,SVG)使用jQuery和svg仿QQ地图测距功能(抛砖引玉)

    不久前看到了QQ地图的测距功能,觉得挺好玩的,就思考模仿一下.本来想通过canvas来画图,可惜对canvas不是很熟悉,就准备用svg了,其实我对svg也不是很熟,纯粹是学习. 代码只是简单的生成图 ...

最新文章

  1. 【iOS-cocos2d-X 游戏开发之十六】Cocos2dx编译后的Android自动使用(-hd)高清图设置自适应屏幕...
  2. [源码和文档分享]基于C语言的物流配送管理信息系统
  3. python简介怎么写-Python开发工程师岗位项目经历怎么写
  4. 【数学与算法】协方差矩阵 与 w*w^T 的关系
  5. mysql 同一张表查询_mysql 同一张表查询 left join
  6. Java学习笔记二十二:Java的方法重写
  7. 3.1 测试能否对标准输入设置偏移量
  8. python+selenium 处理alert弹出框
  9. CentOS安装YAPI
  10. todo Java注解
  11. [DEV] 陷阱技术探秘 ──动态汉化Windows技术的分析
  12. <Linux开发>--驱动开发-- 字符设备驱动(3) 过程详细记录
  13. python爬取音乐并保存的格式_python爬取QQ音乐歌单歌曲保存到本地,json解析
  14. Kali Linux 安装教程和使用技巧
  15. MyBatis详细笔记
  16. 怎么在mysql中创建用户名和密码是什么_mysql中怎么创建用户名和密码
  17. Linux中select IO复用机制
  18. PJ331 PJ501超小型封装PFM DC/DC升压稳压器
  19. 《云计算核心技术剖析》迷你书连载三 – 云计算的商业模式
  20. 做了6年的小猎头跟大家分享工作经验

热门文章

  1. 阿里巴巴山猎:手把手教你玩转全链路监控
  2. 从EOR与TOR架构谈EOR与TOR交换机
  3. 非常详细的eclipse使用svn教程
  4. maya Bifrost液体
  5. 目标检测:Object Detection with Deep Learning: A Review
  6. CVPR 2018摘要:第二部分
  7. 分享:从win10家庭版升级到专业版,以及企业版转变为专业版的坎坷之路
  8. Spring Transaction : TransactionAspectSupport
  9. oracle错误1405,oracle -1405错误解决方法
  10. 致大一计科软件新生——对专业方向以及个人忠告