Dự án tham khảo cây

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

Cây là một trải nghiệm tham khảo nơi người chơi trồng và tưới hạt giống, vì vậy họ có thể sau đó thu hoạch và bán cây kết quả.

Plant project banner

Dự án tập trung vào các trường hợp sử dụng phổ biến mà bạn có thể gặp phải khi phát triển một trải nghiệm trên Roblox.Nếu có hiện hànhdụng, bạn sẽ tìm thấy ghi chú về các mâu thuẫn, sự thỏa hiệp và lý do của các lựa chọn thực hiện khác nhau, để bạn có thể đưa ra quyết định tốt nhất cho trải nghiệm của mình.

Lấy tập tin

  1. Điều hướng đến trang kinh nghiệm Cây .
  2. Nhấp vào nút Chỉnh sửa trong Studio .

Sử dụng các trường hợp

Cây bao gồm các trường hợp sử dụng sau:

  • Dữ liệu phiên và dữ liệu người chơi duy trì
  • Quản lý xem UI
  • Mạng khách-máy chủ
  • Trải nghiệm người dùng lần đầu tiên (FTUE)
  • Mua tiền tệ cứng và mềm

Ngoài ra, dự án này giải quyết các bộ vấn đề nhỏ hơn áp dụng cho nhiều trải nghiệm, bao gồm:

  • Tùy chỉnh một khu vực trong nơi liên quan đến một người chơi
  • Quản lý tốc độ di chuyển của nhân vật người chơi
  • Tạo một đối tượng theo dõi các nhân vật xung quanh
  • Phát hiện phần nào của thế giới mà một nhân vật ở

Lưu ý rằng có một số trường hợp sử dụng trong trải nghiệm này quá nhỏ, quá thu hẹp hoặc không thể hiện giải pháp cho một thử thách thiết kế thú vị; chúng không được bao gồm.

Cấu trúc dự án

Quyết định đầu tiên khi tạo một trải nghiệm là quyết định cách cấu trúc dự án , chủ yếu bao gồm nơi để các ví dụ cụ thể trong mô hình dữ liệu và cách tổ chức và cấu trúc điểm truy cập cho cả client và mã máy chủ.

Môдель dữ liệu

Bảng sau đây mô tả các dịch vụ thùng chứa trong các ví dụ mô hình dữ liệu được đặt vào.

Dịch vụLoại các ví dụ
Workspace

Bao gồm các mô hình tĩnh đại diện cho thế giới 3D, cụ thể là các phần của thế giới không thuộc về bất kỳ người chơi nào.Bạn không cần phải tạo, chỉnh sửa hoặc xóa các ví dụ này một cách năng động trong thời gian chạy, vì vậy nó là chấp nhận được để để chúng ở đây.:

Cũng có một trống Folder , mà các mô hình trang trại của người chơi sẽ được thêm vào khi chạy thời gian thực.

Lighting

Hiệu ứng khí quyển và ánh sáng.

ReplicatedFirst

Bao gồm phần phân khúc nhỏ nhất có thể của các thực thể cần thiết để hiển thị màn hình tải và khởi tạo trò chơi.Càng có nhiều ví dụ được đặt vào ReplicatedFirst , thời gian chờ đợi chúng sao chép trước khi mã trong ReplicatedFirst có thể chạy càng lâu.:

  • Trong thư mục Instances có sẵn màn hình GUI tải.:
  • Trong thư mục Nguồn có mã màn hình tải và mã cần đợi để hoàn thành phần còn lại của trò chơi.The start``Class.LocalScript là điểm nhập cho tất cả mã bên khách trong dự án.
ReplicatedStorage

Phục vụ như một thùng chứa lưu trữ cho tất cả các thực thể cần truy cập trên cả khách hàng và máy chủ.:

Trong thư mục Phụ thuộc có một số thư viện bên thứ ba được sử dụng bởi dự án.: Trong thư mục Instances có rất nhiều ví dụ được sản xuất trước được sử dụng bởi các lớp khác nhau trong trò chơi.: Trong thư mục Nguồn có tất cả mã không cần thiết cho quá trình tải cần truy cập từ cả khách hàng và máy chủ.

