开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

首页   >   博客   >   iaming

unity物体移动的几种常用方式 热度 12

个人分类: Unity | 2017-3-18 12:43
标签:unity基础
1 个评论 | 阅读 5372 | 收藏 | 举报
    说到物体的移动无非就是从一个点移动到另一个点的过程。在unity中实现物体移动有很多种方式,下面就来总结一下:

1.非刚体情况
          假设有物体对象obj,目标位置tarPos,帧率50,1帧时间为1/50 = 0.02;
      1)直接移动到目标位置:
           直接执行obj.transform.position = tarPos;可以看到物体瞬间移动到目标位置。假如该代码放在Update函数中(Update函数每帧执行一次),可以理解为1帧的时间让物体移动到了目标位置。
      2)位置增量移动:
           obj.transform.position = obj.transform.position+移动向量*Time.deltaTime;
           obj.transform.Translate(移动向量*Time.deltaTime);
           从1)中我们可以推导出obj.transform.position = obj.transform.position+(tarPos - obj.transform.position),也就是说1帧的时间物体位移了tarPos - obj.transform.position,那么           如果希望物体移动到目标位置有个平滑的过度,就可以从每帧的位移上做文章了。假如希望对象用1秒移动到目标位置tarPos也就是说1秒位移了tarPos - obj.transform.position,而1秒执行50*1 = 50帧(开头假设帧率50),那么每一帧移动距离就为(tarPos - obj.transform.position)/(50*1) = (tarPos - obj.transform.position)*(0.02*1) ,那么每一帧的变化就为obj.transform.position = obj.transform.position+(tarPos - obj.transform.position)*0.02;Time.deltaTime的意义就是这一帧距离上一帧花费的时间,即一帧花费的时间,这个时间会随着机器性能不同而不同。所以obj.transform.position = obj.transform.position+(tarPos - obj.transform.position)*Time.deltaTime*(1/花费的时间);
        obj.transform.Translate(移动向量*Time.deltaTime);原理和上面的描述差不多。 

       3)利用公式进行平滑移动:
            Vector3.Lerp(a,b,t)
            a:起点,b:终点,t:比率(若t<0 则t=0,若t>1 则t=1,0<=t<=1)
            函数相当于 返回结果相当于t*b+(1-t)*a
            假如起点是a是(0,0,0),终点是b是(100,0,0),t =0.1,那么结果就应该为0.1*(100,0,0)+(1-0.1)*(0,0,0) = (10,0,0),相当于根据起点终点和比               进行插值的到一个介于起点终点的值。
            上面把函数介绍完了,下面就该介绍位移了:物体在Update是怎么通过该函数位移的呢?
             又可以分成两种情况:1通过不断改变起点位置进行位移2通过不断改变t比率进行位移。
             第一种情况:在Update中obj.transform.position  = Vertor3.Lerp(obj.transform.position ,tarPos,Time.deltaTime);
             这种情况下主要关注两点,
              1.首先函数返回值有赋给了物体来当起点,也就是说刚开始物体起点位置是(0,0,0),经过一帧后物体位置就变为(10,0,0),那么下一帧执行该函数时就变为0.1*(100,0,0)+(1-0.1)*(10,0,0) = (10+9,0,0)=(19,0,0),第二针相比第一针位移了19-10 = 9的距离。一直推导下去,不难发现每经过一帧物体向目标移动的具体比上一帧有所减少,所以物体向终点移动时前快后。为什么?因为起点到终点的具体每一帧都变化,每一帧起点都更趋近于终点,那么起点到终点的具体由100到90到81... ...而比率不变都是Time.deltaTime(其实每次都不同,但是误差不大,这里假设每次都相同)。更直观的理解就是100的10%和90的10%,10的10%的变化。
              2.a和b不变,让t不断增加
              在Start函数中用一个全局变量curPos = obj.transform.position 开保存物体的其实位置,一个全局浮点变量t记录比率 t=0;
              在Update函数中obj.transform.position = Vector3.Lerp(curPos,tarPos,t);t+=Time.deltaTime;
              在Update中t每经过一帧都增加Time.deltaTime比率,当t>=1时,通过公式就可以得到obj.transform.position = 1*(100,0,0)+(1-1)*(0,0,0);
       注意比较这两种方式的不同,虽然都是利用同一个函数,但是使用不同的效果也不一样。
       
             Vector3.MoveTowards (a,b,t)
       在这里的MoveTowards与Lerp又不一样,该函数是每执行一次则让a增加t,即返回a+t,如果a+t>b,则返回b,但该函数又可以同Lerp一样分两种情况:1通过不断改变起点位置进行位移2通过不断改变t比率进行位移。
             假如还是以起点(0,0,0)终点(100,0,0) 举例,那么通过该函数的意义可以知道每执行一帧 起点增加t = Time.deltaTime,所以在Update中obj.transform.position = Vector3.MoveTowards(obj.transform.position,tarPos,Time.deltaTime);每帧位移举例为Time.deltaTim。也可以通过t+=Time.deltaTime进行变化,跟Lerp相似,这里就不说明了。
        
             Vector3.SmoothDamp(a,b,ref v,t)
       a:起点,b:终点,v:当前速度,每次调用该函数都会更新,t:a到b花费的时间。
            该函数执行结果是中间递增快,两边慢的类似蛇形的变化。大部分用于摄像机跟随。
2.刚体:
            刚体运动一般放在FixedUpdate中
            1)velocity 速度向量,如给定GetComponent<Rigidbody>().velocity = transform.forward*5;(transform.forward:对象局部坐标系z轴正方向 (0,0,1)),刚体就会朝着该方向以5单位每秒的距离移动
            2)MovePosition(Vector3 tarPos
        GetComponent<Rigidbody>().MovePosition(obj.transform.position+移动向量*Time.deltaTime);  该函数参数表示要移动到的位置
 
              
             
10 1

作者的其他最新博客

评论 (1 个评论)

回复 yifei5917 2017-3-20 09:53
很细腻的教程. 感谢分享.

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册帐号
返回顶部