前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Cocos Creator 3D 物理模块介绍

Cocos Creator 3D 物理模块介绍

作者头像
张晓衡
发布2019-10-22 15:14:05
2.2K0
发布2019-10-22 15:14:05
举报

为提升阅读体验,[参考链接]统一放在文末!

设计思路

简单易用

为了让游戏开发更加简单、友好和高效,Cocos Creator 3D 在研习和摸索中设计了一套比较基础的物理组件,并且还在持续完善中。尽管当前的组件功能还十分有限,但是相信在有了之前的组件设计经验后,很快就可以有更多强大且易用的物理组件。

另外,我们还对物理模块设计了一套抽象层,这是物理组件能够发挥其功能的底层支持,也是我们为多物理后端打下的基础。

多物理后端

用于接入不同的物理引擎,目标是能够在开发时,切换到不同的物理引擎后端中,满足对于不同游戏所需要的不同物理功能。

多物理后端的设计,可以使游戏包体更灵活,但主要的考虑是不同游戏要求的物理功能是不同的,例如:

  • 有些游戏只需要检测系统
  • 有些游戏需要支持基本功能并且包体小的物理
  • 有些游戏需要功能齐全的物理

对于不同的物理引擎后端,抽象层也将致力于提供简单统一的 API 使用,并且将尽力保障相同的参数在每个后端的实际表现达到统一一致。当然,这里针对的是所有后端都支持的功能。我们为多物理后端打下的基础。

目前的状况及后续发展

目前 Cocos Creator 3D 的物理模块已经支持仅碰撞检测的 builtin 和轻量功能的 cannon.js 物理引擎。未来,我们将持续完善已接入 cannon.js 的更多功能特性,并且还将接入功能更加强大齐全的 ammo.js。

使用示例

在介绍使用方法之前,为了更好地展示目前的物理功能,以便更好地结合具体使用与具体情境,我将通过一些示例来进行讲解,文末参考链接[Demo]中可以获取完整示例。

吞噬与吸引效果

上方的动图中,蓝色圈可以看作是一个洞,并具有吸引物体的能力,一个完整的洞效果可以分为物理和渲染两个方面的内容,这里主要介绍的是物理方面。

首先,看一下它们的物理结构:

方块(球类似,区别为碰撞器是球形状的,地面是只有碰撞器的结构)

蓝色圈

通过上面的节点树层级关系,可以知道 Hole 节点负责的是物理的功能,而它的子节点负责的是渲染的功能。当然,这里的层级关系也可以改变,例如,把渲染元素所需要的组件挂载到 Hole 节点上。

在 Hole 节点上,主要体现物理元素的是它挂载的两个球碰撞器组件,并且都是触发器的类型。这里可以分别看作内外圈,它们负责的功能分别为“洞”和“吸引”。

“吸引”的实现:监听外圈的触发器进入的事件,当物体进入时,对其施加向洞中心方向的力,这样就可以实现洞的吸引效果。

“洞”的实现:同样监听内圈的触发器进入事件,当物体进入时,修改物体碰撞器的掩码,使得物体不会与地面产生碰撞,物体的刚体由于受到重力和吸引力的影响,就会掉落下去,这也可以看做“吞噬”的效果。

车辆模拟的效果

物理模拟是为了表现真实世界,所以使用物理的最佳实践,就是把实物结构用基础的元素表达出来,再调整每个基础元素的属性,这样一般都可以模拟出期望的效果。

但物理模拟始终是模拟,在游戏中这类需要实时交互的场景里,需要将表现力和实时交互能力平衡。如果需要更佳的实时性能,那么可以尝试对物理结构简化。

需要注意的是,本文介绍的车辆模拟,是基于现有的物理功能制作的,并不是严格的真实车辆模拟,只是一种取巧的方式,而实现此车辆模拟的主要内容是车辆的结构:

上图结构也是通过真实车的结构简化而来的,设计好结构后,还需要调整每个部分的属性:

重心: 车的重心应该要低一些,否则可能会很容易翻车;

车身和车轮:车辆运动应该是很平稳的,可以把摩擦力系数都设置为 0,另外车轮要比车身低一些,这样在碰到障碍物后车辆会有晃动的效果,用来模拟避震;

