美文网首页
Unity——#06 下落

Unity——#06 下落

作者: MisakiMel | 来源:发表于2019-07-06 06:53 被阅读0次

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


fall

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

1.jump到fall的转换

  二话不说,先给它两者拉个Transition,方向自然就是从jump到fall: jump→fall

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

public static Collider[] OverlapCapsule(Vector3 point0, Vector3 point1, float radius, int layerMask = AllLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

Returns
Collider[] Colliders touching or inside the capsule.

Description
Check the given capsule against the physics world and return all overlapping colliders.

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


虚拟胶囊体
  还有一个int参数layerMask,这个参数是跟Inspector里的Layer有关: Layer
  以后如果有机会就详细介绍一下Layer和layerMask。这个函数的layerMask默认是所有的Layers,即它碰到的所有物体都会放在返回的Collider数组里面,不过可以通过LayerMask.GetMask()方法来指定传递某一个Layer。
  首先,我们现在是要检测是否于地面相撞,所以我们要新增一个Layer命名为Ground,如图:
新增Layer

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


Cube
Plane

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


角色碰撞体的CapsuleCollier
  说完这些参数如何获得之后,我们来真正写如何调用OverlapCapsule:
1.先在角色碰撞体下创建一个空的子物体Create Empty,并命名为senser(传感器),负责各种碰撞的判断。
senser

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


OnGroundSense
3.双击打开,先新建两个Vector3变量、一个CapsuleCollider变量、一个Collider数组、一个float变量
    public CapsuleCollider capcol;  //接收胶囊碰撞器
    Vector3 point1;                 //虚拟胶囊体的底圆坐标
    Vector3 point2;                 //虚拟胶囊体的顶圆坐标
    private Collider[] outputCols;  //用来接收与虚拟胶囊体发生碰撞的物体
    private float radius;           //模型胶囊体的半径

4.把角色胶囊体传给capcol


Capcal

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

    void Awake () {
        radius = capcol.radius;
    }

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

    void FixedUpdate () {
        point1 = transform.position + transform.up * radius;
        point2 = transform.position + transform.up * capcol.height - transform.up * radius;
        outputCols = Physics.OverlapCapsule (point1, point2, radius,LayerMask.GetMask("Ground"));
    }

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

    void FixedUpdate () {
        point1 = transform.position + transform.up * radius;
        point2 = transform.position + transform.up * (capcol.height-offset) - transform.up * radius;
        outputCols = Physics.OverlapCapsule (point1, point2, radius,LayerMask.GetMask("Ground"));
        if (outputCols.Length!=0) {
            SendMessageUpwards ("IsOnGround");
        } else {
            SendMessageUpwards("IsNotOnGround");
        }
    }

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


isGround

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

    void IsOnGround(){          //当与地面发生碰撞时
        anim.SetBool ("isGround", true);
    }
    void IsNotOnGround(){       //当不与地面发生碰撞时,跳跃/下坠状态
        anim.SetBool("isGround", false);
    }   
  至此,在离开jump动画之后,就能判断Transition往哪边走了,可以看看效果: Fall

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

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

相关文章

  • Unity——#06 下落

      角色在高处往下跳亦或是走出高处的边缘时都应该表现出下落的动画,就目前而言,角色下落时只会播放闲置状态(idle...

  • Unity——#08 下落_3

      虽然我想很在上一节就讲完下落,但是由于时间问题(学车真的太鸡儿累了),就只分多一节来讲。  这节解决最后的一个...

  • Unity——#07 下落_2

      上节我们解决了jump到fall的Transition,这节解决第二个Transition。 2.fall到g...

  • Unity UGUI 原理篇(四):Event System M

    http://k79k06k02k.com/blog/440/unity/unity-ugui-原理篇四:even...

  • 下落

    这些年你过的怎么样 一直在苦苦探听你的消息 说来也怪 好多年没见 竟没把你忘 这些年你过的怎么样 说来也怪 竟一直...

  • 下落

    似乎没有什么 能逃脱下落的命运 不需要什么海枯石烂 天长地久 一不留神 它便落下 越陷越深 即便如此 我还是偶尔听...

  • 下落

    每当我以为我自己已经荡到谷底,等待下一刻的触底反弹的时候。生活总是会给我重重一击,残酷的告诉你,你还有下...

  • Unity2019导出地形terrain为obj

    2020-05-06我的unity版本是2019用这个方法可以导出普通物体甚至人物模型,但无法正常导出terrai...

  • unreal和unity引擎比较与选择

    unreal和unity引擎比较与选择 本文写于2022年06月01日,阅读时请注意时效。 本文主要针对初学者选择...

  • 健身气功八段锦囗令

    摘录:健身气功八段锦囗令 1、两手托天理三焦 上托、下落; 上托、下落; 上托、下落; 上托、下落; 上托、下落;...

网友评论

      本文标题:Unity——#06 下落

      本文链接:https://www.haomeiwen.com/subject/lyqyhctx.html