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

我们的热更新脚本在实际使用中,当然也要支持常用的第三方组件,例如这里介绍一个非常实用的第三方UI库:FairyGUI.

什么是FairyGUI

这里照搬FaiyGUI官网的介绍:

重新定义 UI 制作流程,全可视化,零代码,是一款同时适用于程序员、设计师和游戏策划的UI制作工具。 配合FairyGUI-SDK,在各个游戏引擎都能得到高效的渲染表现,独特的FairyBatching技术可自动优化复杂界面的DC数量。

我们这里自然是使用它的Unity组件啦。

我们这篇文章的主旨并非是介绍如何使用FairyGUI制作界面,而是如果让FairyGUI制作的界面可以被我们的热更脚本驱动。

因此,这里我们可以先跳过FairyGUI的编辑器,直接下载它提供的Unity Demo,来进行热更新的改造演示。

在这里下载FairyGUI的Unity组件

导入FairyGUI

  1. 新建一个新的Unity工程。
  2. 将FairyGUI的package导入进来。
  3. 进入 Assets->FairyGUI->Examples->Scenes。这里展示了FairyGUI的全部Demo。

我们这一次先演示最简单的热更新处理,因此本次先选用一个不需要在脚本中继承和扩展FairyGUI的组件的例子。

我们选择Example 23,2D图像滤镜Demo。

准备热更新

  1. 首先我们将这个场景另存为F_Filter。
  2. 导入ActionScript3 虚拟机的unity插件包,并生成热更新项目。如果您不知道怎么操作,可以查看这里
  3. ActionScript3插件包已更新,请下载最新的插件包  v0.96f6 以及以后版本

场景分析:

  • 场景中的UIPanel物件,上面承载了UI界面。
  • UIPanel物件上有FilterMain.cs脚本,里面控制了UI的逻辑。
  • 现在我们尝试将此场景的逻辑改为通过ActionScript3脚本热更新。

操作步骤:

  1. 移除FilterMain.cs。我们将在ActionScript3中操作逻辑。
  2. UIPanel物件下的 UIPanel (Script)设置为禁用状态。我们将在AS3解释器初始化完成后,重新启用它。
  3. 进入Assets->ASRuntimePlayer,将 AS3Player预设和AS3StartupProgress预设拖到场景上。
  4. 将AS3Player物件下的Action Script Start Up 脚本组件的Document Class 设置为Filter。

现在我们将C#脚本的内容移植到ActionScript3脚本中。

原Demo在Start 方法中,将UI上的滑块事件添加了一个处理程序,然后在处理程序中更改UI元素的滤镜参数。见代码:

void Start()
    {
        _mainView = this.GetComponent<UIPanel>().ui;

        BlurFilter blurFilter = new BlurFilter();
        blurFilter.blurSize = 2;
        _mainView.GetChild("n21").filter = blurFilter;

        _s0 = _mainView.GetChild("s0").asSlider;
        _s1 = _mainView.GetChild("s1").asSlider;
        _s2 = _mainView.GetChild("s2").asSlider;
        _s3 = _mainView.GetChild("s3").asSlider;
        _s4 = _mainView.GetChild("s4").asSlider;

        _s0.value = 100;
        _s1.value = 100;
        _s2.value = 100;
        _s3.value = 200;
        _s4.value = 20;

        _s0.onChanged.Add(__sliderChanged);
        _s1.onChanged.Add(__sliderChanged);
        _s2.onChanged.Add(__sliderChanged);
        _s3.onChanged.Add(__sliderChanged);
        _s4.onChanged.Add(__sliderChanged);
    }

    void __sliderChanged(EventContext context)
    {
        int cnt = _mainView.numChildren;
        for (int i = 0; i < cnt; i++)
        {
            GObject obj = _mainView.GetChildAt(i);
            if (obj.filter is ColorFilter)
            {
                ColorFilter filter = (ColorFilter)obj.filter;
                filter.Reset();
                filter.AdjustBrightness((float)(_s0.value - 100) / 100f);
                filter.AdjustContrast((float)(_s1.value - 100) / 100f);
                filter.AdjustSaturation((float)(_s2.value - 100) / 100f);
                filter.AdjustHue((float)(_s3.value - 100) / 100f);
            }
            else if (obj.filter is BlurFilter)
            {
                BlurFilter filter = (BlurFilter)obj.filter;
                filter.blurSize = (float)_s4.value / 100;
            }
        }
    }

现在我们将这个逻辑脚本改写为ActionScript3热更新脚本:

  1. 打开热更新项目,新建Filter类。
  2.  将如下代码复制到Filter类中。
package 
{
    /**
     * ...
     * @author 
     */
    public class Filter 
    {
        
        public function Filter() 
        {
            
        }
        
    }

}

