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游戏热更新方案

  • 相关阅读:
    bzoj 1017 魔兽地图DotR
    poj 1322 chocolate
    bzoj 1045 糖果传递
    poj 3067 japan
    timus 1109 Conference(二分图匹配)
    URAL 1205 By the Underground or by Foot?(SPFA)
    URAL 1242 Werewolf(DFS)
    timus 1033 Labyrinth(BFS)
    URAL 1208 Legendary Teams Contest(DFS)
    URAL 1930 Ivan's Car(BFS)
  • 原文地址:https://www.cnblogs.com/answerwinner/p/6269747.html
Copyright © 2011-2022 走看看