Unity全局調用非靜態函數
- 2020 年 12 月 3 日
- 筆記
- Unity, Unity寫bug之路
Unity全局調用非靜態函數
情形
大概就是做遊戲的時候想做一個給玩家展示資訊的東西,比如玩家按了不該按的鍵提醒一下之類的。這個腳本倒是很簡單,找個Text組件往上面加字就行了。問題在於這個腳本遊戲中的很多其他腳本都需要引用。比如錢不夠花了,管錢的腳本得提醒一句;用還沒好的技能,管技能的腳本得提醒一句;遊戲要是還有點劇情,管劇情的也得說幾句。後面再寫新的腳本,還要每個都加上對資訊展示腳本的引用,這就很麻煩。
方法
剛開始是想使用靜態(static)方法的,畢竟說到全局都能調用,第一個想到的就是靜態函數、靜態類。但是靜態函數內部是不允許干非靜態的事情的,比如,修改文字內容。直接過不了編譯。
正解是寫一個單例類。如果你跟我之前一樣並沒有深入學過C#並且根本不知道單例是個什麼玩意,只需要知道兩點就夠了:第一,單例類在場景里只能有一個它的實例。第二,這個單例裡面的public方法其他的類就都能在沒有引用這個類的情況下用了。
寫法就介紹一個最基本的,大部分時候都是好用的。
public class Logger : MonoBehaviour
{
public static Logger logger;
// ...
private void Awake()
{
logger = this;
}
public void Test()
{
// something to do
}
//...
}
這裡繼承MonoBehaviour是沒所謂的,主要是聲明一個靜態的實例,然後初始化為自己。
這樣在其他類里就可以直接調用單例類中的public函數了:
public class Whatever
{
public void DoSomething()
{
Logger.logger.Test();
}
}
這裡注意盡量別在其他類的Awake函數里調用單例,因為如果這時候單例的Awake還沒有執行,他就還不是個單例,調用會報錯的。
結語
只說了單例最基本的使用,因為高深的東西我不敢亂說。這些在基本的開發里已經夠用了,可以實現想要的效果。如果你很不能理解這是個啥,可以大概把它想像成一個包著靜態殼的動態類。你看,動態的類可以有很多個實例,靜態類沒有實例,只有一個實例的類可不是動靜結合。
其實在遊戲場景中,很多東西都適合做成單例類。比如管遊戲音樂的腳本大概率在場景里只會有一個實例工作,那麼就可以把他做成單例,如果有遊戲對象需要改變遊戲音樂,就可以直接調用。或者說如果是一個主角的單機遊戲,甚至可以把主角做成單例類,這樣比如有一群小怪都要來找主角打架,所有小怪都可以直接訪問到主角的位置資訊。
單例是C#里挺有意思的一個功能,如果你比較感興趣或者經常使用這個,可以去深入學了解一下單例的原理,搞一本《深入理解C#》什麼之類的。