如何打造细致的2D捏脸系统

大家好,我是汉家松鼠的CG,《江湖X》、《汉家江湖》的制作人和主程,今天给大家介绍一下我们游戏中的捏脸系统是如何设计和开发的。

背景介绍

游戏《汉家江湖》是我们一款2D原创武侠题材RPG独立游戏,我们提供了一个2D的捏脸系统供玩家自定义角色,同时也供我们自己捏造游戏中的各种非重要角色。


汉家江湖 捏脸(男)
汉家江湖 捏脸(女)

整个捏脸系统由我和我们的美术(文艺吕布)两个人开发设定而成,一开始做的初衷是因为我们在开发《江湖X》的时候,发现故事设定的NPC数量实在是太多——如果每个都画,则工作量恐怖。为了节省工作量,当时本来打算的方案是只画重要人物,其他人物全部用黑人小剪影(如下)

匿名NPC剪影1
匿名NPC剪影2

后来我们开发时期业余时间玩某个H游戏的时候(是的,你没看错,就是某H游戏……),该游戏随机NPC是从一个随机的头像库里抽取然后进行简单的颜色替换,我们突发灵感的觉得,我们可以更进一步做一个纯2D的捏脸系统嘛!

于是乎我们搜罗了一圈资料,发现大多游戏普遍的2D捏脸都比较简单,能够自定义的部分相当有限。而且也几乎从来没有中国风元素的2D捏脸,我们觉得这里是一个亮点,既可以解决我们的量产NPC的问题,也可以让主角多一个定制化捏脸的功能,同时似乎也是国风2D游戏的首创——所以我们决定来设计自己的标准和规范。

我们第一版在《江湖X》里最终的捏脸系统成品效果如下(请无视当时丑陋的UI)


以及在后续的资料片《汉家江湖》中重做了整个美术素材以及更加优化了整个捏脸系统。

核心问题

开发这个系统的核心是两个层面:美术规范和技术规范

美术规范需要解决的问题——我们需要将美术资源拆成多少层?每一层的美术标准如何制定?各层之间的关系是怎样?每个层可以自定义调整的参数有哪些?如何保证这些参数最终出来的结果“和谐”?(而不是眼睛眉毛鼻子挤到一起之类的)

技术规范需要解决的问题——对于捏好的脸如何存储和读取?资源如何打包存取以达到效率最大化?(运行时内存、运行时绘制效率、资源打包和存储效率)

下面,我们就这些问题一一展开:

美术规范:

我们根据项目设定的需要,考虑主要人物构成由 身体+头部+武器+面部配饰 组成。

其中头部包括 头发(包括帽子等头部配饰)、脸部轮廓、眼睛、鼻子、眉毛、嘴巴、胡须等。同时我们还考虑了角色的肤色变色、衣服调色等……

这一步大家可以根据自己的实际项目需要来设定拆分部分,提几个我们当时考虑的一些特殊情况提炼而成的规范吧:

  • 要想表现力好,头发和帽子不好做分开,否则无法组合出很好的效果(会由于发型和帽子的穿插而美术设计上受限很大)
  • 发型要想表现力好,也得分为多个层:同样一个发型会有部分头发在面部以后、面部以前身体之后、以及身体之前。(见下图对比1:我们是分了4个层——前发、前发阴影、中发、后发。并且后来发现,若干发型还可以做前后发的组合来形成更多的搭配,但是不完全可以适配所有的发型情况,所以最终捏脸规范上也需要做限制——我们后面会做解释)关于前发阴影:为了美观起见,我们设定了前发在面部的投影的层,来处理虚拟光照下统一的阴影绘制(见下图对比2)。

对比1:典型的前、中、后发示意

光头

增加前发和前发阴影

增加中发

增加后发——整体效果图

对比2:前发投影对比示意

无前发投影
含前发投影
  • 同以上道理,一个身体也可能需要分若干层。因为其中涉及到头发在身体表现上的层次穿插,这里就不具体举例示意了。

所以我们最终确定的层次结构从前到后依次是

bitem(身后道具)
bhair(后部分头发)
body(身体)
mhair(中部头发)
head(面部)
fhairshadow(前发阴影投影)
nose(鼻子)
mouth(嘴巴)
reye(右眼)
leye(左眼)
lbrow(左眉)
rbrow(右眉)
beard(胡须)
fitem(身前道具)
fhair(前发)
fbody(身体前部分)

这样,我们最后规范的美术的绘制方法也是按照各个层绘制,然后逐步拆出来,最后组合微调。我们规定了面部、五官、脖子等中心位置范围,根据每一个部位设置偏移(包括横向和纵向)、旋转的锚点。

部分拆出素材示例:






技术规范:

捏脸部分的素材涉及大量的2D资源贴图,那么如何存储是一个问题。在Unity等游戏引擎中,我们需要综合考虑的存储和运行时加载的效率。

