Cách tốt nhất để cấu trúc / quản lý hàng trăm nhân vật 'trong trò chơi'


10

Tôi đã tạo một game RTS đơn giản, chứa hàng trăm nhân vật như Crusader Kings 2, trong Unity. Để lưu trữ chúng, tùy chọn đơn giản nhất là sử dụng các đối tượng có thể viết script, nhưng đó không phải là một giải pháp tốt vì bạn không thể tạo các đối tượng mới khi chạy.

Vì vậy, tôi đã tạo ra một lớp C # gọi là "Ký tự" chứa tất cả dữ liệu. Mọi thứ đều hoạt động tốt, nhưng khi trò chơi mô phỏng, nó liên tục tạo ra các nhân vật mới và giết một số nhân vật (như các sự kiện trong trò chơi xảy ra). Khi trò chơi mô phỏng liên tục, nó tạo ra 1000 nhân vật. Tôi đã thêm một kiểm tra đơn giản để đảm bảo một nhân vật "Sống" trong khi xử lý chức năng của nó. Vì vậy, nó giúp hiệu suất, nhưng tôi không thể xóa "Nhân vật" nếu anh ấy / cô ấy chết, vì tôi cần thông tin của anh ấy / cô ấy trong khi tạo cây gia đình.

Danh sách có phải là cách tốt nhất để lưu dữ liệu cho trò chơi của tôi không? Hoặc nó sẽ đưa ra vấn đề khi có 10000 nhân vật được tạo ra? Một giải pháp khả thi là lập một danh sách khác một khi danh sách đạt đến một số tiền nhất định và di chuyển tất cả các ký tự đã chết trong đó.


9
Một điều tôi đã làm trong quá khứ khi tôi cần một tập hợp con dữ liệu của một nhân vật sau khi nó bị hủy là tạo ra một đối tượng "bia mộ" cho nhân vật đó. Bia mộ có thể mang thông tin tôi cần tìm kiếm sau này, nhưng nó có thể nhỏ hơn và lặp đi lặp lại ít thường xuyên hơn vì nó không cần mô phỏng liên tục như một nhân vật sống.
DMGregory


2
Là trò chơi như CK2, hay chỉ là phần có nhiều nhân vật? Tôi hiểu nó như toàn bộ trò chơi giống như CK2. Trong trường hợp đó, rất nhiều câu trả lời ở đây không phải là không chính xác và chứa đựng bí quyết tốt, nhưng chúng bỏ lỡ điểm của câu hỏi. Không có ích gì khi bạn gọi CK2 là một trò chơi chiến lược thời gian thực khi nó thực sự là một trò chơi chiến lược lớn . Điều đó có vẻ khó chịu, nhưng nó rất phù hợp với các vấn đề bạn gặp phải.
Raphael Schmitz

1
Ví dụ: khi bạn đề cập đến "1000 ký tự", mọi người đang nghĩ đến 1000 mô hình 3D hoặc các họa tiết trên màn hình cùng một lúc - vì vậy, trong Unity, 1000 giây GameObjects. Trong CK2, số lượng ký tự tối đa tôi thấy cùng một lúc là khi tôi nhìn vào tòa án của mình và thấy 10-15 người ở đó (mặc dù tôi không chơi rất xa). Cũng như vậy, một đội quân với 3000 binh sĩ chỉ là một GameObject, hiển thị số "3000".
Raphael Schmitz

1
@ R.Schmitz Có, tôi nên làm cho phần đó rõ ràng rằng mọi Nhân vật không có trò chơi kèm theo. Bất cứ khi nào cần thiết như di chuyển nhân vật từ điểm này sang điểm khác. Một thực thể riêng biệt được tạo ra chứa tất cả thông tin của Nhân vật đó với logic Ai.
paul p

Câu trả lời:


24

