热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

live2D是一个很强大的2D动画组件。我们可以使用AS3脚本对它进行热更新。live2D在Unity中的使用请看这里:如何获取Live2D总得来说,我们可以先去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加入到配置文件中:

  <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


推荐阅读
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • intellij idea的安装与使用(保姆级教程)
    intellijidea的安装与使用(保姆级教程)IntelliJ在业界被公认为最好的java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(gi ... [详细]
author-avatar
sasame
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有