前言

最近在学习如何制作 FPS 游戏,学习了如何使用角色控制器来控制角色的移动跳跃等等,结合之前学到的使用 transform,刚体等使物体移动,不同的移动方式适用于不同的场景,今天就来简要盘点一下各种移动方式以及其优劣之处,若有不对之处,请多多指教。

目录

  • 前言
  • 一、使用 Transform 组件
    • 1. Transform.position
    • 2. Transform.Translate
  • 二、使用 Vector3 的插值方法
    • 1. Vector3.Lerp
    • 2. Vector3.Slerp
    • 3. Vector3.MoveTowards
    • 4. Vector3.SmoothDamp
  • 三、使用刚体(Rigidbody)组件
    • 1. AddForce
    • 2. MovePosition
    • 3. Velocity
  • 四、使用角色控制器(Character Controller)组件
    • 1. SimpleMove
    • 2. Move
  • 五、总结与参考资料
    • 1.总结
    • 2.参考资料

前排提醒:本文仅代表个人观点,以供交流学习,若有不同意见请评论留言,笔者一定好好学习,天天向上。

视频讲解:
详解Unity的几种移动方式实现_BiLiBiLi


一、使用 Transform 组件

Unity 场景中的每个游戏对象都拥有一个 Transform 组件,用于存储该对象的位置、旋转、缩放等基础属性,此种方式的原理就是通过 Update 函数每帧更新其位置来达到移动目的。

1. Transform.position

最最基础的移动方式,每帧+=计算好的新位置,更加直观

    public float speed = 3.0f;void Update(){transform.position += new Vector3(0, 0, speed * Time.deltaTime);}

2. Transform.Translate

每秒向某方向移动多少距离,此种方法和上一种没有太大区别,但当需要坐标转换时,使用此方法可省略转换步骤。
translate(V3 向量,坐标系(留空默认为 Space.Self));

    public float speed = 3.0f;void Update(){transform.Translate(Vector3.forward * Time.deltaTime * speed);}

二、使用 Vector3 的插值方法

Vector3 类型可以存储物体的位置、方向。上述的 transform 组件的基本信息就是由 Vector3 类型存储的,所以可以 V3 自带的类方法通过对位置的一些运算得到相对平滑的参数,其移动本质还是修改物体的 position。需视情况和需求来选择 V3 的 4 种插值方法。Mathf 类中也有这些方法,不过参数是 float,使用方法大致相同,读者若感兴趣,自行学习吧。

1. Vector3.Lerp

两个向量之间的线性差值,适用于从某点移动到某点(或跟随某物体),缓动效果
这里线性移动是由时间参数控制的,若写成 Speed*Time.deltaTime 则理论上永远也抵达不了,但这里就不讨论如何用 Lerp 实现匀速了,以后再写。
Lerp(当前位置(V3),目标位置(V3),时间(float)) 时间越小,缓动效果越慢

    public Transform target; //被跟随的物体public float speed = 3.0f;void Update(){Vector3 lerp =  Vector3.Lerp(transform.position, target.position, Time.deltaTime * speed);transform.position = lerp;}

2. Vector3.Slerp

两个向量之间的球形(弧线)差值,适用于从某点移动到某点(或跟随某物体),缓动效果,当前位置与目标位置距离越远,效果越明显
Slerp(当前位置(V3),目标位置(V3),时间(float)) 时间越小,缓动效果越慢

    public Transform target; //被跟随的物体public float speed = 3.0f;void Update(){Vector3 slerp =  Vector3.Slerp(transform.position, target.position, Time.deltaTime * speed);transform.position = slerp;}

3. Vector3.MoveTowards

和 Lerp 函数基本相同,但此函数多了一个最大速度限制,且是匀速朝目标运动,而 Lerp 和 Slerp 则是将抵达位置时放缓(减速)
MoveTowards(当前位置(V3),目标位置(V3),最大速度(float))
速度参数:取正向目标靠近,取负则远离目标

    public Transform target; //被跟随的物体public float speed = 1.0f;void Update(){Vector3 movetowards =  Vector3.MoveTowards(transform.position, target.position, Time.deltaTime * speed);transform.position = movetowards;}

4. Vector3.SmoothDamp

官方翻译为:“平滑阻尼”,无比丝滑的从 A 移动到 B 点,速度可控,比较适用于摄像机跟随,Lerp 也比较适用于摄像机跟随,这俩的区别在于
SmoothDamp(当前位置(V3),目标位置(V3),当前速度(ref:V3),所需时间(float),最大速度(float,可选),Time.deltaTime(默认)(可选))
当前速度:一开始赋值为 0,每次调用该方法自动修改此参数,注意设为全局变量,且为 ref
所需时间:该值越小,越快抵达目标

    public Transform target; //被跟随的物体public Vector3 currentVelocity = Vector3.zero; //当前速度public float smoothTime = 0.3f; //所需时间void Update(){Vector3 smoothdamp = Vector3.SmoothDamp(transform.position, target.position, ref currentVelocity, smoothTime);transform.position = smoothdamp;}

三、使用刚体(Rigidbody)组件

