[开源] 提升效率的编辑器扩展:Quick Finder

title: Cocos Creator 编辑器扩展:Quick Finder
date: 2021/04/29
updated: 2021/04/29


前言

这一天,渣渣皮终于找回了他的帐户密码…

:tada: 渣 皮 工 厂 再 次 营 业 !

渣皮这次给大家奉上的扩展是:Quick Finder

Quick Finder

:cowboy_hat_face: 这是一个不仅能够提升效率,更重要的是能够提升幸福感的扩展!

想找文件?按下 F1,只需输入模糊的关键字,相关文件即刻奉上,场景和预制体间切换更是来去自如!

轻轻一键,尽在掌握!

:sunglasses: 老板再也不用担心我高血压啦!

渣皮剧场

:clapper: 情景再现

渣皮目前工作中的项目相比以前要大不少,项目的结构也比较复杂,整个项目 assets 目录下有近 9000 个文件(不包括 meta 文件)。

每当我想要打开某个场景和预制体,或者找某个文件,我都需要一层一层地翻文件夹。

万一我不知道文件的准确名称,又不知道在哪个文件夹,那是真不好找…(:thermometer: 血压++)

:robot: 不太对劲

这时就有头铁的小伙伴要说了:

“你个辣鸡瞎了吗!编辑器里不是自带一个搜索吗!”

自带的搜索确实能用,但是我小声表示拒绝。

能用,但是不完全能用~[手动狗头]

其实对于文件不多的项目来说,这个搜索没啥问题。

但是对于文件稍微多一些的项目,搜索就有点慢了,在配置不高的电脑上搜索还会卡顿一下…(:thermometer: 血压++)

最重要的一点就是:自带的搜索不支持模糊搜索!你必须将文件的名字拼对才搜得出来!

:joy_cat: 以上,就是我开发这个扩展的目的,也就是降血压(误)。


正文

:books: 本文主要包含两大部分:

  1. 扩展介绍
  2. 技术解析

扩展介绍

简介

首先,Quick Finder 是一个 Cocos Creator 编辑器扩展。

主要用于快速搜索并打开项目中的场景和预制体,或者快速定位项目中的任意文件。

使用起来很简单,通过按下键盘快捷键(默认 F1)来呼出搜索栏,输入关键字即可(支持不连续模糊搜索)。

视频

使用演示:https://www.bilibili.com/video/BV13p4y147WX/

截图

下载 & 安装

扩展商店安装

本扩展已上架 Cocos 商店,点击 Cocos Creator 编辑器顶部菜单栏中的 扩展 -> 扩展商店 即可打开扩展商店。

在上方搜索栏中输入“Quick Finder”并搜索就可以找到本插件,点进去直接安装即可(建议安装到全局)。

Quick Finder:https://store.cocos.com/app/detail/2745

自行下载安装

在扩展仓库的发行版处下载最新的扩展压缩包。

发行版:https://gitee.com/ifaswind/ccc-quick-finder/releases

下载完成后将压缩包解压:

  • Windows:解压到 C:\Users\${你的用户名}\.CocosCreator\packages\ 目录下
  • macOS:解压到 ~/.CocosCreator/packages/ 目录下

以 Windows 为例,扩展的 main.js 文件在我的电脑上的完整目录为 C:\Users\Shaun\.CocosCreator\packages\ccc-quick-finder\main.js

使用说明

搜索

  1. 按下快捷键(默认为 F1)或者点击编辑器顶部菜单栏中的 扩展 -> Quick Finder -> 搜索 即可打开搜索栏。

  2. 在搜索栏中输入关键词就会得到符合条件的文件列表。

  3. 滑动鼠标滚轮可以滚动列表;按下键盘的上下箭头键可以选择文件;按下左右箭头键可以在编辑器内的资源管理器中定位当前选中的文件。

  4. 找到目标文件后,鼠标点击或者按下回车键即可快速打开(仅场景和预制体)或在资源管理器中定位文件。

搜索栏失焦后会自动关闭,点击搜索栏外的任意位置或者按下 Esc 按键也可以关闭搜索栏。

设置

点击编辑器顶部菜单栏中的 扩展 -> Quick Finder -> 设置 即可打开扩展的设置面板。

在设置面板中你可以更换打开搜索栏的快捷键,也可以自定义一个自己喜欢的快捷键。

