unity优化Unity技术分享Unity技术分享

在Unity游戏中使用Live2D

2017-08-26  本文已影响2163人  一只胖胖的狼

将进酒
君不见,黄河之水天上来,奔流到海不复回。
君不见,高堂明镜悲白发,朝如青丝暮成雪。
人生得意须尽欢,莫使金樽空对月。
天生我材必有用,千金散尽还复来。
烹羊宰牛且为乐,会须一饮三百杯。
岑夫子,丹丘生,将进酒,杯莫停。
与君歌一曲,请君为我倾耳听。
钟鼓馔玉不足贵,但愿长醉不复醒。
古来圣贤皆寂寞,惟有饮者留其名。
陈王昔时宴平乐,斗酒十千恣欢谑。
主人何为言少钱,径须沽取对君酌。
五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。

本文首发于Lohanry's Blog,转载请注明。

什么是Live2D

Unity中的Live2D

Live2D已经增加的了对Unity的支持,所以只需要将SDK下载下来后倒入就可以使用了,里面也有几个简单的例子可以直接跑。

本文讨论的是Unity中使用Live2D,对Live2D的制作不做任何讨论。

我们可以从Live2D导出的文件中看到如下标准格式:

Live2D资源包Live2D资源包

Live2D的Model.json文件

这里主要讲解下model.json这个文件

{
    "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"}
    ]
}

事实上这个Json文件都可以不存在的,只要你手工调用方法加载上MOC文件和贴图文件,Live2D的基本就已经显示出来了。

但是我这边使用了model.json是因为方便资源的统一管理,方便可以看出来一个L2D模型中有多少资源包含。

在代码中虽然可以直接进行加载,但是我们更加希望有一份json作为引导文件告诉我们,现在需要加载哪些资源,然后引用哪些资源,以方便调用。

在游戏中中我们参考了SDK其中包含的Live2D的Demo,加载框架作为基础,然后修改,做出项目能用的框架。

此Model.json的key-value值参考的是Demo中的框架,大家闲得蛋疼可以搞一套属于自己的,但是也可以直接使用已经存在的。

Unity中Live2D的问题

在Unity中使用Live2D需要注意许多问题,我在使用中也踩到了很多坑,虽然现在是有给出了解决的方案,但是这些有可能都不是最终最好的解决方案,希望大家能帮我指出。

1.Live2D的RenderMode。

可能很多人一开始使用的时候都没有注意到这个参数的设置,默认是L2D_RENDER_DRAW_MESH_NOW。

这个参数有两个变量L2D_RENDER_DRAW_MESH_NOWL2D_RENDER_DRAW_MESH

主要区分为L2D_RENDER_DRAW_MESH_NOW是在OnRenderObject时候调用Draw()函数。

在OnRenderObject中调用Draw()会造成其Live2D一直处于最后渲染,而不会被其他物体而覆盖。

而L2D_RENDER_DRAW_MESH是在Update()中调用Draw()函数,可以进行半透明物体的渲染。

2.Live2D中图形层级的问题

在Unity中使用L2DSDK2.1时候,你会发现一个很痛苦的问题,他没办法改变图层。

本人在Ugui与Live2D结合中现在已经使用过这几个方案:

Live2D动作管理

Live2D代码解析(以Demo中SampleApp1这个项目作为例子):

1.资源加载入口函数

LAppModel.LoadFromResource(String dir,String filename);

2.Model.Init函数(修改支持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 解析引导

//事实上所有的动作等资源均是类似管理,如果需要提高性能可以单独实现数组
//通过ModelSettingJson来解析model.json
modelSetting = new ModelSettingJson(modelJson);
//通过函数跟踪可以发现其实是直接返回json而已
len = modelSetting.GetTextureNum();

4.动作播放

游戏中动作被分为:

除了待机动作,所有动作均可以相互交换。
特殊待机动作,触摸动作,震动动作,被维护成一个字典,有唯一索引,进行调用。

//此方法已经是被我修改过的方法,原始方法可以在例子中找到,原始方法是支持以索引号去播放,我修改为可以根据name播放,大家可以根据代码自行修改一下比较简单。
LAppModel.StartMotion(string group,string motionName,int priority);

Live2D表情管理

LAppModel.SetExpression(string name);

Live2D口型管理

在Live2D的动画播放时候有时候希望能使语音与嘴型对上可以有如下几个方法:

Live2D的Pose文件

LAppModel.loadPose(String path);
//非常简单,pose变量是L2DPose类型,是LAppModel上的变量。
//live2DModel就是当前的ALive2DModel。
//这样就可以恢复到加载pose文件之前的。
pose.initParam(live2DModel);

Live2D触摸事件的管理

写在尾巴上的

JokerJoker

最后做个小广告~
喜欢的可以转载下我的小文章
Blog:http://www.hailantown.com

上一篇 下一篇

猜你喜欢

热点阅读