ServerScriptService

Bao gồm một Script phục vụ như điểm nhập cho tất cả mã bên máy chủ trong dự án.

ServerStorage

Phục vụ như một thùng chứa lưu trữ cho tất cả các thực thể không cần phải sao lưu cho khách hàng.:

  • Trong thư mục Instances có một mẫu mô hình Nông trại .Một bản sao của nó được đặt vào Workspace khi người chơi tham gia trò chơi, nơi nó sẽ được sao chép cho tất cả các người chơi.:
  • Trong thư mục Nguồn có tất cả mã độc quyền với máy chủ.
SoundService

Bao gồm các đối tượng Sound được sử dụng cho hiệu ứng âm thanh trong trò chơi.Dưới SoundService , những đối tượng này Sound không có vị trí và không được mô phỏng trong không gian 3D.

Điểm nhập

Hầu hết các dự án tổ chức mã bên trong reusable ModuleScripts có thể được nhập vào toàn bộ bộ mã nguồn. ModuleScripts không thể tái sử dụng nhưng chúng không thực thi trên sở hữuchúng; chúng cần được nhập bởi một Script hoặc LocalScript .Nhiều dự án Roblox sẽ có một lượng lớn ScriptLocalScript đối tượng, mỗi đối với một hành vi hoặc hệ thống cụ thể trong trò chơi, tạo ra nhiều điểm nhập.

Đối với trò chơi thực vật microgame, một phương pháp khác được thực hiện thông qua một LocalScript duy nhất là điểm nhập cho tất cả mã khách hàng, và một Script duy nhất là điểm nhập cho tất cả mã máy chủ.Phương pháp chính xác cho dự án của bạn phụ thuộc vào yêu cầu của bạn, nhưng một điểm nhập duy nhất cung cấp kiểm soát lớn hơn về thứ tự mà các hệ thống được thực hiện theo.

Các danh sách sau đây mô tả những mất mát của cả hai phương pháp:

  • Một đơn Script và một đơn LocalScript bao gồm máy chủ và mã khách hàng lần lượt.
  • Kiểm soát lớn hơn về thứ tự khởi động của các hệ thống khác nhau bởi vì tất cả mã được khởi tạo từ một kịch bản duy nhất.
  • Có thể truyền đối tượng bằng tham chiếu giữa các hệ thống.

Kiến trúc hệ thống cấp cao

Các hệ thống cấp cao trong dự án được mô tả chi tiết dưới đây.Một số hệ thống này phức tạp hơn nhiều so với những hệ thống khác, và trong nhiều trường hợp chức năng của chúng được tách rời trên một hệ thống cấp bậc khác.

Plant project systems architecture diagram

Mỗi hệ thống này là một "đơn vị", trong đó nó là một lớp không thể khởi tạo ngay lập tức mà được khởi tạo thay thế bởi kịch bản khách hàng hoặc máy chủ liên quan start .Bạn có thể đọc thêm về mô hình hát solo sau đây trong hướng dẫn này.

Máy chủ

Các hệ thống sau đây được liên kết với máy chủ.

Hệ thốngMô tả
Mạng
  • Tạo tất cả các RemoteEventRemoteFunction ví dụ.:
  • Tiết lộ các phương pháp để gửi và lắng nghe tin nhắn từ khách hàng.:
  • Xác thực kiểu cho các tham số nhận được từ khách hàng trong thời gian chạy.
Máy chủ dữ liệu người chơi
  • Lưu và tải dữ liệu người chơi vĩnh viễn bằng cách sử dụng DataStoreService .:
  • Lưu dữ liệu người chơi trong bộ nhớ và sao chép các đột biến cho khách hàng.:
  • Tiết lộ các tín hiệu và phương thức để đăng ký, truy vấn và cập nhật dữ liệu người chơi.
Thị trường
  • Xử lý giao dịch tiền mềm từ khách hàng. >
  • Tiết lộ một phương pháp để bán cây được thu hoạch.
Quản lý Nhóm va chạm
  • Gán mô hình nhân vật người chơi cho nhóm va chạm .:
  • Cài đặt nhóm va chạm để các nhân vật người chơi không thể va chạm với toa thực vật.
