查看原文
其他

前端开发者入门 Creator 必读吧

COCOS 2022-06-10

The following article is from Creator星球游戏开发社区 Author 异名

写在前面

因为公司的业务需求,近期学习了Cocos Creator这款游戏引擎的开发,也基于此上线了一款游戏,因此写这系列文章记录一下我从入门到项目发布的学习过程。

相对于 web 开发,像Cocos Creator这种界面化的游戏引擎最大的区别就是可视化的 UI 编辑,以及像动画编辑、物理引擎、资源管理系统等一系列高度封装集成的工具集。所以第一篇文章我主要会介绍一下我从 web 端开发转向游戏开发这个过程中,我对 Cocos 的工作流程的一些认识。尽管文档上有介绍但是新手上路,很多东西一开始被我忽略掉了,随着项目的进展,我断断续续地从文档、社区中学到了一些能提高效率的小方法和配置,在此记录一下,主要给其他新人做参考

熟悉编辑器

因为游戏的界面编辑都是通过编辑器来完成的,所以编辑器的一些基本功能和操作说明我们需要通过文档去理解熟悉,我这里会记录几个我新建一个项目必须会用的设置。

配置项目设置

在开始做项目前,别忘了要在项目-项目设置中先设置下面几个配置,后续的新建场景都会默认使用这些配置,后面就不需要每建一个场景都要设置一下了。

  • 初始预览场景(指定某一个场景/当前打开场景),我一般设置后者

  • 设计分辨率,引擎默认的是 960*640

  • 适配模式(fit-height/fit-width)

调整编辑器布局

在工作中,因为我们绑定资源、脚本和变量的过程都是通过把它们拖拽到属性面板来实现的,而引擎的默认启动界面把属性面板放到最右侧,那当我们需要绑定操作的时候就需要把物体从最左侧面板拖拽到最右侧面板,其实这段超长的操作距离是非常影响效率的,所以大部分的开发者其实都会选择经典布局,像下图这样,把属性面板通过拖拽放在左侧和层级管理器放在一起,这样绑定变量和资源的操作效率就会相对高一点

熟悉常用的界面快捷键

Cocos Creator的快捷键支持是比较弱的,但是它还是提供了几个高频操作的快捷键,通过这四个快捷键我们能快速切换这四个高频工具,很大地提高效率

  • W 移动工具

  • E 旋转工具

  • R 缩放工具

  • T 矩形变换工具

还有就是用过 3D 模式的都知道,在 3D 模式下调整相机视角和位置的操作是相对来说比较困难的,之前的项目中也实现过一个 2.5D 的场景,所以也这里也分享两个快捷键,一个就是调整物体的时候,点击住屏幕,在视图左上角会出现wasd(上下左右)的提示,可以通过键盘上wasd这四个按键来微调方向,相对来说会便捷很多

还有一个就是调整相机的角度,如果我们根据预览效果去调整相机的位置,实际操作起来有一定的麻烦,有一个隐藏的组合快捷键control+shift+f可以把我们场景编辑器的画面同步成相机的预览,它可以让我们更直观得调整相机效果

UI 开发

和 web 端的开发不一样,Cocos 的 UI 是不用写样式的,界面上所有的元素都是用图片堆积起来的,对我来说这个转变过程挺有意思的,把样式编写去掉了可以省掉我们一些布局的时间,我在开发项目过程中也发现了一些比较好的实践方法

精准还原设计稿的窍门

因为我们在可视化的编辑器中都是通过拖拽来实现图片的定位的,我们不写样式文件。但是我在第一个项目的时候思维又还没转换过来,还是习惯 web 端那种开发模式,我每次布局的时候都会去翻一下设计稿,测一下物体的位置,然后再在属性面板上输入正确的 position 信息,这样做当然是没问题的,但是效率真是太低了,后来我看到一位前辈的开发过程后才恍然大悟,改正过来。他是这样做的,在设计稿那里截一张完整的界面图,然后把它当成一个底层的节点,这样子我们就有一个和设计稿一模一样的背景图了,我们布局的时候再把一个个物体放到它正确的位置上,完事之后只需要把那个底层的节点删除就可以了,这样子布局的的效率提升可是质的飞跃。

把 UI 按模块拆分管理

在项目中,我们的一个场景里面的内容可能会很多,比如我这个场景里面有 N 个弹窗,如果我们把所有的弹窗的内容按他们的真实位置塞到canvas节点中,那真的是一件很糟糕的事情,因为一个个物体们会重叠在一起,后期我们将很难进行选中操作。所以我们在做 UI 管理的时候需要一个窍门就是把 UI 按模块拆分,并且移位管理,如下图

我并不会把弹窗一和弹窗二的内容叠加到主界面上,当然一开始我们可以这样做,因为我们可能需要根据背景图来确定每个物体的位置,但是当我们完成布局之后,可以像我一样把他们的父节点移出主界面之外,我这里的父节点是通过 widget 做了拉伸的,完全适配窗口的大小,当父节点被移出其实就是 position 做了偏移,后续在代码里面控制弹窗出现的时候,我们只需要多写一行代码,把父节点的 position 设置为(0,0)就可以了。这样子在后续维护的过程中我们的 UI 界面也能一目了然。如果用了 widget,也别忘了在代码调用的时候去手动更新  widget 的位置:

let widget= this.mapDlg.getComponent(cc.Widget);
widget.right = 0;
widget.left = 0;
widget.updateAlignment();

利用好自定义控件

自定义控件库其实就是给常用的 prefab 增加了一个入口,当然可以直接把 prefab 拖拽到层级管理器里面直接用,但是其实还是一个效率的问题。当你的 prefab 多了之后,先不说你要去翻资源管理器里面的文件夹,当你打开 prefab 所在的文件夹之后,一眼看过去是比较难找到自己需要的控件的,自定义控件不仅仅额外给了一个入口,而且它可以给 prefab 增加一个图标和控件名称,对高频的复用控件的使用来说,这真的太有必要了,打开面板一下就能找到你所需要的控件然后直接拖拽使用了

代码开发

配置 Vscode

虽然这块文档里面有写,但是因为我是从写web端转来做游戏的,以为自己很熟悉 vscode,又因为项目的原因要急于上手就选择性地忽略了这一块,仅仅只使用了代码提示这个工作流,等到看到社区内的前辈们的日常操作之后,才发现配置好 vscode 的工作流其实也是一大效率神器,它包括四块东西

  • 代码智能提示

  • 设置文件搜索范围

  • 手动触发编译

  • 配合 Chrome debug 插件在编译器内 debug

代码提示和文件搜索我就不提了。在正常情况下我们修改了代码,只有回到 Cocos 界面才能触发项目实时热更新,而我们在 vscode 上配置好编译的task,并且设置启动task的快捷键,我设置的快捷键是cmd+r,我们就可以在 vscode 上通过快捷键触发项目的热更新,它可以让我们在写代码的时候更专注在代码上;具体的配置步骤可以查看文档

// .vscode/tasks.json
// 配置vscode任务
{
"version": "2.0.0",
"tasks": [
{
"label": "compile",
"command": "curl",
"args": ["http://localhost:7456/update-db"],
"type":"shell",
"isBackground": true,
"group": "build",
"presentation": {
"reveal": "always"
},
}
]
}
// User/keybindings.json
// 配置任务启动快捷键
[
{
"key": "cmd+r",
"command": "workbench.action.tasks.runTask",
"args": "compile"
}
]

还有一个就是 ChromeDebug 插件,这块的流程只在1.9.0的文档中才有,后续的文档中虽然能搜索出来,但是无法阅读,它支持你在vscode中唤醒 Chrome,并在 vscode 中进行 debug,也是一大效率神器

参数绑定

在处理复杂界面的时候,因为页面上的元素较多,就算我们尽可能地拆分脚本,但是在一个脚本里面需要绑定的变量还是不可避免的增多,然后代码里面就会有一大串@property声明的变量,所以新手们需要充分利用的类型,比如我有 10 个只是单纯用于的显示和隐藏的 node 节点,就可以通过声明一个 node 数组节点来绑定,这样子我在代码里面显式声明的变量就会少很多👇

还有一种常见的情况就是一个物体它有两种甚至多种状态,当我刚上路的时候我对 Cocos 的内置对象还不熟,因为我们界面上的基本组成单元是 sprite 图,我就做了一个很蠢的操作就是有多少状态我就创建多少 sprite 节点,状态切换的时候就切换相应节点的显隐。但是这种情况下其实好的做法是通过一个 spriteFrame 的数组变量去存储不同状态的 spriteFrame 然后状态切换的时候去更新相应的 spriteFrame:

@property([cc.SpriteFrame])
btnStatus: cc.SpriteFrame[] = [];

// 切换不同的状态
this.node.getComponent(cc.Sprite).spriteFrame = this.btnStatus[0];
this.node.getComponent(cc.Sprite).spriteFrame = this.btnStatus[1];
this.node.getComponent(cc.Sprite).spriteFrame = this.btnStatus[2];

当然这样也不是最佳实践,因为后续接手我们代码的人通过代码根本就看不出数组不同下标对应的 spriteFrame 是哪一个,他还得通过界面去查看绑定的资源。所以最佳的实践应该是把该一个物体不同状态图片生成图集,图集里面的每个图片可以精确命名,当需要切换状态的时候,我们就可以通过精确的名称获取到对应的 spriteFrame,虽然这样子我们就需要多维护一个图集,但是它是一个相对更规范的实践方式。

@property(cc.SpriteAtlas)
spacemanAtlas: cc.SpriteAtlas = null;

// 切换不同的状态
this.body.getComponent(cc.Sprite).spriteFrame = this.spacemanAtlas.getSpriteFrame("take_off_state");
this.body.getComponent(cc.Sprite).spriteFrame = this.spacemanAtlas.getSpriteFrame("ready_state");
this.body.getComponent(cc.Sprite).spriteFrame = this.spacemanAtlas.getSpriteFrame("rest_state");
this.body.getComponent(cc.Sprite).spriteFrame = this.spacemanAtlas.getSpriteFrame("fire_state");

