CocosCreater 教程(下) 1.物理系统

这篇具有很好参考价值的文章主要介绍了CocosCreater 教程(下) 1.物理系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.物理系统

1.1 2D刚体

刚体是组成物理世界的基本对象。

1.2 2D 碰撞组件

目前引擎支持三种不同的碰撞组件: 盒碰撞组件(BoxCollider2D)圆形碰撞组件(CircleCollider2D) 和 多边形碰撞组件(PolygonCollider2D)。在 属性检查器 上点击 添加组件 按钮,输入碰撞组件的名称即可添加。

CocosCreater 教程(下)
                    
            
1.物理系统

在 属性检查器 上点击 添加组件,输入 PolygonCollider2D 可添加多边形碰撞组件。

CocosCreater 教程(下)
                    
            
1.物理系统

1.3 3D 物理

CocosCreater 教程(下)
                    
            
1.物理系统

物理系统是将游戏世界赋予现实世界的物理属性(重力、推力等),并抽象为刚体模型,使得游戏物体在力的作用下,仿真现实世界的运动及其之间的碰撞过程。即在牛顿经典力学模型基础之上,通过 API 计算游戏物体的运动、旋转和碰撞

Cocos Creator 支持以下几种物理引擎:

  • ammo.js:默认物理引擎,Bullet 物理引擎 的 asm.js/wasm 版本。具备碰撞检测和物理模拟的物理引擎。
  • builtin:内置物理引擎,仅用于碰撞检测的轻量引擎。
  • cannon.js:具有碰撞检测和物理模拟的物理引擎。
  • PhysX: 由 NVIDIA 公司开发的游戏物理引擎。具备碰撞检测和物理模拟的物理引擎。

开发者根据开发对物理特性需求或应用场景选择不同的物理引擎,详情请参考:设置物理引擎。

1.碰撞组件

碰撞组件可用于定义需要进行物理碰撞的物体形状,不同的几何形状拥有不同的属性。碰撞体通常分为以下几种:

  1. 基础碰撞体。常见的包含 盒、球、圆柱、圆锥、胶囊 碰撞体。
  2. 复合碰撞体。可以通过在一个节点身上添加一个或多个基础碰撞体,简易模拟游戏对象形状,同时保持较低的性能开销。
  3. 网格碰撞体。根据物体网格信息生成碰撞体,完全的贴合网格。
  4. 单纯形碰撞体。提供点、线、三角面、四面体碰撞。
  5. 平面碰撞体。可以代表无限平面或半空间。这个形状只能用于静态的、非移动的物体。
  6. 地形碰撞体。一种用于凹地形的特殊支持。

2.刚体组件

刚体是组成物理世界的基本对象,它可以使游戏对象的运动方式受物理控制。例如:刚体可以使游戏对象受重力影响做自由下落,也可以在力和扭矩的作用下,让游戏对象模拟真实世界的物理现象。

让刚体运动起来

针对不同的类型,让刚体运动的方式不同:

  • 对于静态刚体(STATIC),应当尽可能保持物体静止,但仍然可以通过变换(位置、旋转等)来改变物体的位置。
  • 对于运动学刚体(KINEMATIC),应当通过改变变换(位置、旋转等)使其运动。

对于动力学(DYNAMIC)刚体,需要改变其速度,有以下几种方式:

通过重力

刚体组件提供了 UseGravity 属性,需要使用重力时候,需将 UseGravity 属性设置为 true

通过施加力

刚体组件提供了 applyForce 接口,根据牛顿第二定律,可对刚体某点上施加力来改变物体的原有状态。

import { math } from 'cc'

rigidBody.applyForce(new math.Vec3(200, 0, 0));

通过扭矩

力与冲量也可以只对旋转轴产生影响,使刚体发生转动,这样的力叫做扭矩。

刚体组件提供了 applyTorque 接口,通过此接口可以施加扭矩到刚体上,因为只影响旋转,所以不需要指定作用点。