import fairygui.BlurFilter;
import fairygui.ColorFilter;
import fairygui.EventContext;
import fairygui.GComponent;
import fairygui.GObject;
import fairygui.GSlider;
import fairygui.Stage;
import fairygui.UIPackage;
import fairygui.UIPanel;
import unityengine.Application;
import unityengine.GameObject;
import unityengine.MonoBehaviour;
class FilterMain extends MonoBehaviour
{
    var _mainView:GComponent;
    var _s0:GSlider;
    var _s1:GSlider;
    var _s2:GSlider;
    var _s3:GSlider;
    var _s4:GSlider;

    function Awake()
    {
        Application.targetFrameRate = 60;
        
        UIPackage.addPackage______("UI/Filter");
    }

    function Start()
    {
        _mainView = UIPanel(this.getComponent(UIPanel)).ui;

        var blurFilter:BlurFilter= new BlurFilter();
        blurFilter.blurSize = 2;
        _mainView.getChild("n21").filter = blurFilter;

        _s0 = _mainView.getChild("s0").asSlider;
        _s1 = _mainView.getChild("s1").asSlider;
        _s2 = _mainView.getChild("s2").asSlider;
        _s3 = _mainView.getChild("s3").asSlider;
        _s4 = _mainView.getChild("s4").asSlider;

        _s0.value = 100;
        _s1.value = 100;
        _s2.value = 100;
        _s3.value = 200;
        _s4.value = 20;

        _s0.onChanged.add(__sliderChanged);
        _s1.onChanged.add(__sliderChanged);
        _s2.onChanged.add(__sliderChanged);
        _s3.onChanged.add(__sliderChanged);
        _s4.onChanged.add(__sliderChanged);
    }

    function __sliderChanged(context:EventContext):void
    {
        var cnt:int = _mainView.numChildren;
        for (var i:int = 0; i < cnt; i++)
        {
            var obj:GObject = _mainView.getChildAt(i);
            if (obj.filter is ColorFilter)
            {
                var filter1:ColorFilter= ColorFilter(obj.filter);
                filter1.reset();
                filter1.adjustBrightness((_s0.value - 100) / 100);
                filter1.adjustContrast((_s1.value - 100) / 100);
                filter1.adjustSaturation((_s2.value - 100) / 100);
                filter1.adjustHue((_s3.value - 100) / 100);
            }
            else if (obj.filter is BlurFilter)
            {
                var filter2:BlurFilter = BlurFilter(obj.filter);
                filter2.blurSize = _s4.value / 100;
            }
        }
    }

}


MonoBehaviour( GameObject.find("UIPanel").getComponent(UIPanel)).enabled = true;
GameObject.find("UIPanel").addComponent(FilterMain);
  1. 我们看到as3的代码和C#基本改动不大,几乎直接拷贝复制再改改即可。关注最后两行:我们在包外代码中激活了UIPanel,并挂载了脚本中定义的FilterMain类。
  2. 点击编译。
  3. 在unity中点击播放。我们看到脚本已成功生效。

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Danny的专栏

学习中遇到的小技巧 一(暂停更新)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

992
来自专栏吴柯的运维笔记

Linux下监控软件Zabbix安装部署教学

“每个理性的IT人士都置顶了吴柯的运维笔记” 1.部署LNMP环境 安装php Zabbix 3.0对PHP的要求最低为5.4,而CentOS6默认为5.3.3...

41513
来自专栏杨建荣的学习笔记

查看并行进程的一些简单信息(r3笔记第17天)

在使用并行的时候,总能看到进程中出现一些ora_p这样的进程。有时候查看问题的时候只看到并行进程在运行,却没有思路去查找倒底是哪些session在干些什么,下面...

2976
来自专栏Android相关

IjkPlayer起播速度优化

5582
来自专栏逸鹏说道

SQL Server 2017 安装过程中的一点说明(有点意思)

偶尔冒个泡吧 会提到:“安装程序无法与下载服务器联系。请提供 Microsoft 机器学习服务器安装文件的位置,然后单击“下一步”。可从以下位置下载安装文件” ...

4646
来自专栏烙馅饼喽的技术分享

IISExpress中文版的一个OOXX的问题,及其解决方法-_-

      刚看到有人说IIS7Express有下载,于是马上屁颠屁颠地跑去下载了一个,然后安装. 装完后发现,我擦,居然没有WIN7下的管理界面,汗一个,于是...

3507
来自专栏菩提树下的杨过

老生常谈:利用Membership实现SSO(单点登录)

虽然有一些现成的第三方解决方案比如:OpenID,Passport,SpaceCard等都还不错,但是要么就是收费的(passport),要么就是有点用不习惯(...

2005
来自专栏拂晓风起

cocos2d-js 调试办法 断点调试 Android真机调试

1692
来自专栏黑泽君的专栏

网络通信的三要素

5044
来自专栏北京马哥教育

超详细!使用 LVS 实现负载均衡原理及安装配置详解

负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群。常用的负载均衡开源软件有nginx、lvs、haproxy,商业的硬件负载均衡...

43110

扫码关注云+社区