Máy Chủ Quản Lý Nông Trại
  • Tái tạo mô hình nông trại của một người chơi từ dữ liệu người chơi khi họ tham gia trò chơi.:
  • Loại bỏ mô hình trang trại khi một người chơi rời đi.:
  • Cập nhật dữ liệu người chơi khi nông trại của một người chơi được thay đổi.:
  • Tiết lộ một phương thức truy cập vào lớp Nông trại liên quan đến một người chơi cụ thể.
Thùng chứa đối tượng người chơi
  • Tạo ra các đối tượng khác nhau liên quan đến thời gian sống của một người chơi và cung cấp một phương thức để lấy lại chúng.
Người chơi Tag
  • Thêm CollectionService nhãn cho tất cả các đối tượng người chơi và nhân vật. >
Máy chủ FtueManager
  • Trong suốt FTUE, thực hiện mỗi giai đoạn và chờ đợi nó hoàn thành. >
Tạo nhân vật
  • Hồi sinh nhân vật khi chúng chết.Lưu ý rằng Players.CharacterAutoLoads đã bị vô hiệu hóa để sinh sản bị tạm dừng cho đến khi dữ liệu của người chơi được tải. >

Khách hàng

Các hệ thống sau đây được gắn với khách hàng.

Hệ thốngMô tả
Mạng
  • Chờ máy chủ tạo tất cả RemoteEventRemoteFunction các ví dụ.:
  • Tiết lộ các phương pháp để gửi và lắng nghe tin nhắn đến và từ máy chủ.:
  • Áp dụng kiểm tra chính xác loại tham số chạy thời gian.:
  • Chạy pcall() trên các chức năng được gọi từ xa.
Client dữ liệu người chơi
  • Lưu dữ liệu của người chơi địa phương trong bộ nhớ.:
  • Tiết lộ các phương pháp và tín hiệu để truy vấn và đăng ký các thay đổi trong dữ liệu người chơi.
Khách hàng thị trường
  • Tiết lộ một phương thức để yêu cầu máy chủ mua một mặt hàng cho tiền tiền tệ.
Quản lý nhảy bộ địa phương
  • Tiết lộ các phương pháp để thay đổi WalkSpeed hoặc JumpHeight của một nhân vật thông qua các nhân số để tránh xung đột khi sửa đổi các giá trị này từ nhiều nơi khác nhau. >
Khách hàng quản lý trang trại
  • Nghe cho các thẻ cụ thể CollectionService được áp dụng cho các thực thể và tạo "thành phần" thêm hành vi cho các thực thể này.Một "thành phần" đề cập đến một lớp được tạo khi một thẻ CollectionService được thêm vào một ví dụ và bị phá hủy khi nó được xóa; chúng được sử dụng cho các lời nhắc CTA trong trang trại và các lớp khác gửi tình trạng trang trại cho người chơi.
Cài đặt UI
  • Khởi tạo tất cả các lớp UI.:
  • Tùy chỉnh một số lớp chỉ hiển thị trong các phần vật lý của thế giới trò chơi.:
  • Kết nối một hiệu ứng máy ảnh đặc biệt cho khi menu được bật.
Khách hàng FtueManager
  • Cài đặt các giai đoạn FTUE trên máy khách. >
Tính nhân vật
  • Sử dụng LocalWalkJumpManager để tăng WalkSpeed khi một nhân vật người chơi ở ngoài trang trại của họ. >

Giao tiếp khách-máy chủ

Hầu hết các trải nghiệm Roblox liên quan đến một số yếu tố giao tiếp giữa khách hàng và máy chủ.Điều này có thể bao gồm yêu cầu của khách hàng yêu cầu máy chủ thực hiện một hành động nhất định và máy chủ sao chép cập nhật cho khách hàng.

Trong dự án này, giao tiếp khách-máy chủ được giữ như chung nhất có thể bằng cách giới hạn việc sử dụng RemoteEventRemoteFunction các đối tượng để giảm lượng quy tắc đặc biệt cần theo dõi.Dự án này sử dụng các phương pháp sau, theo thứ tự ưu tiên:

  • Sao lưu qua hệ thống dữ liệu người chơi .
  • Sao lưu qua thuộc tính .
  • Sao lưu qua các thẻ tag.
  • Gửi tin nhắn trực tiếp qua mô-đun Mạng .