rigidBody.applyTorque(new math.Vec3(200, 0, 0));

通过施加冲量

刚体组件提供了 applyImpulse 接口,施加冲量到刚体上的一个点,根据动量守恒,将立即改变刚体的线性速度。 如果冲量施加到的点不是刚体的质心,那么将产生一个扭矩并影响刚体的角速度。

rigidBody.applyImpulse(new math.Vec3(5, 0, 0));

通过改变速度

刚体组件提供了 setLinearVelocity 接口,可用于改变线性速度。

rigidBody.setLinearVelocity(new math.Vec3(5, 0, 0));

刚体组件提供了 setAngularVelocity 接口,可用于改变旋转速度。

rigidBody.setAngularVelocity(new math.Vec3(5, 0, 0));

3.恒力组件

恒力组件是一个工具组件,依赖于刚体组件,每帧都会对一个刚体施加给定的力和扭矩。

4.约束

在物理引擎中,约束 用于模拟物体间的连接情况,如连杆、绳子、弹簧或者布娃娃等。

约束依赖 刚体组件,若节点无刚体组件,则添加约束时,引擎会自动添加刚体组件。

1.4 物理材质

物理材质是一种资源,它记录了物体的物理属性,这些信息用来计算碰撞物体受到的摩擦力和弹力等。

1.5 物理事件

CocosCreater 教程(下)
                    
            
1.物理系统

触发器与碰撞器

碰撞组件属性 IsTrigger 决定了组件为触发器还是碰撞器。将 IsTrigger 设置为 true 时,组件为触发器。触发器只用于碰撞检测和触发事件,会被物理引擎忽略。默认设置 false,组件为碰撞器,可以结合刚体产生碰撞效果。

1.6 射线检测

射线检测是对一条射线和另一个形状进行 相交性判断,如下图所示。

CocosCreater 教程(下)
                    
            
1.物理系统

 1.7 物理应用案例

射击苹果——静态网格、凸包、多步模拟(步长调整)

一般的苹果都带有凹面,处理好凹类或带连续平滑不规则曲面的模型都非常棘手,这是因为目前成熟的理论和技术都建立在离散、凸包的世界之上(微积分中用差分近似表示微分就是最典型的范例)。

CocosCreater 教程(下)
                    
            
1.物理系统

运动表现与模拟参数有非常大的关系,穿透是最具有代表性的现象,这可以通过缩减步长和增加步数来实现,调整步长有个小技巧:输入分式,即 1/Frame,其中 Frame 表示帧率。

2.粒子系统

粒子系统是游戏引擎特效表现的基础,它可以用于模拟的火、烟、水、云、雪、落叶等自然现象,也可用于模拟发光轨迹、速度线等抽象视觉效果。

CocosCreater 教程(下)
                    
            
1.物理系统

3.缓动系统

CocosCreater 教程(下)
                    
            
1.物理系统

缓动系统被广泛的应用于游戏开发中,其主要目的之一是用于解决离线动画无法满足需求时的动态动画的问题。

 4.地形系统

地形系统以一种高效的方式来展示大自然的山川地貌。开发者可以很方便的使用画刷来雕刻出盆地、山脉、峡谷、平原等地貌。

CocosCreater 教程(下)
                    
            
1.物理系统

5.资源管理

Asset Manager 概述

在游戏的开发过程中,一般需要使用到大量的图片、音频等资源来丰富整个游戏内容,而大量的资源就会带来管理上的困难。所以 Creator 提供了 Asset Manager 资源管理模块来帮助开发者管理其资源的使用,大大提升开发效率和使用体验。

5.1 加载资源

1.动态加载 resources

通常我们会把项目中需要动态加载的资源放在 resources 目录下,配合 resources.load 等接口动态加载。你只要传入相对 resources 的路径即可,并且路径的结尾处 不能 包含文件扩展名。

// 加载 Prefab
resources.load("test_assets/prefab", Prefab, (err, prefab) => {
    const newNode = instantiate(prefab);
    this.node.addChild(newNode);
});