从存储和内存加载的角度来说,2的次幂正方形纹理是效率最高的。同时由于我们美术规范上分了如此多的层,加载的时候如何dynamic batch也是一个问题。如何划分图集,如何加载,成为了一个需要取舍的点。

我最终的方案是,分三类资源打包:

1、最大的部分(主要是角色的身体)单独一张图一个文件,存成2的次幂文件,统一放在一个 assetbundle里,运行时按需加载,延迟释放(比如切场景时释放所有临时缓存的该类纹理资源)。

2、较大的部分(占面积较大的头发、物品),根据类型使用TexturePacker打包图集,放在assetbundle里,运行时按需加载,延迟释放


3、最小的部分(脸部、眼睛、鼻子、眉毛等),使用TexturePacker统一打一个图集(为了降低drawcall,动态合批),启动游戏时直接加载常驻内存。


配置约束语法

这里再提供我们的整体捏脸配置的数据结构供大家参考一下

这里template "C"是我们所有的男性捏脸

avata_template节点下

partnumber标志的是各个部位对应的资源数量

canhide是指该部位是否可以被隐藏

pivots是各个部位对应的偏移/旋转的锚点

adjusts是对应我们构图各个部位的像素微调配置

底下的子节点

bind 是指某个项在某些条件下是否可以被使用

bhair是指在某个发型(index)能够使用的后发编号(这里是根据实际美术资源是否协调进行配置的)

<avata_template name="C" w="512" h="512" atlas="2"
partnumber="40 30 37 34 30 34 33 19 0 30"
canhide="0 0 0 0 0 0 0 0 1 1"
bindmode="0 0 0 0 0 0 0 0 1 1"
pivots="0.5 0.57 0.54 0.64 0.47 0.64 0.54 0.64 0.46 0.64 0.5 0.59"
adjusts="6 5 5 5 25 25 12 5 15 15 0.2 5 0.3 3 5 0.2 10 10"
>
<bind part="fitem" index="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21" condition=""/>

<bhair index="1" support="3 4 6 9 10 12 16 17 19 21 22 23 25 26 27"/>
<bhair index="2" support="2 4 5 10 13 16 17 21 22 23 27"/>
<bhair index="3" support="3 9 17 18"/>
<bhair index="4" support="3 4 6 9 10 12 13 16 17 18 19 21 22 23 25 26"/>
<bhair index="5" support="4 5 9 10 12 13 16 18 19 21 22 23 25"/>
<bhair index="6" support="1 3 4 6 9 10 12 16 17 18 19 21 22 23 25 26"/>
<bhair index="7" support="7 13 18 21"/>
<bhair index="8" support="8 13 17 18 27"/>
<bhair index="9" support="1 2 3 4 5 6 7 9 10 13 16 17 18 19 21 22 23 25 26 27"/>
<bhair index="10" support="1 4 9 10 12 13 16 17 18 19 21 22 23 25 26"/>
<bhair index="11" support="5 9 13 17 18"/>
<bhair index="12" support="1 9 10 12 13 16 17 18 19 21 22 23 25 26"/>
<bhair index="13" support="5 10 13 18 21 27"/>
<bhair index="15" support="13 15 18 21"/>
<bhair index="16" support="5 10 12 13 16 19 21 22 23 25 27"/>
<bhair index="17" support="1 3 4 6 9 10 12 13 16 17 18 19 21 22 23 25 26 27"/>
<bhair index="18" support="3 8 9 17 18 21 27"/>
<bhair index="19" support="1 4 5 6 7 9 10 12 13 16 17 18 19 21 22 23 25 26 27"/>
<bhair index="20" support="18 19 20"/>
<bhair index="21" support="3 6 13 17 18 21"/>
<bhair index="22" support="2 3 4 6 9 10 12 13 16 17 18 19 21 22 23 25 26"/>
<bhair index="23" support="1 3 4 6 9 10 12 13 16 17 18 19 21 22 23 25 26 27"/>
<bhair index="24" support="5 9 10 13 17 18 21 25 27"/>
<bhair index="25" support="1 4 5 7 9 10 12 13 16 17 18 19 21 22 23 25 27"/>
<bhair index="26" support="1 4 5 6 9 10 12 13 16 17 18 19 21 22 23 25 26"/>
<bhair index="27" support="1 3 5 13 18 21 27"/>
<bhair index="28" support="21 22 23 25 28"/>
<bhair index="29" support="2 5 13 18 21 27 29"/>
<bhair index="30" support="2 5 13 18 21 27 29 30"/>
</avata_template>

另外我们还做了一些肤色变化、衣服变色的方案,是使用的unity中的颜色混合和调色板,这里就不细说了。

结语

最终我们出的效果还不错,也在标准制定好以后,通过美术外包的小伙伴迅速拓展了内容量。以下是一些有才玩家的捏脸,供大家娱乐娱乐~














更多的玩家捏脸可以看这篇taptap的玩家贴

https://www.taptap.com/topic/424730

想自己捏个脸或者体验一下的话,不妨来试试我们游戏吧!

https://jhx2.hanjiasongshu.com/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336