- 🎬 博客主頁:https://xiaoy.blog.csdn.net
- 🎥 本文由 呆呆敲代碼的小Y 原創,首發于 CSDN🙉
- 🎄 學習專欄推薦:Unity系統學習專欄
- 🌲 游戲制作專欄推薦:游戲制作專欄
- 🏅 歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請指正!
- 📆 未來很長,值得我們全力奔赴更美好的生活?

目錄
- 📢前言
- 🎬Unity腳本代碼優化策略
- 📒獲取游戲物件的方法
- 🏳??🌈GameObject.Find()
- 🏳??🌈Transform.Find()
- 🏳??🌈GameObject.FindWithTag()
- 🏳??🌈GameObject.FindGameObjectWithTag()
- 🏳??🌈Transform.FindGameObjectsWithTag()
- 🏳??🌈GameObject.FindObjectOfType()
- 🏳??🌈GameObject.FindObjectsOfType()
- 🏳??🌈transform.GetChild()
- 🏳??🌈通過 Public 宣告物件,從檢查器面板上手動拖拽獲取
- 📒獲取組件的最佳方法
- 📒移除空的回呼定義
- 💬總結
- 🚀往期優質文章分享
- 【游戲開發愛好者社區】活動進行中,每周打卡送書籍等禮品,期待你的加入
- 👑評論區抽獎送書
- 🎁抽獎規則
- 🎄推薦理由(?????)
📢前言
- 本文是 Unity優化篇 系列的一篇文章,同時也包是含在 『Unity系統學習專欄??』里的文章,
- 本專欄是我總結的Unity學習類的文章,適合Unity入門和進階的小伙伴,
- 訂閱該專欄之后
Unity基礎知識學習、Unity 進階技巧、Unity 優化 篇幾個專欄的文章都可以查看, - 對Unity感興趣的小伙伴千萬不要錯過哦,目前專欄正在優惠中,具體內容可以看該專欄的導航帖,
- 本篇文章就來講一下 Unity中的腳本代碼優化策略,一起來學習一下吧!
🎬Unity腳本代碼優化策略
上一篇文章中介紹了 Unity中的優化概念 和 Unity自帶的性能分析工具Profiler 以及 性能分析的方法
在看完這篇文章之后應該對Unity中的優化有了一個大概的觀念,
那接下來就是來看優化中最常用的 腳本代碼優化 了,
撰寫腳本會占據大量的開發時間,而且腳本撰寫是一個含義寬泛的術語,
所以本系列只限于Unity相關的腳本,包括MonoBehaviour、GameObject 和 相關功能的問題,
大概內容如下所示:
獲取游戲物件、訪問組件、空參考快速檢索、協程、GameObject 和 Transform的使用 、使用合適的資料結構、游戲物件間通信、數學計算、合理反序列化行為等,
下面就來挨著學習一下相關內容,
📒獲取游戲物件的方法
在Unity中獲取游戲物件是經常會用到的,
我們要 獲取某些游戲物件 對其進行一些邏輯處理 或者 拿到該游戲物件身上的某些組件進行某些處理,
而且在Unity中獲取游戲物件的方法有很多種,下面一起來看一下,
- GameObject.Find() 通過物件名稱(Find方法)
- Transform.Find() 通過物件名稱(Find方法)
- GameObject.FindWithTag 通過標簽獲取單個游戲物件(FindWithTag方法)
- GameObject.FindGameObjectWithTag() 通過標簽獲取單個游戲物件(FindGameObjectWithTag方法)
- Transform.FindObjectOfType() 通過型別獲取單個游戲物件(FindObjectOfType方法)
- Transform.FindObjectsOfType() 通過型別獲取多個游戲物件(FindObjectsOfType方法)
- transform.GetChild() 通過索引獲取單個游戲物件
- 通過 Public 宣告物件,從檢查器面板上手動拖拽獲取
Unity中查找獲取游戲物件的方法應該都在這里了,下面簡單來介紹下這幾種方法,
🏳??🌈GameObject.Find()
GameObject.Find() 通過物件名稱(Find方法)
該方法通過輸入物件名稱的方式獲取對應的游戲物件
static GameObject Find (string name )
使用示例如下:
// 找物件
GameObject parent = GameObject.Find("GameObject/ObjectName");
特點:
- 全域查找引數名稱游戲物體;
- 不對禁用(隱藏)物體進行查找;
- 若有同名物體時根據層級關系進行查找,
🏳??🌈Transform.Find()
Transform.Find() 通過物件名稱(Find方法)
該方法也是通過輸入物件名稱的方式獲取對應的游戲物件
與GameObject.Find() 使用方法一致,不過也是有區別的
具體請看這篇【100個 Unity小知識點】 | Unity兩種獲取游戲物件的方法,GameObject.Find 和 Transform.Find區別
public Transform Find(string name);
使用示例:
// 找物件
Transform parent = transform.Find("Root/ObjectName");
特點:
- 只能找其子物體,不能找其同級或更高層級物體
- 找子物體時不考慮是否被禁用(隱藏)
- 找多層子物體時需寫全路徑(否則即使存在也找不到)
🏳??🌈GameObject.FindWithTag()
GameObject.FindWithTag() 通過標簽獲取單個游戲物件(FindWithTag方法)
回傳一個用tag做標識的活動的物件,如果沒有找到則為null,
static GameObject FindWithTag (string tag)
使用示例:
GameObject p1= GameObject.FindWithTag("player1");
if (null != p1)
{
Debug.Log("p1!");
}
Tag標簽 可以在面板上進行 添加和復制,先選中游戲物件然后進行操作,