// 加载 AnimationClip
resources.load("test_assets/anim", AnimationClip, (err, clip) => {s
    this.node.getComponent(Animation).addClip(clip, "anim");
});

2.加载 SpriteFrame 或 Texture2D

图片设置为 sprite-frame 或 texture 或其他图片类型后,将会在 资源管理器 中生成一个对应类型的资源。但如果直接加载 test_assets/image,得到的类型将会是 ImageAsset。你必须指定路径到具体的子资源,才能加载到图片生成的 SpriteFrame

// 加载 SpriteFrame,image 是 ImageAsset,spriteFrame 是 image/spriteFrame,texture 是 image/texture
resources.load("test_assets/image/spriteFrame", SpriteFrame, (err, spriteFrame) => {
    this.node.getComponent(Sprite).spriteFrame = spriteFrame;
});
// 加载 texture
resources.load("test_assets/image/texture", Texture2D, (err: any, texture: Texture2D) => {
    const spriteFrame = new SpriteFrame();
    spriteFrame.texture = texture;
    this.node.getComponent(Sprite).spriteFrame = spriteFrame;
});

3.加载图集中的 SpriteFrame

// 加载 SpriteAtlas(图集),并且获取其中的一个 SpriteFrame
// 注意 atlas 资源文件(plist)通常会和一个同名的图片文件(png)放在一个目录下, 所以需要在第二个参数指定资源类型
resources.load("test_assets/sheep", SpriteAtlas, (err, atlas) => {
    const frame = atlas.getSpriteFrame('sheep_down_0');
    sprite.spriteFrame = frame;
});

4.加载 FBX 或 glTF 模型中的资源

在将 FBX 模型或 glTF 模型导入编辑器后,会解析出该模型中包含的相关资源如网格,材质,骨骼,动画等,如下图所示:

CocosCreater 教程(下)
                    
            
1.物理系统

// 加载模型中的网格资源
resources.load("Monster/monster", Mesh, (err, mesh) => {
    this.node.getComponent(MeshRenderer).mesh = mesh;
});

// 加载模型中的材质资源
resources.load("Monster/monster-effect", Material, (err, material) => {
    this.node.getComponent(MeshRenderer).material = material;
});

// 加载模型中的骨骼
resources.load("Monster/Armature", Skeleton, (err, skeleton) => {
    this.node.getComponent(SkinnedMeshRenderer).skeleton = skeleton;
});

5.资源批量加载

resources.loadDir 可以加载相同路径下的多个资源:

// 加载 test_assets 目录下所有资源
resources.loadDir("test_assets", function (err, assets) {
    // ...
});

// 加载 test_assets 目录下所有 SpriteFrame,并且获取它们的路径
resources.loadDir("test_assets", SpriteFrame, function (err, assets) {
    // ...
});

6.预加载资源

因为预加载没有去解析资源,所以需要在预加载完成后配合加载接口进行资源的解析和初始化,来完成资源加载。

resources.preload('test_assets/image/spriteFrame', SpriteFrame);

// wait for while
resources.load('test_assets/image/spriteFrame', SpriteFrame, (err, spriteFrame) => {
    this.node.getComponent(Sprite).spriteFrame = spriteFrame;
});

7.加载远程资源和设备资源

// 远程 url 带图片后缀名
let remoteUrl = "http://unknown.org/someres.png";
assetManager.loadRemote<ImageAsset>(remoteUrl, function (err, imageAsset) {
    const spriteFrame = new SpriteFrame();
    const texture = new Texture2D();
    texture.image = imageAsset;
    spriteFrame.texture = texture;
    // ...
});

// 用绝对路径加载设备存储内的资源,比如相册
const absolutePath = "/dara/data/some/path/to/image.png";
assetManager.loadRemote<ImageAsset>(absolutePath, function (err, imageAsset) {
    const spriteFrame = new SpriteFrame();
    const texture = new Texture2D();
    texture.image = imageAsset;
    spriteFrame.texture = texture;
    // ...
});