不过需要注意的是,并非所有的按键都可以使用,因为有些快捷键已被系统或 Cocos Creator 占用。

键盘快捷键参考:https://www.electronjs.org/docs/api/accelerator

技术解析

搜索栏

选择方案

:mag_right: 关于搜索栏,我一开始的想法是做成和 macOS 的 Spotlight(聚焦)一样的样式。

但是,Cocos Creator 编辑器提供的窗口限制太多了,功能上也有缺失,如没有无边框模式,无法设置透明度等…

:crazy_face: 这可不行!功能可以砍,档次不能低!

不过好消息是,我们可以在编辑器中直接使用 Electron 的接口来创建窗口。

:ghost: Cocos Creator 与 Electron

应该有许多小伙伴都知道,Cocos Creator 的编辑器就是基于 Electron 开发的。

所以我们可以直接在扩展中引入 Electron 并使用,不需要任何额外的操作。

:sunglasses: 就这么办!

最终我选择了 [ Electron + Vue 2.x ] 的组合来制作这个搜索栏。

一顿打码之后,我们就拥有了这么一个搜索栏…

别笑!我自己感觉还挺满意的!

看起来和 Spotlight 不能说一模一样,只能说毫不相干哈哈哈哈哈~

:joy_cat: 这可能是因为写着写着我有了自己的想法,肯定不是因为做不出来,信我!

给自己挖坑:关于搜索栏的开发我会单独写一篇文章来详细介绍,着急的小伙伴也可以直接翻源码。

两种窗口

这里给大家简单说一下编辑器提供的窗口和使用 Electron 创建的窗口之间的区别。

编辑器的窗口

首先,编辑器提供的窗口实际上也是使用 Electron 创建的,只不过编辑器内部对窗口进行了二次封装,并建立了自己的开发规范。

可以把窗口比喻成一个固定样式的画框,你需要按照一定的规范来进行作画。

  • 优点:集成了多种布局和样式,与编辑器交互较为方便,让我们可以快速开发出一个与编辑器风格相匹配的面板,并且面板可以嵌入到编辑器中。
  • 缺点:限制颇多,离不开“窗口”,调试起来比较麻烦,还有二次封装带来的一些“坑”,需要开发者对 Shadow DOM 有一定了解,无形中增加了不少开发成本。

还有就是,编辑器集成的 Vue 版本太旧了(大概是 1.x 的样子),渣皮建议自行下载并引入最新的 Vue 2.x 来进行开发。

Electron 窗口

如果直接使用 Electron 创建窗口,我们可以把扩展的页面完成当做一个 Web 前端项目来做,写起来舒服多了。

这种窗口也可以比喻成一个画框,边框的样式可以自定义,框中的内容可以随意发挥。

  • 优点:解锁各种窗口特性(无边框、透明等),自由度拉满,各种框架都能直接用,可以搞出各种花样。
  • 缺点:需要一定的 Web 前端知识,与编辑器交互较为麻烦,且不能嵌入到编辑器中。

搜索

搜索文件无非就是遍历项目中所有文件,并与输入的名称进行对比。

遍历项目文件

为了不遗漏任何文件,我们需要使用递归去遍历整个项目的文件,这个操作听起来有点不太聪明的样子,会不会很慢?

实际上,由于扩展只进行信息采集(名称,扩展名),并不读取文件内容,处理起来还是非常快的。项目里 8000+ 的文件也就是一下子的功夫,可以说是无感。

所以我选择在每次打开搜索栏之后进行文件信息的采集,且关闭搜索栏后也不会缓存本次的结果数据。

另外有一点就是,由于搜索栏失焦后就会自动关闭,所以也基本不会有新增文件而没有被采集到的情况。

编辑器自带的资源搜索慢的原因可能就是需要对文件做一些处理吧~

文件名称匹配

这一项任务主要是通过正则表达式中的非贪婪匹配来完成的。

非贪婪匹配 (懒惰匹配)

:magnet: 非贪婪匹配的特点是:在满足匹配时,匹配尽可能少的内容。

我们只需在输入的关键词的字与字之间插入表达式 .*? 即可。

这时不了解正则表达式的小伙伴懵了,这几个符号我都认识,但是连起来就看不懂了哈哈哈~

