• 用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);
    3. 我们看到as3的代码和C#基本改动不大,几乎直接拷贝复制再改改即可。关注最后两行:我们在包外代码中激活了UIPanel,并挂载了脚本中定义的FilterMain类。
    4. 点击编译。
    5. 在unity中点击播放。我们看到脚本已成功生效。
  • 相关阅读:
    学习笔记
    聊聊字节序
    SPDK发送和接收连接请求的处理
    企业设备维护——不仅仅是解决问题
    怎样快速找到某一行代码的git提交记录
    生产环境中利用软链接避免"rm -rf /"的方法
    程序员五年小结
    Django Model 数据库增删改查
    python中字符串列表字典常用方法
    python编辑配置
  • 原文地址:https://www.cnblogs.com/ashei/p/9020702.html
Copyright © 2020-2023  润新知