unity 多种角色控制方式介绍 以及 CharacterController角色控制器详解_unity 角色控制器可以有多个?-程序员宅基地

技术标签: unity  character  controller  角色控制  # unity3D 使用、技巧笔记  unity控制  

简介

操作人物移动,我们一般有以下几种办法:

  1. 直接操作坐标
  2. 使用物理引擎操控
  3. 使用动作 Root Motion
  4. 使用角色控制器
关于坐标操作

坐标操作,就是通过设置transoform.position坐标 或是Vector.transform 等方法使物体移动到指定坐标。
该方式的优点,当然是简单暴力。坏处么,各种无互动无反馈,效果太楞。只适合简单的变化操作或是2d游戏。如果需要复杂点的效果,比如曲线过度,重力下降都要自己去实现。需要自己实现呀,兄弟们我们使用引擎的目的是什么,当然是使用提供的工具提升工作效率。不能什么都自己搞呀。所以这个方式只推荐应用在npc或是机关变化。

关于物理引擎操作

物理引擎操作的好处是可以使用诸多物理特性。当游戏有大量碰撞或移动特性时,使用这个比较好。比如赛车游戏。你可能需要设置赛车的重量来决定过弯的表现和撞车时力反馈的计算,又或是爆炸时被波及的力度。
使用物理引擎操作的主要方式就是添加力。由此可知,向前移动就是添加向前的作用力,跳跃就是添加向上的作用力,物理效果会让人物跳跃后自动下降。

关于Root Motion

这个方式是我认为最合理,过度最平滑,效果最好的方式。只可惜成本太高实现太难。
他所需要的技术包括:角色骨骼绑定 + Animation动作库 + Animator动画控制器 + Root Motion根坐标移动
这就需要我们不仅拥有质量高且数量庞大的动作库,以及各种对动画的精确控制才能实现。我们使用市面上已有的动作库可以实现基本的移动等操作。但总的来说,性能还是不如下面那个,而且开发成本还是比较高的,调试周期特别长,在遇到一些自适应需求的时候开发难度也会增加。
我相信,不久的将来它会成为游戏引擎中的操控最高级形态,并且在技术的推动下变得更加易用。

使用角色控制器(CharacterController)操作

这是个unity的组件。一般情况下控制人物的不二选择。那么为什么首选角色控制器呢,有以下几个理由:

  1. 首先他简化了刚体组件,去掉了很多不必要的计算。在人物比较多的场景中,这节省了大量的物理计算。例如物理引擎中的翻转、重力等效果,你肯定不希望你在移动过程中,会因为碰撞到物体而自动变换方向吧,一般做法就是用freezon来限制,其实这些都是没有必要的性能浪费。如果场景中人物较多时,这种优化就等于性能的巨幅提升。
  2. 其次,他内置了爬坡、登阶阈值设置。可以比较简单的处理多路况的移动问题。
  3. 第三,这个控制器,非常适合与nevmesh agent连用。即unity自带的巡路系统。当我们使用寻路系统时,如果人物身上有物理刚体,那么不仅会被沿途障碍物所影响,还会出现各种意想不到的情况比如惯性等性质。 如果使用角色控制器。则不必担心出现这种情况。一切都那么顺滑,防侧漏,夜夜安心。
  4. 不必担心被坐标被动作库写死。更不必担心由于动作库的坐标移动而出现意外的坐标干扰。
  5. 这可能是最重要的理由了:如果是网络游戏类型,最好使用坐标或Character Controller的控制实现。这是因为当网络数据传输-帧同步时,我们必须要保证多个客户端的场景数据的一致性。所以不应该使用其他的比较容易出现意外的实现方式。 关于网络游戏数据传输和帧同步,这里有清晰的介绍

角色控制器(CharacterController)组件参数介绍

