Tại sao tôi phải luôn luôn cân nhắc việc tạo và sử dụng nhóm đối tượng thay vì khởi tạo đối tượng mới một cách nhanh chóng?


25

Tôi đã đọc về mẫu này nhiều lần (từ góc độ thực hành tốt nhất):

Phân bổ bộ nhớ : Thay vì khởi tạo đối tượng mới một cách nhanh chóng, hãy luôn xem xét việc tạo và sử dụng nhóm đối tượng. Nó sẽ giúp phân mảnh bộ nhớ ít hơn và làm cho trình thu gom rác hoạt động ít hơn.

Tuy nhiên, tôi không biết ý nghĩa thực sự của nó. Làm thế nào tôi có thể thực hiện nó?

Ví dụ: tôi có thể khởi tạo một phương thức GameObjectsử dụng Instantiatephương thức Unity không?

Instantiate(prefab, new Vector3(2.0F, 0, 0), Quaternion.identity);

Là sử dụng này không khuyến khích? Nó có thể có ý nghĩa gì khác?



Cảm ơn Hellium tôi đã không xem video đã cho (quá lớn) nhưng văn bản thực sự giúp tôi hiểu "Hành động bắt chước và phá hủy là không hiệu quả và có thể làm chậm các dự án của bạn"
Muhammad Faizan Khan

1
Lưu ý rằng mặc dù lời khuyên này là phổ biến, nhưng nó không phải là một yêu cầu tuyệt đối cho mọi trò chơi. Đặc biệt, nếu bạn đang tạo một trò chơi nhỏ / ngắn trên máy tính để bàn, gửi bài hoặc nguyên mẫu, bạn không cần phải thực hiện việc tổng hợp. Trong các thử nghiệm ngâm của tôi, Unity nắm giữ thậm chí sinh sản lớn và phá hủy tốt hơn chúng tôi cho nó tín dụng. )
DMGregory

Cảm ơn @DMGregory Bạn đã đúng. đầu vào của bạn luôn có giá trị. Chúng ta không nên lo lắng về việc gộp đối tượng trong các trò chơi nhỏ vì nó sẽ đòi hỏi thêm công việc mã hóa.
Muhammad Faizan Khan

1
Đây là một mô hình rất phổ biến, nhưng hãy đảm bảo tiết chế nó theo quy tắc: "Hồ sơ trước, sau đó tối ưu hóa". Thật dễ dàng để tối ưu hóa những thứ không quan trọng.
Cort Ammon - Phục hồi Monica

Câu trả lời:


41

Nếu bạn dự định khởi tạo nhiều phiên bản của cùng một prefab, bạn chắc chắn nên nghĩ về việc sử dụng nhóm đối tượng. Gọi chức năng Instantiate của Unity là một trong những phương thức gọi thuế nhiều nhất bạn có thể thực hiện.

Nhóm đối tượng là khi bạn khởi tạo prefabs trước khi chúng được sử dụng. Chúng bị vô hiệu hóa ngay lập tức khi khởi tạo và chỉ được kích hoạt lại khi cần thiết. Mặc dù điều này không làm tăng mức sử dụng bộ nhớ, nhưng nó tránh được tình trạng quá tải CPU trong quá trình chơi trò chơi.

Ví dụ, tôi hiện đang làm việc trong một trò chơi địa ngục đạn đòi hỏi hàng trăm viên đạn được sinh ra trong thời gian chạy. Ban đầu tôi đã cố gắng làm cho trò chơi không có đối tượng gộp nhưng điều đó đã trở thành một thảm họa (dưới 2 khung hình / giây). Bây giờ, tôi tập hợp 500 viên đạn trước khi trò chơi bắt đầu và trò chơi chạy nhanh một cách đáng kinh ngạc (200 khung hình / giây).

Có những tình huống mà đối tượng gộp lại không thể được sử dụng. Chẳng hạn, nếu bạn có một trò chơi trong đó đầu vào của người chơi chỉ ra những gì prefab được sinh ra, thì bạn có thể không có lựa chọn nào khác ngoài sử dụng cuộc gọi Instant tức thì thông thường. Nhóm đối tượng chỉ có thể khi bạn biết trước những đối tượng sẽ cần.

Hướng dẫn YouTube của Sebastian Lague là một tài nguyên tuyệt vời để tìm hiểu về nhóm đối tượng: https://youtu.be/LhqP3EghQ-Q


"Hành động khởi tạo và phá hủy là không hiệu quả và có thể làm chậm các dự án của bạn". đây là lý do? Vì vậy, điều đó có nghĩa là chúng ta phải mã hóa thêm một chút (như kích hoạt chức năng vô hiệu hóa hoặc đặt lại vị trí của viên đạn để chúng ta có thể bắn lại)
Muhammad Faizan Khan

12
Có thể đáng để đề cập đến việc phân bổ và thu gom rác với tư cách là những người đóng góp chính cho chi phí khởi tạo và phá hủy lặp đi lặp lại. Tạo đủ rác và cuối cùng toàn bộ trò chơi phải chờ người thu gom rác quét hết. ;)
DMGregory

3
@corsiKa đó sẽ là tối ưu hóa thời đại của thập niên 80. Unity chỉ có thể hủy kích hoạt prefabs trong câu hỏi, làm cho các hệ thống của nó bỏ qua nó.
congusbongus

2
"Chẳng hạn, nếu bạn có một trò chơi trong đó đầu vào của người chơi chỉ ra những gì prefab được sinh ra, thì bạn có thể không có lựa chọn nào khác ngoài sử dụng cuộc gọi Instant tức thì thông thường." - Không hẳn. Bạn có thể dễ dàng có nhiều nhóm đối tượng cho các prefab khác nhau được phân bổ cho các kích thước mong muốn khi khởi động (hoặc tải cảnh). Hoặc, nếu một người muốn tạo ra nó, một nhóm đối tượng lưu trữ nhiều loại prefab cũng có thể hoạt động.
Ethan Bierlein

1
@DMGregory Trong môi trường GC điển hình, việc phân bổ lại hầu hết là chi phí; trong một môi trường không phải là GC điển hình, phân bổ là phần lớn chi phí. Nhóm đối tượng hoạt động tuyệt vời cho cả hai, hầu hết chúng chỉ là hai mặt của cùng một đồng tiền. Trong trường hợp cực đoan, các trò chơi cũ thường được viết với tất cả các đối tượng được "phân bổ" từ việc di chuyển - rất ít hoặc không có sự phân bổ bộ nhớ trong khi trò chơi đang chạy. Bạn đã không thực sự sử dụng bất cứ thứ gì không được "gộp" theo một cách nào đó. Vì Unity sử dụng rất nhiều "siêu dữ liệu" thời gian thực, nên việc gộp chung có thể giúp ích khá nhiều - mặc dù nó cũng có thể khó thực hiện hơn.
Luaan
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.