Rigidbody 组件通过物理模拟来控制一个物体的位置,当使用此组件控制物体移动时,应在 FixedUpdate 函数中更新数据,该方法会在每一次执行物理模拟前被调用,这样要比 Update 函数更加精确,具体原因以后再说或可自行搜索。

1. AddForce

添加一个方向的力到刚体,刚体将开始移动,这种方式适合模拟外力作用下的刚体运动,如子弹。但注意,此力是累加的,不适合重复施加力来模拟物体!
AddForce(有方向的力(V3),力的模式(ForceMode,默认:ForceMode.Force))

ForceMode(力的模式):
Force(可持续的力,受质量影响)
Acceleration(可持续的加速度,不受质量影响)
Impulse(一个瞬间冲击力,受质量影响)
VelocityChange(一个瞬间速度变化,不受质量影响)
笔者对于这些东西的区别有点懵,还是大家自己悟吧,例图演示的是第一种力,20 的向 Z 的力

    public float forceNumber = 20f;public Rigidbody rig; //获取当前物体的刚体组件void FixedUpdate(){Vector3 force = new Vector3(0, 0, forceNumber);rig.AddForce(force, ForceMode.Force);}

2. MovePosition

移动刚体到一个新的位置,移动的同时受到物理模拟的影响
MovePosition(新的位置(V3))

    public Vector3 speed = new Vector3(0, 0, 1);public Rigidbody rig; //获取当前物体的刚体组件void FixedUpdate(){rig.MovePosition(transform.position + speed * Time.deltaTime);}

3. Velocity

瞬间给一个物体恒定的速度,将该物体提升到这个速度,保持。相比较 AddForce 更加适合跳跃功能。每次跳跃都是恒定高度,做跳跃的话,图二记得每次跳跃完置零就行。

    public Vector3 high = new Vector3(0, 0, 10);public Rigidbody rig; //获取当前物体的刚体组件private void FixedUpdate() {rig.velocity += high * Time.deltaTime;}

    public Vector3 high = new Vector3(0, 10, 0);public Rigidbody rig; //获取当前物体的刚体组件private void Update() {if(Input.GetKeyDown(KeyCode.J)){rig.velocity = high;}}

四、使用角色控制器(Character Controller)组件

角色控制器顾名思义,是 Unity 推出的特别用于角色移动的组件,使用角色控制器的物体有刚体的效果,但不会翻滚(意思是运动仅受限于碰撞体,不受其他因素影响),很适合角色移动。还可以设置斜坡参数,一定坡度自动抬升,本身也是个碰撞体,具体的细节本篇就不多赘述。

1. SimpleMove

以一定速度移动角色,以秒为单位,无需乘以时间,具备重力
SimpleMove(有方向的力(V3))

    public float speed = 5;public CharacterController cc; //获取当前物体的刚体组件void Update() {cc.SimpleMove(transform.forward * speed);}

2. Move

以一定速度移动角色,不具备重力,需要自行计算下落
Move(有方向的力(V3))

    public float speed = 5;public CharacterController cc; //获取当前物体的刚体组件void Update() {cc.Move(transform.forward * speed * Time.deltaTime);}

五、总结与参考资料

1.总结

简单区分以上几种方式,可分为物理移动和非物理移动,读者应自行区分何种物体应该使用何种方式。

  • 如关卡中的移动障碍应用非物理移动,因为不需要相关障碍进行物理运算。
  • 如摄像机跟随人物移动,简单方式可直接作为角色的子物体或直接算出偏移量,直接加给摄像机的 position,但太生硬,所以考虑加入 Lerp 或 SmoothDamp,让摄像机跟随更加平滑。
  • 比如角色移动,若使用非物理方式,则无法与环境交互,若使用刚体组件,则可能发生碰撞倾倒,会产生很多方向的力,处理比较复杂,所以考虑使用角色控制器,仅在发生碰撞时限制物体运动,不会导致很多奇怪的情况发生。
  • 对于 V3 插值函数的应用,可对某些运动转换更加流畅的处理,具体用法读者自行拓展。

本篇中我还有好多没有理清楚的地方,日后理清楚了会再修改,若读者对其中的一些片段有些不同的看法,请留言讨论。

2.参考资料

1.https://blog.csdn.net/jiumengdz/article/details/78537758
2.https://www.cnblogs.com/claireyuancy/p/7266586.html
3.https://www.sohu.com/a/211459755_667928
4.https://www.cnblogs.com/CasualAttachment/p/7308993.html
5.https://blog.csdn.net/six_sex/article/details/51114083
6.https://blog.csdn.net/renkai0406/article/details/63800248
7.https://blog.csdn.net/weixin_44370124/article/details/90080871

