Đối tượng bạn muốn khởi tạo là null. Nhưng nó hoạt động, tôi có thể bỏ qua lỗi không?


18

Điều này chưa bao giờ xảy ra với tôi vì vậy tôi có một chút bối rối.

GameObject someObject = Instantiate (Resources.Load ("Prefabs/Items/" + someName)) as GameObject;

Điều này đưa ra một lỗi nhưng đối tượng thực sự được khởi tạo và mọi thứ hoạt động như dự định. Lỗi không dừng chương trình cho dù tôi có tái tạo điều này bao nhiêu lần đi chăng nữa.

Tôi có thể bỏ qua lỗi này không hoặc có một số vấn đề mà tôi không thấy?


32
bạn không bao giờ nên bỏ qua lỗi. Họ luôn ở đó vì một lý do;)
Gabriele Vierti

5
Tôi muốn thứ hai ý tưởng không bao giờ bỏ qua lỗi chỉ vì "nó hoạt động". Theo định nghĩa, nếu có lỗi, nó không hoạt động. Chắc chắn, nó dường như có thể làm mọi thứ bạn muốn, nhưng điều đó chỉ có nghĩa là bạn chưa tìm thấy bit bị hỏng.
Vụ kiện của Quỹ Monica

Câu trả lời:


46

Nếu đối tượng được khởi tạo chính xác mặc dù Intantiate() dòng ném một ngoại lệ, thì lỗi xuất phát từ một phiên bản khác của tập lệnh - bạn có thể vô tình có một bản sao thứ hai trong cảnh của mình.

Một phiên bản được cấu hình đúng và thực hiện Instantiate()như mong đợi mà không có lỗi, vì vậy đối tượng được tạo như mong muốn.

Một trường hợp khác được cấu hình không chính xác và đưa ra một lỗi. Nhưng nếu bạn chỉ nhìn vào trường hợp được cấu hình chính xác, lỗi này dường như đến từ đâu và không có hậu quả rõ ràng.

Bạn có thể in đường dẫn đến đối tượng trên Bắt đầu - hoặc trong kiểm tra null ngay trước dòng vi phạm - để giúp theo dõi các bản sao cảnh không mong muốn.

Bạn tuyệt đối không nên bỏ qua lỗi này.

Tốt nhất, nó đang đốt các chu kỳ tính toán không cần thiết. Tệ nhất, đó là một dấu hiệu cho thấy trò chơi của bạn đang làm điều gì đó mà bạn không hiểu đầy đủ và đó có thể là gốc rễ của những vấn đề lớn hơn nhiều.


12
+1, lỗi không giống như cảnh báo, nếu có lỗi, bạn không bao giờ biết khi nào nó sẽ leo thang đến toàn bộ trò chơi bị sập.
TomTsagk

13
Không phải lúc nào cũng an toàn để bỏ qua các cảnh báo. Ngay cả khi đó không phải là lỗi, nó vẫn có khả năng dẫn đến tình huống trò chơi gặp sự cố.
Sean Burton

2
Tôi đồng ý với @SeanBurton, bỏ qua các cảnh báo không phải là một thực hành an toàn. Bạn nên bỏ qua một cảnh báo nếu, và chỉ khi, bạn hiểu điều gì gây ra nó và thoải mái rằng nó không gây ra vấn đề trong mã của bạn. Ngay cả sau đó, hãy tự hỏi nếu bạn không thể làm điều đó tốt hơn.
Jack Aidley

3
Mỗi dự án tôi từng làm việc với một nhóm lớn có lúc đã quá tải với những cảnh báo "không thể biết được" rằng nó bắt đầu che giấu những vấn đề thực sự. Vì vậy, tôi chắc chắn sẽ ủng hộ việc xử lý các cảnh báo một cách nghiêm túc, và nếu không thể tránh khỏi, hãy vô hiệu hóa nó cho dòng liên quan cùng với một nhận xét xác định rõ ràng lý do tại sao lại an toàn khi bỏ qua việc tạo cảnh báo ở đó.
DMGregory