// 远程音频
remoteUrl = "http://unknown.org/sound.mp3";
assetManager.loadRemote(remoteUrl, function (err, audioClip) {
    // play audio clip
});

// 远程文本
remoteUrl = "http://unknown.org/skill.txt";
assetManager.loadRemote(remoteUrl, function (err, textAsset) {
    // use string to do something
});

5.2 资源释放

1.自动释放

场景的自动释放可以直接在编辑器中设置。在 资源管理器 选中场景后,属性检查器 中会出现 自动释放资源 选项。

 CocosCreater 教程(下)
                    
            
1.物理系统

 勾选后,点击右上方的 应用 按钮,之后在切换该场景时便会自动释放该场景所有的依赖资源。建议场景尽量都勾选自动释放选项,以确保内存占用较低,除了部分高频使用的场景(例如主场景)。

另外,所有 Asset 实例都拥有成员函数 Asset.addRef 和 Asset.decRef,分别用于增加和减少引用计数。一旦引用计数为零,Creator 会对资源进行自动释放(需要先通过释放检查,具体可参考下部分内容的介绍)

start () {
    resources.load('images/background', Texture2D, (err, texture) => {
        this.texture = texture;
        // 当需要使用资源时,增加其引用
        texture.addRef();
        // ...
    });
}

onDestroy () {
    // 当不需要使用资源时,减少引用
    // Creator 会在调用 decRef 后尝试对其进行自动释放
    this.texture.decRef();
}

自动释放的优势在于不用显式地调用释放接口,开发者只需要维护好资源的引用计数,Creator 会根据引用计数自动进行释放。这大大降低了错误释放资源的可能性,并且开发者不需要了解资源之间复杂的引用关系。对于没有特殊需求的项目,建议尽量使用自动释放的方式来释放资源。

2.手动释放

当项目中使用了更复杂的资源释放机制时,可以调用 Asset Manager 的相关接口来手动释放资源。例如:

assetManager.releaseAsset(texture);

3.资源的动态引用

当开发者在编辑器中没有对资源做任何设置,而是通过代码动态加载资源并设置到场景的组件上,则资源的引用关系不会记录在序列化数据中,引擎无法统计到这部分的引用关系,这些引用关系就是动态引用。

如果开发者在项目中使用动态加载资源来进行动态引用,例如:

resources.load('images/background/spriteFrame', SpriteFrame, function (err, spriteFrame) {
    self.getComponent(Sprite).spriteFrame = spriteFrame;
});

此时会将 SpriteFrame 资源设置到 Sprite 组件上,引擎不会做特殊处理,SpriteFrame 的引用计数仍保持 0。如果动态加载出来的资源需要长期引用、持有,或者复用时,建议使用 addRef 接口手动增加引用计数。例如:

resources.load('images/background/spriteFrame', SpriteFrame, function (err, spriteFrame) {
    self.getComponent(Sprite).spriteFrame = spriteFrame;
    spriteFrame.addRef();
});

增加引用计数后,可以保证该资源不会被提前错误释放。而在不需要引用该资源以及相关组件,或者节点销毁时,请 务必记住 使用 decRef 移除引用计数,并将资源引用设为 null,例如:

this.spriteFrame.decRef();
this.spriteFrame = null;

5.3 下载与解析

Asset Manager 底层使用了多条加载管线来加载和解析资源,每条管线中都使用了 downloader 和 parser 模块,也就是下载器和解析器。开发者可以通过 assetManager.downloader 和 assetManager.parser 来访问。文章来源地址https://www.toymoban.com/news/detail-469020.html

