live2D是一个很强大的2D动画组件。我们可以使用AS3脚本对它进行热更新。

live2D在Unity中的使用请看这里

如何获取Live2D

总得来说,我们可以先去live2D官网下载它的Unity SDK,然后即可在Unity中使用。我们这里使用的是live2d 2.1版。

我们的目标是把 Live2D_SDK_Unity_2.1.02_1_jp\sample\Demo\ 这个unity示例工程改造成as3热更新版本。

准备热更新工程

首先您要先创建一个空白的Unity工程。然后将下载好的Live2D SDK目录中,上面提到的Live2D_SDK_Unity_2.1.02_1_jp\sample\Demo\下的所有文件拖拽到Unity项目里。

然后使用ActionScript3热更新脚本系统将Live2D 的API导出给AS3脚本备用。如果您不了解这个热更新脚本,请看这里的链接和之前的系列教程

  • 现在将AS3 热更脚本的Unity插件导入Unity工程。
  • 从菜单创建ActionScript3热更新工程。
  • 由于live2D的类库并非代码提供,而是以dll形式提供,因此我们需要在ActionScript3项目中配置将这个dll也导出到API。打开热更新工程的genapi.config.xml文件,将Live2DUnity.dll加入到配置文件中:
<!--Configure DLLs to export-->
<buildassemblys> <assembly value="D:\Program Files\Unity\Editor\Data\Mono\lib\mono\2.0\System.dll"></assembly>
<assembly value="D:\Program Files\Unity\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll"></assembly>
<assembly value="D:\Program Files\Unity\Editor\Data\UnityExtensions\Unity\GUISystem\UnityEngine.UI.dll"></assembly>
<assembly value="F:\UnityAS3\Live2DDemo\Library\ScriptAssemblies\Assembly-CSharp.dll"></assembly>
<assembly value="F:\UnityAS3\Live2DDemo\Assets\Live2D\Live2DUnity.dll"></assembly> </buildassemblys>
  • live2D的特殊之处:live2D的Demo中,角色的绘制是通过 MonoBehaviour 的 OnRenderObject 方法被调用时绘制的。OnRenderObject默认不会在脚本中使用,因此我们需要在Unity工程中创建一个类代理一下。 我们在主工程中创建如下代码:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    namespace Live2DUtil
    {
    public class Live2DBehaviour : MonoBehaviour
    { // Use this for initialization
    public virtual void Start()
    { } // Update is called once per frame
    public virtual void Update()
    { } public virtual void OnRenderObject()
    { }
    }
    }

    Live2DBehaviour

  • 执行CreateUnityAPI.bat,导出API代码。
  • 新建一个场景。然后将 Assets/ASRuntimePlayer/下的AS3Player和AS3StartupProgress 两个预设添加到场景中。操作完成后界面应该是这样
  • 点击AS3Player,将文档类设置为Live2DDemo。
  • 将摄像机的参数设置为如下参数:
  • 现在可以在ActionScript3热更工程中写代码了。在as3工程中新建类Live2DDemo.as。
  • 然后将如下代码写入as3热更脚本。然后编译执行,我们就能用热更新脚本创建live2d动画角色,并且还能和鼠标互动。
    package
    {
    /**
    * ...
    * @author ...
    */
    public class Live2DDemo
    { public function Live2DDemo()
    { } } }
    import live2d.EyeBlinkMotion;
    import live2d.Live2D;
    import live2d.Live2DModelUnity;
    import live2d.UtSystem;
    import live2d.framework.L2DPhysics;
    import live2d.framework.L2DTargetPoint;
    import live2dutil.Live2DBehaviour;
    import unityengine.Camera;
    import unityengine.GameObject;
    import unityengine.Input;
    import unityengine.Matrix4x4;
    import unityengine.MonoBehaviour;
    import unityengine.Resources;
    import unityengine.Screen;
    import unityengine.TextAsset;
    import unityengine.Texture2D; var lmodel:GameObject = new GameObject("as3live2dmodel"); class SimpleModel extends Live2DBehaviour
    {
    var mocFile:TextAsset;
    var physicsFile:TextAsset; var live2DModel:Live2DModelUnity;
    var eyeBlink:EyeBlinkMotion = new EyeBlinkMotion();
    var dragMgr:L2DTargetPoint = new L2DTargetPoint();
    var physics:L2DPhysics;
    var live2DCanvasPos:Matrix4x4; override public function start():void
    {
    Live2D.init();
    load();
    } function load():void
    {
    mocFile = Resources.load("haru.moc") as TextAsset;
    physicsFile = Resources.load("haru.physics.json") as TextAsset;
    live2DModel = Live2DModelUnity.loadModel__(mocFile.bytes); live2DModel.setTexture(0,Resources.load_("haru.1024/texture_00", Texture2D) as Texture2D);
    live2DModel.setTexture(1,Resources.load_("haru.1024/texture_01", Texture2D) as Texture2D);
    live2DModel.setTexture(2,Resources.load_("haru.1024/texture_02", Texture2D) as Texture2D); var modelWidth:Number = live2DModel.getCanvasWidth();
    live2DCanvasPos = Matrix4x4.ortho(0, modelWidth, modelWidth, 0, -50.0, 50.0); if (physicsFile != null) physics = L2DPhysics.load(physicsFile.bytes); trace("loaded");
    } override public function update():void
    {
    if (live2DModel == null) return;
    live2DModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos); var pos = Input.mousePosition;
    //if (Input.getMouseButtonDown(0))
    //{
    ////
    //}
    //else
    if (Input.getMouseButton(0))
    {
    dragMgr.set(pos.x / Screen.width * 2 - 1, pos.y / Screen.height * 2 - 1);
    }
    //else if (Input.GetMouseButtonUp(0))
    //{
    //dragMgr.Set(0, 0);
    //} dragMgr.update();
    live2DModel.setParamFloat("PARAM_ANGLE_X", dragMgr.getX() * 30);
    live2DModel.setParamFloat("PARAM_ANGLE_Y", dragMgr.getY() * 30); live2DModel.setParamFloat("PARAM_BODY_ANGLE_X", dragMgr.getX() * 10); live2DModel.setParamFloat("PARAM_EYE_BALL_X", -dragMgr.getX());
    live2DModel.setParamFloat("PARAM_EYE_BALL_Y", -dragMgr.getY()); var timeSec:Number = Number( UtSystem.getUserTimeMSec()) / 1000.0;
    var t:Number = timeSec * 2 * Math.PI;
    live2DModel.setParamFloat("PARAM_BREATH", (0.5 + 0.5 * Math.sin(t / 3.0))); eyeBlink.setParam(live2DModel); if (physics != null) physics.updateParam(live2DModel); live2DModel.update(); } override public function onRenderObject():void
    {
    if (live2DModel == null)
    return;
    if (live2DModel.getRenderMode() == Live2D.L2D_RENDER_DRAW_MESH_NOW)
    live2DModel.draw(); } } lmodel.addComponent(SimpleModel);

    Live2DDemo

    其中我们可以看到,绝大多数代码都可以直接照着Demo的C#代码照搬即可。
    我们在脚本中使用的SimpleModel 继承自 之前C#工程里创建的Live2DBehaviour,它提供了onRenderObject方法,我们直接在脚本中override此方法即可。
    最终效果如下:

