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

用ECMAScript4(ActionScript3)实现Unity的热更新--使用原型链和EventTrigger

原型链是JS的必备,作为ECMAScript4,原型链也是支持的。特别说明,ActionScript3是支持完整的面向对象继承支持的,原型链只在某些非常特殊的情况下使用。本文旨在介绍如何使用原

原型链是JS的必备,作为ECMAScript4,原型链也是支持的。

特别说明,ActionScript3是支持完整的面向对象继承支持的,原型链只在某些非常特殊的情况下使用。

本文旨在介绍如何使用原型链。

任意对象类型都有一个prototype属性,包括导入的Unity的API也有。我们可以和JS一样的对这个prototype进行操作,比如动态的添加成员,添加方法等。

  1. 如果您决定使用原型链,那么必须舍弃编译时类型检查。如果使用强类型,则编译器会认为动态添加的成员不存在,而提示编译错误。解决办法为去掉变量的类型说明,或者将变量强制转换成Object。
  2. 和JS引擎一样,原型链必须在运行时顺着prototype链查找。因此会影响性能。

本文说明,如何在脚本中,动态监听 EventTrigger。我们将这篇文章中介绍的使用不可热更的C#代码做的监听,改写为ActionScript3实现。

工程说明

  1. 新建一个Untiy工程,并且创建AS3热更新项目。如果不会创建,请参考这里
  2. 在HotFixDemoScene1上添加一个Image。
  3. 本次代码需要使用 RectTransformUtility 这个类。如果是Unity2017.2版本以后,由于这个类型被分拆到了其他dll (UnityEngine.UIModule.dll),因此需要将它加入到配置表里。
  4. 打开热更新工程的genapi.config.xml ,将如下配置加入配置节中:
    
      <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\Managed\UnityEngine\UnityEngine.UIModule.dll">assembly>
        <assembly value="D:\Program Files\Unity\Editor\Data\UnityExtensions\Unity\GUISystem\UnityEngine.UI.dll">assembly>
        
        <assembly value="F:/ASTool_UnityTest/HotFix_EventTrigger\Library\ScriptAssemblies\Assembly-CSharp.dll">assembly>
        
      buildassemblys>
  5. 打开热更新项目的Main.as文件,将内容改为如下代码:
    package
    {
        
        [Doc]
        /**
         * ...
         * @author 
         */
        public class Main
        {
            
            
            public function Main() 
            {    
            }
    
            public function update():void
            {    
            }
            
        }
        
    }
    import as3runtime.RefOutStore;
    import system.collections.generic.List_Of_EventTrigger_Entry;
    import unityengine.GameObject;
    import unityengine.MonoBehaviour;
    import unityengine.RectTransform;
    import unityengine.RectTransformUtility;
    import unityengine.Vector3;
    import unityengine.events.UnityAction_Of_BaseEventData;
    import unityengine.eventsystems.BaseEventData;
    import unityengine.eventsystems.EventTrigger;
    import unityengine.eventsystems.EventTriggerType;
    import unityengine.eventsystems.EventTrigger_Entry;
    import unityengine.eventsystems.PointerEventData;
    
    
    class UGUIEventTriggerTool
    {
        /**
         * 静态方法。检查某个GameObject上是否包含EventTrigger组件。如果有则返回它,否则创建一个并返回。
         * @param    go 输入的GameObject
         * @return  返回EventTrigger
         */
        public static function Get(go:GameObject):EventTrigger 
        {  
            var trigger:EventTrigger = go.getComponent(EventTrigger) as EventTrigger;  
            if (null == trigger)
            {  
                trigger = EventTrigger(go.addComponent(EventTrigger));  
            }  
            return trigger;  
        }  
    }
    
    /* *
     *  在EventTrigger的原型链上定义AddEventListener方法。
     *  EventTrigger类型没有公开构造函数,因此API导出时,不会为他创建在脚本中继承的接口。
     *  这里我们可以用原型链来对它进行扩展。
     *  包外代码只会执行一次。所以只会在原型链上定义一次AddEventListener方法。
     * */
    EventTrigger.prototype.AddEventListener =    
        function (eventTriggerType:EventTriggerType,  action:UnityAction_Of_BaseEventData):void
        {
            /**
             * EventTrigger有一个嵌套内部类 UnityEngine.EventSystems.EventTrigger.Entry。
             * 由于ActionScript3并不支持嵌套类,因此它被导出成为EventTrigger_Entry。
             */        
            var entry:EventTrigger_Entry = new EventTrigger_Entry();  
            entry.eventID = eventTriggerType;  
            entry.callback.addListener(action);  
            
            this.triggers.add(entry);
            
        }  
    
    /**
     * 扩展MonoBehaviour,让Image组件可以被拖拽。
     */
    class UGUIEventTriggerTest extends MonoBehaviour
    {
        function Start()
        {
            /**
             * 此处使用 * 类型来代表任意类型。
             * 这样即可跳过编译时类型检查,使用原型链。
             * 否则将会提示编译错误。
             */
            var t:* = UGUIEventTriggerTool.Get(gameObject);
            /**
             * 调用在原型链上定义的方法,给Drag事件添加处理函数。
             *  我们可以直接使用匿名函数来作为处理函数。
             */
            t.AddEventListener(EventTriggerType.Drag, 
            
                    function (baseData:BaseEventData):void
                    {
                        var data:PointerEventData = baseData as PointerEventData;
                        var rt:RectTransform = data.pointerPress.getComponent(RectTransform) as RectTransform;
                        var globalMousePos:Vector3;
                        
                        /**
                         * RectTransformUtility.screenPointToWorldPointInRectangle的参数
                         * worldPoint : (Out)UnityEngine.Vector3
                         * 是一个Ref Out参数。ActionScript3是没有ref和out关键字的,
                         * 因此这里使用RefOutStore来接收返回的参数。
                         */
                        var store:RefOutStore = new RefOutStore();                    
                        if (RectTransformUtility.screenPointToWorldPointInRectangle(rt, data.position, data.pressEventCamera, globalMousePos,store))
                        {
                            //传入形参名,来提取值。
                            globalMousePos = store.getValue("worldPoint") as Vector3;
                            rt.position = globalMousePos;
                        }
                    }
                    
            
            );
        }
    
        
    }
    //将脚本挂载到Image上。
    GameObject.find("Image").addComponent(UGUIEventTriggerTest);
  6. 点击编译,然后在Unity中点击播放。我们现在即可拖动这个Image。



推荐阅读
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了[从头学数学]中第101节关于比例的相关问题的研究和修炼过程。主要内容包括[机器小伟]和[工程师阿伟]一起研究比例的相关问题,并给出了一个求比例的函数scale的实现。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 本文总结了在开发中使用gulp时的一些技巧,包括如何使用gulp.dest自动创建目录、如何使用gulp.src复制具名路径的文件以及保留文件夹路径的方法等。同时介绍了使用base选项和通配符来保留文件夹路径的技巧,并提到了解决带文件夹的复制问题的方法,即使用gulp-flatten插件。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 突破MIUI14限制,自定义胶囊图标、大图标样式,支持任意APP
    本文介绍了如何突破MIUI14的限制,实现自定义胶囊图标和大图标样式,并支持任意APP。需要一定的动手能力和主题设计师账号权限或者会主题pojie。详细步骤包括应用包名获取、素材制作和封包获取等。 ... [详细]
author-avatar
kyf召世星bdc
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有