在正则表达式中,这三个符号的含义分别是:

  • .: 表示匹配除换行符(\n)外的任意单字符
  • *: 表示前一个字符 0 次或无数次
  • ?: 表示前面的内容出现 0 次或 1 次

.* 合体就变成了贪婪匹配(.*),而再加上 ? 就是非贪婪匹配(.*?)。

贪婪匹配的特点是:在满足匹配时,匹配尽可能多的内容。

:memo: 示例代码:

const keyword = 'hoe';
// 插入表达式后变成:'h.*?o.*?e'
const pattern = keyword.split('').join('.*?');
const regExp = new RegExp(pattern, 'i');
const names = [
    'handsome', 'hello', 'hardware',
    'home', 'ohh', 'chrome', 'hour'
  ];
for (let i = 0; i < names.length; i++) {
  //匹配
  if (regExp.test(names[i])) {
    // 匹配成功
    // 'handsome'、'home'、'chrome'
  } else {
    // 匹配失败
    // 'hello'、'hardware'、'ohh'、'hour'
  }
}

这样一来,我们就可以瞬间从成千上万个文件中找出与关键词相匹配的文件了。

:clown_face: 妙啊!真是妙蛙种子吃着妙脆角进了米奇妙妙屋,妙到家了!

排序

当名称匹配成功后,还需要保存匹配结果的长度,然后就可以根据这个长度来进行匹配度排序。

:memo: 示例代码:

const names = [
    'handsome', 'hello', 'hardware',
    'home', 'ohh', 'chrome', 'hour'
  ];
const results = [];
for (let i = 0; i < names.length; i++) {
  // 匹配
  if (regExp.test(names[i])) {
    // 匹配到的字符串长度
    const similarity = names[i].match(regExp)[0].length;
    results.push({ name, similarity });
    // 匹配到的内容
    // 'handsome'、'home'、'hrome'
  }
}
// 排序(similarity 越小,匹配的长度越短,匹配度越高)
results.sort((a, b) => a.similarity - b.similarity);
// 排序后:'home'、'chrome'、'handsome'

经过排序之后,匹配度越高的文件排越前,这下更容易找到目标文件了。

:star_struck: 非常的鹅妹子嘤啊!

渣皮感言

:cow::beer: 不得不说,正则表达式真的很方便很强大(同时也相对吃性能)。

:tired_face: 但是正则表达式也真的太难了啊啊啊呜呜呜…

不得不佩服那些能够熟记正则的大佬。


传送门

微信推文版本

个人博客:菜鸟小栈

开源主页:陈皮皮

Eazax Cocos 游戏开发工具包


更多分享

《为什么选择使用 TypeScript ?》

《Cocos Creator 性能优化:DrawCall》

《在 Cocos Creator 里画个炫酷的雷达图》

《用 Shader 写个完美的波浪》

《在 Cocos Creator 中优雅且高效地管理弹窗》

《Cocos Creator 源码解读:引擎启动与主循环》

《JavaScript 内存详解 & 分析指南》


公众号

菜鸟小栈

:smiley_cat: 我是陈皮皮,一个还在不断学习的游戏开发者,一个热爱分享的 Cocos Star Writer。

:art: 这是我的个人公众号,专注但不仅限于游戏开发和前端技术分享。

:sparkling_heart: 每一篇原创都非常用心,你的关注就是我原创的动力!

Input and output.

11赞

好东西,支持!

这么便宜 先买为敬 :grinning:

皮皮真棒!

优秀的大佬

优秀啊。。。

能在搜索的每个结果后面加个资源路径就好了 :innocent:

妙啊!我下个版本加上!!!

1赞

好东西啊,支持3.0吗

后面会支持 3.0,目前还在适配中~~

可以的,小功能大作用,牛逼

哈哈好,先买一个等升级

我刚想说3.0商城搜不到

不错的工具。

F1出来搜索框的时候有点慢。

牛皮啊!又牛又皮!

2.4.5 按回车,cocos 会闪退。2.4.3 和 2.4.4 正常

能支持搜索文件夹吗?有时知道文件在哪个文件夹,但是不知道文件名,这时想通过定位到文件夹来找文件

get,我查下

已加入需求池中,如果可以实现,下个版本加上~

是一直都慢吗,还是第一次慢呀?