Bản sao lưu qua hệ thống dữ liệu người chơi

Hệ thống dữ liệu người chơi cho phép dữ liệu được liên kết với người chơi vẫn tồn tại giữa các phiên lưu .Hệ thống này cung cấp sao lưu từ khách hàng sang máy chủ và một bộ API có thể được sử dụng để truy vấn dữ liệu và đăng ký thay đổi, làm cho nó lý tưởng để sao lưu thay đổi trạng thái người chơi từ máy chủ sang khách hàng.

Ví dụ, thay vì bắn một bespoke UpdateCoins``Class.RemoteEvent để cho khách hàng biết có bao nhiêu tiền xu, bạn có thể gọi các điều sau và cho phép khách hàng đăng ký nó thông qua sự kiện PlayerDataClient.updated.


PlayerDataServer:setValue(player, "coins", 5)

Tất nhiên, điều này chỉ hữu ích cho sao lưu máy chủ sang khách hàng và cho các giá trị bạn muốn giữ giữa các phiên, nhưng điều này áp dụng cho một số trường hợp đáng ngạc nhiên trong dự án, bao gồm:

  • Giai đoạn FTUE hiện tại
  • khocủa người chơi
  • Số tiền xu mà người chơi có
  • Tình trạng nông trại của người chơi

Bản sao lưu qua các thuộc tính

Trong các tình huống mà máy chủ cần sao chép một giá trị tùy chỉnh cho khách hàng cụ thể cho một Instance nhất định, bạn có thể sử dụng thuộc tính .Roblox tự động sao chép các giá trị thuộc tính, vì vậy bạn không cần duy trì bất kỳ con đường mã nào để sao chép trạng thái liên quan đến một đối tượng.Lợi thế khác là sao lưu này xảy ra cùng với instance chính.

Điều này đặc biệt hữu ích đối với các ví dụ được tạo khi chạy, bởi vì các thuộc tính được thiết lập trên một ví dụ mới trước khi nó được gán cho mô hình dữ liệu sẽ sao chép toàn bộ với chính ví dụ.Điều này bỏ qua bất kỳ nhu cầu phải viết mã để "chờ đợi" dữ liệu bổ sung được sao lưu qua một RemoteEvent hoặc StringValue .

Bạn cũng có thể trực tiếp đọc các thuộc tính từ mô hình dữ liệu, từ máy khách hoặc máy chủ, với phương pháp GetAttribute(), và đăng ký các thay đổi bằng phương pháp GetAttributeChangedSignal().Trong dự án Cây, phương pháp này được sử dụng để, trong số những thứ khác, sao chép tình trạng hiện tại của cây cho khách hàng.

Sao lưu qua các thẻ

CollectionService cho phép bạn áp dụng một thẻ chuỗi cho một Instance . Điều này hữu ích để phân loại các ví dụ và sao chép việc phân loại đó cho khách hàng.

Ví dụ, thẻ CanPlant được áp dụng trên máy chủ để thông báo cho khách hàng rằng một chiếc chậu nhất định có thể nhận được một cây.

Tin nhắn trực tiếp qua mô-đun mạng

Đối với các tình huống không có lựa chọn trước đó nào áp dụng, bạn có thể sử dụng cuộc gọi mạng tùy chỉnh thông qua mô-đun Mạng .Đây là lựa chọn duy nhất trong dự án cho phép giao tiếp khách hàng-máy chủ và do đó hữu ích nhất để gửi yêu cầu khách hàng và nhận được phản hồi của máy chủ.

Cây sử dụng cuộc gọi mạng trực tiếp cho một loạt các yêu cầu khách hàng, bao gồm:

  • Tưới nước cho một cây
  • Gieo một hạt giống
  • Mua một mặt vật phẩm

Nhược điểm của phương pháp này là mỗi tin nhắn cần một số cấu hình riêng biệt có thể làm tăng sự phức tạp của dự án, mặc dù điều này đã được tránh ở mức tối đa, đặc biệt là đối với giao tiếp máy chủ-khách hàng.

