[Unity] 以 Interface 介面搜尋場景上所有物件

有在 Unity 用過 Interface 介面的工程師們應該都知道 GetComponent<介面名稱>; 的用法,但卻沒辦法用 FindObjectsByType<介面名稱> 來找物件。

而在 2014 年的 Unity 論壇中有人提出的 How can I find all objects that have a script that implements a certain interface? 討論串中有人以 LINQ 實作出用介面找物件的功能。

但為了要能更方便使用,我將它重寫成擴充功能,但這個目前沒研究出來能直接在 MonoBehaviour 中使用的辦法,所以就先讓它依附在 GameObject 之下。

如何使用?

先新開一個腳本,儲存以下程式碼:

using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public static partial class Extension
{
    public static List<T> FindInterfacesOfType<T>(this GameObject _)
    {
        return Object.FindObjectsOfType<MonoBehaviour>().OfType<T>().ToList();
    }
}

簡單來說就是,因為我們不能直接搜尋 Interface,所以就往更上層的 MonoBehaviour 搜尋,再往下去找有指定介面的物件,感覺就超吃效能,慎用。

用法如下,它會回傳一個 List。

gameObject.FindInterfacesOfType<介面名稱>();

使用範例

var iReady = gameObject.FindInterfacesOfType<IReady>();
foreach (var e in iReady)
{
    e.Ready();
}

IReady 是我自己寫的介面,裡面有個 Ready() 函數。上面先以 iReady 儲存它用 FindInterfacesOfType 找出來的物件 List,再透過 foreach 呼叫 Ready()。

切記,別把這個玩意兒塞在 Update 中讓它瘋狂執行,Find 與 LINQ 系列的程式碼都很吃效能的!

0 留言
Inline Feedbacks
View all comments
[convertkit form=2362222]
0
對這邊的內容有什麼想法嗎?你可以在討論區留言喲!x
()
x