Unity——#06 下落

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity——#06 下落相关的知识,希望对你有一定的参考价值。

参考技术A   角色在高处往下跳亦或是走出高处的边缘时都应该表现出下落的动画,就目前而言,角色下落时只会播放闲置状态(idle)的动画,所以应该给它添加一个下落动画,如图:

  现在要想的就是,fall动画与其他动画的转换(Transition),应该要有:
1.jump到fall的转换,从高处按跳跃键往低处跳时触发这个转换
2.ground到fall的转换,在高处没跳跃但直接走/跑到高处的边缘时(高低差很大)触发
3.fall到ground的转换,下落到地面时触发这个转换。
这里要注意区分好jump到ground和fall到ground两个转换的触发条件,如果跳的不高就不用播放fall了,直接转回到ground,不过这是后话。
  一步一步来,逐渐实现各个转换,看上去只有3大步,其实里面有很多问题需要考虑。

  那么遇到的第一个问题就是,该怎么触发这个转换呢?我们应该在一个时间点设一个判断,在jump的动画播放完后,要准备进行转换,此时jump动画由两条路可以选,一个是fall,一个是ground,那决定它的去向自然就是角色此刻是否在地上,这个时间点就是在jump动画播放完后。
  要实现这个判断,就要引入一个虚拟碰撞体,虚拟碰撞体能在角色发生碰撞时返回与其碰撞的物体的名称。实现这个虚拟碰撞体的是一个叫Physics.OverlapCapsule的函数,其实Overlap的函数有很多,因为角色本身用的就是胶囊碰撞体,所以在投射一个Capsule能比较好的检测碰撞。这个函数的官方描述是:

  由此得知,功能就是给定一个胶囊,然后检查这个胶囊与物理世界的碰撞(against),然后返回所有碰撞体,据Returns得知返回的碰撞体放在了一个Collider类型的数组里。
  由声明式知,它吃两个Vector3变量,这两个Vector3变量确定这个胶囊的位置;吃一个float变量radius,这个radius决定胶囊体上下两个圆的半径,画个图就是这个亚子:

  然后我们把地面Plane和这个作为斜坡的Cube的Layer设为Ground:

  3个参数中的layerMask准备就绪,现在来看看怎么设置这个虚拟碰撞体的坐标和半径。我们暂时把这个虚拟碰撞体跟角色的碰撞体重合,这样利用角色自身坐标和角色碰撞体的半径和高度得到虚拟碰撞体的坐标。角色的自身坐标是transform.position,而角色碰撞体的半径可以通过外传一个CapsuleCollier来获得:

2.在这个senser里Add Component,命名为OnGroundSenser:

4.把角色胶囊体传给capcol

5.在Awake()函数里获得角色碰撞体的半径

6.在FixedUpdate()函数(角色的移动是在FixedUpdate()里完成)里建立坐标并传给Physics.OverlapCapsule()函数:

  虚拟碰撞体的底圆坐标(point1)为角色当前坐标在加一个角色碰撞体半径的高度,顶圆坐标(point2)为角色当前坐标加一角色碰撞体的高度再减一个角色碰撞体半径的高度。然后使用 LayerMask.GetMask("Ground") 函数获得Layer里的Ground,这样它就只会返回与虚拟碰撞体碰撞到的Layer为Ground的GameObject。
7.用先前宣告的Collider数组来接收Physics.OverlapCapsule()的返回值,并判断如果这个数组的长度不为0,就往上层(这里是角色的碰撞体PlayerHandle)发消息:

  现在,这个传感器就基本ok了,现在应该处理一下传感器的反馈了。
我们应该设置一个bool变量,在senser给出反馈(发消息)后,修改这个bool变量的布尔值,这个bool变量就是角色是否在地上的依据。在Animator视窗里的Paramaters创建一个bool参数命名为isGround:

  在ActorController.cs里,接收senser发送的信息,并改变isGround的布尔值:

  因为我们现在并没有拉fall到ground的Transition所以进入到fall动画之后就出不去了,这问题不大,之后肯定会解决。现在我们能看到,当地面跳跃的时候,在jump动画还没播放完,isGround就已经经历上勾→消勾→上勾的过程,所以到fall动画的Transition不会触发,回到ground;而在斜波上一跃而下时,由于在jump动画播放完后,isGround仍处在消勾状态,即不在地面,所以触发到fall动画Transition,播放fall动画。

  前几天开始每天的时间都用来练车了,所以每天能写的内容不算多,但日更不能断,共勉!

unity3D中,给物体添加刚体后,为啥不是掉在地面上,而是穿过地形一直往下落呢?

为fbx物体添加capsule collider组件之后再添加刚体组件,物体就不会穿过地面下沉了。在立方体上面添加一个Rigidbody刚体组件,并在上面添加一个Tertest脚本。给脚本添加OnCollisionEnter方法,可以检测碰撞collider,详细步骤:

1、打开unity3d创建一个地面Terrain。

2、接着创建一个立方体模型Cube。

3、在立方体上面添加一个Rigidbody刚体组件。

4、并在上面添加一个Tertest脚本。

5、给脚本添加OnCollisionEnter方法,可以检测碰撞collider。

6、在方法判断是否与地面Terrain接触并发生碰撞了,是的话就修改为红颜色。

if(theCollision.gameObject.name=="Terrain")

GetComponent<Renderer>().material.color = new Color (255,0,0);

7、运行unity3d场景,发现立方体会下落,当掉落到地面后就变成了红颜色。

参考技术A 碰撞体厚度小于unity里的物理设置 default contact offset就会往下掉。
Edit-project settings-physics里设置contact offset,默认是0.1调小。
比如物体碰撞体z是0.2,scale的z是0.2,0.2*0.2<0.1,就会往下掉
参考技术B 添加刚体后,你还必须给该物体添加一个碰撞。
并且该碰撞不能是meshCollider。
如果非要是MeshCollider,那你还必须给Convex打上勾
参考技术C 你这个是导入的fbx文件吧 ,为fbx物体添加capsule collider组件之后再添加刚体组件,物体就不会穿过地面下沉了 参考技术D

我也是这个问题,我最后是修改了碰撞检测collision detection模式,你看一下你的

以上是关于Unity——#06 下落的主要内容,如果未能解决你的问题,请参考以下文章

Unity CharacterController的transform赋值无效(一直下落)问题

unity3D中,给物体添加刚体后,为啥不是掉在地面上,而是穿过地形一直往下落呢?

Unity之导航网格寻路相关参数

Unity3D_(Rigidbody组件)物理引擎

unity3d中如何检测车轮是不是接触地面?

unity3d如何使刚体不被穿越?