专栏首页烙馅饼喽的技术分享用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 热更新Live2D

用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 热更新Live2D

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()
        {

        }
    }
}
  • 执行CreateUnityAPI.bat,导出API代码。
  • 新建一个场景。然后将 Assets/ASRuntimePlayer/下的AS3Player和AS3StartupProgress 两个预设添加到场景中。操作完成后界面应该是这样
  • 点击AS3Player,将文档类设置为Live2DDemo。
  • 将摄像机的参数设置为如下参数:
  • 现在可以在ActionScript3热更工程中写代码了。在as3工程中新建类Live2DDemo.as。
  • 然后将如下代码写入as3热更脚本。然后编译执行,我们就能用热更新脚本创建live2d动画角色,并且还能和鼠标互动。 其中我们可以看到,绝大多数代码都可以直接照着Demo的C#代码照搬即可。 我们在脚本中使用的SimpleModel 继承自 之前C#工程里创建的Live2DBehaviour,它提供了onRenderObject方法,我们直接在脚本中override此方法即可。 最终效果如下:
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);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Junit5系列-Junit5中assertThrows()与assertDoesNotThrow()方法详解

    Junit5中新添加了对方法抛出异常的断言Assertions类中的assertThrows()和assertDoesNotThrow(),使用此方法可以对被测...

    yoylee_web
  • RSS的发展历史简单回顾

        作者:田春峰     链接:http://blog.csdn.net/accesine960/archive/2005/03/05/312308.asp...

    田春峰-JCJC错别字检测
  • 微软新产品连接

    一些第三方工具 Yukon 的下载地址 SQL Server大型服务器:伸缩性、可用性与易管理性

    田春峰-JCJC错别字检测
  • Url排重Bloom Filter 算法、误差及其他

    fly with me , in the perfect world --- 题记

    田春峰-JCJC错别字检测
  • 米斯特白帽培训讲义(v2)实战篇 迅雷 CMS

    起因是这样,我们随便找了一个网站,访问后台登录页面(/admin/login.asp),然后使用弱密码admin:admin进了后台(/admin/index....

    ApacheCN_飞龙
  • 绕过JS写爬虫

          最近要把很多数据抓下来先存起来,现有历史数据再说。其中,东方财富网有许多数据,其中有一个是机构调研的数据。

    钱塘小甲子
  • GCD swift dispatch_set_target_queue 小例

    let  Queue1  = DispatchQueue(label:"Queue1")

    ZY_FlyWay
  • SharePoint如何配置Ipad跳转等问题

    Apple iPad 设备上不支持 SharePoint 标准视图。用户可以改用移动视图在 iPad 设备上查看 SharePoint 内容。默认情况下,iPa...

    雪雁-心莱科技
  • 2015-2018机器人操作系统(ROS)及其应用暑期学校资料汇总 ROS Summer School 持续更新

    2018年ROS暑期学校报名链接:http://www.huodongxing.com/go/ros2018

    zhangrelay

扫码关注云+社区

领取腾讯云代金券