详解Unity的几种移动方式实现相关推荐

  1. 详解二叉树的三种遍历方式(递归、迭代、Morris算法)

    详解二叉树的三种遍历方式(递归.迭代.Morris算法) 最重要的事情写在前面:遍历顺序不一定就是操作顺序!!! 递归解法 首先,一颗二叉树它的递归序列是一定的,导致其前中后序不同的原因只不过是访问节 ...

  2. RDMA技术详解——原理和三种实现方式

    RDMA作为一种host-offload, host-bypass技术,使低延迟.高带宽的直接的内存到内存的数据通信成为了可能.目前支持RDMA的网络协议有: 1.InfiniBand(IB): 从一 ...

  3. 详解Unity的移动控制实现

    前言 上一篇写了数种Unity中的移动方式,有物理移动,有非物理移动等,这篇我们来谈谈Unity中的移动控制方式,来结合上一篇所说的方法,用起来.一般控制是通过获取用户输入来处理角色移动逻辑的,而用户 ...

  4. 详解Unity中的粒子系统Particle System (七)

    前言 本篇来讲一讲Collision和Triggers模块,这两个模块主要用于粒子系统与物理世界的交互,一个是碰撞器,另一个是触发器.有了这两个模块我们又可以做出更炫酷的粒子效果啦! 目录 前言 本系 ...

  5. 详解Unity中的粒子系统Particle System (十二 | 终)

    前言 终于来到了最后一篇,粒子系统宣告终结!这十来篇博客删删改改写了半个多月,真是离谱.今天该讲案例与粒子系统的应用,那么我们就进入正题吧! 目录 前言 本系列提要 一.如何做出效果 二.案例演示 1 ...

  6. Spring事务管理详解_基本原理_事务管理方式

    Spring事务管理详解_基本原理_事务管理方式 1. 事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,使用JDBC的事务管理机制,就是利用java.sql.Connection对象 ...

  7. 详解Unity中的粒子系统Particle System (二)

    前言 上一篇我们简要讲述了粒子系统是什么,如何添加,以及基本模块的介绍,以及对于曲线和颜色编辑器的讲解.从本篇开始,我们将按照模块结构讲解下去,本篇主要讲粒子系统的主模块,该模块主要是控制粒子的初始状 ...

  8. 详解Unity中的粒子系统Particle System (四)

    前言 上一篇我们主要讲解了Shape形状模块,以及Emission发射模块,这是粒子系统中最为重要的两个模块,学会了它们我们足以做出惊艳的效果,比如霰弹枪的发射,蘑菇蛋的冲击波等等.本篇讲的内容依旧重 ...

  9. 详解Unity中的粒子系统Particle System (十一)

    前言 今天讲最后一个模块--External Forces,该模块需要和Force Field组件配合使用,作用是模拟物理的力对粒子的影响.至此,Unity内置粒子系统的最后一块物理砖补齐,理论上来讲 ...

  10. 详解Unity中的粒子系统Particle System (九)

    前言 今天讲Texture Sheet Animation模块,先前我们已经讲了很多很多模块,通过上述模块可以实现很酷的效果,但是缺了一点真实感.比如说爆炸特效,仅指望单独的粒子来模拟真实的爆炸效果是 ...

最新文章

  1. nmap 添加自定义指纹
  2. yum安装mysql
  3. 【❤️Mark一下❤️】markdown中写上标、下标
  4. 请详细描述一下线程从创建到死亡的几种状态都有哪些?
  5. 2021年自驾游数据报告
  6. MinGW 64的安装 - 官网sourceforge安装失败非翻墙解决办法
  7. 数据库主备_数据库周刊40丨OceanBase官网上线开发者社区;人民日报关注易鲸捷;数据库迁移经验分享…...
  8. uni app对接php,thinkphp5 对接手机uni-app的unipush推送(个推)
  9. 学生宿舍管理项目开发计划书_第六组学生宿舍管理系统项目计划书
  10. 阶段3 1.Mybatis_10.JNDI扩展知识_2 补充-JNDI搭建maven的war工程
  11. 噫吁嚱!文言文亦能编程!此诚年度最骚语言也
  12. java sql2000驱动下载_SQL Server 2000 JDBC驱动程序
  13. 基于java实现的一个电话号码程序,3位,5位,7位,8位,11位
  14. 雷军:《我十年的程序员生涯》系列之一:我的程序人生路
  15. 华为机试真题 C++ 实现【最大化控制资源成本】【100%通过率】【2022.11 Q4 新题】
  16. OM | 浅谈收益管理与动态定价
  17. Wormhole for mac(在Mac上控制iOS和Android设备)
  18. python无法调用urlopen_python urlopen 不了一个url 而用curl 是可以的
  19. mysql端口号3306被占用_使用pandas将excel表格数据导入到mysql中
  20. (转)VC++之系统控制之设置显示系统当前时间

热门文章

  1. javascript的几种继承方式
  2. NLP论文阅读1--More Data, More Relations, More Context and More Openness: A Review and Outlook for Relati
  3. 专题:固体力学中应力与应变分析详解(4.应力张量的转换)
  4. Ubuntu20.04安装有道云词典
  5. ecshop 首页调用多个促销,显示到计时
  6. 从30天到17小时,如何让HSPICE仿真效率提升42倍?
  7. ImageJ如何获取图片RGB强度和灰度值
  8. 逻辑回归算法梳理(从理论到示例)
  9. 【C语言】C语言实现泛型编程
  10. 视频教程-以太坊区块链实战视频教程(全球同步升级)-区块链