特點:
- 查找不到禁用物體,使用時需確認要查找的物體是啟用(顯示)狀態;
- 有多個有游戲物體使用同一標簽時,盡量不使用
FindWithTag此方式查找單一游戲體,因為查找順序會受到層級影響; - 查找未定義標簽會報錯,使用時需確認查找的字串是已定義的標簽;
- 查找的標簽是已定義但是未使用過,會找不到游戲物體,回傳空值,
🏳??🌈GameObject.FindGameObjectWithTag()
FindGameObjectWithTag() 通過標簽獲取單個游戲物件(FindGameObjectWithTag方法)
FindGameObjectWithTag 和 上面的FindWithTag用法一致,功能也是一樣的
他倆的具體區別我暫時沒有發現,如果知道的小伙伴歡迎評論區告訴我呀!
public static GameObject FindGameObjectWithTag(string tag);
🏳??🌈Transform.FindGameObjectsWithTag()
Transform.FindObjectsOfType() 通過型別獲取多個游戲物件(FindObjectsOfType方法)
public static GameObject[] FindGameObjectsWithTag(string tag);
回傳一個用tag做標識的活動的游戲物體的串列
上面說了一下Transform.FindObjectOfType() 方法,與這個 Transform.FindObjectsOfType() 的方法使用起來也是一樣的,
只不過該方法可以根據 標簽 查找當前場景中 所有這個標簽的游戲物體 并回傳所有物體的陣列,
所以他們的區別就是一次性 獲取單個符合要求的游戲物件 和 獲取多個游戲物件,
要注意的是Transform.FindObjectsOfType() 回傳的是一個游戲物件的陣列,找不到則回傳null
🏳??🌈GameObject.FindObjectOfType()
Transform.FindObjectOfType() 通過型別獲取單個游戲物件(FindObjectOfType方法)
public static T FindObjectOfType<T>() where T : Object;
回傳型別為type的活動的第一個游戲物件
使用示例:
Camera c1 = GameObject.FindObjectOfType<Camera>();
Debug.Log("游戲物件c1:" + c1);
特點:
- 查找不到禁用物體,使用時需確認要查找的物體是啟用(顯示)狀態;
- 查找場景中不存在型別時會回傳null,不會報錯;
🏳??🌈GameObject.FindObjectsOfType()
Transform.FindObjectsOfType() 通過型別獲取多個游戲物件(FindObjectsOfType方法)
public static T[] FindObjectsOfType<T>() where T : Object;
該方法和上面的方法使用方式一樣,只不過回傳的是一個該型別的陣列
使用示例:
Camera[] c2 = Transform.FindObjectOfType<Camera>();
Debug.Log("游戲物件c2:" + c2);
🏳??🌈transform.GetChild()
transform.GetChild() 通過索引獲取單個游戲物件
public Transform GetChild(int index);
使用實體:
//找一級子物體的第一個物體
Transform child1 = transform.GetChild(0);
使用方式:幾個層級就幾個GetChild(),引數就是當前層級的第幾個物體(從0開始)
特點:
- 以自身為基礎,查找子物體(注意索引從0開始,寫多報錯)
- 可以使用transform.parent.parent 的形式無限向上,然后再GetChild(),就達到了查找父層級或更高層級物體的目的
- 弊端是依賴游戲物體的層級關系,使用時需確保層級關系相對穩定,若不穩定會導致每次修改游戲體時還要修改代碼,這就加大了作業量了,
🏳??🌈通過 Public 宣告物件,從檢查器面板上手動拖拽獲取
在Unity中除了上面的幾種通過代碼獲取游戲物件的方法之外,
還有一種很常用的方式來獲取游戲物件或者組件,那就是使用Public修飾符來宣告物件,
public GameObject _g1;
public Button _button1;