Lớp và một người duy nhất

Các lớp trong dự án Nhà máy có thể được tạo và phá hủy, giống như các ví dụ trên Roblox.Cú pháp lớp của nó được truyền cảm hứng bởi cách tiếp cận idiomatic Lua đối với lập trình hướng đối tượng với một số thay đổi để bật hỗ trợ kiểm tra chặt chẽ.

Ngay lập tức

Nhiều lớp trong dự án được liên kết với một hoặc nhiều Instances .Các đối tượng của một lớp được tạo bằng cách sử dụng một phương pháp new() , phù hợp với cách các ví dụ được tạo trong Roblox bằng cách sử dụng Instance.new() .

Mẫu này thường được sử dụng cho các đối tượng mà lớp có đại diện vật lý trong mô hình dữ liệu, và lớp mở rộng chức năng của nó.Một ví dụ tốt là đó tạo ra một đối tượng giữa hai đối tượng được cung cấp và giữ các phụ kiện đó hướng về phía trên để làm cho tia luôn hướng lên.Các ví dụ này có thể được sao chép từ một phiên bản được sản xuất trước trong ReplicatedStorage hoặc được chuyển sang new() như một tham số và lưu bên trong đối tượng dưới self .

Các ví dụ tương ứng

Như đã đề cập ở trên, nhiều lớp trong dự án này có một đại diện mô hình dữ liệu, một ví dụ phù hợp với lớp và được thao tác bởi nó.

Thay vì tạo các ví dụ này khi một đối tượng lớp được khởi tạo, mã thường chọn Clone() một phiên bản được sản xuất trước của Instance được lưu dưới ReplicatedStorage hoặc ServerStorage .Mặc dù sẽ có thể serialize các thuộc tính của các instance này và tạo chúng từ đầu trong các chức năng lớp new(), việc làm như vậy sẽ làm cho việc chỉnh sửa các đối tượng rất phức tạp và khiến chúng trở nên khó khăn hơn cho một người đọc để phân tích.Ngoài ra, sao chép một ví dụ thường là một hoạt động nhanh hơn so với việc tạo một ví dụ mới và tùy chỉnh các thuộc tính của nó trong thời gian thực.

Tổng hợp

Mặc dù kế thừa là khả thi trong Luau bằng cách sử dụng bảng biểu tượng, dự án lại chọn cho phép các lớp mở rộng lẫn nhau thông qua tổ hợp .Khi kết hợp các lớp thông qua sự kết hợp, đối tượng "con" được khởi tạo trong phương pháp new() của lớp và được bao gồm là thành viên dưới self .

Đối với ví dụ về hành động này, hãy xem lớp CloseButton lớp này đóng gói lớp Button .

Làm sạch

Tương tự như cách một Instance có thể bị phá hủy bằng cách sử dụng phương pháp Destroy(), các lớp có thể được khởi tạo cũng có thể bị phá hủy.Phương pháp tiêu diệt cho lớp dự án là với một chữ thường cho sự phù hợp giữa các phương pháp trong codebase, cũng như để phân biệt giữa các lớp dự án và các thực thể Roblox.

Vai trò của phương pháp destroy() là phá hủy bất kỳ instancce được tạo bởi đối tượng, ngắt kết nối bất kỳ kết nối nào, và gọi destroy() trên bất kỳ đối tượng con nào.Điều này rất quan trọng đối với các kết nối bởi vì các thực thể có kết nối hoạt động không được xóa bởi Luau garbage collector, ngay cả khi không có tham chiếu đến thực thể hoặc kết nối đến thực thể còn lại.

Các đơn vị duy nhất

Singletons, như tên cho thấy, là các lớp mà chỉ có một đối tượng có thể tồn tại bao giờ.Chúng là tương đương với các dịch vụ của Roblox Services .Thay vì lưu một tham chiếu đến đối tượng duy nhất và chuyển nó xung quanh trong mã Luau, Cây sử dụng lợi thế của việc yêu cầu một ModuleScript lưu trữ giá trị trả lại của nó.Điều này có nghĩa là yêu cầu cùng một đối tượng duy nhất ModuleScript từ nhiều nơi khác nhau đồng nhất cung cấp cùng một đối tượng trả về.Ngoại lệ duy nhất đối với quy tắc này sẽ là nếu các môi trường khác nhau (khách hàng hoặc máy chủ) truy cập vào ModuleScript .