Có ba điều bạn nên xem xét:

  1. thực sự gây ra một vấn đề hiệu suất? 1000s là, tốt, không nhiều thực sự. Máy tính hiện đại rất nhanh và có thể xử lý rất nhiều thứ. Theo dõi xem việc xử lý nhân vật mất bao nhiêu thời gian và xem liệu nó có thực sự gây ra vấn đề hay không trước khi lo lắng quá nhiều về nó.

  2. Độ trung thực của các nhân vật hiện đang hoạt động tối thiểu. Một lỗi thường gặp của các lập trình viên trò chơi mới bắt đầu là ám ảnh về việc cập nhật chính xác các nhân vật ngoài màn hình giống như các nhân vật trên màn hình. Đây là một sai lầm, không ai quan tâm. Thay vào đó, bạn cần tìm cách tạo ấn tượng rằng các nhân vật ngoài màn hình vẫn đang hành động. Bằng cách giảm số lượng ký tự cập nhật ngoài màn hình, bạn có thể giảm đáng kể thời gian xử lý.

  3. Xem xét định hướng dữ liệu-thiết kế. Thay vì có 1000 đối tượng ký tự và gọi cùng một hàm cho mỗi đối tượng, hãy có một mảng dữ liệu cho 1000 ký tự và có một vòng lặp chức năng trên 1000 ký tự cập nhật lần lượt từng ký tự. Loại tối ưu hóa này có thể cải thiện đáng kể hiệu suất.


3
Thực thể / Thành phần / Hệ thống hoạt động tốt cho việc này. Xây dựng mỗi "hệ thống" cho những gì bạn cần, để nó giữ hàng nghìn hoặc hàng chục nghìn ký tự (thành phần của chúng) và cung cấp "ID ký tự" cho hệ thống. Điều này cho phép bạn tách các mô hình dữ liệu khác nhau và nhỏ hơn và bạn cũng có thể xóa các ký tự chết khỏi các hệ thống không cần chúng. (Bạn cũng có thể tải hoàn toàn một hệ thống, nếu bạn không sử dụng nó vào lúc này.)
Der Kommissar

1
Bằng cách giảm số lượng ký tự cập nhật ngoài màn hình, bạn có thể tăng đáng kể thời gian xử lý. Bạn không có nghĩa là giảm?
Tejas Kale

1
@TejasKale: Vâng, đã sửa.
Jack Aidley

2
Một ngàn ký tự không phải là nhiều, nhưng khi mỗi người trong số họ liên tục kiểm tra xem liệu họ có thể thiến từng người khác không, điều đó có ảnh hưởng lớn đến hiệu suất tổng thể không ...
tò mò

1
Luôn luôn tốt nhất để thực sự kiểm tra, nhưng nói chung là một giả định làm việc an toàn rằng người La Mã sẽ muốn thiến nhau;)
tò mò

11

Trong tình huống này, tôi khuyên bạn nên sử dụng Thành phần :

Nguyên tắc rằng các lớp nên đạt được hành vi đa hình và sử dụng lại mã theo thành phần của chúng (bằng cách chứa các thể hiện của các lớp khác thực hiện chức năng mong muốn)


Trong trường hợp này, có vẻ như Characterlớp của bạn đã trở nên giống như thần và chứa tất cả các chi tiết về cách một nhân vật hoạt động ở tất cả các giai đoạn trong vòng đời của nó.

Ví dụ, bạn lưu ý rằng các ký tự chết vẫn được yêu cầu - vì chúng được sử dụng trong các cây gia đình. Tuy nhiên, không chắc rằng tất cả thông tin và chức năng của các nhân vật còn sống của bạn, vẫn cần thiết chỉ để hiển thị chúng trong cây gia đình. Họ có thể, ví dụ, chỉ cần tên, ngày sinh và biểu tượng chân dung.


Giải pháp, là chia các phần riêng biệt của bạn Characterthành các lớp con, Charactersở hữu một thể hiện của. Ví dụ:

  • CharacterInfo có thể là một cấu trúc dữ liệu đơn giản với tên, ngày sinh, ngày chết và phe nhóm,

  • Equipmentcó thể có tất cả các vật phẩm mà nhân vật của bạn có, hoặc tài sản hiện tại của chúng. Nó cũng có thể có logic quản lý các chức năng này.

  • CharacterAIhoặc CharacterControllercó thể có tất cả thông tin cần thiết về mục tiêu hiện tại của nhân vật, các chức năng tiện ích của họ, v.v. Và nó cũng có thể có logic cập nhật thực tế phối hợp việc ra quyết định / tương tác giữa các bộ phận riêng lẻ.

Khi bạn đã tách nhân vật ra, bạn không còn cần phải kiểm tra cờ Sống / Chết trong vòng cập nhật.

Thay vào đó, bạn muốn chỉ cần thực hiện một AliveCharacterObjectmà có CharacterController, CharacterEquipmentCharacterInfokịch bản đính kèm. Để "giết" nhân vật, bạn chỉ cần xóa các phần không còn phù hợp (chẳng hạn như CharacterController) - giờ đây nó sẽ không lãng phí bộ nhớ hoặc xử lý thời gian.

Lưu ý, làm thế nào CharacterInfocó khả năng là dữ liệu duy nhất thực sự cần thiết cho cây gia đình. Bằng cách phân tách các lớp của bạn thành các phần chức năng nhỏ hơn - bạn có thể dễ dàng giữ đối tượng dữ liệu nhỏ đó sau khi chết mà không cần phải giữ toàn bộ nhân vật do AI điều khiển.


Điều đáng nói là mô hình này là một Unity được xây dựng để sử dụng - và đó là lý do tại sao nó xử lý mọi thứ với nhiều tập lệnh riêng biệt. Xây dựng các đối tượng thần lớn hiếm khi là cách tốt nhất để xử lý dữ liệu của bạn trong Unity.


8

Khi bạn có một lượng lớn dữ liệu để xử lý và không phải mọi điểm dữ liệu được đại diện bởi một đối tượng trò chơi thực tế, thì thường không phải là ý tưởng tồi để từ bỏ các lớp cụ thể của Unity và chỉ đi với các đối tượng C # cũ. Bằng cách đó bạn giảm thiểu chi phí. Vì vậy, bạn dường như đang đi đúng hướng ở đây.

Lưu trữ tất cả các ký tự, sống hoặc chết, trong một Danh sách ( hoặc mảng ) có thể hữu ích vì chỉ mục trong danh sách đó có thể đóng vai trò là ID ký tự chính tắc. Truy cập vị trí danh sách theo chỉ mục là một hoạt động rất nhanh. Nhưng nó có thể hữu ích để giữ một danh sách ID riêng của tất cả các nhân vật sống, bởi vì bạn có thể sẽ cần phải lặp đi lặp lại những điều đó thường xuyên hơn bạn sẽ cần các nhân vật đã chết.

Khi việc triển khai cơ chế trò chơi của bạn đạt được tiến bộ, bạn cũng có thể muốn xem xét loại tìm kiếm nào khác mà bạn thực hiện nhiều nhất. Giống như "tất cả các nhân vật sống ở một vị trí cụ thể" hoặc "tất cả tổ tiên sống hoặc chết của một nhân vật cụ thể". Có thể có ích khi tạo thêm một số cấu trúc dữ liệu thứ cấp được tối ưu hóa cho các loại truy vấn này. Chỉ cần nhớ rằng mỗi người trong số họ phải được cập nhật. Điều này đòi hỏi lập trình bổ sung và sẽ là nguồn gây ra lỗi bổ sung. Vì vậy, chỉ làm điều đó nếu bạn mong đợi một sự gia tăng hiệu suất đáng chú ý.

CKII "cắt xén " các ký tự từ cơ sở dữ liệu của nó khi nó coi chúng là không quan trọng để tiết kiệm tài nguyên. Nếu đống nhân vật chết của bạn tiêu tốn quá nhiều tài nguyên trong một trò chơi dài, thì bạn có thể muốn làm điều gì đó tương tự (tôi không muốn gọi đây là "bộ sưu tập rác". Có lẽ là "gia tăng đáng kính"?).

Nếu bạn thực sự có một đối tượng trò chơi cho mọi nhân vật trong trò chơi, thì hệ thống Unity ECS và Jobs mới có thể hữu ích cho bạn. Nó được tối ưu hóa để xử lý một số lượng lớn các đối tượng trò chơi rất giống nhau theo cách thức biểu diễn. Nhưng nó buộc kiến ​​trúc phần mềm của bạn vào một số mẫu rất cứng nhắc.

