Xin chào, Hackeroon! Hôm nay mình tiếp tục thảo luận về ECS (Entity-Component-System) trong phát triển Unity. Trong , tôi đã thảo luận về ECS (Thực thể-Thành phần-Hệ thống) là gì, tại sao lại cần ECS, cách làm việc với ECS, ưu điểm của ECS trong Unity và nhược điểm của ECS trong . hướng dẫn về ECS (Thực thể-Thành phần-Hệ thống) trong Unity: phần 1 Unity Trong phần này, tôi sẽ tập trung vào những sai lầm của người mới bắt đầu và những cách thực hành tốt khi sử dụng ECS trong trò chơi Unity. Tôi cũng sẽ trình bày một chút về các khuôn khổ cho Unity/C#. Những sai lầm của người mới bắt đầu khi sử dụng ECS trong game Unity Trong phần này, tôi sẽ cho bạn biết về những lỗi mà những người có kinh nghiệm hơn đã nhận thấy trong mã cũ của tôi và điều đó đã ngăn cản tôi phát triển. Tôi cũng sẽ đề cập đến các lỗi mà nhiều người mới bắt đầu mắc phải khi họ bắt đầu thành thạo ECS. Tôi hy vọng điều này sẽ giúp bạn tránh được một số lỗi. Kế thừa thành phần và giao diện Kế thừa các thành phần và sử dụng giao diện là một sai lầm phổ biến của người mới bắt đầu. Vậy tại sao nó không tốt cho sự phát triển của Unity? 4 lý do: Trừu tượng hóa ở cấp độ thành phần hoàn toàn không mang lại lợi ích gì so với trừu tượng hóa ECS thông qua dữ liệu Nó tạo ra những hạn chế cho bạn: bạn sẽ thấy khó mở rộng các thành phần như vậy và tinh chỉnh logic liên quan hơn Nó dẫn đến tình huống khi một thành phần có logic riêng, như chúng tôi nhớ, điều này vi phạm các nguyên tắc của ECS, điều mà bạn không nên làm. Nó dẫn đến một sự cần thiết phi lý là kế thừa các hệ thống hoặc tạo ra tất cả các loại trường hợp chuyển đổi theo loại. Tôi sẽ lưu ý ngay rằng kế thừa các hệ thống không phải lúc nào cũng là một ý tưởng hay, nhưng nó không gây ra điều gì ghê gớm, không giống như kế thừa thành phần. Vì vậy, nếu bạn muốn kế thừa các thành phần, đừng làm điều đó. Hãy suy nghĩ lại về cách bạn có thể giải quyết vấn đề theo cách khác. Không có khả năng sử dụng trừu tượng hóa ECS đúng cách Trừu tượng hóa ECS là khi bạn chỉ cần đặt dữ liệu chung (sẽ được kế thừa trong OOP) vào một thành phần riêng biệt. Bạn tạo một "người thừa kế" của một thành phần như vậy chỉ bằng cách thêm một thành phần mới với dữ liệu bạn cần và lọc các thực thể bằng và . Tất cả mọi thứ là tiểu học. Nếu bạn có một số dữ liệu chung giữa các thành phần/thực thể, hầu như bạn luôn có thể đặt chúng vào một thành phần riêng biệt. Bạn làm điều đó càng sớm thì càng tốt. BaseComponent InheritorComponent Bật/tắt hệ thống để thay đổi logic Trong ECS, thế giới và các hệ thống xử lý thế giới là tĩnh và luôn tồn tại, nhưng các thực thể và dữ liệu của chúng rất động. Và nếu bạn cần vô hiệu hóa một số logic, việc vô hiệu hóa một hệ thống không phải là giải pháp chính xác. Thường không có quyền truy cập vào các hệ thống khác (và đó là một điều tốt). Một tùy chọn thiết thực hơn nhiều là tạo một số thành phần đánh dấu. Nó sẽ nói rằng logic hệ thống sẽ không hoạt động đối với một thực thể có điểm đánh dấu. Nhiều người mới đến tuyên bố: "Nhưng nếu tôi không có các thực thể cho hệ thống, tại sao hệ thống phải hoạt động? Chẳng phải tốt hơn là tắt nó đi để tối ưu hóa sao?". Không, nó không tốt hơn. Nếu bạn thừa nhận rằng có thể không có thực thể nào, thì việc thêm đến phần đầu của phương thức chính của hệ thống. Trong quy mô của , việc gọi một hàm và so sánh hai số nguyên là giọt nước trong đại dương sẽ không ảnh hưởng đến hiệu suất của bạn theo bất kỳ cách nào. if (entities.Length < 1) return; trò chơi Unity Các trường hợp vô hiệu hóa hệ thống hợp pháp duy nhất trong thời gian chạy là thử nghiệm A/B và gỡ lỗi/thử nghiệm các hệ thống cụ thể. Tuy nhiên, hầu hết các khung cung cấp các công cụ để thực hiện việc này không phải từ mã mà từ cửa sổ soạn thảo. Làm cho ECS trở thành tuyệt đối Cần nhớ rằng OOP không bị cấm đối với các tín đồ ECS :D Khi làm việc với ECS, bạn không nên bị ECS ám ảnh hoàn toàn và chuyển mọi thứ cho nó vì nó có thể phản tác dụng. Bên cạnh đó, như tôi đã đề cập trong : không phải tất cả các cấu trúc dữ liệu đều phù hợp với ECS. Vì vậy, tốt hơn hết là tạo một lớp OOP riêng trong những trường hợp như vậy. phần nhược điểm của ECS Một số còn đi xa hơn và tạo một số yếu tố của dự án (ví dụ: giao diện người dùng) không theo ECS, mà hơi sang một bên theo bất kỳ cách thuận tiện nào khác và sau đó kết nối với ECS bằng một số cầu nối. Ngoài ra, tất cả logic bổ sung (tải cấu hình, làm việc trực tiếp với mạng, lưu vào tệp) sẽ dễ dàng hơn để tạo OOP và làm việc với nó trực tiếp từ hệ thống mong muốn. nhà phát triển Unity Bạn nên chọn những việc cần làm dựa trên lẽ thường. ECS sẽ giúp phát triển chứ không phải cản trở nó. Cố gắng chuyển mã hiện tại sang ECS mà không có bất kỳ thay đổi nào Rất thường xuyên, những người mới bắt đầu cố gắng chuyển nguyên văn mã hiện tại của họ sang ECS. Đây không phải là một ý tưởng hay vì cách tiếp cận của ECS để viết mã khác với các mẫu kiến trúc truyền thống. Kết quả của việc chuyển như vậy thường là một mớ hỗn độn từ ECS và mã cuối cùng rất kém. Nếu bạn cần chuyển mã cũ sang ECS, thì tùy chọn tốt nhất là viết cùng một logic từ đầu trên ECS. Tất cả những gì bạn cần làm là sử dụng kiến thức và mã hiện có của mình làm hướng dẫn. Sử dụng Đại biểu/Gọi lại hoặc logic phản ứng trong hệ thống Trong ECS, có thể nguy hiểm khi lấy một số logic từ hệ thống và lưu trữ nó trong một thành phần để sử dụng sau này hoặc để phản ứng ngay lập tức với một số thay đổi (ví dụ: một hệ thống phản ứng với việc thêm một thành phần vào hệ thống khác). Nó không chỉ bổ sung khả năng kết nối không cần thiết cho các hệ thống (chúng trở nên phụ thuộc nhiều vào các cuộc gọi bên ngoài). Nó cũng phá vỡ quy trình xử lý dữ liệu tuyệt đẹp của chúng tôi bằng cách thêm logic mà chúng tôi có ít quyền kiểm soát đối với việc gọi. Sắp xếp tệp vào các thư mục theo loại Khi bạn bắt đầu làm việc với ECS, trước tiên bạn muốn đặt các tệp mới theo loại: thành phần trong thư mục Thành phần và hệ thống trong thư mục Hệ thống. Nhưng với kinh nghiệm, tôi nhận ra rằng cách sắp xếp này không hiệu quả lắm. Không dễ điều hướng với nó để hiểu thành phần nào có liên quan đến hệ thống nào. Tùy chọn tốt nhất là sắp xếp theo các tính năng khi mọi thứ liên quan đến một tính năng cụ thể nằm trong một thư mục (có thể với hệ thống phân cấp nội bộ của các thành phần/hệ thống). Tức là tất cả các thành phần và hệ thống liên quan đến sức khỏe và thiệt hại sẽ nằm trong thư mục Sức khỏe. Điều này sẽ cho phép một người nhìn vào thư mục để hiểu bối cảnh dữ liệu cơ bản cho các hệ thống trong đó và giúp điều hướng dự án dễ dàng hơn. Các phương pháp hay nhất để sử dụng ECS trong trò chơi Unity Ở trên, có lẽ bạn đã đọc về chính xác những điều KHÔNG nên làm khi phát triển trò chơi Unity trên ECS. Bây giờ hãy nói về những thực hành hữu ích và lời khuyên về những gì bạn có thể làm. Gắn thẻ các thực thể với các thành phần đánh dấu Trong ECS, có một khái niệm như thành phần thẻ. Nó là một thành phần không có trường chỉ thực hiện vai trò gắn thẻ thực thể. Bạn có thể coi nó như một cờ boolean trong một lớp: nó ở đó (đúng) hoặc không ở đó (sai). Ví dụ: chúng tôi có một nghìn đơn vị, một trong số đó do người chơi điều khiển. Bạn có thể đánh dấu nó bằng một thành phần trống. Điều này sẽ cho phép bạn chỉ nhận các đơn vị người chơi trong bộ lọc cũng như hiểu được liệu bạn đang làm việc với đơn vị thông thường hay do người chơi điều khiển khi bạn xem qua tất cả các đơn vị cùng một lúc. PlayerMarker Giảm thiểu những nơi mà thành phần thay đổi Càng ít nơi thay đổi một thành phần thì càng tốt. Nói chung, đây là loại chỉ tuân theo nguyên tắc có lợi của Đừng lặp lại chính mình (tôi khuyên mọi người nên làm như vậy). Có rất nhiều lợi ích khi thực hành điều này: Nó cho phép bạn hiểu rõ hơn về quá trình thay đổi dữ liệu trong dự án của mình và đơn giản hóa việc gỡ lỗi nếu có sự cố xảy ra Khi cập nhật logic thay đổi dữ liệu, bạn sẽ cần cập nhật ít mã hơn, lý tưởng nhất là chỉ một nơi Đơn giản là có ít cơ hội hơn để cho phép lỗi dữ liệu xảy ra nhanh chóng Ví dụ: thay vì thay đổi HealthComponent trong mọi hệ thống có thiệt hại, sẽ tốt hơn nếu tạo một DamageSystem với mục đích gây sát thương cho các thực thể bằng HealthComponent. Quên hậu tố Thành phần Hậu tố thành phần rất hữu ích cho người mới bắt đầu vì nó nhắc nhở họ rằng "chỉ có dữ liệu ở đây". Nhưng theo thời gian, nhu cầu nhắc nhở biến mất và mã vẫn khó hiểu với Thành phần phổ biến. Đó là lý do tại sao tôi muốn khuyên bạn: bạn có thể yên tâm quên hậu tố Thành phần đi. Nó không cung cấp bất cứ điều gì hữu ích ngoại trừ, có lẽ, một số đơn giản hóa tìm kiếm trong IntelliSense. Đó chỉ là một mẹo và thậm chí có thể là vấn đề về sở thích, vì vậy cách bạn đối phó với nó là tùy thuộc vào bạn :) Ví dụ: chỉ trở thành và mã trở thành thực thể dễ đọc hơn một . Trong trường hợp này, vẫn không thay đổi vì hậu tố mang thông tin hữu ích trong trường hợp này, lưu ý rằng nó không phải là một thành phần đơn giản. HealthComponent Health entity.Has<Health>() PlayerMarker Phản ứng bị trì hoãn và các thành phần khung đơn Khả năng phản ứng trong ECS có thể gây hại. Nhưng phải làm gì khi cần phải có phản ứng? Câu trả lời là phản ứng bị trì hoãn. Phản ứng bị trì hoãn là khi thay vì gọi logic trực tiếp vào thời điểm xảy ra sự kiện, bạn tạo dữ liệu cho biết sự kiện đã xảy ra và mọi người sẽ chỉ phản ứng với sự kiện vào thời điểm họ muốn. Tôi có thể rút ra một sự tương tự với Cờ bẩn trong OOP, nơi bất kỳ ai cũng có thể khai báo một sự kiện , nhưng logic sẽ phản ứng với sự kiện đó khi nó thấy phù hợp. SetDirty(true) Trong ECS, bạn chỉ cần tạo một thành phần có hoặc không có dữ liệu (bạn chỉ có thể thêm một cờ boolean vào một thành phần hiện có) mà hệ thống sẽ xử lý khi đến lúc. Không hiếm những linh kiện như vậy trên thế giới chỉ tồn tại một khung cảnh báo cho tất cả các hệ thống nhưng không lặp lại logic ở khung hình tiếp theo. Việc xóa có thể được xử lý bởi hệ thống tạo sự kiện hoặc bởi một số hệ thống riêng biệt sẽ xóa tất cả các thành phần của loại X ở nơi bạn muốn. Ví dụ, bạn có một . Để cho nó biết mức độ thiệt hại cần gây ra, bạn khai báo với mức độ thiệt hại và thêm nó vào thực thể sẽ chịu thiệt hại. đi qua tất cả các thực thể có và , làm hỏng thực thể, xóa và tạo để thông báo cho tất cả các hệ thống sau về thực thể bị hỏng. Ở cuối khung, hệ thống riêng lẻ sẽ xóa để hệ thống không xử lý lại điểm đánh dấu này trong khung tiếp theo. DamageSystem MakeDamageComponent DamageSystem HealthComponent MakeDamageComponent MakeDamageComponent DamagedEntityMarker DamageSystem DamagedEntityMarker Yêu cầu/Sự kiện dưới dạng API cho hệ thống Phát triển ý tưởng về các thành phần khung đơn, chúng ta có thể sử dụng chúng để thể hiện một loại API cho các hệ thống. Chúng ta nên phân biệt các thành phần yêu cầu cho các yêu cầu bên ngoài và các thành phần sự kiện để thông báo cho mọi người về sự kiện. Bản thân hệ thống có thể kiểm soát vòng đời của cả hai thành phần. Có thể xóa Yêu cầu ngay sau khi xử lý và làm sạch Sự kiện trước khi khởi chạy sự kiện mới. Việc đặt tên chính xác cho chúng như thế nào và có thêm hậu tố Yêu cầu/Sự kiện hay không là tùy thuộc vào bạn. Ví dụ, bạn có từ đoạn trước. Bạn có thể thể hiện yêu cầu thiệt hại cho nó bằng cách sử dụng thành phần và sử dụng thành phần để thông báo cho các hệ thống khác. Logic bên trong hệ thống như sau: xóa tất cả khỏi khung cuối cùng, làm hỏng tất cả các thực thể bằng một yêu cầu, xóa yêu cầu và thêm thành phần . DamageSystem MakeDamageRequest DamagedEntityEvent DamagedEntityEvent DamagedEntityEvent Lưu trữ một tham chiếu đến một thực thể khác trong một thành phần Chắc hẳn bạn đang thắc mắc "Làm cách nào để xây dựng liên kết giữa các thực thể trong ECS? Có cần thiết phải đánh dấu các thực thể bằng các thành phần rồi tìm kiếm chúng trong một vòng lặp không?". Dĩ nhiên là không. Mọi thứ đơn giản và phổ biến hơn nhiều: chúng tôi chỉ lưu tài liệu tham khảo. Sự khác biệt duy nhất là tham chiếu không phải là một thành phần của thực thể khác mà chúng ta quan tâm mà là chính thực thể đó. Vì vậy, bạn thêm một trường có thực thể (hoặc bất kỳ cách nào mà khung của bạn lưu trữ các thực thể) vào thành phần. Trước khi sử dụng, bạn kiểm tra xem thực thể còn sống và có thành phần mong muốn hay không. Sau đó, bạn lấy thành phần này và làm việc với nó theo ý muốn. Ví dụ: bạn có thể tạo không trực tiếp trên thực thể nhưng chạy nó dưới dạng một sự kiện thực thể riêng biệt có tham chiếu đến thực thể đích. Để thực hiện việc này, bạn thêm trường vào và làm lại . Bây giờ, nó sẽ thực hiện tất cả các yêu cầu, kiểm tra xem mục tiêu có phải là một thực thể sống với , lấy và gây sát thương. MakeDamageRequest Entity target MakeDamageRequest DamageSystem HealthComponent HealthComponent Chạy bây giờ cũng sẽ khác. Thay vì thêm thành phần trực tiếp vào thực thể, bạn tạo một thực thể mới với và chỉ định . Bằng cách này, với chi phí lọc thuận tiện, bạn có thể kích hoạt một số sự kiện thiệt hại khác nhau cho một thực thể . MakeDamageRequest MakeDamageRequest target target Di chuyển logic lặp đi lặp lại sang StaticUtils/Extensions Theo thời gian, bạn bắt đầu nhận thấy rằng bạn đang chạy cùng một logic trên các hệ thống khác nhau. Thông thường, đó là dấu hiệu cho thấy đã đến lúc tạo một hệ thống mới :D Nhưng điều xảy ra là logic lặp đi lặp lại chỉ là thứ yếu, liên quan đến một hoặc hai thành phần/thực thể cụ thể và kết quả của nó được sử dụng cho các mục đích khác nhau. Giả sử, một diễn giải đặc biệt của dữ liệu trong một thành phần. Một số nhà phát triển cho phép khai báo logic bổ sung như vậy trực tiếp trong thành phần (ví dụ: ở dạng getters). Nhưng để tránh vi phạm ECS, tôi đề xuất một tùy chọn khác: tiện ích tĩnh (hoặc Tiện ích mở rộng trong C#) mà chúng tôi gọi từ hệ thống. Ví dụ: chúng tôi có . Bên trong nó, một màu đội được đặt. Việc kiểm tra xem hai thực thể có thuộc về cùng một nhóm hay không có thể cần thiết trong nhiều hệ thống. Vì vậy, chúng tôi tạo một lớp tĩnh và một phương thức trong đó , mô tả logic định kỳ của việc so sánh các nhóm cho hai thực thể. InTeamComponent TeamUtils IsInSameTeam(Entity, Entity) Nhóm các hệ thống theo thời điểm thực hiện Như bạn đã biết, thứ tự gọi các hệ thống là rất quan trọng trong ECS. Vì vậy, thật thuận tiện khi nhóm các hệ thống ở mức cao nhất theo thứ tự mà chúng được gọi trong một khung. Ví dụ, các hệ thống đầu tiên được gọi trong một khung có thể là tất cả các hệ thống liên quan đến đầu vào. Họ sẽ thu thập dữ liệu đầu vào của người dùng và chuẩn bị ở định dạng ECS. Xếp thứ hai sẽ là một nhóm các hệ thống có logic trò chơi, sẽ diễn giải dữ liệu đầu vào theo cách của nó và cập nhật thế giới ECS. Và cuối cùng, chúng tôi có thể có một nhóm hệ thống chịu trách nhiệm kết xuất hoặc chỉ những thứ bổ sung khác sẽ được gọi sau tất cả logic của trò chơi. Tách các tính năng chính thành các cụm riêng biệt Cách tiếp cận này sẽ tách biệt các tính năng với nhau và kiểm soát sự phụ thuộc của chúng. Trong một thế giới lý tưởng, chúng không nên trùng nhau chút nào. Thứ tự giữa các tính năng không quan trọng. Cũng cần có một Hội đồng lõi, nơi đặt các thành phần mà tất cả các tính năng cần để hoạt động. Tôi có nên chia các thành phần/hệ thống thành các phần nhỏ hơn trong ECS không? Câu hỏi này rất thú vị vì các nhà phát triển Unity với kinh nghiệm khác nhau có ý kiến khác nhau về nó. Nhưng tôi sẽ cố gắng trình bày cả hai câu trả lời để giúp bạn hiểu nhu cầu của mình. Vâng, luôn luôn cần phải chia nhỏ các thành phần Cách tiếp cận này trong tổ chức ECS có thể được gọi là nguyên tử. Điểm cao nhất của cách tiếp cận này là mỗi thành phần chỉ có một trường. Điều này sẽ cho phép chúng tôi đạt đến đỉnh cao của dự án về tổ hợp và loại bỏ nhu cầu tái cấu trúc dưới danh nghĩa trừu tượng hóa ECS. Chúng tôi không còn có thể nghĩ về "làm thế nào để kết hợp các thực thể với thuộc tính X." Nhược điểm của việc luôn chia nhỏ các thành phần trong ECS: Số lượng các lớp và tệp sẽ tăng lên, điều này có thể dẫn đến sự nhầm lẫn trong các dự án lớn nếu bạn không chú ý đúng mức đến việc tổ chức dự án Số lượng thành phần (nói chung hoặc theo từng thực thể) có thể ảnh hưởng đến hiệu suất của khung của bạn Thật khó để hiểu một thực thể là gì bởi một loạt các thuộc tính (có thể được giải quyết bằng một điểm đánh dấu có tên bình thường) Bây giờ hãy chuyển sang ý kiến thứ hai. Không, bạn chỉ nên tách các thành phần khi cần thiết Nguyên tắc này được gọi là "Không chia tách trước thời hạn." Đây là nguyên tắc mà cá nhân tôi tuân thủ. Khi bạn cần phân tách dữ liệu, số liệu rất đơn giản: dữ liệu này có được sử dụng/dự định sử dụng ở nơi nào khác ngoài thành phần này không? Nếu không, không có lý do gì để dành thời gian cho nó. Bạn có thể thực hiện một cách tiếp cận tương tự để phân vùng logic thành các hệ thống. Nhược điểm của việc tách các thành phần trong ECS chỉ khi được yêu cầu: Sẽ vẫn phải dành thời gian cho việc trừu tượng hóa ECS Ít tự do hơn để thiết kế các thực thể Tùy bạn chọn phe của mình :) Khung cho Unity/C# Nếu bạn là người mới bắt đầu, tôi sẽ cho rằng bạn đang nghĩ đến việc học Unity DOTS trước tiên. Nhưng tôi muốn cảnh báo bạn. Unity DOTS không phải là một lựa chọn tốt cho người mới bắt đầu vì nó rất lớn và phức tạp. Không có nhiều tài liệu và những người có kinh nghiệm về nó như chúng ta mong muốn. Hơn nữa, nó không tương thích tốt với mã Unity cũ (tất cả điều này có thể thay đổi sau khi xuất bản bài viết này). Nếu bạn thích Unity Editor và đã quen với việc treo các thành phần trực tiếp trên GameObject, thì là lựa chọn tốt nhất của bạn. Nó cung cấp API đơn giản, tích hợp chặt chẽ vào Unity Editor (nó có thể hoạt động bên ngoài Unity) và hoạt động thuận tiện với MonoBehaviour. Nó là đơn giản và thuận tiện. Mọi thứ bạn cần để làm việc với Unity đều có trong đó. Bạn chỉ cần cài đặt nó và làm việc với nó. Nhược điểm chính của nó là nó yêu cầu một trả phí để hoạt động đầy đủ trong Unity. Morpeh Thanh tra Odin Entitas và DOTS (Unity ECS): bạn có nên thành thạo chúng không? Và bây giờ là một bài đánh giá ngắn gọn về các khung Unity/C# mà tôi đã gặp cá nhân và những ưu/nhược điểm mà tôi đã nhận thấy. Điều đáng chú ý là mọi thứ được mô tả bên dưới có thể thay đổi kể từ khi bài viết này được xuất bản, vì vậy tốt hơn hết bạn nên tự mình kiểm tra các khuôn khổ. Thực thể Đây là khung ECS lâu đời nhất cho Unity/C# và vẫn là khung phổ biến nhất. Đây là điều thường thấy nhất trong các tin tuyển dụng với ECS. Entitas ưu: Great WorldViewer trong trình chỉnh sửa Unity Kiểu mã thông thạo (nhờ tạo mã) tài liệu tốt Cộng đồng rất lớn Nhiều dự án thành công trên đó Hỗ trợ bắt buộc từ nhà phát triển (nhờ AssetStore) Có thể được sử dụng bên ngoài Unity trong C# thuần túy Nhược điểm: Hiệu suất kém so với các khung ECS khác (nhưng vẫn tốt hơn MonoBehaviour) Rất nhiều phân bổ, ảnh hưởng tiêu cực đến GC Yêu cầu tạo mã cho mọi thay đổi trong cấu trúc thành phần Trên các dự án lớn, API trở nên rất cồng kềnh do tạo mã Phiên bản Github không cho phép gọi tạo mã do lỗi biên dịch, trong khi phiên bản AssetStore thì có Bạn nên thành thạo nó, ít nhất là ở mức cơ bản. DOTS (Thống nhất ECS) Tôi nghĩ rằng nó không cần giới thiệu. DOTS không phải là một khung mà là một nền tảng chính thức (ngăn xếp công nghệ) với Unity ECS làm khung bên trong. Tôi muốn chỉ ra rằng sau đây là một kinh nghiệm hơi lỗi thời. Tôi thừa nhận rằng DOTS cập nhật có thể loại bỏ các vấn đề được mô tả bên dưới. Ưu điểm của DOTS (Unity ECS): Một nền tảng chính thức để phát triển trên ECS Được xây dựng bởi các nhà phát triển công cụ với sự tích hợp chặt chẽ nhất có thể vào trình chỉnh sửa Hỗ trợ Jobs và Burst Cùng với Jobs và Burst, nó đạt được hiệu suất tối đa trong các khung ECS. Có một thư viện mạng tuyệt vời với các dự đoán NetCode Cơ chế SubScene DOTS (Unity ECS) nhược điểm: Công việc đang tiến hành, dẫn đến phá vỡ các thay đổi mã cũ và các lỗi mới Tài liệu yếu, thường không theo kịp các thay đổi, bạn phải đọc mã nguồn Yêu cầu viết nhiều mã kỹ thuật hơn so với các chất tương tự Mã khó đọc và không ngắn gọn Hoạt động không nhanh hơn các giải pháp nguồn mở không có Burst/Jobs (và trong một số trường hợp chậm hơn) Không phù hợp với mã Unity cũ DOTS về cơ bản là một thời gian chạy và không phải tất cả các chức năng cũ đã được chuyển sang DOTS. Điều này hạn chế khả năng sử dụng. Kết luận về ECS trong Unity Như bạn có thể nhận thấy từ danh sách lớn các nhược điểm, ECS không phải là viên đạn bạc. Giải pháp kiến trúc này, giống như bất kỳ giải pháp nào khác, có những ưu điểm và nhược điểm mà bạn phải chấp nhận nếu bạn chọn phát triển bằng cách sử dụng mẫu kiến trúc này. Vì vậy, lựa chọn sử dụng ECS trong các dự án của bạn hay không hoàn toàn phụ thuộc vào bạn. Tôi thực sự khuyên bạn ít nhất hãy thử thực hiện một dự án nhỏ trên ECS để hiểu liệu bạn có thích cách tiếp cận này hay không. Tôi cũng khuyên bạn nên xem này , nơi có câu trả lời cho nhiều câu hỏi liên quan đến ECS. Bạn sẽ tìm thấy các liên kết đến các báo cáo, danh sách các khuôn khổ cho các ngôn ngữ khác nhau, cũng như các ví dụ về trò chơi và chương trình sử dụng ECS. kho lưu trữ Theo quan điểm cá nhân của tôi, ECS có vẻ là một lựa chọn tuyệt vời để tạo game Unity. Đối với cá nhân tôi, việc phát triển trên đó là một niềm vui: bạn đang phát triển một trò chơi chứ không phải cố gắng tìm cách tích hợp mã mới vào một hệ thống cũ mà không vi phạm bất cứ điều gì. Cần lưu ý rằng khả năng sử dụng của quá trình phát triển ECS bị ảnh hưởng rất nhiều bởi việc lựa chọn khung, vì vậy hãy thử các tùy chọn khác nhau và lựa chọn cẩn thận. Dựa trên kinh nghiệm của mình, tôi có xu hướng nghĩ rằng ECS (hoặc biến thể của nó) là tương lai của việc phát triển trò chơi tương tác. Và không chỉ vì (và thậm chí có thể là Epic) đã chọn nó làm trọng tâm chính của họ, mà đơn giản là vì ECS có những lợi ích thuận lợi trong bối cảnh phát triển trò chơi. Unity Technologies Và nói chung, đó là một cách tiếp cận thực tế có vẻ khó xử khi bắt đầu nhưng sẽ mang lại hiệu quả về lâu dài.