Unity3D热更新全书-脚本(二) 两级分化
原地址:http://www.cnblogs.com/crazylights/p/3886840.html
上篇明確了我們探討的腳本是什么:是寫在文本文件里面的代碼,可以作為資源加載,取得字符串再執(zhí)行。
可是為什么世界上會有那么多的腳本?而其使用方法完全看起來不一樣呢?這是因為每種腳本都有自己的定位,在不同的復(fù)雜度腳本將表現(xiàn)出完全不同的樣貌,我們來看一下。
我們把腳本與程序的結(jié)合方式劃分成五種,以復(fù)雜度排序說明。
C#Light是定位復(fù)雜度較低的腳本,C#Evil是定位復(fù)雜度較高的腳本,他們就在腳本定位的兩級,可是有相當(dāng)復(fù)用部分的代碼,所以他們被合并成一個項目,你可以從GitHub上取得他們的源碼。
代碼獲取及文中示例的位置,在文后說明。
簡言之,腳本可以兩級分化成兩種:
程序調(diào)用腳本,腳本為程序提供靈活性
腳本調(diào)用程序,程序為腳本提供擴展性
究竟是極左還是極右,怎么使用,是你的自由。
我們用C#Light/Evil來說明各種腳本結(jié)合方式。
?
復(fù)雜度一:計算
執(zhí)行字符串的核心函數(shù)應(yīng)該是這樣的
int i = Eval(“1+2”);
我們有一套例子,本文最后有如何取得例子的說明。
程序里就可以通過執(zhí)行字符串來執(zhí)行邏輯,字符串的變更就可以得到邏輯的變更。
試想如果要做公式計算,他看起來應(yīng)該是這樣
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”);
復(fù)雜度二:包含邏輯分支和調(diào)用
當(dāng)腳本邏輯的復(fù)雜度到一個程度,直接嵌入字符串就變得不可取了
我們希望在計算HP的同時,腳本打點Log,就要讓腳本可以調(diào)用函數(shù),同時腳本要知道今天星期幾,也得給他一個函數(shù)調(diào)用
這時候最好就把腳本寫到一個單獨的文本文件里
Script1:
Debug.Log(“Today=”+Today());
if(Today()==Monday)
????? return HP1+HP2;
if(Today()==SunDay)
???? return HP1+HP2*2;
return HP1+HP2*0.5;
調(diào)用代碼:
int i =Script.Eval(GetScriptFromFile(“Script1”));
?
復(fù)雜度三:函數(shù)與類型
當(dāng)腳本邏輯再復(fù)雜下去,僅靠表達式已經(jīng)很難組織邏輯了,此時的腳本就會引入函數(shù)甚至類型
Script1:
int Calc1()
{
?? …
}
int Calc2()
{
?? …
}
int Calc3()
{
?? …
}
int GetHP()
{
??? if(Today()==Monday)
??? {
??????? return Calc1();
??? }
??? if(…)
??? {
?????? ….
??? }
??? ….
}
調(diào)用代碼:
Script.Build(GetScriptFromFile(“Script1”));
int i =Script.Eval(“GetHP();”);
這部分代碼比較多,我們拆開來看
首先是腳本文件,這個看起來像代碼一樣的東西就是我們的腳本
然后我們把這個cs文件當(dāng)做文本加載進來作為腳本,放在streamingasset目錄就可以
我們有兩種辦法來訪問Build好的腳本,一種是合成一段字符串,然后通過這組字符串腳本去執(zhí)行
另一種是像反射那樣進行操作
?
?
?
特別提醒:我們的建議是止步復(fù)雜度三
腳本一旦跨越復(fù)雜度三進入復(fù)雜度四就會產(chǎn)生重心的完全反轉(zhuǎn)。
復(fù)雜度一二三是程序調(diào)用腳本,腳本為程序提供靈活性。
復(fù)雜度四五則變成了腳本調(diào)用程序,程序為腳本提供擴展性。
?
復(fù)雜度四:腳本文件進化成腳本項目
再進一步復(fù)雜,腳本就會進化為完全不同的東西
單個腳本無法完成邏輯,腳本和腳本之間可以產(chǎn)生關(guān)聯(lián)
產(chǎn)生了項目的概念
Script1:
class ScriptClass1
{
????? static void Run()
???? {
????????? ScriptClass2 s2 =new ScriptClass2();
????????? s2.xxx
????????? …
????????? …
????????? …
???? }
}
Script2:
class ScriptClass2
{
????? …
????? ….
????? …
}
調(diào)用代碼:
Script.BuildProject(“Scirpt1”,”Script2”)
Script.Run(“ScriptClass1.Run();”);
當(dāng)腳本變成了腳本項目,再去觀察程序端的代碼就沒什么意義了
我們的例子里有用完全一致的程序端代碼,僅僅切換了不同的腳本,就完成了不同的功能。
按頂上的按鈕,直接載入兩個不同的腳本項目進來運行
復(fù)雜度五:反客為主
當(dāng)腳本已經(jīng)產(chǎn)生項目的概念,他已經(jīng)可以脫離專用的程序宿主
像Python那樣用一個通用的Python.exe 啟動程序,變成一種擁有獨自運行能力的語言。
我們也提供一個這樣的例子,在這種情況下,程序員完全變成了腳本編寫員和模塊編寫員。
?
?
?
?
具體代碼參考GitHub上的代碼
https://github.com/lightszero/CSLightStudio
GITHUB源碼中的Unity\ScriptHelloWorld中有四個場景
ScriptTest1_xx 分別對應(yīng)復(fù)雜度一二三
ScriptTest2對應(yīng)復(fù)雜度四
GITHUB源碼中的Unity\ScriptLoader對應(yīng)復(fù)雜度五,這個會在以后另外的文章中介紹
總結(jié)
以上是生活随笔為你收集整理的Unity3D热更新全书-脚本(二) 两级分化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Asp.Net中几种标记符号解释及用法
- 下一篇: apt-mirror建立本地ubuntu