挡板:因为车身摩檫力设置为 0 了,为了防止车滑起来,加一个摩檫力不为 0 的挡板;

刚体:默认质量为 10,这里可以改成 200;因为摩檫力都为 0,避免车一直滑动,将阻力(damping)设置为 0.9;角速度因子 x 轴向设置成 0.5,减低车在 x 轴向的旋转抖动。

使用简介

根据所需物理功能,选择不同物理

在开发前,可以先想好大致需要什么样的物理功能,根据不同的功能,选择不同的物理,以下条件可供参考:

  • 只需要规则的运动模拟,例如转动风扇、简单的跳跃,可以通过造型方程进行模拟,例如通过圆的方程进行圆周运动。
  • 只需要碰撞检测,可以考虑使用 builtin + collider 组件或者使用 gemotry 模块中的 intersect 相交性检测 API。
  • 需要物理模拟,目前可以考虑使用 cannon + 物理相关组件,或者通过直接获取引擎底层的物理进行开发。
  • 更加复杂的物理,如复杂约束、车量模拟、布娃娃模拟等,目前组件还未提供,但可以考虑在自己项目中嵌入第三方物理。

在使用物理之前,建议先阅读[物理文档]、物理[测试例]和简单的[Demo],在这些参考文档中,你可以了解到一些简单 API 的功能和使用方式,建议文档和测试例同时查看,会更助于理解物理模块。

选择好相应的物理后,接下来通过以下情况做一个简单演示。

规则的运动模拟

在 Cocos Creator 3D 中,可以通过节点 Transform 数据(即 position、rotation、scale 等属性)对节点进行变换,这也同样会驱动其节点链上的模型、粒子、刚体等组件的矩阵信息,以下脚本将通过修改节点的 Transform 信息进行椭圆方程的运动:

代码语言:javascript
复制
    // 这里演示节点以椭圆方程进行运动
    // 注:椭圆的参数方程 x = a*cosθ, y = b*sinθ。
    const _v3_0 = new Vec3();
    update (deltaTime: number) {
        const now = performance.now() / 1000;
        _v3_0.x = this.a * Math.cos(now);
        _v3_0.z = this.b * Math.sin(now);
        this.node.setPosition(_v3_0);
    }

builtin 物理检测

builtin 碰撞检测,底层实际调用的就是[intersect]提供的接口。首先选择物理模块为 builtin ,如下图:

然后,为需要进行检测的节点,加上碰撞体并调整大小,最后根据注册的触发事件来做出相应的行为。

代码语言:javascript
复制
    // 触发事件分三种类型,Enter\Stay\Exit,需要通过 ColliderComponent 组件注册
    start () {
        const collider = this.getComponent(ColliderComponent);
        collider.on('onTriggerEnter', this.onTriggerEnter, this);
        collider.on('onTriggerStay', this.onTriggerStay, this);
        collider.on('onTriggerExit', this.onTriggerExit, this);
    }
    onTriggerEnter (event: ITriggerEvent) { /* TODO */ }
    onTriggerStay (event: ITriggerEvent) { }
    onTriggerExit (event: ITriggerEvent) { }

cannon.js 物理模拟

选择物理模块为 cannon.js,为需要模拟的节点加上 RigidBodyComponent 组件,这样该节点就会进行物理模拟。再加上相应的 ColliderComponent,该节点的刚体就会增加相应的碰撞体,这会用于检测是否与其它碰撞体产生碰撞。

刚接触物理模拟,遇到最大的问题,大概是不知道如何控制刚体,建议各位开发者先熟悉刚体的每个参数所代表的物理意义,在[官方文档]中有详细介绍。

这里将根据一些简单例子来介绍一些可采用的做法:

模拟跳跃行为:由于运动是可以分解的,所以跳跃和移动等可以看作是一类问题,只要让相应的轴向拥有速度,刚体就会运动起来了。

在 cannon.js 物理中改变速度有多种方式,比如可以通过 setLinearVelocity 直接设置线性速度,以及通过 setAngularVelocity 直接设置角速度,这种方式将会使得物体由最大的速度开始往上。但由于受重力影响,物体 Y 轴向的速度将时间变化减小至 0;

