Mengembangkan permainan di Unity, saya memanfaatkan secara liberal [RequireComponent(typeof(%ComponentType%))]
untuk memastikan semua komponen telah terpenuhi.
Saya sekarang menerapkan sistem tutorial yang menyoroti berbagai objek UI. Untuk melakukan penyorotan, saya mengambil referensi ke GameObject
dalam adegan, lalu saya mengkloningnya dengan Instantiate () dan kemudian menghapus semua komponen yang tidak diperlukan untuk ditampilkan secara rekursif. Masalahnya adalah bahwa dengan penggunaan liberal RequireComponent
dalam komponen-komponen ini, banyak yang tidak dapat dihapus begitu saja dalam urutan apa pun, karena mereka bergantung pada komponen lain, yang belum dihapus.
Pertanyaan saya adalah: Apakah ada cara untuk menentukan apakah Component
dapat dihapus dari yang GameObject
saat ini dilampirkan.
Kode yang saya posting secara teknis berfungsi, namun ia melempar kesalahan Unity (tidak tertangkap di blok try-catch, seperti yang terlihat pada gambar
Berikut kodenya:
public void StripFunctionality(RectTransform rt)
{
if (rt == null)
{
return;
}
int componentCount = rt.gameObject.GetComponents<Component>().Length;
int safety = 10;
int allowedComponents = 0;
while (componentCount > allowedComponents && safety > 0)
{
Debug.Log("ITERATION ON "+rt.gameObject.name);
safety--;
allowedComponents = 0;
foreach (Component c in rt.gameObject.GetComponents<Component>())
{
//Disable clicking on graphics
if (c is Graphic)
{
((Graphic)c).raycastTarget = false;
}
//Remove components we don't want
if (
!(c is Image) &&
!(c is TextMeshProUGUI) &&
!(c is RectTransform) &&
!(c is CanvasRenderer)
)
{
try
{
DestroyImmediate(c);
}
catch
{
//NoOp
}
}
else
{
allowedComponents++;
}
}
componentCount = rt.gameObject.GetComponents<Component>().Length;
}
//Recursive call to children
foreach (RectTransform childRT in rt)
{
StripFunctionality(childRT);
}
}
Jadi cara kode ini menghasilkan tiga baris terakhir dari log debug di atas adalah sebagai berikut: Dibutuhkan sebagai input GameObject
dengan dua komponen: Button
dan PopupOpener
. PopupOpener
meminta agar suatu Button
komponen hadir dalam GameObject yang sama dengan:
[RequireComponent(typeof(Button))]
public class PopupOpener : MonoBehaviour
{
...
}
Iterasi pertama dari loop sementara (dilambangkan oleh teks "ITERATION ON Button Invite (clone)") berusaha untuk menghapus yang Button
pertama, tetapi tidak bisa karena tergantung pada PopupOpener
komponen. ini menimbulkan kesalahan. Kemudian ia mencoba untuk menghapus PopupOpener
komponen, yang ia lakukan, karena tidak bergantung pada hal lain. Dalam iterasi berikutnya (Ditandai oleh teks kedua "ITERATION ON Button Invite (clone)"), itu berusaha untuk menghapus Button
komponen yang tersisa , yang sekarang bisa dilakukan, karena PopupOpener
telah dihapus dalam iterasi pertama (setelah kesalahan).
Jadi pertanyaan saya adalah apakah mungkin untuk memeriksa sebelumnya apakah komponen tertentu dapat dihapus dari saat ini GameObject
, tanpa meminta Destroy()
atau DestroyImmediate()
. Terima kasih.
Destroy
menghapus komponen di akhir frame (sebagai lawan Immediate
ly). DestroyImmediate
dianggap gaya yang buruk, tapi saya pikir beralih ke Destroy
sebenarnya dapat menghilangkan kesalahan ini.