Các Singletons được phân biệt với các lớp không thể thay đổi bởi thực tế là chúng không có phương pháp new().Thay vào đó, đối tượng cùng với các phương pháp và trạng thái của nó được trả lại trực tiếp thông qua ModuleScript .Vì các đối tượng đơn không được khởi tạo, ngữ pháp self không được sử dụng và các phương pháp thay vào đó được gọi với một chấm ( . ) thay vì một dấu chấm câu ( : ).

Kiểm tra kiểu nghiêm ngặt

Luau hỗ trợ gõ từ từ có nghĩa là bạn có thể tự do thêm các định nghĩa loại bắt buộc vào một số hoặc tất cả mã của bạn.Trong dự án này, strict kiểm tra loại được sử dụng cho mọi kịch bản.Đây là lựa chọn cho phép tối thiểu cho công cụ phân tích kịch bản của Roblox và do đó có khả năng bắt lỗi loại trước khi chạy.

Cú pháp lớp được gõ

Cách tiếp cận được thiết lập để tạo lớp trong Lua là được tài liệu tốt , tuy nhiên nó không phù hợp với kiểu Luau mạnh mẽ.Trong Luau, cách đơn giản nhất để có được loại của một lớp là phương pháp typeof() :


type ClassType = typeof(Class.new())

Cách này hoạt động nhưng không hữu ích lắm khi lớp của bạn được khởi tạo với các giá trị chỉ tồn tại khi chạy, ví dụ Player các đối tượng.Ngoài ra, giả định được thực hiện trong cú pháp lập trường Lua là tuyên bố một phương thức trên một lớp self sẽ luôn luôn là một ví dụ của lớp đó; đây không phải là một giả định mà máy phân tích loại có thể thực hiện.

Để hỗ trợ loại suy luận nghiêm ngặt, dự án Cây sử dụng một giải pháp khác với cú pháp lớp Lua giao tiếp trong một số cách, một số có thể cảm thấy không thân thiện:

  • Định nghĩa của self được sao chép, cả trong tuyên bố loại và trong constructor.Điều này giới thiệu một gánh nặng duy trì, nhưng cảnh báo sẽ bị đánh dấu nếu hai định nghĩa rơi ra khỏi đồng bộ với nhau.
  • Các phương pháp lớp được tuyên bố với một chấm, vì vậy self có thể được tuyên bố rõ ràng là của loại ClassType .Các phương thức vẫn có thể được gọi với một dấu chấm câu như mong đợi.

--!nghiêm ngặt
local MyClass = {}
MyClass.__index = MyClass
export type ClassType = typeof(setmetatable(
{} :: {
property: number,
},
MyClass
))
function MyClass.new(property: number): ClassType
local self = {
property = property,
}
setmetatable(self, MyClass)
return self
end
function MyClass.addOne(self: ClassType)
self.property += 1
end
return MyClass

Loại trừ các kiểu sau khi bảo vệ logic

Tại thời điểm viết, loại của một giá trị không bị hẹp sau một câu lệnh điều kiện bảo vệ.Ví dụ, sau khi theo dõi người bảo vệ bên dưới, loại optionalParameter không bị thu hẹp thành number .


--!nghiêm ngặt
local function foo(optionalParameter: number?)
if not optionalParameter then
return
end
print(optionalParameter + 1)
end

Để giảm thiểu điều này, các biến mới được tạo sau những người bảo vệ này với loại của họ được rút ra rõ ràng.


--!nghiêm ngặt
local function foo(optionalParameter: number?)
if not optionalParameter then
return
end
local parameter = optionalParameter :: number
print(parameter + 1)
end

Xuyên qua cấu trúc dữ liệu mô hình hierarchies