在目标物体的inspector窗口中 点击add components ,添加character controller 即可完成组件添加。
在这里插入图片描述
【Slope Limit:】:斜坡角度。允许角色在指定的坡度上行动。
比如在手游和平精英中,你可能会发现某些房顶的斜坡就能走上去,某些房顶斜坡就走不上去。这都是这个参数所致。虽然和平精英用的是ue4引擎,但使用了和unity原理相似的控制组件。他们都有这个斜坡设置。
【Step Offset】:台阶高度。允许角色自动越过多高的障碍物。 这个设置就是诸如楼梯,台阶,马路牙子之类的障碍,你总不能遇到个小东西就卡住吧,有了这个就可以越过去。有人说,我没有用character controller,用刚体也能越过比较低矮的障碍物啊,怎么回事呢? 那是因为你的碰撞盒下方并不平整,比如胶囊或圆形碰撞盒,由于下方是曲线过度的,所以会在接触物体时通过物理计算的推动下摩擦过去。这种方式不容易控制并且会可能发生意外情况。
【Skin Width】:皮肤宽度。这个就相当于第二层碰撞盒。这个值不能大于下方的碰撞盒的Radius值。否则会卡在某个地方。一般情况这个值应该在Radius的5%左右会比较好
【Min Move Distance】:最小移动范围。当你在代码中使用Move方法移动时,小于这个值的移动将被忽略。这个值可以帮你减少角色因操作产生的抖动。
【Center】:角色碰撞盒偏移。设置物理空间的位置,你需要通过调整这个来使碰撞盒与角色模型重合。
【Radius】:碰撞盒半径。角色控制器的自带碰撞盒是胶囊,这个值用来设置胶囊半径。这个设置还有另一个影响,这个半径值将影响脚本中的isGrounded属性的作用范围。这对我们实现控制角色y坐标位置,比如跳跃等功能极其重要。
【Height】:碰撞盒高度。同上,胶囊高度。

角色控制器(CharacterController)使用

在添加了CharacterController的物体上新建一个脚本。

//获取 CharacterController对象
CharacterController _characterController = gameObject.GetComponent<CharacterController> ();
移动的实现

以下是两种移动方式。分别是世界坐标和本地坐标

//移动方向
private Vector3 moveDirection = Vector3.zero;
//移动速度
float movespeed  = 2f;
void FixedUpdate(){
    
	//世界坐标移动  适用于2d游戏,有固定的方向
	_characterController.Move(Vector3.up * movespeed * Time.deltaTime);

	//角色坐标移动实现   基于当前角色视角的方向移动,适用于3d游戏
	//根据输入的x y值获得移动方向
	float vertical = Input.GetAxis ("Vertical");
    float horizontal = Input.GetAxis ("Horizontal");
    moveDirection = new Vector3(horizontal, 0f, vertical);
    // 计算 基于当前物体坐标,要移动的方向
    moveDirection = transform.TransformDirection(moveDirection) * movespeed;
    // 移动
    _characterController.Move(Vector3.up * movespeed * Time.deltaTime);
}
跳跃的实现
public float jumpPower = 3f;
public float speed = 10f;
public float gravity = 10f;
private Vector3 moveDirection = Vector3.zero;
void FixedUpdate() {
    
   //isGrounded属性 用于 检测当前角色下方是否接触到地面。这个属性表现并不稳定,至少在我的unity2020中他不够稳定,经常闪烁。所以需要我们再用一个射线检测的方法来辅助。
    if(_characterController.isGrounded || IsGrounded(0.2f)) {
    
       moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0f, 				Input.GetAxis("Vertical"));
       moveDirection = transform.TransformDirection(moveDirection);
       moveDirection *= speed;
       if (Input.GetButton("Jump"))
           moveDirection.y = jumpPower ;
       }
       // 角色在世界中自动下降,模拟重力
       moveDirection.y -= gravity * Time.deltaTime;
       controller.Move(moveDirection * Time.deltaTime);
}
// 射线检测,抛砖引玉 我这里使用五个射线。实际上不需要这么多
 public bool IsGrounded(float distance){
    
 		//pointOffset: 点的偏移位置, distance:检测物体与地面的距离
        float pointOffset= 0.12f;
        bool b = Physics.Raycast(new Vector3(transform.position.x, transform.position.y, transform.position.z), -Vector3.up, distance);
        bool b1 = Physics.Raycast(new Vector3(transform.position.x - pointOffset, transform.position.y, transform.position.z), -Vector3.up, distance);
        bool b2 = Physics.Raycast(new Vector3(transform.position.x + pointOffset, transform.position.y, transform.position.z), -Vector3.up, distance);
        bool b3 = Physics.Raycast(new Vector3(transform.position.x, transform.position.y, transform.position.z + pointOffset), -Vector3.up, distance);
        bool b4 = Physics.Raycast(new Vector3(transform.position.x, transform.position.y, transform.position.z - pointOffset), -Vector3.up, distance);
        return b || b1 || b2 || b3 || b4;
    }

