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 GameObjectcả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 RequireComponenttrong 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 Componentcó thể được gỡ bỏ khỏi GameObjectnó 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 GameObjectvới hai thành phần: Buttonvà PopupOpener. PopupOpeneryêu cầu một Buttonthà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 PopupOpenerthành phần. Điều này đã gây ra một lỗi. Sau đó, nó đã cố gắng để xóa PopupOpenerthà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 Buttonthà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.
Destroyloại bỏ thành phần ở cuối khung (trái ngược với Immediately). DestroyImmediateDù sao cũng bị coi là xấu, nhưng tôi nghĩ chuyển sang Destroythực sự có thể loại bỏ những lỗi này.