Trong một số trường hợp, codebase cần phải đi qua cấu trúc hệ thống dữ liệu của một cây các đối tượng được tạo ra khi chạy thời gian thực.Điều này tạo ra một thách thức thú vị cho việc kiểm tra loại.Tại thời điểm viết, không thể xác định một cấu trúc dữ liệu chung như một đánh máy.Kết kết quảlà, có những trường hợp mà loại thông tin duy nhất có sẵn cho cấu trúc mô hình dữ liệu là loại của ví ví dụ / trường hợpcấp cao nhất.

Một cách tiếp cận đối với thách thức này là phát đến any và sau đó tinh chỉnh. Ví dụ:


local function enableVendor(vendor: Model)
local zonePart: BasePart = (vendor :: any).ZonePart
end

Vấn đề với phương pháp này là nó ảnh hưởng đến khả năng đọc.Thay vào đó, dự án sử dụng một mô-đun chung có tên là getInstance để duyệt qua các cấp bậc mô hình dữ liệu mà phát sang any bên trong.


local function enableVendor(vendor: Model)
local zonePart: BasePart = getInstance(vendor, "ZonePart")
end

Khi kiểu động cơ hiểu biết về mô hình dữ liệu tiến triển, có thể các mẫu như thế này sẽ không còn cần thiết.

Giao diện người dùng

Cây bao gồm nhiều giao diện người dùng 2D phức tạp và đơn giản.Chúng bao gồm các mục không tương tác như màn hình hiển thị thông báo (HUD) như bộ đếm tiền xu và các menu tương tác phức tạp như cửa chọn mua.

Cách tiếp cận UI

Bạn có thể so sánh lỏng Roblox UI với HTML DOM, bởi vì nó là một hệ thống các đối tượng mô tả những gì người dùng nên nhìn thấy.Các tiếp cận để tạo và cập nhật giao diện người dùng Roblox được phân chia rộng rãi thành bắt buộctuyên bố thực hành.

Tiếp cậnƯu và nhược điểm
Bắt buộc

Trong tiếp cận bắt buộc, UI được xử lý giống như bất kỳ hệ thống phân cấp khác trên Roblox.Cấu trúc UI được tạo trước khi chạy trong Studio và được thêm vào mô hình dữ liệu, thường trực tiếp trong StarterGui .Sau đó, khi chạy, mã sẽ thao tác các mảnh cụ thể của UI để phản ánh trạng thái mà người tạo yêu cầu.:

Phương pháp này có một số ưu điểm.Bạn có thể tạo UI từ đầu trong Studio và lưu nó vào mô hình dữ liệu.Đây là một trải nghiệm chỉnh sửa đơn giản và hình ảnh có thể tăng tốc việc sản phẩmUI.Bởi vì mã UI bắt buộc chỉ quan tâm đến những gì cần thay đổi, nó cũng làm cho các thay đổi UI đơn giản dễ dàng thực hiện.:

Một hạn chế đáng chú ý là, vì các tiếp cận UI bắt buộc yêu cầu trạng thái phải được thực hiện thủ công dưới dạng biến đổi, các biểu diễn trạng thái phức tạp có thể trở nên rất khó tìm và gỡ lỗi.Thông thường các lỗi xuất hiện khi phát triển mã UI bắt buộc, đặc biệt là khi trạng thái và giao diện người dùng trở nên không đồng bộ do nhiều cập nhật tương tác theo trật tự không mong đợi.:

Thử thách khác với các tiếp cận bắt buộc là khó hơn để phá vỡ giao diện người dùng thành các thành phần có ý nghĩa có thể được tuyên bố một lần và được sử dụng lại.Bởi vì toàn bộ cây UI được tuyên bố tại thời điểm chỉnh sửa, các mẫu thông thường có thể được lặp lại trong nhiều phần của mô hình dữ liệu.

Tuyên bố

Trong tiếp cận tuyên bố, trạng thái UI mong muốn được tuyên bố rõ ràng, và việc thực hiện hiệu quả của trạng thái này được tách rời bởi các thư viện như Roact hoặc Fusion.:

Lợi thế của phương pháp này là việc thực hiện trạng thái trở nên đơn giản và bạn chỉ cần mô tả những gì bạn muốn UI của bạn trông như thế nào.Điều này làm cho việc xác định và giải quyết lỗi dễ dàng hơn đáng kể.:

