概述:
很多射击游戏都有用箭头提示敌人(受击)方向的功能,比如CS中受到伤害是的六方提示。
笔者在开发DEMO的过程中,研究了类似功能,本文主要总结在制作全方向方位提示时的开发思路。
知识储备:
开发前,要先了一些和向量相关的知识。
点乘:向量点乘与叉乘的概念及几何意义 - 知乎
计算两个向量的夹角:UE4_相对于某一个Actor的夹角计算_SimpleCloud94的博客-CSDN博客_ue4求夹角
开发思路:
UI制作:
作为功能演示,笔者在屏幕中央放置一个警示图片代替箭头图标。
如上文视频所示,移动镜头时,警示图片的顶部会始终指向目标的方向。其中,图标旋转是通过修改Render Transform中的Angle实现的。
特别要注意的是,当摄像机朝左旋转时,方位箭头则向右旋转,此时Angle取值范围是· 【0,180】;当摄像机朝右旋转时,方位箭头朝左旋转,Angle取值范围是【-180,0】
为何要着重提及这Angle的取值问题呢?因为这涉及到下文会提及的夹角转换问题。
蓝图编写:
1.我们先打开Widget的蓝图图表,创建一个名为SetDirectionEvent的自定义事件,目的是给箭头图标的Angle赋值。
2.打开关卡蓝图,创建并把UI添加到视口。
3.从Tick事件拉出引脚,依次获取摄像机摇臂的向前向量,向右向量以及摄像机与目标的方向向量。其中方向向量可以用摄像机位置减去目标位置得到。
4.获得了方向向量和摄像机的向前向量,可以套用提及的向量夹角公式,求出目标与摄像机前方的角度。
获得角度后为什么不直接把角度赋值给箭头图标的Angle呢?这是很多人,包括我一开始会犯的一个错误。
其实只要每帧去Print一下夹角,就能看到问题所在:无论是摄像机正对还是背对目标,能观察到夹角的取值范围只有【0,180】。这是因为根据向量的夹角公式,两个向量的夹角的取值范围只落【0,180】这个区间。
而根据上文笔者提到,图标在摄像机在左旋与右旋时,其旋转的取值区间分别是【0,180】以及【-180,0】。所以夹角和Angle的取值区间不一致,两者需要转换。
5.转换的方式也很简单,当摄像机向左旋转时,则用夹角减去180(请无视截图里脑抽的写法);而右旋转时,直接用180减去夹角。
6,最后是判断摄像机是左旋还是右旋。做法也很简单,用相机(摇臂)的向右向量和方向向量点乘,然后判断正负,即可,大于零,摄像机右旋,反之则左旋。
而更深层次的原理呢,则和点乘的性质有关:当摄像机向右旋转时,向右向量与距离的夹角落在【0,90】这个区间,点乘值大于零;向右旋转时,向右向量与距离的夹角落在【90,180】这个区间,点乘值大于零。
为了方便理解,笔者把Tick事件的逻辑拆成3个部分(步骤3~步骤66)文章的结尾放一张Tick事件全图: