Unity全局調用非靜態函數

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#》什麼之類的。