![05f67323700895fa525f6766c09d60da.png](https://img-blog.csdnimg.cn/img_convert/05f67323700895fa525f6766c09d60da.png)
年末小(诈)更(尸)一波,嘛虽然我写的文章也没什么人看啦...
你们点个赞就那么难吗?还有dalao们,萌新希望能跟你们友好交流,不要高位喷我嘛...人家会不开心的(哼哒~)
今天来总结一下之前在做塔防游戏架构的时候,偶然间出现的血条朝向问题,并用到了一个不常用的方法Vector3.ProjectOnPlane
1.先来介绍一下Vector3.ProjectOnPlane方法吧
方法原型:Vector3.ProjectOnPlane(Vector3 投影向量,Vector3 投影平面法向量);
返回:Vector3 平面上的投影向量
Vector3.ProjectOnPlane是Vector3提供的一个静态方法,用于计算某个向量在某个平面上的投影向量
2.我们遇到的问题
---2.1一个特殊的摄像机
在塔防游戏中我们设计了一个特殊的观察摄像机,它将根据自己的任意初始位置,并接收Horizontal与Vertical轴线+键盘QE的输入控制进行视角的变换,没错这个摄像机就和unity中Scence窗口里场景漫游时的摄像机控制一样,不过只是键盘操作一样啦,不能使用鼠标去转动摄像机视角(鼠标的输入需要用来完成设置防御塔的操作)
---2.2血条的出现
![31a3f2fead5c28eb9a5f61f895860ff8.png](https://img-blog.csdnimg.cn/img_convert/31a3f2fead5c28eb9a5f61f895860ff8.png)
塔防游戏里血条的设定原因就不多赘述了。总之我们现在有了一个血条,用Sprite Render组件来完成渲染。设定要求血条应朝向摄像机,且在横向上平行于游戏画面的横轴显示
但由于摄像机初始位置的不固定(根据场景模型和路线设计的不同摄像机的初始视角可能被放在狗策划指定的任意位置),怪物生成位置的不固定,以及摄像机自身和怪物的位置变换等等因素
我们不能使用一个确定的欧拉角旋转参数,而是需要动态的修改血条的朝向位置
这里首先我们就想到了一个常用的方法Tansform.LookAt 在Update里不断更新它的朝向位置,让其看向摄像机的位置
---2.3事情好像没有那么简单
![38d4e2add1b3bbd15b1bdbcc19842f78.png](https://img-blog.csdnimg.cn/img_convert/38d4e2add1b3bbd15b1bdbcc19842f78.png)
gameObject
结果如上图,它好像没看对位置,而且还根据怪物的移动,血条转起来了...
但我们使用Tansform.LookAt的想法是没错的,“设定要求血条应朝向摄像机,且在横向上平行于游戏画面的横轴显示”,现在血条起码正确的朝向了摄像机,只不过横向上不平行于游戏画面横轴
也就是说现在的问题是Tansform.LookAt看向的位置我们没有找对,不过正确的位置应该跟现在的传参位置Camera.main.transform有点关系
那么问题来了,血条应该看向哪里?
3.分析问题
---3.1来自突破口的一个提示
![6fe54e0597762a2dbde2e768ca99899e.png](https://img-blog.csdnimg.cn/img_convert/6fe54e0597762a2dbde2e768ca99899e.png)
我们再结合画面仔细观察一下,我们发现虽然现在血条转起来了,但某一个时刻血条还是能转动到与游戏画面横轴平行的位置,经过测试发现此时该血条正好处于屏幕的中间位置
血条在屏幕中间->正确的LookAt位置才正好是摄像机的位置
---3.2视角聚合的端倪
Debug
我们加了上面的一段代码用于绘制出血条朝向Camera位置时的连线
![c38a8f6396269dd855616481271a01d3.png](https://img-blog.csdnimg.cn/img_convert/c38a8f6396269dd855616481271a01d3.png)
我们似乎看出一点端倪了,那些在视野边缘位置的血条,它们看向摄像机时,由于广角视野的特点,血条需要看向的摄像机在视野的中心位置。这个视角的从边缘到中心的聚合产生了一个旋转使得横向上血条无法平行于游戏画面的横轴位置
---3.3对朝向的正确理解
由于血条是一个2D的平面物体,为保证能够正确的渲染在视野中,血条需要看向摄像机的位置来保持一个正确的朝向
我们再结合一下缘由去理解一下这个朝向,这个朝向就是血条的2D平面需要平行于摄像机的视野平面
---3.4我们真正想要LookAt的位置
总结我们的分析,
为保证正确的朝向,那么血条应该需要看向摄像机的视野平面上的一个点
但这个点并不是摄像机自身的位置,摄像机自身的位置的确也在摄像机的视野平面上,但由于视角聚合的影响会导致视野边缘的物体产生错误的旋转
不过我们有来自突破口的一个提示:血条在屏幕中间->正确的LookAt位置才正好是摄像机的位置
到这里,答案就已经呼之欲出了,
血条应看向的点是其位置在摄像机视野平面上的投影点的位置
4.计算这个位置
自然这时候我们应该去翻一翻Vector3的脚本API看看有没有什么可用的方法了
这里复习过3遍脚本开发基础课程的我(哼哒人家就是这么厉害),自然就想到了Vector3.ProjectOnPlane,
没有将一个点直接投影到一个平面上的计算方法啦,传参法向量代表平面,有点3维欧氏空间的几何知识的话应该知道那样子是说不清的吧
(哼哒人家就是懒得自己讲,就交给dalao们啦,其实我也将不清楚,欢迎dalao在下面留言赐教,鄙人先谢为敬)
你可以翻上去在看看一开始对Vector3.ProjectOnPlane的介绍,这里不在过多赘述
那么我们先创建一个需要投影的向量:
gameObject.transform.position - Camera.main.transform.position;/*(从摄像机位置指向血条位置)*/
摄像机视野平面法向量:
Camera.main.transform.forward;
完成投影:
Vector3 lookPoint = Vector3.ProjectOnPlane(gameObject.transform.position - Camera.main.transform.position, Camera.main.transform.forward);
那么返回结果应是摄像机视野平面上,摄像机位置 指向 血条位置在摄像机视野平面上的投影点的位置(我们想要的结果位置) 的一个向量
那么我们想要的结果位置就应该是:
lookPoint+Camera.main.transform.position
让血条物体动态的看向结果位置
gameObject.transform.LookAt(lookPoint+Camera.main.transform.position);
5.OK问题解决
![4ad0033393e8a76a391cbb2c686034ed.png](https://img-blog.csdnimg.cn/img_convert/4ad0033393e8a76a391cbb2c686034ed.png)
![1490f6f88051b8e394815a522c4f2fe5.png](https://img-blog.csdnimg.cn/img_convert/1490f6f88051b8e394815a522c4f2fe5.png)
![cbfa0bb952b4d6427304240aa5710360.png](https://img-blog.csdnimg.cn/img_convert/cbfa0bb952b4d6427304240aa5710360.png)
![aef7d7d2fbbde47ef736767379257a49.png](https://img-blog.csdnimg.cn/img_convert/aef7d7d2fbbde47ef736767379257a49.png)
无论摄像机初始视角,还是摄像机和怪物的位置变换,血条都看向了正确的位置,完成渲染
6.文末
这个塔防架构的展示视频链接(让人家骗下播放量嘛):
https://www.bilibili.com/video/av41559074/www.bilibili.com如果还有什么想知道的 关于这个塔防架构或者是其他的架构模块的实现,欢迎点赞+留言
欢迎dalao们留言指正,希望能端正态度好好交流,若能不吝赐教,鄙人先谢为敬
还是初六,各位新年快乐,
明天要上班的前辈们工作加油哦(虽然我这个大一狗还能再宅10天,手动滑稽)