用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 热更新Live2D的更多相关文章

  1. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新

    unity热更新是一个经久不衰的话题.除了最常见的lua之外,还有如JSBinding,C#等等.这里介绍一个使用ECMAScript4进行热更新的方案.它吸收了各家的优点,特色很鲜明. 项目地址: ...

  2. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用原型链和EventTrigger

    原型链是JS的必备,作为ECMAScript4,原型链也是支持的. 特别说明,ActionScript3是支持完整的面向对象继承支持的,原型链只在某些非常特殊的情况下使用. 本文旨在介绍如何使用原型链 ...

  3. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- Demo分析

    如何创建工程 下载最新的Unity发布插件包. 打开Unity,新建一个项目 将插件包导入 在菜单中点击ASRuntime/Create ActionScript3 FlashDevelop HotF ...

  4. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用第三方组件

    Unity开发中,常常会用到一些第三方组件.本文以实例介绍如何在热更新脚本中使用这些第三方组件. 首先说明几个基本步骤: 第三方组件通常是以dll或者源码方式提供的,它们本身往往无法热更. 我们在脚本 ...

  5. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- CustomYieldInstruction 自定义中断指令

    ActionScript3脚本引擎为了方便热更新逻辑开发,提供的从脚本继承Unity类库功能在一些情况下可以提供开发的便利. 这次来建立一个示例,演示一下如何在脚本中自定义协程中断指令 Unity中的 ...

  6. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用FairyGUI (一)

    我们的热更新脚本在实际使用中,当然也要支持常用的第三方组件,例如这里介绍一个非常实用的第三方UI库:FairyGUI. 什么是FairyGUI 这里照搬FaiyGUI官网的介绍: 重新定义 UI 制作 ...

  7. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用FairyGUI (二)

    上次讲解了FairyGUI的最简单的热更新办法,并对其中一个Demo进行了修改并做成了热更新的方式. 这次我们来一个更加复杂一些的情况:Emoji. FairyGUI的   Example 04 - ...

  8. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 在脚本中使用MonoBehaviour

    继上次分析了热更新的Demo后,这次来介绍如何在热更新代码中使用MonoBehaviour. MonoBehaviour挂载到GameObject对象上的脚本的基类.平常Unity开发时,简单的做法就 ...

  9. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 操作符重载和隐式类型转换

    C#中,某些类型会定义隐式类型转换和操作符重载.Unity中,有些对象也定义了隐式类型转换和操作符重载.典型情况有:UnityEngine.Object.UnityEngine.Object的销毁是调 ...