Hạn chế chính là phải tuyên bố toàn bộ cây UI trong mã.Các thư viện như Roact và Fusion có ngữ pháp để làm cho việc này dễ dàng hơn, nhưng vẫn là một quá trình tốn thời gian và kinh nghiệm chỉnh sửa ít hơn khi tạo giao diện người dùng.

Cây sử dụng một phương pháp bắt buộc dưới khái niệm rằng hiển thị các biến đổi trực tiếp cho thấy một tổng quát hiệu quả hơn về cách UI được tạo và thao tác trên Roblox.Điều này sẽ không thể thực hiện được với một tiếp cận tuyên bố.Một số cấu trúc UI lặp lại và logic cũng được chiết xuất thành các thành phần có thể tái sử dụng để tránh một sự cố chung trong thiết kế UI bắt buộc để tránh một sự cố chung trong thiết kế UI bắt buộc

Kiến trúc cấp cao

Plant project UI architecture diagram

Lớp và thành phần

Trong Cây, tất cả các cấu trúc UI đều là một Layer hoặc một Component.

  • Layer được định nghĩa là một nhóm phân cấp cấp cao đóng gói các cấu trúc UI được sẵn sàng trước trong ReplicatedStorage .Một lớp có thể chứa một số thành phần, hoặc nó có thể bao bọc toàn bộ logic của riêng mình.Ví dụ về lớp là menu kho hàng hoặc số lượng chỉ số tiền xu trong màn hình hiển thị nổi bật.
  • Component là một thành phần UI có thể tái sử dụng.Khi một đối tượng thành phần mới được khởi tạo, nó sẽ sao chép một mẫu có sẵn từ ReplicatedStorage .Các thành phần có thể chứa các thành phần khác trong chính nó.Ví dụ về các thành phần là một lớp nút chung hoặc khái niệm về một danh sách các mục.

Xem xử lý

Một vấn đề quản lý UI phổ biến là xử lý xem.Dự án này có một loạt các menu và vật phẩm HUD, một số trong đó lắng nghe nhập력 của người dùng, và quản lý cẩn thận về thời gian chúng xuất hiện hoặc bật được yêu cầu.

Cây tiếp cận vấn đề này với hệ thống UIHandler của nó, quản lý khi một lớp UI nên hay không nên hiển thị.Tất cả các lớp UI trong trò chơi được phân loại thành HUD hoặc Menu và tầm nhìn của chúng được quản lý bởi các quy tắc sau:

  • Tình trạng bật được của MenuHUD lớp có thể được chuyển đổi.
  • Các lớp bật HUD được hiển thị chỉ khi không có lớp Menu được bật.
  • Các lớp bật Menu được lưu trong một đống và chỉ có một lớp Menu duy nhất có thể nhìn thấy cùng một lúc.Khi một lớp Menu được bật, nó được chèn vào phía trước của đống và được hiển thịKhi lớp Menu bị vô hiệu hóa, nó được xóa khỏi đống và lớp tiếp theo được bật Menu được hiển thị trong hàng đợi.

Cách tiếp cận này dễ hiểu bởi vì nó cho phép các menu được điều hướng với lịch sử.Nếu một menu được mở từ menu khác, việc đóng menu mới sẽ hiển thị lại menu cũ.

Các đơn vị UI lớp đăng ký bản thân với UIHandler và được cung cấp với một tín hiệu bắt lửa khi hiển thị của nó nên thay đổi.

Đọc thêm

Từ tổng quát toàn diện về dự án Nhà máy, bạn có thể muốn khám phá các hướng dẫn sau đây mà đi sâu hơn về các khái niệm và chủ đề liên quan.

  • Mô hình khách-máy chủ — Tổng quát về mô hình khách-máy chủ trong Roblox.
  • Luau — Chi tiết về Luau , ngôn ngữ lập trình do Roblox tạo ra từ Lua 5.1 .
  • Sự kiện và cuộc gọi từ xa — Tất cả về sự kiện mạng từ xa và cuộc gọi trả lại để giao tiếp qua ranh giới client-server.
  • UI — Chi tiết về các đối tượng giao diện người dùng và thiết kế trên Roblox.