zoukankan      html  css  js  c++  java
  • Unity3D热更新全书-脚本(二) 两级分化

    原地址:http://www.cnblogs.com/crazylights/p/3886840.html

    上篇明确了我们探讨的脚本是什么:是写在文本文件里面的代码,可以作为资源加载,取得字符串再执行。

    可是为什么世界上会有那么多的脚本?而其使用方法完全看起来不一样呢?这是因为每种脚本都有自己的定位,在不同的复杂度脚本将表现出完全不同的样貌,我们来看一下。

    我们把脚本与程序的结合方式划分成五种,以复杂度排序说明。

    C#Light是定位复杂度较低的脚本,C#Evil是定位复杂度较高的脚本,他们就在脚本定位的两级,可是有相当复用部分的代码,所以他们被合并成一个项目,你可以从GitHub上取得他们的源码。

    代码获取及文中示例的位置,在文后说明。

    简言之,脚本可以两级分化成两种:

    程序调用脚本,脚本为程序提供灵活性

    脚本调用程序,程序为脚本提供扩展性

    究竟是极左还是极右,怎么使用,是你的自由。

    我们用C#Light/Evil来说明各种脚本结合方式。

    复杂度一:计算

    执行字符串的核心函数应该是这样的

    int i = Eval(“1+2”);

    imageimage

    我们有一套例子,本文最后有如何取得例子的说明。

    程序里就可以通过执行字符串来执行逻辑,字符串的变更就可以得到逻辑的变更。

    试想如果要做公式计算,他看起来应该是这样

    int i=Eval(“HP1+HP2*0.5);

    这里HP1,HP2怎么来,就要把值传给脚本,让脚本计算

    Script.SetValue(“HP1”,GetFromIni(“HP1”));

    Script.SetValue(“HP2”,GetFromIni(“HP2”));

    int i=Script.Eval(“HP1+HP2*0.5”);

    image

    复杂度二:包含逻辑分支和调用

    当脚本逻辑的复杂度到一个程度,直接嵌入字符串就变得不可取了

    我们希望在计算HP的同时,脚本打点Log,就要让脚本可以调用函数,同时脚本要知道今天星期几,也得给他一个函数调用

    这时候最好就把脚本写到一个单独的文本文件里

    Script1:

    Debug.Log(“Today=”+Today());

    if(Today()==Monday)

          return HP1+HP2;

    if(Today()==SunDay)

         return HP1+HP2*2;

    return HP1+HP2*0.5;

    调用代码:

    int i =Script.Eval(GetScriptFromFile(“Script1”));

    image

    image

    复杂度三:函数与类型

    当脚本逻辑再复杂下去,仅靠表达式已经很难组织逻辑了,此时的脚本就会引入函数甚至类型

    Script1:

    int Calc1()

    {

       …

    }

    int Calc2()

    {

       …

    }

    int Calc3()

    {

       …

    }

    int GetHP()

    {

        if(Today()==Monday)

        {

            return Calc1();

        }

        if(…)

        {

           ….

        }

        ….

    }

    调用代码:

    Script.Build(GetScriptFromFile(“Script1”));

    int i =Script.Eval(“GetHP();”);

    这部分代码比较多,我们拆开来看

    首先是脚本文件,这个看起来像代码一样的东西就是我们的脚本

    image

    然后我们把这个cs文件当做文本加载进来作为脚本,放在streamingasset目录就可以

    image

    我们有两种办法来访问Build好的脚本,一种是合成一段字符串,然后通过这组字符串脚本去执行

    image

    另一种是像反射那样进行操作

    image 


    特别提醒:我们的建议是止步复杂度三

    脚本一旦跨越复杂度三进入复杂度四就会产生重心的完全反转。

    复杂度一二三是程序调用脚本,脚本为程序提供灵活性。

    复杂度四五则变成了脚本调用程序,程序为脚本提供扩展性。


     

    复杂度四:脚本文件进化成脚本项目

    再进一步复杂,脚本就会进化为完全不同的东西

    单个脚本无法完成逻辑,脚本和脚本之间可以产生关联

    产生了项目的概念

    Script1:

    class ScriptClass1

    {

          static void Run()

         {

              ScriptClass2 s2 =new ScriptClass2();

              s2.xxx

              …

              …

              …

         }

    }

    Script2:

    class ScriptClass2

    {

          …

          ….

          …

    }

    调用代码:

    Script.BuildProject(“Scirpt1”,”Script2”)

    Script.Run(“ScriptClass1.Run();”);

    当脚本变成了脚本项目,再去观察程序端的代码就没什么意义了

    imageimage

    我们的例子里有用完全一致的程序端代码,仅仅切换了不同的脚本,就完成了不同的功能。

    按顶上的按钮,直接载入两个不同的脚本项目进来运行

    复杂度五:反客为主

    当脚本已经产生项目的概念,他已经可以脱离专用的程序宿主

    像Python那样用一个通用的Python.exe 启动程序,变成一种拥有独自运行能力的语言。

    我们也提供一个这样的例子,在这种情况下,程序员完全变成了脚本编写员和模块编写员。

    具体代码参考GitHub上的代码

    https://github.com/lightszero/CSLightStudio

    GITHUB源码中的UnityScriptHelloWorld中有四个场景

    image

    ScriptTest1_xx 分别对应复杂度一二三

    ScriptTest2对应复杂度四

    GITHUB源码中的UnityScriptLoader对应复杂度五,这个会在以后另外的文章中介绍

  • 相关阅读:
    golang zip 压缩,解压(含目录文件)
    c3p0参数详解
    golang协程——通道channel阻塞
    乔恩与加菲猫引发的思考
    部署bugzilla(bugzilla+apache+mysql+linux)
    新的篇章
    SQL基础2
    SQL基础1
    引用
    const 对象默认为文件的局部变量
  • 原文地址:https://www.cnblogs.com/123ing/p/3901603.html
Copyright © 2011-2022 走看看