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此方法即可。
    最终效果如下:

 

posted @ 2018-12-07 17:19 烙馅饼喽 阅读(780) 评论(0) 推荐(0) 编辑
摘要: 上次讲解了FairyGUI的最简单的热更新办法,并对其中一个Demo进行了修改并做成了热更新的方式。 这次我们来一个更加复杂一些的情况:Emoji. FairyGUI的 Example 04 - Emoji 场景是一个聊天对话框。玩家可以输入文本和表情,对面的机器人还会回复一句话。回复的对话中还附带 阅读全文
posted @ 2018-05-15 19:53 烙馅饼喽 阅读(905) 评论(0) 推荐(0) 编辑
摘要: 我们的热更新脚本在实际使用中,当然也要支持常用的第三方组件,例如这里介绍一个非常实用的第三方UI库:FairyGUI. 什么是FairyGUI 这里照搬FaiyGUI官网的介绍: 重新定义 UI 制作流程,全可视化,零代码,是一款同时适用于程序员、设计师和游戏策划的UI制作工具。 配合FairyGU 阅读全文
posted @ 2018-05-10 18:15 烙馅饼喽 阅读(621) 评论(0) 推荐(0) 编辑
摘要: ActionScript3脚本引擎为了方便热更新逻辑开发,提供的从脚本继承Unity类库功能在一些情况下可以提供开发的便利。 这次来建立一个示例,演示一下如何在脚本中自定义协程中断指令 Unity中的协程 unity中协程经常被用到,从本质上来讲,当调用startCoroutine时,传入的参数是一 阅读全文
posted @ 2018-04-28 13:52 烙馅饼喽 阅读(416) 评论(0) 推荐(1) 编辑
摘要: Unity开发中,常常会用到一些第三方组件。本文以实例介绍如何在热更新脚本中使用这些第三方组件。 首先说明几个基本步骤: 本文以DOTween为例,说明如何在工程中使用DOTween。 最后有些地方需要说明:DoTween这个项目使用了大量的扩展方法。但是ActionScript3脚本是不能直接支持 阅读全文
posted @ 2018-04-24 18:05 烙馅饼喽 阅读(422) 评论(0) 推荐(0) 编辑
摘要: C#中,某些类型会定义隐式类型转换和操作符重载。Unity中,有些对象也定义了隐式类型转换和操作符重载。典型情况有:UnityEngine.Object。UnityEngine.Object的销毁是调用 Destory。被调用过Destory的对象,并不是真的变成null了,但是再对它操作会导致异常 阅读全文
posted @ 2018-04-23 10:48 烙馅饼喽 阅读(400) 评论(4) 推荐(0) 编辑
摘要: 原型链是JS的必备,作为ECMAScript4,原型链也是支持的。 特别说明,ActionScript3是支持完整的面向对象继承支持的,原型链只在某些非常特殊的情况下使用。 本文旨在介绍如何使用原型链。 任意对象类型都有一个prototype属性,包括导入的Unity的API也有。我们可以和JS一样 阅读全文
posted @ 2018-04-20 14:57 烙馅饼喽 阅读(460) 评论(0) 推荐(0) 编辑
摘要: 继上次分析了热更新的Demo后,这次来介绍如何在热更新代码中使用MonoBehaviour。 MonoBehaviour挂载到GameObject对象上的脚本的基类。平常Unity开发时,简单的做法就是编写一个继承自MonoBehaviour的脚本,将它挂载到要操纵的GameObject上,赋予它各 阅读全文
posted @ 2018-04-19 14:14 烙馅饼喽 阅读(555) 评论(0) 推荐(0) 编辑
摘要: 如何创建工程 Demo详解 这个Demo场景提供了一些元素,可以概览热更项目的执行流程。 Unity工程部分 AS3Player 一个GameObject。它挂载了ActionScriptStartUp.cs 脚本。这个脚本承载了初始化脚本引擎的所有功能。 Canvas 下的元素,是UGUI的界面组 阅读全文
posted @ 2018-04-18 14:32 烙馅饼喽 阅读(1076) 评论(0) 推荐(0) 编辑
摘要: unity热更新是一个经久不衰的话题。除了最常见的lua之外,还有如JSBinding,C#等等。这里介绍一个使用ECMAScript4进行热更新的方案。它吸收了各家的优点,特色很鲜明。 项目地址: https://github.com/asheigithub/apple-juice-actions 阅读全文
posted @ 2018-04-17 18:53 烙馅饼喽 阅读(1114) 评论(0) 推荐(1) 编辑
点击右上角即可分享
微信分享提示