一、怎么創建腳本
在Project窗口下,右鍵Create C#Script 即可創建腳本
創建腳本的注意事項 :
1)類名和文件名必須一致,不然不能掛載(因為反射機制創建對象,會通過文件名去找Type)
2)沒有特殊需求 不用管命名空間
3)創建的腳本默認繼承MonoBehavior
4)可以放在Assets文件夾下的任何位置(建議同一文件夾管理)
二、關于MonoBehavior的介紹
? ? ? ? 首先它是一個基類,任何生命周期函數的執行都需要直接或者間接繼承這個類,至于生命周期函數是是什么,我們后面講。所有 Unity 腳本若需要與引擎生命周期事件(如初始化、更新、銷毀等)交互,必須直接或間接繼承?MonoBehaviour
。這是 Unity 設計的基礎規則,只有繼承此類的腳本才能被引擎識別為“組件”,從而掛載到?GameObject
?上并參與游戲邏輯的驅動。它有以下特點:
????????①創建的腳本基本都默認繼承MonoBehavior 繼承了它才能夠掛載在GameObject上。因為Unity 通過繼承?MonoBehavior 的類來標記其為“可掛載組件”。Unity 編輯器會掃描腳本是否繼承自?MonoBehavior ,只有符合條件的腳本才會出現在“Add Component”菜單中。
????????②繼承了MonoBehavior的腳本不能new 只能掛!!!!!!!!繼承?MonoBehaviour
?的腳本?不能手動實例化(如?MyScript script = new MyScript();
)。因為Unity 要求組件必須依附于?GameObject
,而?new
?創建的實例未綁定任何對象,無法被引擎管理。生命周期函數(如?Awake
、Update
)由引擎自動觸發,未掛載的腳本不會執行這些邏輯。
????????③繼承了MonoBehavior的腳本不要去寫構造函數,因為我們不會去new它,寫構造函數沒有任何意義。Unity 不會調用?MonoBehaviour
?的構造函數,初始化邏輯應由?Awake
?或?Start
?實現。構造函數可能在非預期時機執行(如編輯器加載時),導致不可控行為。等后面學習了生命周期函數,就知道一般是使用Awake和Start進行初始化了。
????????④繼承了MonoBehavior的腳本可以在一個對象上掛多個(如果沒有加DisallowMultipleComponent特性)例如,為敵人掛載多個“攻擊效果”腳本,每個腳本控制不同的攻擊邏輯。或為 UI 元素掛載多個“動畫控制器”腳本,分別處理不同狀態的動畫。
????????⑤繼承MonoBehavior的類也可以再次被繼承,遵循面向對象繼承多態的規則。MonoBehaviour
?的子類可以進一步被繼承,遵循面向對象的基本原則。子類可以重寫父類的生命周期方法(如?Update
),并通過?base.Method()
?調用父類邏輯。當然這些都是后話。
了解小知識:為什么會這樣設計呢?
組件化開發
????????每個腳本代表一個獨立功能模塊,通過組合不同組件構建復雜對象(如角色 = 移動組件 + 動畫組件 + 攻擊組件)。
????????避免“上帝腳本”(一個腳本處理所有邏輯),提升代碼可維護性。
引擎控制權
????????Unity 引擎完全掌控組件的生命周期(如創建、更新、銷毀),開發者只需填充邏輯,無需手動管理內存或執行順序。
事件驅動模型
????????通過生命周期方法和事件回調(如?
OnCollisionEnter
)響應游戲狀態變化,而非傳統的主循環控制。
三、關于不繼承Mono的類
????????①不繼承MonoBehavior的類 不能掛載在GameObject上。因為上面提到了,Unity 編輯器通過反射檢查腳本是否繼承?MonoBehaviour
,只有符合條件的類才會出現在“Add Component”菜單中,只有繼承了的才有組件成為權!
????????②不繼承MonoBehavior的類 想怎么寫就怎么寫 如果要使用需要自己new。非?MonoBehaviour
?類本質是普通的 C# 類,不依賴 Unity 的組件系統,因此:
-
無需遵循 Unity 的約束:可以隨意定義構造函數、靜態方法或字段。
-
實例化方式:必須通過?
new
?關鍵字手動創建對象(如?MyClass obj = new MyClass();
)。
????????③不繼承MonoBehavior的類一般是單例模式的類(用于管理模塊,全局管理游戲狀態、資源、配置等。)或者數據結構類(用于存儲數據,純粹用于存儲和操作數據。)
????????④不繼承MonoBehavior的類 不用保留默認出現的那幾個函數。因為Unity 的生命周期方法(如?Awake
、Update
)是?MonoBehaviour
?提供的特性。非?MonoBehaviour
?類不具備這些功能,因此:無需保留默認函數:如?Start
?或?Update
?不會被 Unity 調用,定義它們無意義。
四、關于腳本的執行先后順序
五、默認腳本內容
? ? ? ? 你有沒有每次發現我們創建的腳本都長得一樣,這是因為Untiy自己配置了模版,當然,這模版它Untiy配的,我們就配不得嗎,走,我們去看看在哪里配置。?
首先:先得來到這個Untiy hub中,點擊這個在資源管理器中查看
然后走這個路徑:就可以看到很多很多的txt文件,這些就是模版文件
?不建議自己隨意修改?
來來來,做幾道題目練練手!!
問題一:MonoBehaviour 的構造函數問題
????????在 Unity 中,為什么繼承?MonoBehaviour
?的腳本不應定義構造函數?如果在構造函數中初始化變量,可能會導致什么問題?
? ? ? ? 參考答案:Unity?不會調用?MonoBehaviour
?的構造函數,初始化邏輯應由?Awake
?或?Start
?完成。構造函數可能在編輯器模式下意外觸發(如腳本重新編譯時),導致不可控行為。
? ? ? ? 可能存在的問題:若在構造函數中初始化組件引用(如?GetComponent<T>()
),此時?GameObject
?可能未完全初始化,導致空引用異常。構造函數中的邏輯可能破壞 Unity 的組件依賴鏈,引發初始化順序混亂。
問題二:單例模式的選擇
????????在 Unity 中,實現單例模式時,為何通常選擇不繼承?MonoBehaviour
?的普通類,而不是通過掛載到?GameObject
?的?MonoBehaviour
?腳本實現?請比較兩種方式的優缺點。
? ? ? ? 參考答案:
普通類單例(非 MonoBehaviour):
-
優點:
無需依賴?
GameObject
,內存占用更低。生命周期完全由代碼控制,跨場景時更穩定。
-
缺點:
無法直接使用 Unity 的生命周期方法(如?
Update
)。需要手動管理初始化和銷毀邏輯
MonoBehaviour 單例:
-
優點:
可方便使用 Unity 生命周期方法(如?
Awake
?初始化)。可在 Inspector 中配置公開變量。
-
缺點:
依賴?
GameObject
,跨場景時需通過?DontDestroyOnLoad
?防止銷毀。可能因場景切換或對象失活導致單例失效。
????????結論:若單例需要與 Unity 生命周期或場景對象交互(如 UI 管理),使用?MonoBehaviour
;若僅需全局邏輯管理(如配置讀取),優先使用普通類單例。
問題三:數據類的設計選擇
????????假設需要設計一個?PlayerData
?類,用于存儲玩家的血量、等級和裝備信息。為什么這個類不應繼承?MonoBehaviour
?如果需要在 Inspector 中編輯該類的數據,如何實現?
? ? ? ? 參考答案:
不繼承 MonoBehaviour 的原因:
PlayerData
?是純粹的數據容器,無需與?GameObject
?綁定或參與 Unity 生命周期。繼承?
MonoBehaviour
?會引入不必要的開銷(如組件內存占用),破壞代碼簡潔性。
在 Inspector 中編輯數據:
????????將?PlayerData
?聲明為可序列化的普通類:
[System.Serializable]
public class PlayerData { public int health; public int level; public List<string> equipment;
}
????????在某個?MonoBehaviour
?腳本中聲明?PlayerData
?的字段,即可在 Inspector 中編輯:
public class Player : MonoBehaviour { public PlayerData data;
}
這樣子就可以了