1
Tôi 100% với @DMGregory, tôi chỉ làm việc trong các nhóm rất nhỏ, nhưng cặp lần cảnh báo bắt đầu chồng chất thật kinh khủng khi tìm thấy các vấn đề "chính hãng" hoặc bạn luôn nhớ họ. MO của tôi là giữ cho nhật ký sạch sẽ trừ khi thử nghiệm, ngay cả khi tôi phải vô hiệu hóa các cảnh báo về mã của plugin (xin vui lòng, đừng tạo ra các plugin có cảnh báo EVER), trong IMO dài hạn sẽ tốt hơn nhiều. Chỉnh sửa: để rõ ràng, không bao giờ tắt cảnh báo trừ khi bạn chắc chắn 100% không có cách nào khác (xảy ra 0,001% thời gian), luôn thực sự khắc phục chúng.
Trisibo

21

Câu trả lời

Hãy để tôi bắt đầu bằng cách trả lời trực tiếp câu hỏi của bạn:

Nó hoạt động, tôi có thể bỏ qua lỗi?

Bạn có thể . Bạn nên không , bởi vì nó có nghĩa là một cái gì đó đang đi sai. Bạn sẽ quen với lỗi này, nhưng nó có thể "ẩn" hoặc gây ra lỗi khác.

Hiện tại bạn có một thông báo lỗi và nó vẫn hoạt động chính xác. Cách khác, nó không động và không có (hoặc đúng hơn: không nhận ra) thông tin phản hồi tại sao, còn tồi tệ hơn nhiều!

Lời khuyên

Để tìm ra nơi này đến từ đâu, hãy chia toàn bộ điều này thành nhiều dòng.

string resourceLocation = "Prefabs/Items/" + someName;
Object prefab = Resources.Load(resourceLocation);
Object instance = Instantiate(prefab);
GameObject someObject = instance as GameObject;

Một lỗi chỉ cho bạn biết nó đã xảy ra ở dòng nào. Nếu lỗi xảy ra trong mã này, số dòng sẽ cho bạn biết thêm về phần nào bị lỗi ở đây. Ngoài ra, tôi khuyên bạn nên sử dụng phiên bản chung của Resources.Load, điều đó thực sự sẽ giúp chúng tôi bớt đi một bước để lo lắng về:

string resourceLocation = "Prefabs/Items/" + someName;
GameObject prefab = Resources.Load<GameObject>(resourceLocation);
GameObject someObject = Instantiate(prefab);

Tìm hiểu tại sao

  • Bây giờ, một chút kinh nghiệm của Unity cho chúng ta biết rằng Đối tượng mà bạn muốn tạo tức thì là null. Instantiate() .
  • Vì vậy, điều đó có nghĩa prefabnull.
  • Vì vậy, điều đó có nghĩa là Resources.Loadtrở lại null.
  • Các tài liệu choResources.Load biết " Returns tài sản tại pathnếu nó có thể được tìm thấy nếu không thì trả null. "
  • Vì vậy, điều đó có nghĩa là nó không tìm thấy đường dẫn đã cho (chuỗi tôi đã gọi resourceLocation)

Có gì đó không ổn với con đường này, vì vậy bước đầu tiên rõ ràng sẽ là xem cuối cùng nó thực sự là gì, với Debug.Log. Vì "mọi thứ hoạt động như dự định", có thể có một số sự trùng lặp đang diễn ra khi một phiên bản hoạt động và phiên bản kia cung cấp cho bạn lỗi này.

Trong trường hợp đó, nên sử dụng phiên bản 2 tham số của Debug.Log Debug.Log(resourceLocation, gameObject);. Bây giờ nếu bạn nhấp vào thông điệp tường trình trong trình soạn thảo Unity, nó sẽ chọn GameObjectnơi nó đến.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.