
Unity小知识 大智慧 博客主页https://xiaoy.blog.csdn.net 本文由呆呆敲代码的小Y原创首发于CSDN 学习专栏推荐Unity系统学习专栏 游戏制作专栏推荐游戏制作Unity实战100例专栏推荐Unity 实战100例 教程 欢迎点赞 收藏 ⭐留言 如有错误敬请指正 未来很长值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------Unity实用技巧学习Unity移动物体的8个不同方法前言向某个方向移动Transform.PositionTransform.Translate()移动到指定位置Vector3.MoveTowards()固定速度Vector3.SmoothDamp()平滑移动Vector3.Lerp()线性时间移动物理引擎移动Rigidbody.AddForce()Rigidbody.VelocityRigidbody.MovePosition()原文完结前言在游戏开发中如何移动物体是我们需要思考的事情。Unity 引擎也提供了众多的方法每个开发者的使用习惯也各不相同所以往往不是很清楚在这种场景下哪种方式最好的或者最有效的。那么这篇文章我想分享一下移动物体的一些方法和优缺点。向某个方向移动Transform.Position众所周知我们可以给对象的Transform组件赋予一个坐标来决定其位置。transform.positionnew Vector3(2,1,0);当我们每一帧给对象赋予一个新的坐标那么看起来这个物体就是在运动的。voidUpdate(){vardirnew Vector3(0.02f,0,0);transform.positiondir;}效果如下Transform.Translate()由于直接改变 Position 属性看起来不太优雅。所以 Transform 组件提供了一个更友好的方法Transform.Translate()。voidUpdate(){vardirnew Vector3(0.02f,0,0);transform.Translate(dir);}其实他的内部与Transform.Position无异。public void Translate(Vector3 translation,[DefaultValue(Space.Self)]Space relativeTo){if(relativeToSpace.World)this.positiontranslation;elsethis.positionthis.TransformDirection(translation);}效果与 Transform.Position 一致但是这种方法产生了一个问题。由于设备之间的差异或者动态数据的变化会导致每一帧之间的间隔是不相等的因此如果以帧数来控制物体移动物体的移动距离就没办法准确把握。效果如下所以我们需要在原来的基础上乘以 Time.deltaTime属性的值从而保证每秒移动的距离是一致的。voidUpdate(){vardirnew Vector3(2f,0,0)*time;transform.Translate(dir);}这样不同的帧数移动距离都会一致。效果如下但这还不够优雅。在游戏中我们经常需要改变物体的速度。为了方便实现我们通常会使用单位向量来确定方向增加一个浮点值来控制速度。public float speed2;voidUpdate(){vardirnew Vector3(2,0,0)transform.Translate(dir.normalized * speed * Time.deltaTime);}移动到指定位置移动到指定位置大概有两种方式。速度物体通过特定速度向目标移动。时间物体在时间内到达目标。Vector3.MoveTowards()固定速度以固定的速度移动到目标位置public Vector3 targetPosition;public floatspeed10;voidUpdate(){transform.positionVector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);}效果Vector3.SmoothDamp()平滑移动又或者我们可以用平滑的方式到达目标位置。平滑到达位置前提前减速publicVector3targetPosition;publicfloatsmoothTime0.5f;publicfloatspeed10;Vector3velocity;voidUpdate(){transform.positionVector3.SmoothDamp(transform.position,targetPosition,refvelocity,smoothTime,speed);}效果Vector3.Lerp()线性时间移动该方法的意思是在调用方法期间已经过的时间除以总持续时间得到当前的位移目标。// 终点publicVector3targetPosition;// 开始位置publicVector3startPosition;// 持续时间publicfloatlerpDuration4;// 记录运行时间privatefloat_timeElapsed0;voidStart(){startPositiontransform.position;}voidUpdate(){// 记录下一个位置Vector3valueToLerp;_timeElapsedTime.deltaTime;if(_timeElapsedlerpDuration){valueToLerpVector3.Lerp(startPosition,targetPosition,_timeElapsed/lerpDuration);}else{valueToLerptargetPosition;}transform.positionvalueToLerp;}效果如下以上的这些方法足以让我们准确且随心的操纵物体移动。但有一些场景我们并不希望如此精确或始终如一的运动轨迹我们想物体的移动受 Unity 的物理引擎影响或者其他物体影响。同时如果用以上方法移动在 Unity 的物理引擎下会出现抖动穿过刚体等奇怪的现象。那么接下来我们就需要用到一些涉及到物理引擎的移动方式。物理引擎移动Rigidbody.AddForce()使用这个方法给物体添加一个方向力。在力的作用下物体将会移动。那么移动速度和位移就会与物理特效有关比如物体质量阻力甚至还有重力。一般会有两种使用方式。在初始时给物体一个力让其顺着物理规律下运动。使用场景一般时跳跃或者碰撞。// 赋予200的力publicfloatforce200;privateRigidbody2D_rigidbody2D;// 移动方向privateVector3dirVector3.right;voidStart(){_rigidbody2DGetComponentRigidbody2D();_rigidbody2D.AddForce(Vector2.right*force);}为了更好演示刚体的运动我还给刚体的线性阻力改为1这样没有持续施加外力的情况下物体会因为摩擦力的存在而停下。效果如下可以看到物体很快就停下了第二种会在每一帧持续给物体施加力使物体可以持续运动。// 赋予2的力publicfloatforce2;privateRigidbody2D_rigidbody2D;// 移动方向privateVector3dirVector3.right;voidStart(){_rigidbody2DGetComponentRigidbody2D();}voidFixedUpdate(){_rigidbody2D.AddForce(Vector2.right*force);}效果如下从效果可以看到在持续给外力的作用下物体移送越来越快但在阻挡物前会停下。Rigidbody.Velocity直接赋予 Velocity 属性一个向量可以立即改变物体的速度。一般情况下我们不需要直接修改速度除非你非常明确需要立即改变物体的速度。publicfloatspeed10;privateRigidbody2D_rigidbody2D;// 移动方向privateVector3dirVector3.right;voidStart(){_rigidbody2DGetComponentRigidbody2D();}voidFixedUpdate(){_rigidbody2D.velocitydir*speed;}效果如下看到物体一开始就已经有速度而通过AddForce方法添加力的物体速度时慢慢提高的。Rigidbody.MovePosition()该方法有比较局限的使用场景当物体的刚体类型是 Kinematic 时使用Rigidbody.MovePosition() 方法进行移动。因为 Kinematic 类型下不会受到重力和AddForce、AddTorque等力相关的函数的影响publicfloatspeed10;privateRigidbody2D_rigidbody2D;// 移动方向privateVector3dirVector3.right;voidStart(){_rigidbody2DGetComponentRigidbody2D();}privatevoidFixedUpdate(){varpositondir*(speed*Time.deltaTime);_rigidbody2D.MovePosition(transform.positionpositon);}效果如下刚体类型是 Kinematic 时 会对刚体类型为 Dynamic 施加力而无视 static 类型。原文链接https://blog.csdn.net/GG_and_DD/article/details/126917358资料白嫖技术互助学习路线指引点击解锁知识定位人群定位 Unity系统学习专栏入门级本专栏从Unity入门开始学习快速达到Unity的入门水平 Unity实战类项目进阶级计划制作Unity的 100个实战案例助你进入Unity世界争取做最全的Unity原创博客大全。❤️ 游戏制作专栏难度偏高分享学习一些Unity成品的游戏Demo和其他语言的小游戏 游戏爱好者万人社区互助/吹水数万人游戏爱好者社区聊天互助白嫖奖品 Unity100个实用技能Unity查漏补缺针对一些Unity中经常用到的一些小知识和技能进行学习介绍核心目的就是让我们能够快速学习Unity的知识以达到查漏补缺