Nhân tiện, tôi thực sự thích CKII và cách nó mô phỏng một thế giới với hàng ngàn nhân vật do AI điều khiển độc đáo, vì vậy tôi rất mong được chơi trò chơi thể loại này.


Xin chào, Cảm ơn bạn đã trả lời. Tất cả các tính toán được thực hiện bởi Một Trình quản lý GameObject duy nhất. Tôi chỉ gán các đối tượng trò chơi cho các Diễn viên Cá nhân khi cần thiết (như hiển thị Quân đội Nhân vật di chuyển từ vị trí này sang vị trí khác).
paul p

1
Like "all living characters in a specific location" or "all living or dead ancestors of a specific character". It might be beneficial to create some more secondary data-structures optimized for these kinds of queries.Từ kinh nghiệm của tôi với modding CK2, điều này gần với cách CK2 xử lý dữ liệu. CK2 dường như sử dụng các chỉ mục về cơ bản là các chỉ mục cơ sở dữ liệu, giúp tìm nhanh hơn các ký tự cho một tình huống cụ thể. Thay vì có một danh sách các ký tự, nó dường như có một cơ sở dữ liệu nội bộ của các ký tự, với tất cả các nhược điểm và lợi ích đòi hỏi.
Morfildur

1

Bạn không cần phải mô phỏng / cập nhật hàng ngàn ký tự khi chỉ có một vài người ở gần trình phát. Bạn chỉ cần cập nhật những gì người chơi thực sự có thể nhìn thấy tại thời điểm hiện tại, do đó, các nhân vật ở xa người chơi nên bị đình chỉ cho đến khi người chơi ở gần họ hơn.

Nếu điều này không hiệu quả vì cơ chế trò chơi của bạn yêu cầu các nhân vật ở xa thể hiện thời gian trôi qua, bạn có thể cập nhật chúng trong một bản cập nhật "lớn" khi người chơi đến gần hơn. Nếu cơ chế trò chơi của bạn yêu cầu mỗi nhân vật thực sự phản ứng với các sự kiện trong trò chơi khi chúng xảy ra, bất kể nhân vật đó có liên quan đến người chơi hay sự kiện nào, thì nó có thể hoạt động để giảm tần suất các nhân vật tiếp theo từ người chơi được cập nhật (nghĩa là chúng vẫn được cập nhật đồng bộ với phần còn lại của trò chơi, nhưng không thường xuyên, do đó sẽ có một chút chậm trễ trước khi các nhân vật ở xa phản ứng với một sự kiện nhưng điều này không có khả năng gây ra sự cố hoặc thậm chí được người chơi chú ý ). Ngoài ra, bạn có thể muốn sử dụng một phương pháp lai,


đó là một RTS. Chúng ta nên cho rằng tại bất kỳ thời điểm nào, một số lượng đáng kể các đơn vị thực sự xuất hiện trên màn hình.
Tom

Trong một RTS, thế giới cần tiếp tục trong khi người chơi không tìm kiếm. Một bản cập nhật lớn sẽ mất nhiều thời gian nhưng sẽ bùng nổ khi bạn di chuyển máy ảnh.
PStag

1

Làm rõ câu hỏi

Tôi đã tạo một game RTS đơn giản, chứa hàng trăm nhân vật như Crusader Kings 2 trong Unity.

Trong câu trả lời này, tôi giả định rằng toàn bộ trò chơi được cho là giống như CK2, thay vì chỉ có một phần về việc có rất nhiều nhân vật. Mọi thứ bạn thấy trên màn hình trong CK2 đều dễ thực hiện và sẽ không gây nguy hiểm cho hiệu suất của bạn cũng như không phức tạp khi thực hiện trong Unity. Dữ liệu đằng sau nó, đó là nơi nó trở nên phức tạp.

Các Characterlớp không có chức năng

Vì vậy, tôi đã tạo ra một lớp C # gọi là "Ký tự" chứa tất cả dữ liệu.

