Tìm hiểu về Steering Behaviors (Phần 4.5) - Steering Behaviors và Unity ECS

6
Nguyễn Thanh Long viết 5 năm trước

Giới thiệu

Bài viết lần này sẽ chỉ là một phần mở rộng thuộc về series Steering Behaviors, chính ra nó có thể thành một bài viết riêng biệt nhưng mà em không thích như thế nên sẽ lồng vào đây để tăng độ dài của series :v (Thật ra demo cũng là của Steering Behaviors thôi). Ai dùng Unity cũng biết khi phiên bản Unity 2018 ra mắt đã có road map của một phương pháp lập trình mới mà mọi người gọi đó là ECS (Entities Components System) kết hợp với tính năng mới của C# Job System. Em thì cũng không hiểu nhiều về mấy cái này lắm nhưng nhìn demo thì nó dành cho việc xử lý nhiều (rất nhiều (rất rất nhiều)) những object đòi hỏi việc update thông tin liên tục như particle effect hay là việc giả lập nhiều AI 1 lúc. Cho nên tại sao lại không thử sử dụng phương pháp này cho Steering Behaviors nhỉ?

Unity ECS

Vậy thì Unity ECS là gì. Như ở phần giới thiệu thì đầy đủ của cấu trúc này là Entities Components System. Trong đó Entities là tập hợp của các Components (Na ná như gameobject), Components là nơi chứa những data cần thiết và System là nơi xử lý những data đó.
Unity ECS có 2 loại: Pure ECS và Hybrid ECS. Cho đến thời điểm hiện tại như em tìm hiểu thì Pure ECS có performance cao hơn rất là nhiều so với Hybrid ECS, tuy nhiên sự hỗ trợ hay tính liên quan đến những cấu trúc của Unity hiện tại rất có ít liên quan đến Pure ECS nên bài viết này sẽ không đề cập tới loại này (Mong là sau này sẽ có thể có nhiều tài liệu liên quan đến cái này hơn do hiện tại Pure ECS có những thư viện mà gần như hỗ trợ rất ít đến 2D)
Giờ thì chúng ta đến với Hybrid ECS. Hybrid ECS là việc kết hợp với những tính năng của ECS cùng với hệ thống MonoBehavior của Unity để dễ dàng có được những cầu nối cần thiết để dễ dàng thực hiện việc test ECS.
Dựa trên định nghĩa về ECS thì ta cần tạo ra Components đầu tiên. Vậy thì Components sẽ bao gồm những gì. Hiện tại em có sử dụng 2 Class tên là SteeringResolver và SteerAgent. SteerAgent là một trong những thành phần Components đầu tiên mà chúng ta sử dụng.
alt text
Hàm Start sẽ thiết vị trí ngẫu nhiên của Gameobject được gắn SteerAgent Behavior vào
Class SteeringResolver thực chất là tổng hợp của 4 phần trước và có hàm public duy nhất trả ra Velocity cần thiết để thực hiện việc update vị trí của các GameObject.
Sau đây sẽ là System. Tạo một hàm mới là SteerSystem như sau. Do bản chất của Hybrid ECS là sử dụng cùng với MonoBehavior nên ta sẽ tạo một C# Script với Class kế thừa từ MonoBehavior. Trong đó có nested class là SteerSystem. Đây chỉ là ý kiến cá nhân của em, mọi người đều có thể đưa Class Steer System vào trong bất kỳ Script nào mà kế thừa từ MonoBehavior.
alt text
Trong System thì cần phải khai báo Components mà System cần phải thực hiện việc tính toán. Components ở đây bao gồm SteerAgent (Như đã tạo ở trên) và Transform để thực hiện việc Update thông tin về tọa độ vị trí, translate dựa trên velocity.
Có thể thấy thì SteerSystem kế thừa từ ComponentSystem, ComponentSystem có hàm bắt buộc phải implement vào là hàm OnUpdate(). Tương tự như Update của MonoBehavior, OnUpdate cũng được sử dụng ở mỗi Frame mà hệ thống trải qua.
Trong hàm OnUpdate() thì cần phải thực hiện việc Update các thông tin cần thiết của tất cả các Entities mà có gán Components. Hàm GetEntities() sẽ đảm nhiệm vai trò tìm và trả ra tất cả các Entities mà có chứa các thành phần đã khai báo ở Components. Và sẽ chỉ cần thực hiện việc cập nhật thông tin của các Components từ những Entities có chứa kiểu Struct trên. Kể cả có 4 hay 8 hay 8 chục Components ở trong Gameobject nếu như có chứa Struct thì đều sẽ được hàm GetEntites trả ra.
Việc loop qua tất cả các Object ở trong tập hợp các Entities như trong đoạn script trên thì em không giải thích nữa vì thực sự nó cũng giống như hàm Update bình thường của Steering Behavior ở các bài trước.
Như vậy đã xong. Ta sẽ gán đoạn C# script này vào đâu đó trong scene như là MainCamera chẳng hạn. Sau đó tạo ra vài nghìn gameobject được gán Transform và SteerAgent vào. Ít nhất thì Scene hiện tại của em nhìn như sau:
alt text
Ở trong scene trên Hierachy gồm 1 Main Camera và 12k Game Object gồm có SpriteRenderer, Transform, SteerAgent và Game Object Entity Components.
alt text
Bấm Play và chứng kiến điều kỳ diệu
alt text
Em cũng có 1 Scene khác cũng bao gồm 12k game Object nhưng Scene này lại chứa Update cổ điển của Unity
alt text
Có khác gì không? Thực ra thì không như em mong đợi. Với một hệ thống như Steering Behaviors thì 12k Object là không phải là nhiều, 2 kiểu thì nhìn qua không khác gì nhau về performance là mấy. Tuy nhiên có thể thấy fps trung bình của Hybrid ECS cao hơn một chút so với Update cổ điển. Tức là có cải thiện nhưng mà không nhiều. Thôi thì méo mó có còn hơn không, việc cải thiện 2~3 fps là không nhiều nhưng mà nó đánh dấu việc chứng minh thấy ECS có gì đó hơn Update cổ điển, chỉ là hiện tại cách tiếp cận của em dành cho Hybrid ECS là chưa chính xác.

Kết luận

Bài viết chỉ mang tính chất tham khảo cho những ai muốn tìm hiểu về Unity ECS, và đây là những gì cơ bản nhất của Unity ECS mà có thể dể dàng thực hiện. Trong những demo của những người sử dụng Pure ECS thì việc Update đến hàng chục nghìn thậm chí đến hàng trăm nghìn gameobject mà fps vẫn trên được 30 là hoàn toàn có thể. Nhưng mà hiện tại thì ECS vẫn đang rất khó tiếp cận do việc hạn chế nhiều đầu vào nên hãy chờ đợi (Hoặc tạo ra) những helper class sau này để khiến cho việc implements Unity ECS hay đặc biệt là Pure ECS dễ dàng hơn.

Bình luận


White
{{ comment.user.name }}
Hay Bỏ hay
{{ comment.like_count}}
White

Nguyễn Thanh Long

12 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}

  Cùng một tác giả


{{like_count}}

kipalog

{{ comment_count }}

Bình luận


White
{{userFollowed ? 'Following' : 'Follow'}}
12 bài viết.
0 người follow

 Đầu mục bài viết

 Cùng một tác giả