將進(jìn)酒
君不見,黃河之水天上來周荐,奔流到海不復(fù)回付呕。
君不見,高堂明鏡悲白發(fā)豌鹤,朝如青絲暮成雪。
人生得意須盡歡枝缔,莫使金樽空對月布疙。
天生我材必有用,千金散盡還復(fù)來愿卸。
烹羊宰牛且為樂灵临,會須一飲三百杯。
岑夫子擦酌,丹丘生俱诸,將進(jìn)酒,杯莫停赊舶。
與君歌一曲睁搭,請君為我傾耳聽。
鐘鼓饌玉不足貴笼平,但愿長醉不復(fù)醒园骆。
古來圣賢皆寂寞,惟有飲者留其名寓调。
陳王昔時(shí)宴平樂锌唾,斗酒十千恣歡謔。
主人何為言少錢夺英,徑須沽取對君酌晌涕。
五花馬,千金裘痛悯,呼兒將出換美酒余黎,與爾同銷萬古愁。
本文首發(fā)于Lohanry's Blog,轉(zhuǎn)載請注明载萌。
什么是Live2D
- Live2D是日本Cybernoids公司開發(fā)惧财。
- Live2D現(xiàn)階段有兩個(gè)主要的版本是2.1的版本和3.0的版本。
- 國內(nèi)2.1版本用的比較多(ps.此為自己的感覺扭仁,并沒有數(shù)據(jù)支持垮衷,只是感覺國內(nèi)討論的比較多的就是2.1了)。
- 大家可以到官網(wǎng)去下載2.1版本乖坠,由于3.0版本的無法支持當(dāng)前項(xiàng)目的Unity版本搀突,所以暫時(shí)沒有使用。
Unity中的Live2D
Live2D已經(jīng)增加的了對Unity的支持熊泵,所以只需要將SDK下載下來后倒入就可以使用了描姚,里面也有幾個(gè)簡單的例子可以直接跑涩赢。
本文討論的是Unity中使用Live2D,對Live2D的制作不做任何討論轩勘。
我們可以從Live2D導(dǎo)出的文件中看到如下標(biāo)準(zhǔn)格式:
- model.1024文件夾中放的是人物的模型貼圖筒扒,由于多貼圖導(dǎo)致DrawCall升高的,所以在游戲中盡量只使用一張貼圖绊寻。
- motions文件夾是所有的動作文件.mtn
- expressions文件夾是所有表情動作.mtn
- model.moc是Live2D的模型文件
- physics是物理演算文件
- pose.json 可以用于動態(tài)的切換部件以實(shí)現(xiàn)特定需求
Live2D的Model.json文件
這里主要講解下model.json這個(gè)文件
{
"version":"Sample 1.0.0",
"model":"model.moc",
"textures":[
"model.1024/texture_00.png"
],
"motions":{
"idle":[
{"file":"motions/idle_01.mtn"}
],
"":[
{"file":"motions/x1.mtn"}
]
},
"physics":"physics.json",
"hit_areas":[
{"name":"face","id":"D_REF.FACE"},
{"name":"body","id":"D_REF.BODY"},
{"name":"arm_l","id":"D_REF.ARM_L"}
]
}
事實(shí)上這個(gè)Json文件都可以不存在的花墩,只要你手工調(diào)用方法加載上MOC文件和貼圖文件,Live2D的基本就已經(jīng)顯示出來了澄步。
但是我這邊使用了model.json是因?yàn)榉奖阗Y源的統(tǒng)一管理冰蘑,方便可以看出來一個(gè)L2D模型中有多少資源包含。
在代碼中雖然可以直接進(jìn)行加載村缸,但是我們更加希望有一份json作為引導(dǎo)文件告訴我們祠肥,現(xiàn)在需要加載哪些資源,然后引用哪些資源梯皿,以方便調(diào)用仇箱。
在游戲中中我們參考了SDK其中包含的Live2D的Demo,加載框架作為基礎(chǔ)东羹,然后修改剂桥,做出項(xiàng)目能用的框架。
此Model.json的key-value值參考的是Demo中的框架属提,大家閑得蛋疼可以搞一套屬于自己的权逗,但是也可以直接使用已經(jīng)存在的。
Unity中Live2D的問題
在Unity中使用Live2D需要注意許多問題冤议,我在使用中也踩到了很多坑斟薇,雖然現(xiàn)在是有給出了解決的方案,但是這些有可能都不是最終最好的解決方案恕酸,希望大家能幫我指出奔垦。
1.Live2D的RenderMode。
可能很多人一開始使用的時(shí)候都沒有注意到這個(gè)參數(shù)的設(shè)置尸疆,默認(rèn)是L2D_RENDER_DRAW_MESH_NOW。
這個(gè)參數(shù)有兩個(gè)變量L2D_RENDER_DRAW_MESH_NOW和L2D_RENDER_DRAW_MESH惶岭。
主要區(qū)分為L2D_RENDER_DRAW_MESH_NOW是在OnRenderObject時(shí)候調(diào)用Draw()函數(shù)寿弱。
在OnRenderObject中調(diào)用Draw()會造成其Live2D一直處于最后渲染,而不會被其他物體而覆蓋按灶。
而L2D_RENDER_DRAW_MESH是在Update()中調(diào)用Draw()函數(shù)症革,可以進(jìn)行半透明物體的渲染。
2.Live2D中圖形層級的問題
在Unity中使用L2DSDK2.1時(shí)候鸯旁,你會發(fā)現(xiàn)一個(gè)很痛苦的問題噪矛,他沒辦法改變圖層量蕊。
本人在Ugui與Live2D結(jié)合中現(xiàn)在已經(jīng)使用過這幾個(gè)方案:
- 采用Unity的RT技術(shù)。
- 采用專門的一個(gè)攝像機(jī)進(jìn)行拍攝艇挨,然后渲染到UI上残炮。
- 實(shí)際使用時(shí)候需要進(jìn)行矩陣的換算。
- 而且比較吃性能和內(nèi)存缩滨,沒有特別比必要就沒有使用势就。
- 采用sortorder進(jìn)行層級控制。
- 調(diào)整其他非Live2D的UI的sortorder脉漏。
- Ugui中可以使用sortorder來指定渲染層級苞冯。
- 但是由于項(xiàng)目一開始并沒有考慮到會有l(wèi)ive2D,所以Layer的定義都在同一個(gè)Deaflut中侧巨。
- 我猜測L2d在渲染時(shí)候是全部渲染到了order為0的層上了舅锄。
- 所以假設(shè)情況允許可以考慮將需要分層的下層物體的order分別設(shè)置為負(fù)數(shù),需要在上層的物體的order設(shè)置為正數(shù)可以解決圖層分層的問題司忱。
- 使用L2D_RENDER_DRAW_MESH_NOW直接疊加皇忿。
- 如果兩個(gè)Live2D模型需要疊加的話推薦使用L2D_RENDER_DRAW_MESH_NOW。
- 那有人會說那這樣誰會渲染在誰上面烘贴?
- 經(jīng)過測試這樣的情況下禁添,誰后實(shí)例化誰會最后進(jìn)行渲染。
- 所以如果采用此方案進(jìn)行最好自己創(chuàng)建一個(gè)Live2D生成隊(duì)列進(jìn)行管理桨踪。來維護(hù)渲染順序老翘。
- 使用L2D_RENDER_DRAW_MESH進(jìn)行疊加。
- 假設(shè)遇到了情況是兩個(gè)Live2D疊加而且需要使用L2D_RENDER_DRAW_MESH作為渲染模式時(shí)候锻离。
- 兩個(gè)Live2D的疊加順序符合場景中的排序铺峭。
- 但是要注意的是在某些情況下會出現(xiàn)兩個(gè)Live2D的部分部件相互穿透的問題。
- 這個(gè)問題的出現(xiàn)我猜測是在Live2D制作中圖層的穿透問題汽纠。
- 但是在某些情況下并沒有復(fù)現(xiàn)卫键,而且美術(shù)最近比較忙,沒有來得及詳細(xì)測試找出原因虱朵。
- 使用RenderQueue莉炉。
- 如果你的方案是Unity+NGUI+Live2D,可以考慮使用RenderQueue來進(jìn)行排序碴犬。
- 在Live2D自帶的Shader中為3000絮宁,你可以根據(jù)層級來設(shè)置你自己的UI的RenderQueue,同樣他不支持設(shè)置Live2D的RenderQueue服协。
- 同時(shí)即使采用UGUI也可以使用RnederQueue绍昂,比如疊加粒子時(shí)候。
Live2D動作管理
- 在Live2D中動作的文件均是以mtn后綴的文件
- 在model.json中可以使用motions這個(gè)字典來管理
- 通過key來管理多個(gè)不同種類的動作文件。
Live2D代碼解析(以Demo中SampleApp1這個(gè)項(xiàng)目作為例子):
1.資源加載入口函數(shù)
LAppModel.LoadFromResource(String dir,String filename);
2.Model.Init函數(shù)(修改支持DrawMode切換)
public void Init(String modelJson,int DrawMode)
{
updating = true;
initialized = false;
modelSetting = new ModelSettingJson(modelJson);
if (LAppDefine.DEBUG_LOG) Debug.Log("Start to load model");
// Live2D Model
if (modelSetting.GetModelFile() != null)
{
loadModelData(modelHomeDir + modelSetting.GetModelFile());
//setRenderMode必須要在加載Moc文件后窘游,加載貼圖前唠椭。
GetLive2DModelUnity().setRenderMode(DrawMode);
var len = modelSetting.GetTextureNum();
for (int i = 0; i < len; i++)
{
loadTexture(i, modelHomeDir + modelSetting.GetTextureFile(i));
}
}
}
3.Model.Json 解析引導(dǎo)
//事實(shí)上所有的動作等資源均是類似管理,如果需要提高性能可以單獨(dú)實(shí)現(xiàn)數(shù)組
//通過ModelSettingJson來解析model.json
modelSetting = new ModelSettingJson(modelJson);
//通過函數(shù)跟蹤可以發(fā)現(xiàn)其實(shí)是直接返回json而已
len = modelSetting.GetTextureNum();
4.動作播放
游戲中動作被分為:
- 待機(jī)動作忍饰,
- 特殊待機(jī)動作贪嫂,
- 觸摸事件動作,
- 震動事件動作喘批。
除了待機(jī)動作撩荣,所有動作均可以相互交換。
特殊待機(jī)動作饶深,觸摸動作餐曹,震動動作,被維護(hù)成一個(gè)字典敌厘,有唯一索引台猴,進(jìn)行調(diào)用。
//此方法已經(jīng)是被我修改過的方法俱两,原始方法可以在例子中找到饱狂,原始方法是支持以索引號去播放,我修改為可以根據(jù)name播放宪彩,大家可以根據(jù)代碼自行修改一下比較簡單休讳。
LAppModel.StartMotion(string group,string motionName,int priority);
Live2D表情管理
- 游戲中沒有太多的使用表情,所以也不展開討論尿孔。
- 標(biāo)簽文件為json格式俊柔。
- 使用方法與動作類似 。
- 表情使用時(shí)候要注意覆蓋的問題活合。
LAppModel.SetExpression(string name);
Live2D口型管理
在Live2D的動畫播放時(shí)候有時(shí)候希望能使語音與嘴型對上可以有如下幾個(gè)方法:
-
通過控制PARAM_MOUTH_OPEN_Y雏婶。
- 使用系統(tǒng)級API獲得當(dāng)前的設(shè)備的播放音量
- 量化到0-1之間去
- 然后設(shè)置PARAM_MOUTH_OPEN_Y來控制最新的張口。
-
使用單獨(dú)mtn嘴型文件
- 單獨(dú)做出關(guān)于嘴型參數(shù)的mtn動作
- 創(chuàng)建不同的MotionQueueManager來管理嘴型和一般動畫
- 需要同時(shí)播放才可以對上白指。
Live2D的Pose文件
- 我們可以在游戲中使用Pose.json文件來實(shí)現(xiàn)某些特性
- 其實(shí)主體的方法就是切換部件來實(shí)現(xiàn)某些特性留晚。
- 在需要的時(shí)候會讀取Pose.json文件然后加載上需要的組件
LAppModel.loadPose(String path);
- 然后大家會發(fā)現(xiàn)自從切換上Pose文件后就不管樣都無法恢復(fù)到一開始的樣子了。
- 后來通過測試發(fā)現(xiàn)通過重新初始化來恢復(fù)告嘲。代碼如下:
//非常簡單错维,pose變量是L2DPose類型,是LAppModel上的變量橄唬。
//live2DModel就是當(dāng)前的ALive2DModel赋焕。
//這樣就可以恢復(fù)到加載pose文件之前的。
pose.initParam(live2DModel);
Live2D觸摸事件的管理
- 在游戲中Live2D觸摸事件在每個(gè)場景中是不一樣的轧坎,為了提高整個(gè)組件的復(fù)用。
- 組件中的觸摸事件是一個(gè)事件鏈
- 在不同場景中的控制器可以使用委托來事件觸摸事件的反應(yīng)泽示,而且在做出反應(yīng)后可以通過函數(shù)的返回值來確定下一級時(shí)候繼續(xù)要處理整個(gè)事件缸血,增加了這個(gè)的靈活性蜜氨。
寫在尾巴上的
- 事實(shí)上Live2D的更多功能還并沒有完全的被探索使用出來,
- 本文由于本人自己的能力有限只是簡單探索捎泻,作為拋磚引玉作用飒炎。
- 國內(nèi)資料暫時(shí)還比較缺少,本人斗膽分享了出來笆豁,希望各位大牛不要恥笑郎汪。
最后做個(gè)小廣告~
喜歡的可以轉(zhuǎn)載下我的小文章
Blog:http://www.hailantown.com