第三方工具

我目前用到的第三方工具主要有这下面几个:

利用 Texture Packer 生成图集

虽然引擎在打包阶段给我们提供了自动合图功能,但是为方便资源的维护、代码变量的管理以及后面性能优化上很重要的 drawcall 优化处理等等,我们还是很有必要在开发阶段就要有意识地去做图集管理。

ShoeBox

异常强大的 ps 插件,我目前用得最多的就是拆分图集、gif 图拆解、生成位图字体、合成 gif 图,它也可以合成图集,但是我觉得Texture Packer在这方面更好维护。拆分图集、gif 图拆解这两个功能我主要用来获取一些游戏的公共资源,最简单的像一些金币的动画,我需要它的序列帧,如果设计师那边有现成可用的固然好,如果没有的话特意让人家去做一份也没有很大的必要,我比较常去爱给网翻一些 CC0 版权的资源来用。比如下面我需要用到一张合图里面的某一张图片,我就会利用 ShoeBox 拆分合图

游戏当中不可避免的会用到一些卡通点的字体,比如数字由 0 到 9 组成,是我们设计师独出心裁设计的,需要应用到游戏当中。应该会有部分的前端像我一样是做 web 开发的,以前没有接触过游戏开发,那要实现这个需求就一脸懵逼,总不能让我用一个个 sprite 去代替吧。其实还真的是,位图字体的做法就是将会使用到的每个文字对应的字体做成位图,生成文字内容和位图的映射,游戏中动态的调用显示位图。这样即在游戏中呈现了漂亮的字体,又节省了资源。位图字体是由一张 png 的图片集和一个 fnt 配置文件组成的。其中 png 图片集中包括了所有会使用到的位图,fnt 配置文件里描述了这些位图应该怎么从 png 图片集中切分出来。下面就是利用 ShoeBox 制作位图字体的过程

Sketch

我司的设计工具,之前做 web 端开发的时候我和设计师的交付都是通过 sketch 的导出的网页或者通过蓝湖,但是做了游戏项目之后,我发现开发这边对稿子的调整还是挺多的,当稿子已经基本交付过来之后,我们这边有小的调整的话能够自己搞定的话,也没必要再去麻烦人家,所以像切图、去色、通过变换工具减少九宫格图片的多余面积等一些基本又高频的操作能不麻烦设计师就自己搞定吧,同时还有一些特殊交互动画需要对切图有一定的拆分处理,如果自己能搞定的话也能省去沟通以及交付的成本。

字蛛

这个其实用得相对低频,还是回到游戏中的字体需求,如果我希望界面上的用的字体比较符合整个 UI 的风格,比如我要一个圆体,但是用户的系统字体默认是那种瘦体,UI 上看起来肯定是体验不好的,设计师同事也不可能给每个字都做成位图字的,圆体中文字体库起码几 M 以上,我们又不可能全部当成资源引入,所以我们需要做字体库的切割,我们的游戏里面用到哪些字就用只提取那些字,切割后的字体库只有几 k,那就可以满足我们的生产环境使用了,具体的用法可以去官网查看。因为每次都需要启动服务,我很早之前嫌麻烦做过一个小工具(Mac 下载,window 下载),下面基于它做一个演示:

总结

以上就是这篇文章的全部内容了,主要记录一下我从新手开始做游戏开发后,一些后知后觉才学会的能够提高工作效率的工作流和配套小工具,因为是在公司内做第一个螃蟹的人,团队内部还没有这块的沉淀,加上这些小经验要么在文档中被我忽略而过,要么就零零散散在论坛中,所以后面会尝试做一些小结沉淀下来,后面我如果发现还有别的能提高效率的工作流程我也会在这里更新。除了上面这些新手上路的絮絮叨叨外,还有一些在真实项目中遇到的坑以及解决方案,我也觉得比较有意思,后面也会尝试做成一系列的总结沉淀下来,让我们不见不散~


 


以上就是今天的教程详解
再次感谢异名的倾情分享
感兴趣的童鞋可以扫码关注作者公众号哦~


如果您在使用 Cocos Creator 2D/3D 的过程中
 get 了独到的开发心得、见解或是方法
欢迎随时向我们投稿
帮助更多开发者们解决技术问题
让游戏开发更简单~

期待您与我们联系~


商务合作 | 技术支持 

请联系:赵铮雄 1501 2668 919


 市场合作 | 文章投稿 

请联系:刘丽云 1855 9780 603

【更多精彩】


ironSource Abby:畅谈出海买量变现闭环方法论

产品收入上不去,你该怎么办?

【更新至6P】Cocos Creator 3D 官方中文视频教程

为武汉游戏人点赞!3D《巅峰漂移》技术分享

深夜长谈:聊聊 Cocos Creator 3D 的未来

《江湖医馆》专访:用 Cocos Creator 开发原生游

引擎组 up 主上线,为你贴心准备 3D 官方教程
我打辅助!安利一款不错的游戏数据工具
原生 3D 超休闲游戏《弹无虚发》是如何炼成的?

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存