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

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

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

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

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

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

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

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

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

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

复杂度一:计算

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

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

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

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

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

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”);

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

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

我们希望在计算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”));

复杂度三:函数与类型

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

Script1:

int Calc1()

{

   …

}

int Calc2()

{

   …

}

int Calc3()

{

   …

}

int GetHP()

{

    if(Today()==Monday)

    {

        return Calc1();

    }

    if(…)

    {

       ….

    }

    ….

}

调用代码:

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

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

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

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

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

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

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


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

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

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

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


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

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

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

产生了项目的概念

Script1:

class ScriptClass1

{

      static void Run()

     {

          ScriptClass2 s2 =new ScriptClass2();

          s2.xxx

          …

          …

          …

     }

}

Script2:

class ScriptClass2

{

      …

      ….

      …

}

调用代码:

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

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

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

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

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

复杂度五:反客为主

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

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

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

具体代码参考GitHub上的代码

https://github.com/lightszero/CSLightStudio

GITHUB源码中的Unity\ScriptHelloWorld中有四个场景

ScriptTest1_xx 分别对应复杂度一二三

ScriptTest2对应复杂度四

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

Unity3D热更新全书-脚本(二) 两级分化的更多相关文章

  1. Unity3D热更新全书-脚本(一) 初识脚本

    开篇之前还是要先说明,这是一份给经验并不丰富的程序员阅读的文字. 有需求.有疑惑,往下看. 第一个问题什么是脚本?程序和脚本如何区分?我们给Unity编写的组件是程序还是脚本? 这些问题本文无意去解答 ...

  2. Unity3D热更新全书-脚本(四) 用C#LightEvil搭建实际开发使用的脚本框架

    C#LightEvil之前提供了很多和Unity结合的例子,都是采用把脚本文件放置在StreamingAssets中的方法. 这样可以利用Unity的特性,放在这个目录中的CS文件会被编译器编译,我们 ...

  3. Unity3D热更新全书-脚本(五) NGUI

    让我们实际的研究一下如何将NGUI和C#LightEvil结合起来. 这里使用NGUI2.7,因为他是一个开源的版本,NGUI最新的版本未经作者的许可,是不可以带入我们的开源项目使用的. 这个例子完成 ...

  4. Unity3D热更新全书-脚本(三) C#LightEvil语法与调试

    调试,这是一个无法规避的问题 C#Light 由于有 词法解释.语法解释.运行时三种情况 所以和C#也是有类似的问题 出错大致可以分为编译错误和运行时错误 拼写出莫名的东西或者语法不正确,会在编译阶段 ...

  5. Unity3D热更新全书-PageZero

    由于深刻的认识到自己是个思维跳跃的人,深入浅出是个我还要努力很久的目标,为了让大家不至于在我乱七八糟的文字中迷失,特整理目录一份 无分类 <Unity3D热更新全书-何谓热更新,为何热更新,如何 ...

  6. Unity3D热更新全书FAQ

    只要有程序员朋友们问过两次的问题 就会收录在此FAQ中 1.C#Light对比LUA有什么好处 C#Light是静态类型脚本语言,语法同C#,Lua是动态类型脚本语言,这两种都有人喜欢. 我更喜欢静态 ...

  7. Unity3D热更新全书-重头再来

    之前写了Unity3D热更新全书系列Blog 提出了下载.加载.脚本三个方面的开源类库 下载方面有EasyDown加载方面有GameObjParser脚本方面有C#Light另外有一个没有独立成库,但 ...

  8. Unity3D热更新全书-何谓热更新,为何热更新,如何热更新

    首先来赞叹一下中文,何谓为何如何,写完才发现这三个词是如此的有规律. 为何赞叹中文?因为这是一篇针对新手程序员的文字,是一节语文课. 然后来做一下说文解字,也就是 何谓热更新 热更新,每个程序员一听就 ...

  9. Unity3d热更新全书-加载(一)从AssetBundle说起

    Unity3D动态下载资源,有没有解?有,AssetBundle就是通用解,任何一本书都会花大幅篇章来介绍AssetBundle. 我们也来说说AssetBundle 我们试全面的分析一下Unity3 ...

随机推荐

  1. Win7上的ASP.NET MVC3项目在Win10上运行的一个坑

    先解释一下问题:我原来的电脑环境是Win7+VS2015,因为新换了个电脑环境变成Win10+VS2015了,所以就把原先的项目复制到新的机器上,那么问题来了,原先的一个项目在VS2015上打开竟然直 ...

  2. 1341 - Aladdin and the Flying Carpet ---light oj (唯一分解定理+素数筛选)

    http://lightoj.com/volume_showproblem.php?problem=1341 题目大意: 给你矩形的面积(矩形的边长都是正整数),让你求最小的边大于等于b的矩形的个数. ...

  3. 【温故Delphi】Win32API之CreateMutex

    解决问题 如何让一个软件在一台机器上只能运行一个实例呢?这个问题用专业术语就是进程互斥.这个问题可以通过CreateMutex来解决. 进程互斥的核心思想:进程在启动时首先检查是否存在此进程实例,如果 ...

  4. 【CMD】日常总结

    命令脚本可以提升工作效率,之前用过也写过一些脚本,但时间一长就忘记了.写篇随笔记录一下,随用随记哈. 调用程序 //切换到某个路径下 cd D:\Glodon\GDW\GDW\Release\Bin ...

  5. 一些比较常用的Linux命令

    我有一些是我是参考别人的,忘记是谁了,在这里要感谢一下ta. #命令格式就是就是由命令+空格+一些命令用法的选项(可以选择多个用法)+空格+/+目录名或者文件名,有些是直接打命令就可以了,比如ls - ...

  6. Ubuntu 16.04 启动错误 "a start job is running for hold until boot process finishes up"

    老司机也差点翻船... 升级16.04的时候,将默认启动管理器(default display manager)选为gm3(gnome3)了(应该使用默认的lightgm)如果改成gm3,好像是nvi ...

  7. 如何用70行Java代码实现深度神经网络算法(转)

    对于现在流行的深度学习,保持学习精神是必要的——程序员尤其是架构师永远都要对核心技术和关键算法保持关注和敏感,必要时要动手写一写掌握下来,先不用关心什么时候用到——用不用是政治问题,会不会写是技术问题 ...

  8. Excel公式设置单元格颜色

    Excel2010 “条件格式"-"新建规则"-"使用公式确定要设置格式的单元格" 公式如下: =OR(H2<=-20%,H2>=20%, ...

  9. TSP旅行商问题的Hopfield求解过程

      连续型Hopfield在matlab中没有直接的工具箱,所以我们们根据Hopfield给出的连续行算法自行编写程序.本文中,以求解旅行商 问题来建立Hopfield网络,并得到解,但是该解不一定是 ...

  10. 不常用的toLocaleString()方法

    在javascript中所有的对象都具有toLocaleString().toString()和valueOf()方法. 其中,很多情况调用toString()和valueOf方法会返回相同的值,但是 ...