Tốt, bởi vì một nhân vật trong game của bạn chỉ dữ liệu. Những gì bạn nhìn thấy trên màn hình chỉ là sự thể hiện của dữ liệu đó. Những Characterlớp học này là trung tâm của trò chơi và vì thế có nguy cơ trở thành " đối tượng thần ". Vì vậy, tôi sẽ khuyên các biện pháp cực đoan chống lại điều đó: Loại bỏ tất cả chức năng khỏi các lớp đó. Một phương thức GetFullName()kết hợp tên và họ, OK, nhưng không có mã nào thực sự "làm gì đó". Đặt mã đó vào các lớp chuyên dụng thực hiện một hành động; ví dụ: một lớp Birthervới một phương thức Character CreateCharacter(Character father, Character mother)sẽ trở nên sạch hơn nhiều so với việc có chức năng đó trong Characterlớp.

Không lưu trữ dữ liệu trong mã

Để lưu trữ chúng, tùy chọn đơn giản nhất là sử dụng các đối tượng có thể script

Không. Lưu trữ chúng ở định dạng JSON, sử dụng JsonUtility của Unity. Với các Characterlớp không có chức năng này , việc làm là không đáng kể. Điều đó sẽ làm việc cho các thiết lập ban đầu của trò chơi cũng như để lưu trữ nó trong trò chơi lưu trữ. Tuy nhiên, đó vẫn là một điều nhàm chán để làm, vì vậy tôi chỉ đưa ra lựa chọn dễ nhất trong tình huống của bạn. Bạn cũng có thể sử dụng XML hoặc YAML hoặc bất kỳ định dạng nào thực sự, miễn là nó vẫn có thể được đọc bởi con người khi nó được lưu trữ trong tệp văn bản. CK2 làm như vậy, thực tế hầu hết các trò chơi đều làm. Đây cũng là thiết lập tuyệt vời để cho phép mọi người sửa đổi trò chơi của bạn, nhưng đó là một suy nghĩ cho nhiều sau này.

Nghĩ trừu tượng

Tôi đã thêm một kiểm tra đơn giản để đảm bảo nhân vật là "Sống" trong khi xử lý [...] nhưng tôi không thể xóa "Nhân vật" nếu anh ta chết vì tôi cần thông tin của anh ta trong khi tạo cây gia đình.

Điều này nói thì dễ hơn làm, bởi vì nó thường va chạm với lối suy nghĩ tự nhiên. Bạn đang suy nghĩ theo cách "tự nhiên", của một "nhân vật". Tuy nhiên, về mặt trò chơi của bạn, có vẻ như có ít nhất 2 loại dữ liệu khác nhau "là một nhân vật": Tôi sẽ gọi nó ActingCharacterFamilyTreeEntry. Một nhân vật đã chết FamilyTreeEntrykhông cần phải cập nhật và có lẽ cần ít dữ liệu hơn nhiều so với một hoạt động ActingCharacter.


0

Tôi sẽ nói từ một chút kinh nghiệm, từ thiết kế OO cứng nhắc sang thiết kế Entity-Element-System (ECS).

Một thời gian trước tôi cũng giống như bạn , tôi có một loạt các loại khác nhau có tính chất tương tự và tôi đã xây dựng các đối tượng khác nhau và cố gắng sử dụng sự kế thừa để giải quyết nó. Một người rất thông minh đã nói với tôi rằng đừng làm điều đó, và thay vào đó, hãy sử dụng Thực thể-Thành phần-Hệ thống.

Bây giờ, ECS là một khái niệm lớn và thật khó để làm đúng. Có rất nhiều công việc đi vào nó, xây dựng các thực thể, các thành phần và hệ thống đúng cách. Tuy nhiên, trước khi chúng ta có thể làm điều đó, chúng ta cần xác định các điều khoản.

  1. Thực thể : đây là thứ , người chơi, động vật, NPC, bất cứ điều gì . Đó là một thứ cần các thành phần gắn liền với nó.
  2. Thành phần : đây là thuộc tính hay tài sản , chẳng hạn như là một "Name" hoặc "Age", hoặc "Cha mẹ", trong trường hợp của bạn.
  3. Hệ thống : đây là logic đằng sau một thành phần hoặc hành vi . Thông thường, bạn xây dựng một hệ thống cho mỗi thành phần, nhưng điều đó không phải lúc nào cũng có thể. Ngoài ra, đôi khi các hệ thống cần ảnh hưởng đến các hệ thống khác .