這種方式在我們日常開發的時候也可以使用,因為直觀方便還不用多寫代碼就可以直接獲取物件,
網上對比最多的就是 Public 和 Transform.Find 的方式哪種更消耗性能,
在我查閱了一些資料之后并沒有看到有關于這塊很詳細的資料,簡單測驗發現這兩種性能消耗的差異不大,
所以說還是要看平時個人的代碼規范 和 專案要求 來選擇使用哪種方式,
整理了以上幾個獲取物件的方法,各有特點,
但是我通常使用的就是Transform.Find(),該方法可以獲取到非激活狀態的游戲物件,性能消耗也不高,
獲取游戲物件部分 參考了 陳言必行大佬 的這篇博客https://czhenya.blog.csdn.net/article/details/117530824
可以去這篇博客查看更詳細的實體方法,獲取游戲物件的方法這里就簡單介紹到這,下面看一下獲取組件的最佳方法,
📒獲取組件的最佳方法
上面說完了獲取游戲物件的幾種方法,接下來再來講一下獲取組件的最快方法,
在Unity中獲取組件的方法也有幾種,下面一起來看一下,
獲取組件的方法主要是使用 GetComponent() 方法,但是 GetComponent() 有一些變體,他們性能消耗有所不同,
- GetComponent(string)
- GetComponent()
- GetComponent(typeof(T))
public Component GetComponent(string type);
public T GetComponent<T>();
public Component GetComponent(Type type);
主要是通過這三個變體方法來獲取組件
根據上百萬次測驗發現 GetComponent<T>() 和 GetComponent(typeof(T)) 方法性能差異不大,
但是 GetComponent(string) 方法則比上面兩種方法慢的多,
所以說正常情況下盡量不使用 GetComponent(string) 方法即可
大多數情況下還是使用 GetComponent<T>() 比較多,平時都在使用這個方法獲取組件,
使用示例:
Demo1 _demo1;
_demo1 = transform.GetComponent<Demo1>();
_demo1 = (Demo1)transform.GetComponent("Demo1");
_demo1 = (Demo1)transform.GetComponent(typeof(Demo1));
📒移除空的回呼定義
Unity中撰寫腳本的主要意義是從 MonoBehaviour 繼承的類中撰寫回呼函式,然后Unity會在必要時進行呼叫,
一般來說最常用的四個回呼是 Awake()、Start()、Update()、FixedUpdate()
我們在創建一個新腳本的時候默認會幫我們添加兩個回呼 Awake() 和 Update()

關于 Awake() 和 Update() 方法的意義就不多做講解了,看優化篇的應該都知道是干嘛用的,
Awake()主要是在程式運行的第一幀進行呼叫,而Update()則是在每一幀都會進行呼叫,
MonoBehaviour 在場景中第一次實體化的時候,Unity會將任何定義好的回呼添加到一個函式指標串列中,他會在關鍵時刻呼叫這個串列,
即使我們在Awake() 和 Update() 中并沒有寫任何的方法,Unity也會掛接到這些回呼中,
核心Unity引擎可能沒有意識到這些函式體是空的,由于引擎呼叫他們的開銷就會浪費少量的CPU,
但是我們每當在Unity中創建一個MonoBehaviour 腳本的時候,都會添加這兩個回呼,
所以說一旦專案偏大,腳本偏多,功能比較復雜之后,因為這個原因造成的性能浪費是沒有任何收益的,
所以未使用的回呼一定要直接洗掉掉,防止不必要的浪費,
下面使用3000個組件進行的測驗實體,都帶有Update的回呼,左邊是未激活組件的狀態,右邊則是激活組件之后的狀態,
可以看出CPU使用情況的差異還是很大的,所以移除空的回呼很有必要,

