被疫情困在家无聊翻翻以前的文章,发现好黑历史啊,虽然是刚学unity的时候写的,后面学习了DX11并且补了3D数学,发现这些问题都是小case了O(∩_∩)O。
在我最近制作的小游戏中,需要实现防御塔面向小兵的功能。(即物体A需要面向物体B)
这很容易让人想到Unity中自带的LookAt()函数,可惜Unity自带的LookAt()函数是3D的,如果把他用在2D游戏上,一样会让物体绕X轴和Y轴旋转,这不是我们想要的效果。
既然不能用LookAt()函数,比较朴素或者说比较常用的算法(至少我是这样想到的)就是,既然我们拥有了物体A和物体B的位置,那我们肯定就能算出它们的X轴差长度和Y轴差长度,之后把他抽象成直角三角形,利用反三角函数得出我们需要绕Z轴旋转的角度(在2D中Z轴我们只能看到一个点)
当时可能是下意识的觉得这方法有一丁点麻烦,也可能觉得为啥unity没有自带LookAt2D()这样的函数,反正就是去搜了一下看下别人或官方有没有更简洁的实现方法。
然后便看到了Unity官方社区中的这个问题 https://answers.unity.com/questions/585035/lookat-2d-equivalent-.html
讨论的质量还是比较高的,其中也有跟我一样思路的人。
其中让我比较在意也是发这篇文章原因的的代码是目前点赞最多(但不是题主指定最佳答案)的回答
transform.right = target.position - transform.position;
其中transform.right是物体自身的红色轴向(X轴)在世界坐标中所指向的位置
第一眼看上去其实还是有一点小小的不理解的,当时就在想,我知道让transform.right(看贴图,一些是需要调整transofrm.up,原贴链接也有说,这里统一写transofrm.right)指向目标位置就能实现朝向效果了,可问题是为什么两个位置差就能调整transform.right呢?难道在给transform.right赋值时它里面也进行了反三角函数运算吗?(其实这样理解也行啊是吧=_=)
然后我查了一下,看到了有人这样写
// Direction vector towards other object (relative to this transform):
var directionTo = (other.transform.position - transform.position).normalized;
// align forward axis to direction:
transform.forward = directionTo;
看到了这个normalized(归一化),才拍脑门想起来这个数学知识点。原来我陷入了思维泥潭,我在做反三角函数时把两个顶点位置相减,是为了得到他们两个的长度差来进行反三角函数运算。但是这里的两个顶点相减是为了获得一个指向对方的向量,再做归一化运算确定方向,原代码为了简洁省去了normalized导致一时没看出来,赋值给transform.right时系统是会做的。
这里给数学基础比较薄弱的人再简介一下向量和向量归一化吧,顺便也当自己的一个小总结。
这里假设有3个顶点A(1,1),B(2,2),C(3,3),顶点B减顶点A获得了一个由A指向B的向量,顶点C减顶点A获得了一个由A指向C的向量。这个时候我们可以观察到向量与向量的方向其实是一致的,那我们怎么判断向量的方向是否一致(或者说获得它的方向)呢?答案是使用向量归一化来判断,也就是转为单位向量。
我们都知道向量的模(长度)是 (平面向量z==0),而向量归一化就是把向量转换为单位向量,也就是模为1.即找到满足,并且x:y:z的值始终不变(比例不变)的这个方程的解。
在unity中transform.right、transform.up、transoform.right等都是单位向量(所以在赋值时也会自动归一化)