Vì vậy, đây là nơi tôi sẽ đi với điều này:

Đầu tiên và quan trọng nhất, tạo ra một ID cho các nhân vật của bạn. An int, Guidbất cứ điều gì bạn thích. Đây là "Thực thể".

Thứ hai, bắt đầu suy nghĩ về các hành vi khác nhau mà bạn đang diễn ra. Những thứ như "Cây gia đình" - đó là một hành vi. Thay vì mô hình hóa như các thuộc tính trên thực thể, hãy xây dựng một hệ thống chứa tất cả thông tin đó . Hệ thống sau đó có thể quyết định phải làm gì với nó.

Tương tự như vậy, chúng tôi muốn xây dựng một hệ thống cho "Nhân vật còn sống hay đã chết?" Đây là một trong những hệ thống quan trọng nhất trong thiết kế của bạn, bởi vì nó ảnh hưởng đến tất cả các hệ thống khác. Một số hệ thống có thể xóa các ký tự "chết" (chẳng hạn như hệ thống "sprite"), các hệ thống khác có thể sắp xếp lại nội bộ để hỗ trợ tốt hơn cho trạng thái mới.

Chẳng hạn, bạn sẽ xây dựng một hệ thống "Sprite" hoặc "Vẽ" hoặc "Kết xuất". Hệ thống này sẽ có trách nhiệm xác định những gì nhân vật cần được hiển thị cùng và cách hiển thị nó. Sau đó, khi một nhân vật chết, loại bỏ chúng.

Ngoài ra, một hệ thống "AI" có thể cho nhân vật biết phải làm gì, đi đâu, v.v. Điều này sẽ tương tác với nhiều hệ thống khác và đưa ra quyết định dựa trên chúng. Một lần nữa, các nhân vật đã chết có thể bị xóa khỏi hệ thống này, vì họ không thực sự làm gì nữa.

Hệ thống "Tên" và hệ thống "Cây gia đình" của bạn có thể sẽ giữ nhân vật (còn sống hoặc đã chết) trong bộ nhớ. Hệ thống này cần nhớ lại thông tin đó, bất kể trạng thái của nhân vật là gì. (Jim vẫn là Jim, ngay cả sau khi chúng tôi chôn anh ấy.)

Điều này cũng mang lại cho bạn lợi ích của việc thay đổi khi hệ thống phản ứng hiệu quả hơn: hệ thống có bộ đếm thời gian riêng. Một số hệ thống cần phải bắn nhanh, một số thì không. Đây là nơi chúng ta bắt đầu tìm hiểu những gì làm cho trò chơi chạy hiệu quả. Chúng ta không cần tính toán lại thời tiết mỗi mili giây, chúng ta có thể làm điều đó cứ sau 5 phút.

Nó cũng mang lại cho bạn đòn bẩy sáng tạo hơn: bạn có thể xây dựng hệ thống "Pathfinder" có thể xử lý việc tính toán đường dẫn từ A đến B và có thể cập nhật khi cần thiết, cho phép hệ thống Chuyển động nói "tôi cần ở đâu Đăng nhập?" Bây giờ chúng ta có thể tách biệt hoàn toàn những mối quan tâm này, và lý do về chúng hiệu quả hơn. Phong trào không cần tìm đường đi, nó chỉ cần đưa bạn đến đó.

Bạn sẽ muốn để lộ một số phần của hệ thống ra bên ngoài. Trong Pathfinderhệ thống của bạn có thể bạn sẽ muốn một Vector2 NextPosition(int entity). Bằng cách này, bạn có thể giữ các thành phần đó trong các mảng hoặc danh sách được kiểm soát chặt chẽ. Bạn có thể sử dụng các structloại nhỏ hơn, có thể giúp bạn giữ các thành phần trong các khối bộ nhớ nhỏ hơn, liền kề nhau, có thể giúp cập nhật hệ thống nhanh hơn nhiều . (Đặc biệt nếu ảnh hưởng bên ngoài đến một hệ thống là tối thiểu, thì bây giờ nó chỉ cần quan tâm đến trạng thái bên trong của nó, chẳng hạn như Name.)

