Phát triển một trò chơi trong Unity, tôi đang sử dụng tự do [RequireComponent(typeof(%ComponentType%))]
để đảm bảo các thành phần có tất cả các phụ thuộc được đáp ứng.
Tôi hiện đang thực hiện một hệ thống hướng dẫn làm nổi bật các đối tượng UI khác nhau. Để làm nổi bật, tôi lấy tham chiếu đến GameObject
cảnh trong đó, sau đó tôi sao chép nó bằng Instantiate () và sau đó loại bỏ đệ quy tất cả các thành phần không cần thiết để hiển thị. Vấn đề là với việc sử dụng tự do RequireComponent
trong các thành phần này, nhiều thành phần không thể bị xóa đơn giản theo bất kỳ thứ tự nào, vì chúng phụ thuộc vào các thành phần khác, chưa bị xóa.
Câu hỏi của tôi là: Có cách nào để xác định xem một cái Component
có thể được gỡ bỏ khỏi GameObject
nó hiện đang được gắn vào hay không.
Mã tôi đang đăng hoạt động về mặt kỹ thuật, tuy nhiên, nó đưa ra các lỗi Unity (không bị bắt trong khối thử bắt, như đã thấy trong hình ảnh
Đây là mã:
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);
}
}
Vì vậy, cách mã này tạo ra ba dòng cuối cùng của nhật ký gỡ lỗi ở trên là như sau: Nó lấy đầu vào a GameObject
với hai thành phần: Button
và PopupOpener
. PopupOpener
yêu cầu một Button
thành phần có mặt trong cùng GameObject với:
[RequireComponent(typeof(Button))]
public class PopupOpener : MonoBehaviour
{
...
}
Lặp lại đầu tiên của vòng lặp while (được biểu thị bằng văn bản "ITERATION ON Nút Mời (bản sao)") đã cố xóa Button
đầu tiên, nhưng không thể vì nó phụ thuộc vào PopupOpener
thành phần. Điều này đã gây ra một lỗi. Sau đó, nó đã cố gắng để xóa PopupOpener
thành phần, như nó đã làm, vì nó không phụ thuộc vào bất cứ điều gì khác. Trong lần lặp tiếp theo (Được biểu thị bằng văn bản thứ hai "ITERATION ON Nút Mời (bản sao)"), nó đã cố xóa Button
thành phần còn lại , điều mà bây giờ có thể làm được, vì PopupOpener
đã bị xóa trong lần lặp đầu tiên (sau lỗi).
Vì vậy, câu hỏi của tôi là liệu có thể kiểm tra trước thời hạn nếu một thành phần được chỉ định có thể được gỡ bỏ khỏi hiện tại của nó GameObject
, mà không cần gọi Destroy()
hay DestroyImmediate()
. Cảm ơn bạn.
Destroy
loại bỏ thành phần ở cuối khung (trái ngược với Immediate
ly). DestroyImmediate
Dù sao cũng bị coi là xấu, nhưng tôi nghĩ chuyển sang Destroy
thực sự có thể loại bỏ những lỗi này.