这里只是简单的实现,在实际的需求中,你可能要捕捉人物的跳跃状态,为人物跳跃指定起跳、浮空、落地等动作,还要设置原地起跳高度,移动跳跃距离等设定等。

注意事项
  1. 如果主人公身上有animator 需要看情况去掉root motion选项。该选项有可能导致坐标冲突
  2. CharacterController.isGrounded 这个会闪烁。所以会导致很多意外情况。可选的解决方案是:
    一、碰撞盒替代。是比较理想的方案。
    二、CharacterController.isGrounded + 射线辅助的方式。性能会好一些。不可以单独只使用射线。这样会存在盲点。
完成的效果

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lengyoumo/article/details/107015378

智能推荐

使用JDBC连接数据库出现 The server time zone value ‘�й���׼ʱ��‘ is unrecognized or represents more than one解决方案_jdbc.properties timezone-程序员宅基地

文章浏览阅读553次。在 jdbc.properties 文件中的 url 后面加上 ?serverTimezone=UTC加入之前的jdbc.properties文件:user=rootpassword=12345678url=jdbc:mysql://localhost:3306/testdriverClass=com.mysql.cj.jdbc.Driver加入之后:user=rootpassword=12345678url=jdbc:mysql://localhost:3306/test?serv_jdbc.properties timezone

计算机图形学孔令德基础知识,计算机图形学基础教程孔令德答案-程序员宅基地

文章浏览阅读1.4k次。计算机图形学基础教程孔令德答案【篇一:大学计算机图形学课程设】息科学与工程学院课程设计任务书题目:小组成员:巴春华、焦国栋成员学号:专业班级:计算机科学与技术、2009级本2班课程:计算机图形学指导教师:燕孝飞职称:讲师完成时间: 2011年12 月----2011年 12 月枣庄学院信息科学与工程学院制2011年12 月20日课程设计任务书及成绩评定12【篇二:计算机动画】第一篇《计算机图形学》..._计算机图形学基础教程 孔令德 答案

python xlwings追加数据_大数据分析Python库xlwings提升Excel工作效率教程-程序员宅基地

文章浏览阅读1k次。原标题:大数据分析Python库xlwings提升Excel工作效率教程Excel在当今的企业中非常非常普遍。在AAA教育,我们通常建议出于很多原因使用代码,并且我们的许多数据科学课程旨在教授数据分析和数据科学的有效编码。但是,无论您偏爱使用大数据分析Python的程度如何,最终,有时都需要使用Excel来展示您的发现或共享数据。但这并不意味着仍然无法享受大数据分析Python的某些效率!实际上,..._xlwings通过索引添加数据

java8u211_jre864位u211-程序员宅基地

文章浏览阅读911次。iefans为用户提供的jre8 64位是针对64位windows平台而开发的java运行环境软件,全称为java se runtime environment 8,包括Java虚拟机、Java核心类库和支持文件,不包含开发工具--编译器、调试器和其它工具。jre需要辅助软件--JavaPlug-in--以便在浏览器中运行applet。本次小编带来的是jre8 64位官方版下载,版本小号u211版..._jre8是什么

kasp技术原理_KASP基因分型-程序员宅基地

文章浏览阅读5k次。KASP基因分型介绍KASP(Kompetitive Allele-Specific PCR),即竞争性等位基因特异性PCR,原理上与TaqMan检测法类似,都是基于终端荧光信号的读取判断,每孔反应都是采用双色荧光检测一个SNP位点的两种基因型,不同的SNP对应着不同的荧光信号。KASP技术与TaqMan法类似,它与TaqMan技术不同的是,它不需要每个SNP位点都合成特异的荧光引物,它基于独特的..._kasp是什么

