zoukankan      html  css  js  c++  java
  • JSBinding+Bridge.NET:Inspector拖变量支持

     之前的文档说了,JSB的设计是不允许gameObject上挂逻辑脚本的。原因很简单,在Js工程中根本就不存在C#形式的逻辑脚本,如果在Cs工程中挂上了,到了Js工程这边,直接Missing。

    实际在使用的过程发现如果Prefab无法静态“关联”逻辑脚本,则必须在某个地方动态地确定需要挂什么脚本上去。这样子的确是有点麻烦。

     

    首先要记住,ScriptAgent只是用于“逻辑脚本”,也就是需要更新的脚本。对于框架脚本,是直接挂就可以的。

     

    解决如何对一个gameObject静态指定一个逻辑脚本。

    gameObject上挂一个框架脚本ScriptAgent,ScriptAgent上有一个ScriptName表示脚本名字(例如LoginUI),可在Inspector中输入。

    public class ScriptAgent : MonoBehaviour
    {
        public string ScriptName;
        void Awake()
        {
    #if JS
            var jsCom= AddComponent<JSComponent>();
            jsCom.jsClassName = ScriptName;
            //...
    #else
            Type type = FindTypeByName(ScriptName);
            AddComponent(type);
    #endif
    
            // Destroy self
            Destroy(this);
        }
    }

    如上所示,运行时,

    1. 如果是Js版本,则挂上去JSComponent对象,并初始化Js对象。

    2. 如果是C#版本,则根据名字查找类型,找到后,调用 AddComponent(type)。

    3. 把自己干掉

     

    接下来的问题是要想办法在 ScriptAgent 支持一些 public 变量的拖放,以减少写查找gameObject的代码。

    假设有一个脚本LoginUI,上面有一个public变量,如下

    public class LoginUI : MonoBehaviour
    {
        // 登录按钮的gameObject
        public GameObject goLogin;
    }

     

    目前的使用步骤是,首先挂上 ScriptAgent,输入脚本名(全名,包括namespace):

    然后点击 Update 按钮:

    会发现,出现了LoginUI那个public变量!此时可以赋值了。

     

    在 ScriptAgent 的 Awake 中,会把这些 public 变量,赋值给具体的逻辑脚本对象。

    1. 如果是Js版本,则赋值给Js对象

    2. 如果是Cs版本,则使用反射赋值给C#对象

    赋值的操作是很容易的,不需要深入讨论。

     

    这里的难点是 Update 按钮的实现。在Js工程中,LoginUI这个脚本实际不是以C#形式存在的。只在BridgeProj才是以C#形式存在的。

    1. 在Js工程中,Update按钮的实现原理是:使用 Cecil 加载 BridgeProj/bin/Debug/BridgeProj.dll,查找 LoginUI 这个类型里的 public 变量,返回回来;

    2. 在Cs工程中,Update按钮的实现原理是:使用 Cecil 加载 Cs工程/Library/ScriptAssemblies/Assembly-CSharp.dll,查找 LoginUI 这个类型里的 public 变量,返回回来;

     

    ScriptAgent理论上是可以支持所有Unity可序列化类型的(包括嵌套,如结构体套数组,再套结构体),实现起来也不难。不过,考虑到项目中很少使用过于复杂的序列化类型,目前只添加了int,string,bool,gameObject 4种类型。

     

    另外,这个方法有一个明显的限制,那就是,如果在 LoginUI.Awake 中去取 goLogin 对象的值,是会为 null 的。原因是,ScriptAgent 在 AddComponent(typeof(LoginUI)) 的同时,LoginUI.Awake 已经调用了,之后才有机会处理序列化数据。

    所以我们项目中,规定:对于逻辑脚本,一律不准使用 Awake 函数,而改用 OnAwake(必须是public,无参)。ScriptAgent 在处理完序列化数据后,会主动调用 OnAwake。

     

    返回:JSBinding+Bridge.NET:Unity游戏热更新方案

  • 相关阅读:
    MongoDB安装与启动
    Mac node.js express-generator脚手架安装
    AJAX状态值与状态码
    博客园 Markdown编辑器简要教程
    高效、可维护、组件化的CSS
    如何在mac上运行vue项目
    前端chrome调试
    Light of future-冲刺集合
    团队作业第六次—事后诸葛亮
    Light of future-冲刺总结
  • 原文地址:https://www.cnblogs.com/answerwinner/p/6269747.html
Copyright © 2011-2022 走看看