Nhưng, và tôi không thể nhấn mạnh điều này đủ, giờ đây Entitychỉ là một ID, bao gồm gạch, vật thể, v.v ... Nếu một thực thể không thuộc về một hệ thống, thì hệ thống sẽ không theo dõi nó. Điều này có nghĩa là chúng ta có thể tạo các đối tượng "Cây" của mình, lưu trữ chúng trong SpriteMovementcác hệ thống (cây sẽ không di chuyển, nhưng chúng có thành phần "Vị trí") và tránh xa các hệ thống khác. Chúng ta không còn cần một danh sách đặc biệt cho cây nữa, vì việc dựng hình một cây không khác gì một nhân vật, ngoài việc làm giấy. ( SpriteHệ thống nào có thể kiểm soát hoặc Paperdollhệ thống có thể kiểm soát.) Bây giờ chúng ta NextPositioncó thể viết lại một chút: Vector2? NextPosition(int entity)và nó có thể trả về một nullvị trí cho các thực thể mà nó không quan tâm. Chúng tôi cũng áp dụng điều này cho chúng tôi NameSystem.GetName(int entity), nó trả lại nullcho cây và đá.


Tôi sẽ kết thúc vấn đề này, nhưng ý tưởng ở đây là cung cấp cho bạn một số nền tảng về ECS và cách bạn thực sự tận dụng nó để cung cấp cho bạn một thiết kế tốt hơn trong trò chơi của bạn. Bạn có thể tăng hiệu suất, tách các yếu tố không liên quan và giữ mọi thứ theo cách có tổ chức hơn. (Điều này cũng kết hợp tốt với các ngôn ngữ / thiết lập chức năng, như F # và LINQ, tôi khuyên bạn nên kiểm tra F # nếu bạn chưa có, nó kết hợp rất tốt với C # khi bạn sử dụng kết hợp chúng.)


Xin chào, Cảm ơn bạn đã phản hồi chi tiết như vậy. Tôi chỉ sử dụng One GameObject Manager có chứa tham chiếu đến tất cả các Nhân vật trong trò chơi khác.
paul p

Phát triển trong Unity xoay quanh các thực thể được gọi là GameObjectkhông làm được gì nhiều nhưng có một danh sách các Componentlớp thực hiện công việc thực tế. Có một sự thay đổi mô hình liên quan đến vòng xoay ECS một thập kỷ trước , vì việc đưa mã diễn xuất vào các lớp hệ thống riêng biệt sẽ sạch hơn. Unity gần đây cũng đã triển khai một hệ thống như vậy, nhưng GameObjecthệ thống của họ luôn luôn là một ECS. OP đã sử dụng ECS.
Raphael Schmitz

-1

Khi bạn đang làm điều này trong Unity, cách tiếp cận dễ nhất là:

  • tạo một đối tượng trò chơi cho mỗi nhân vật hoặc loại đơn vị
  • lưu chúng dưới dạng prefabs
  • sau đó bạn có thể khởi tạo một prefab bất cứ khi nào cần
  • Khi một nhân vật bị giết, phá hủy trò chơi và nó sẽ không chiếm bất kỳ CPU hay bộ nhớ nào nữa

Trong mã của bạn, bạn có thể giữ các tham chiếu đến các đối tượng trong một cái gì đó như Danh sách để tiết kiệm cho bạn khỏi việc sử dụng Find () và các biến thể của nó mọi lúc. Bạn đang giao dịch các chu kỳ CPU cho bộ nhớ, nhưng một danh sách các con trỏ khá nhỏ, do đó, ngay cả với một vài nghìn đối tượng trong đó cũng không phải là vấn đề.

Khi bạn tiến bộ trong trò chơi của mình, bạn sẽ thấy rằng việc có các đối tượng trò chơi riêng lẻ mang lại cho bạn vô số lợi thế, bao gồm cả điều hướng và AI.

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.