华为p50预装鸿蒙系统,华为p50会不会预装鸿蒙系统_华为p50会预装鸿蒙系统吗-程序员宅基地

文章浏览阅读154次。华为现在比较火的还真就是新开发的鸿蒙系统了,那么在即将上市的华为p50手机上会不会预装鸿蒙系统呢?接下来我们就来一起了解一下华为官方发布的最新消息吧。1.华为p50最新消息相信大家都知道,随着华为鸿蒙OS系统转正日期临近,似乎全网的花粉们都在关注华为鸿蒙OS系统优化、生态建设等等,直接忽略了不断延期发布的华为P50手机,如今华为P50系列手机终于传来了最新的好消息,在经过一系列方案修改以后,终于被..._华为手机p50直接预装鸿蒙系统

随便推点

python用什么软件编程好-初学python编程,有哪些不错的软件值得一用?-程序员宅基地

文章浏览阅读2.1k次。Python编程的软件其实许多,作为一门面向大众的编程言语,许多修正器都有对应的Python插件,当然,也有特地的PythonIDE软件,下面我简单引见几个不错的Python编程软件,既有修正器,也有IDE,感兴味的朋友可以本人下载查验一下:1.VSCode:这是一个轻量级的代码修正器,由微软规划研发,免费、开源、跨途径,轻盈活络,界面精练,支撑常见的自动补全、语法提示、代码高亮、Git等功用,插..._python入门学什么好

pytorch一步一步在VGG16上训练自己的数据集_torch vgg训练自己的数据集-程序员宅基地

文章浏览阅读3.2w次,点赞30次,收藏307次。准备数据集及加载,ImageFolder在很多机器学习或者深度学习的任务中,往往我们要提供自己的图片。也就是说我们的数据集不是预先处理好的,像mnist,cifar10等它已经给你处理好了,更多的是原始的图片。比如我们以猫狗分类为例。在data文件下,有两个分别为train和val的文件夹。然后train下是cat和dog两个文件夹,里面存的是自己的图片数据,val文件夹同train。这样我们的..._torch vgg训练自己的数据集

毕业论文管理系统设计与实现(论文+源码)_kaic_论文系统设计法-程序员宅基地

文章浏览阅读968次。论文+系统+远程调试+重复率低+二次开发+毕业设计_论文系统设计法

在python2与python3中转义字符_Python 炫技操作:五种 Python 转义表示法-程序员宅基地

文章浏览阅读134次。1. 为什么要有转义?ASCII 表中一共有 128 个字符。这里面有我们非常熟悉的字母、数字、标点符号,这些都可以从我们的键盘中输出。除此之外,还有一些非常特殊的字符,这些字符,我通常很难用键盘上的找到,比如制表符、响铃这种。为了能将那些特殊字符都能写入到字符串变量中,就规定了一个用于转义的字符 \ ,有了这个字符,你在字符串中看的字符,print 出来后就不一定你原来看到的了。举个例子>..._pytyhon2、python3对%转义吗

java jar 文件 路径问题_「问答」解决jar包运行时相对路径问题-程序员宅基地

文章浏览阅读1.3k次。我这几天需要做一个Java程序,需要通过jar的形式运行,还要生成文件。最终这个程序是要给被人用的,可能那个用的人还不懂代码。于是我面临一个问题:生成的文件一定不能存绝对路径。刚开始我想得很简单,打绝对路径改成相对路径不就行了吗?于是有了这样的代码:String path = "../test.txt";File file = new File(path);……这个写法本身并没有问题,直接运行代码..._jar启动文件路径中存在!

微信读书vscode插件_曾经我以为 VSCode 是程序员专属的工具,直到发现了这些……...-程序员宅基地

文章浏览阅读598次。如果你知道 VSCode,一说起它,你可能第一个想到的就是把它当做一个代码编辑器,而它的界面应该可能大概率是这样的——如果你恰好又是个程序员,那你可能经常会用到它,不管是 Python、JS 还是 C++ 等各种语言对应的文件,都可以用它来进行简单的编辑和整理,甚至是运行和 debug......但是今天要讲的显然不是这些,经过小美的多方研究,发现了即使是对于大多数并不了解 VSCode,也完全不..._vscode weixin read

推荐文章

热门文章

相关标签