随机推荐

  1. Python自动化开发 - 常用模块(二)

    本节内容 1.shutil模块 2.shelve模块 3.xml处理模块 4.configparser模块 5.hashlib模块 6.subprocess模块 7.re模块 一.shutil模块 高 ...

  2. 工作随笔——elasticsearch数据冷热分离、数据冷备

    概述: 适合日志类型的数据存储方案.即当日数据写入,历史数据只读. 节省部分硬件成本.热数据采用更好的硬件. 环境: 已有6个ES节点,使用docker-compose方式搭建. es1:master ...

  3. JS原生事件处理(跨浏览器)

    一.关于获取事件对象 FF有点倔强,只支持arguments[0],不支持window.event.这次真的不怪IE,虽然把event作为window的属性不合规范,但大家都已经默许这个小问题存在了, ...

  4. 【转载】uwp 获取系统字体库

    效果图: 要获取到字体库首先要在 NuGet 添加 SharpDx.Direct2D1  api: /// <summary> /// 获取系统字体库列表 /// </summary ...

  5. Win10 安装 digits

    安装caffe配置python接口 接下来就按照官方教程来安装了... 1. If the installation process complains compiler not found, you ...

  6. Xamarin中 ios 修改Assets.xcassets 文件后 无法调试和编译

    根本问题是因为 vs项目里面 没有包含 如果提示找不到对应png 请检查 iOS 项目卸载后 编辑 并找到对应文件检查 <ImageAsset Include="Assets.xcas ...

  7. 课程一(Neural Networks and Deep Learning),第三周(Shallow neural networks)—— 0、学习目标

    Learn to build a neural network with one hidden layer, using forward propagation and backpropagation ...

  8. 集成学习算法总结----Boosting和Bagging

    1.集成学习概述 1.1 集成学习概述 集成学习在机器学习算法中具有较高的准去率,不足之处就是模型的训练过程可能比较复杂,效率不是很高.目前接触较多的集成学习主要有2种:基于Boosting的和基于B ...

  9. Proxy代理模式(结构型模式)

    1.问题 在面向对象系统中,有些对象由于某种原因(比如创建对象的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给调用者带来麻烦,那么如何在不损失接口透明性的情况下,解决这些麻 ...

  10. Postman入门