到了这里,关于CocosCreater 教程(下) 1.物理系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 工单管理系统哪家好?如何让学校后勤报修更方便?

    随着互联网的高速发展,学校宿舍管理也必须随之向数字化方向迈进。越来越多的企业利用云计算服务的优势,使后勤维护整个流程实现数字化、自动化运行以及资源共享。这些技术创新的运用,大大提高了学校宿舍的后勤维修管理水平,同时,学校宿舍报修系统以其便利、

    2024年02月13日
    浏览(41)
  • 设备工单管理系统如何实现工单流程自动化?

    设备工单管理系统属于工单系统的一种,基于其丰富的功能,它可以同时处理不同的多组流程,旨在有效处理发起人提交的事情,指派相应人员完成服务请求和记录全流程。该系统主要面向后勤管理、设备维护、物业管理、酒店民宿等服务行业设备工单管理系统可以帮助企业

    2024年02月13日
    浏览(36)
  • 【开源】基于JAVA+Vue+SpringBoot的大病保险管理系统

    基于Vue+SpringBoot+MySQL的城乡居民大病保险管理系统,包含患者档案、医保充值、保险档案、手术档案、看病登记、保险审核模块,包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,大病保险管理系统基于

    2024年01月23日
    浏览(53)
  • 高效的工单管理系统具备哪些特点?“的修”工单系统对民宿运营管理有什么好处?

    随着企业不断发展和业务扩展,工单管理已成为企业运营的必要组成部分。一个有效且高效的工单管理系统对企业的运营至关重要。为了实现这一目标,企业需要选择适合自身需求的工单管理解决方案,并建立科学的工单管理流程。 高效的工单管理系统具备以下特点: 高自

    2024年02月08日
    浏览(51)
  • java版工程管理系统Spring Cloud+Spring Boot+Mybatis实现工程管理系统源码

     工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理    工程项目各模块及其功能点清单 一、系统管理     1、数据字典:实现对数据字典

    2024年02月07日
    浏览(45)
  • vue-springboot微信小程序房地产房屋销售预约看房管理系统

    相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低房地产公司的运营人员成本,实现了房地产销售的标准化、制度化、程序化的管理,有效地防止了房地产销售的随意管理,提高了信息的处理速度和精确度,能够及时、准确地查询和修正房地产信息、房源信息

    2024年02月04日
    浏览(39)
  • 基于python图书馆管理系统和读者系统(附完整代码以及打包好的exe文件)

    摘要:         本文基于python的图书馆管理系统和读者系统,实现了登录、注册、忘记密码、书籍查询、借阅、归还、修改等功能,通过csv文件将数据存储在本地。注册时采用了邮箱验证码,模拟了现实场景。( 全部源代码地址见文末 )如果有其他奇思妙想或者bug欢迎提

    2024年02月07日
    浏览(46)
  • Unity物理组件之刚体Rigidbody

    1、刚体简介 刚体:Rigidbody,属于物理类组件 作用:添加了刚体组件的游戏物体,可以在物体系统的控制下来运动,刚体可接受外力和扭矩力用来保证游戏对象像在真实世界中那样进行运动。任何游戏对象只有添加了刚体组件才能受到重力的影响,通过脚本为游戏对象添加的作

    2023年04月09日
    浏览(89)
  • 大学物理·第4章刚体的转动

    例题 这题不难,但是也是学习思路(因为一开始写,不会写) 首先,看到转多少转就想到求角位。ω是变化的,所以用定积分(ωdt)。将ω表达为含t的表达式,根据题意(角加速度是变化的)用定积分(αdt)表达ω即可  F要与r垂直,才是有效的 例题 只有对于几何形状规则

    2023年04月15日
    浏览(45)
  • Unity --- 物理引擎 ---- 刚体RigidBody 与 碰撞器 collider

      1.RigidBody(刚体)的作用是让物体具有物理特性(比如说重力,摩檫力等等) 2.如果想让物体能够与其它物体发生碰撞的话,我们还需要一个组件 --- Colider碰撞器组件 1.上图就是Unity中提供的已经准备好的各种形状的碰撞器组件 2.形成不同形状的碰撞器所需的面数不同,面数

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包