也可以通过施加力或者冲量的方式, applyForce 或 applyImpluse,这种方式是根据公式定律计算得出的速度,以 applyForce 举例:

  • F=M·a F 是刚体的受力,M 是质量,a 是加速度
  • v=a·t v 是瞬时速度,a 是加速度,t 是时间

这种方式需要理解一些参数去实现效果,如施加力时需要考虑刚体的质量,以及对刚体施加的时间(在这里可以说是施加次数或帧数)。

限制刚体在 Y 轴旋转:这类问题可以看作是对刚体的约束,目前在刚体组件里面提供了对线性速度和角速度的缩放属性,即 linearFactor 与 angularFactor (可以看作是与刚体速度执行分量积),将 angularFactor 的 y 分量设置成 0 ,就可以达到这个效果。理解这些属性,并灵活的使用它们,可以实现非常多的效果。

目前的 cannon.js 支持情况:

  • 刚体
  • box\sphere 形状
  • 支持触发、碰撞事件,分别为:enter\stay\exit
  • 物理材质
  • 射线检测

更多功能

组件层服务的是所有的开发者,稳定性、通用性是首要的目标,Cocos 将在这个基础上持续不断的加入更多的功能。

对于一些暂不清晰的功能需求,我们将会提供实验性的组件,例如 mesh collider(没有发布正式组件的主要原因是目前的底层支持不够)

访问底层接口:

对于某些暂未提供组件化服务的功能,各位开发者可以考虑在现有的框架之下直接使用底层的物理接口(例如现有的 cannon.js)。以下步骤将会介绍如何在项目工程中直接访问到底层的物理接口:

1. 校验,在预览页面的控制台中输入 CANNON,判断其是否存在,若存在,则不用执行下列子步骤;

(1)将 CANNON 暴露到 Window 中,这里需要改动引擎代码:首先点击编辑器右上角的安装目录按钮,在相对路径 \resources\3d\engine\cocos\physics\cannon\cannon-world.ts 下,打开该文件;在合适位置加上此行代码 window.CANNON = CANNON;然后点击编辑器的开发者选项栏的编译引擎的选项(快捷键 Ctrl +F7),最后刷新编辑器(快捷键 Ctrl+R)

(2)重复步骤 1 ,确保 CANNON 可以被访问到。

2. 将 CANNON 的类型声明文件复制到项目工程当中 (下载[声明文件],后缀为 .d.ts 的文件)

3. 在脚本中用命名空间的方式访问 CANNON 提供的接口(注意不要使用模块的方式,即 import CANNON from 'cannon')

通过以上步骤就可以在项目工程中直接获取底层的接口进行开发了,需要注意的是,模块需要设置成相应的物理底层。

注:暴露其他的模块是类似的方式。

结合现有框架

目前的框架还没有暴露底层的对象,如果要和现有框架结合起来,哪么需要通过 hack 的方式去访问。这里以获取物理系统中的底层世界对象为例子:

首先可以通过控制台打印出 PhysicsSystem.instance 对象,查看他的属性列表,如下图:

通过对象的层级就可以找到底层对象的实体(上图中红色框标注的),即 cc.PhysicsSystem.instance._world._world。

这种方式虽然可以达到目的,但仍需要注意以下几点:

  • 只是提供一种方案,这种方式是不推荐的,更希望大家一起参与讨论和设计;
  • 为满足上层框架,底层物理可能存在一些 API 改动;
  • 未来结构可能会变化,对于这种方式需要自己去维护。

参考文档

[物理文档]

https://docs.cocos.com/creator3d/manual/zh/physics/physics.html

[测试例]

https://github.com/cocos-creator/test-cases-3d

[Demo]

https://github.com/cocos-creator/example-3d

[intersect]

https://github.com/cocos-creator/engine/blob/3d-v1.0.0/cocos/core/geom-utils/intersect.ts

[声明文件]

https://github.com/cocos-creator/cannon.js/blob/cocos-master


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Creator星球游戏开发社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档