💬總結
- 本文對 獲取 游戲物件 和 組件 的方法進行了一個較詳細的說明
- 還包括 空的回呼定義 造成的影響,當專案越大時浪費的性能則越多,
- 關于腳本代碼優化策略的內容還有一些,等下一篇博客在接著進行學習介紹,
- 本篇文章就先講到這里,后續的Unity腳本代碼優化策略會繼續更新,
🚀往期優質文章分享
- ??Unity零基礎到入門 | 游戲引擎 Unity 從0到1的 系統學習 路線【全面總結-建議收藏】!
- 🧡花一天時間做一個高質量飛機大戰游戲,過萬字Unity完整教程!漂亮學妹看了直呼666!
- 💛通宵一晚做出來的一款類似CS的第一人稱射擊游戲Demo!原來做游戲也不是很難
- 💚重回童年的經典系列??|【貪吃蛇小游戲】近兩萬字完整制作程序+決議+原始碼 【建議收藏學習】
- 🤍重回童年的經典系列??| 【皇室戰爭 】 的 即時戰斗類 復刻游戲Demo!兩萬多字游戲制作程序+決議!
- 💙重回童年的經典系列??| 【橫版街機格斗游戲】類似“恐龍快打” 該如何制作? | 一起來學習 順便送原始碼【建議收藏學習】
- 💜重回童年的經典系列??|【炸彈人小游戲】制作程序+決議 | 收藏起來跟曾經的小伙伴一起夢回童年!
| 🚀 優質專欄分享 🚀 |
- 🎄如果感覺文章看完了不過癮,可以來我的其他 專欄 看一下哦~
- 🎄比如以下幾個專欄:Unity基礎知識學習專欄、Unity游戲制作專欄、Unity實戰類專案 和 演算法學習專欄
- 🎄可以學習更多的關于Unity引擎的相關內容哦!直接點擊下面顏色字體就可以跳轉啦!
【游戲開發愛好者社區】活動進行中,每周打卡送書籍等禮品,期待你的加入
| 🚀 社區活動,重磅來襲 🚀 |
【游戲開發愛好者社區】在本周重磅新推出【每日打卡】活動
🎁 新玩法,獎勵升級!游戲開發愛好者社區:https://bbs.csdn.net/forums/unitygame
社區中心思想:今天你學到了什么?
在社區你可以做些什么: 每日強化知識點,白嫖書籍禮品!
一個人可以走的很快,一群人才能走的更遠!🔥爆C站的游戲開發愛好者社區歡迎您的加入!
更多白嫖活動詳情:https://bbs.csdn.net/forums/unitygame?typeId=19603
👑評論區抽獎送書
最后在評論區進行抽取三名幸運的小伙伴送下面這本書籍
-
這次博主多方聯系,最終在
清華出版社搞到了一些unity 相關的書籍,在這里搞個小活動抽獎送給大家,對看書感興趣的小伙伴可以參加一波呀,剛開始可能參與的不多,抽中概率很大哦! -
《C#實踐入門(快捷學習C#編程和Unity游戲開發第4版.NET開發經典名著) 》
-
一本非常經典的C#編程名著,結合Unity開發使用效果卓佳!
-
尤其是想從事Unity開發剛入門的小伙伴,沒必要去買專門的C#書籍,這本書就可以讓你了解Unity用到的C#相關知識,對癥下藥可以極大地提高學習效率!
🎁抽獎規則
規則如下:
| 🚀 規則如下🚀 |
-
給本篇博客文章
點贊收藏評論三連,然后在評論區評論里點贊數 排名前五的評論抽取三個小伙伴!送一本Unity的書籍! -
總共
抽三本,中的幾率還是很大的哦~ 想看書的小伙伴參與起來! -
中獎資訊明天下午本篇文章評論區公布!記得留意呀! -
沒抽到的,但是喜歡這本書的小伙伴也可以在網上自行購買哈,官方正品商店購買即可!
| 🚀 規則如上🚀 |
🎄推薦理由(?????)
-
?在如今的技識訓境中學習編程無疑是一項艱巨的任務,尤其是當面對眾多可選的編程語言時,幸運的是,《C#實踐入門(快捷學習C#編程和Unity游戲開發第4版.NET開發經典名著) 》消除了充滿不確定性的學習程序,為初學者指明了一條成為有競爭力的Unity程式員的捷徑,
-
?在本書中,你將首先學習編程的基本構成要素,涵蓋從變數、方法、條件陳述句到類、面向物件編程在內的所有知識,打好基礎后,你將開始探索Unity介面并創建C#腳本,進而將學到的知識轉換為簡單的游戲機制,
-
?在整個學習程序中,你將掌握編程方面的最佳實踐以及宏觀的架構知識,例如游戲管理器與靈活的應用程式架構,等到本書結束時,你將對C#的一些中級主題了然于胸,例如泛型、委托、事件等,從而在自己的專案中加以靈活運用,
書本圖片如下,喜歡的小伙伴參與起來!也可自行京東官網購買哦!
京東鏈接:https://item.jd.com/13263338.html

溫馨提示: 點擊下面卡片可以獲取更多編程知識,包括各種語言學習資料,上千套PPT模板和各種游戲原始碼素材等等資料,更多內容可自行查看哦!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/404216.html
標籤:其他
上一篇:【100個 Unity小知識點】 | Unity兩種獲取游戲物件的方法,GameObject.Find 和 Transform.Find區別
下一篇:自學三個月撰寫簡單走迷宮游戲
