天气:阴。
雨一直下,下在外,却滴在我心...
unity中什么时候会运用到数学,无非就是当对游戏物体进行旋转或者是移位的时候。
通常,于很多新手而言,我们对一个游戏物体进行移位的时候是直接使用里边的API即,transform.Translate。但是,这样会有很大的局限性,为什么这么说,往下看你就会知道原因...不着急!. 哈哈哈。
我这里又个假设,假如你手上有这么个需求,要求你对图片进行移位,怎么个移位法呢?就是:当鼠标点击屏幕的时候,图片移动到改点击的位置,就这样完事了?不,在加上一点就是:图片自身的x轴向指向鼠标点击的位置,有点类似(LookAt)的感觉...额,干脆,上张图更加明了
就如上图,image的x轴向(红色)指向了鼠标点击的位置,然后,再移动到鼠标的点击位置(组成三角形的三条边的线段是辅助线,可以不用去管它,下边也会讲到如何去绘制)
那么,问题来了,要实现这样的功能,我们该怎么做.实际上就俩个功能点,一个是旋转,一个是移动。先不说旋转,先说移动,毕竟,在文章一开始的时候就是由移动牵引出来的。那,想想,用Translate能办到 ? 答案是肯定的,怎么做呐?我能想到的就是鼠标点击处的位置坐标可以获取到,那就同时沿着图片的xy轴移动,移动到什么位置停止呢,条件就是:当图片的x坐标和点击处的x坐标相等&&图片的y坐标和点击处的y坐标相等的时候或者说相差无几的时候,必须是同时满足。想想是不是这样... 好开森,赶紧是实践看看.
但是, 真当你去实践的时候,你就会发现:这样还是有问题的,就是当你的鼠标点击处到图片的水平距离和垂直距离不相等的时候,也就是说上图中的黄线长度和白线的长度不相等的时候,此时,就不会到达鼠标点击处了,因为,此时的&&符号左右的条件只会有一个满足.当然,如果大家有什么好的想法,欢迎拍砖,狠狠的拍死我....!!!所以,对于用Translate来移动,个人表示不好控制,这就是我在开头所讲到的局限性.
那我们到底又怎么移动呢?对于新手而言,此时估计皱显额头了... 别急,答案,你很快就知道了,就在下边了.嘻嘻..!!! 就在下边了.
那么,本文的重点也就是在这里了, 大家都知道有向量,那么向量的概念是什么呢,特别是向量如何在unity中表示的呢? 或许,很多读者在想,向量不就是一个三维的或者二维的矢量(Vector3或者Vector2),在我看来,这样的回答只能是答对一半。在我通俗的看来,向量必须有两个点,一个始点一个终点,那既然有了始末那必然就是有方向和大小。
那说到这里,有的读者可能会讲:那如此说来在Unity中的一个Vector3变量就不是一个向量了? 是不是向量,答案是肯定的,此时,严格意义上的表示:应该是该变量减去Vector3.zero所代表的向量,比如(new Vector3(0,10,0) - Vector3.zero),想想是不是,再上一张图,就会更加的明了了
由图02所示,那么,我们如何将游戏物体移动至鼠标点击处呢? 那么这就要涉及到另外一个概念了,即向量的减法,其实,有的读者可能已经想到,向量减法的概念和减去原点不是一样的?没错,是一样的,(b - a) 代表的是 由a的末端指向b的末端的向量,就如图所示.那么具体在unity中的表现是怎么呐?很浅显了,b向量:鼠标点击点的position -(减去)Vector3.zero = 鼠标点击点本身的position;同理a向量就是游戏物体本身的position。而本例中既然是移动一直图片,那么图片就是游戏物体我用image代表,鼠标点击点就用targetPos表示,所以这里的(b - a)就是targetPos - image.transform.position。想一想,是不是这样。!ok,到这里,离成功我们又进了一步,我们暂且用dir来表示这个表达式,意思为方向,后边会用到,读者得用心记住.
ok,我们继续,不知道有没有读者在观察(图02)的时候有没有发觉跟我们中学学的哪个知识点有点相似....誒,我似乎听到有声音说直线。直线,对的,不过不够完整,准确的说应该是直线方程,延长dir两段直到和xy轴各有一个交点,如图03
y = kx + n;直线方程表达式,看到这的读者是否感到很熟悉,很亲切,有没有瞬间怀念起你的中学生涯,是不是美美哒。!!oh,No,我自己都走远了,还是赶紧扯回来的要紧,不然,未完待续四个字就出现在这里了....
我们接着,直线方程虽然是直线方程,但是我前边有说到只是有点相似。为什么我这么讲呢,这么说吧,我们在初中学习的时候:k斜率,n是常量,知道两个点(y2 - y1 / x2- x1)就可以算出k,k也就是一个数值,比如我们可以写成 y = 2x + 3,此时的k,n都是一个数值,这是我们中学时候所学习到的。而k,n可以看成是一维的,而我们现在的计算的是image的position,而position是三维的,当然z一直为0,所以我们对于UI物体可以看成是二维的。 这到底的是什么意思,有什么关系呐?通俗的说:我们此时按道理是要求出斜率k = (image.transform.position.y - targetPos.y) / (image.transform.position.x - targetPos.x),然后,再乘上一个变量x,再加上一个常量n,用表达式表示就是:image.transform.position = k * timer + n;而n就是当timer为0的时候即:image.transform.position。所以,image.transform.position = k * timer + image.transform.position;(timer是个变量用来充当x。我们且称该表达式为:表达式1)。而此时你会发觉position是三维的,k*timer是一个float类型的,所以,这么写就会报语法错误。想想是不是,慢慢想,不着急,我们什么都缺,但就是不缺时间...!!!嘻嘻xi..
那怎么办呢?我估计着有的读者可能已经想到说都是k惹的祸。没错,就是斜率惹的祸,额,不对,确切的说应该是我们计算斜率的方法惹的祸,如果,此时的k是三维的该有多好呀,是不是!!。所以,这也就是我上边为什么用"相似"这个词.,k和n在这里这里应该是一个三维的量,而不是一维的量。读者看到这里,有没有豁然开朗,柳暗花明的赶脚!!哇咔咔....
虽然,或许有些柳暗花明,但是我们又该怎么做呐?怎么求k呢?别急,答案就快揭晓了,读者也可以自行想想。
ok,在这之前,还得明白一个概念,就是直线上的向量,那么什么是直线上的向量呢?它指的是向量的起点与终点都在直线上.这里,我们将游戏物体和鼠标点击处分别当做p1和p2两个点,则我们可以知道图04中可以表示的信息
根据向量的坐标运算,一目了然可以看到直线上的向量和斜率k的关系(当然,什么是直线上的向量?什么是平行向量?什么是直线的方向向量?不知道的读者可以百度一下,就会明白了),而我们知道:直线的方向向量和法向量体现了直线的方向,同时也刻画出了直线与横轴X轴的倾斜程度(即斜率),这是教材上给的定义。所以,我们就可以将p1p2当做直线的斜率,所以,我们此时的斜率k1应该这样来计算:k1 = new Vector3(targetPos.x - image.transform.position.x) * (1,k),即 k1 = new Vector3(1, (targetPos.y - image.transform.position.y) / (targetPos.x - image.transform.position.x), 0) * (targetPos.x - image.transform.position.x)。所以,我们可以重写表达式1为:image.transform.position = k1 * timer + image.transform.position;
当然,我们也没有必要像表达式1这样写的那么,唔唔...,那么啰嗦...
为什么说它这么啰嗦呢?聪明的读者可能已经想到:如果我们不想使用斜率,既然我们可以将直线的方向向量当做直线的斜率,那么我们为什么不用直线的方向向量来计算呢?perfect...没错,就是这样,图04中不是给出来一个表达式,然后化简为3个式子,而我们k1用的是第3个式子,那我们用第一个式子不就看起来舒服多了,所以,我们此时的斜率k1也可以这么来写:k1 = new Vector3(targetPos.x - image.transform.position.x, targetPos.y - image.transform.position.y,0)。那,这样写了,是否有些许的眼熟,跟我们上边的什么很像?
还记得我们的dir表达式?上边我还叫读者用心记住,现在是它的表现时间了....
我们的dir = targetPos - image.transform.position;跟我们的k1是不是一模一样,就像一个妈生下来的一样(本质上都有一个妈,实际上外观给人看着不一样),那,有的读者可能会说k1的z为0,纠结这个问题的读者,估计你没有好好的看这篇文章,为什么这么说呢?因为,你k1的z是可以写成targetPos.z - image.transform.position.z;而对于UI物体z都是为0的,所以为了方便写就直接写成0了。
所以,我们就可以将方向dir当成直线的斜率。而我们称dir为方向,其实严格意义上应该称为方向向量。所以,我们的表达式1也可以写成:image.transform.position = dir * timer + image.transform.position;而其中的timer是一个自变量,那,自增的方式会有很多,我这里给出两种:第一种:可以让timer每秒自增1或者是自增多少;第二种:简单粗暴,直接用上下帧的时间间隔量来从当timer。估计,对于很多初始这个的朋友,看的是云里雾里的。没关系,我下边会给出代码,看了代码你一定会明白,噢,原来是这个玩意。
代码区:
var dir = targetPos - image.transform.position;
image.transform.position = (dir) * Time.deltaTime * speed * 10f + image.transform.position;
其中dir也可用k1来充当,感兴趣的读者可以自行带入试试看.这里的timer = Time.deltaTime * speed * 10f; 也就是我所说的timer的第二种自增方式,其中speed是一个float类型的量,调节speed就可以来调节实际的速度
当然,第一种自增方式可以这么来写:
var dir = targetPos - image.transform.position;
_timer += Time.deltaTime;
image.transform.position = (dir) *_timer * speed * 10f + image.transform.position;
ok,到这里,就圆满完成一个游戏物体的移动,也就是这是移动的核心。当然,也有其他的方式移动,比如使用插值来移动。有兴趣的读者可以去尝试一下,这里不过多的阐述。下边贴出源码:
相信都能看得懂,还是比较简单的,就不过的阐述了。当然,开篇还讲到旋转和画线,原本是打算一起讲完的,但是,现在看来还是分篇讲比较好,这篇文章已经字数太多了...所以,所以,欢迎交流,欢迎拍砖,喜欢被你们这么狠狠的拍死!!!咱们下期见.....哇哈哈
本文链接:http://www.jianshu.com/p/b8308eebff48
转载请注明出处...谢谢!!!