Lobby
Thẻ hồ sơ ở Lobby hiện tên và cấp của người chơi đã đăng nhập. Hồ sơ được tải trong lúc khởi động, nên Lobby thường mở ra với hồ sơ đã sẵn sàng; khi quay về từ một nhiệm vụ hay scene khác, hồ sơ đã cập nhật được hiện ngay mà không cần tải lại gì.
| Bạn dùng | Nó cho bạn |
|---|---|
IProjectVLobbyScreen | Screen contract: theo dõi thẻ hồ sơ |
ProjectVLobbyView | Những gì cần vẽ: trạng thái đang tải và hồ sơ |
ProjectVLobbyProfile | Tên và cấp của người chơi |
Màn này không có command (lệnh) nào: chỉ cần theo dõi và vẽ (render). Xem Screen contract để biết các màn hoạt động thế nào nói chung.
Bắt đầu nhanh
using System;
using SilverTiger.ProjectV.Unity.Presentation.Lobby;
using UnityEngine;
using VContainer;
public sealed class LobbyProfileCard : MonoBehaviour
{
private IProjectVLobbyScreen lobby = null!;
private IDisposable? observation;
[Inject]
public void Construct(IProjectVLobbyScreen screen) => lobby = screen;
private void OnEnable()
{
ShowLoading(null); // until the first Render call
observation = lobby.Observe(Render);
}
private void OnDisable()
{
observation?.Dispose();
observation = null;
}
// Always called on the Unity main thread.
private void Render(ProjectVLobbyView view)
{
if (view.IsLoading)
{
ShowLoading(view.LoadError); // null while loading; an error code after a failed load
return;
}
ShowProfile(view.Profile!.DisplayName, view.Profile.Level);
}
// Retry button shown with a load error.
public void OnRetryClicked()
{
observation?.Dispose();
observation = lobby.Observe(Render);
}
private void ShowLoading(string? loadError) { }
private void ShowProfile(string displayName, long level) { }
}
Đó là toàn bộ thẻ: theo dõi và vẽ. Render chỉ chạy lại khi hồ sơ thay đổi,
ví dụ sau khi một nhiệm vụ làm người chơi lên cấp.
Cần vẽ gì
Render nhận một ProjectVLobbyView:
| Member | Type | Dùng để |
|---|---|---|
IsLoading | bool | True khi chưa có hồ sơ nào được hiện: trước lần tải đầu, sau khi lần tải đầu lỗi, và sau khi đăng xuất. Hiện spinner |
LoadError | string? | Mã lỗi của lần tải thất bại, hoặc null. Không phải chữ cho người chơi: hiện thông báo "không tải được" của riêng bạn kèm nút thử lại (Retry), và giữ mã lỗi để ghi log |
Profile | ProjectVLobbyProfile? | Hồ sơ; null khi IsLoading |
lobby.Current chứa cùng view đó.
Với ProjectVLobbyProfile:
| Để hiện | Đọc |
|---|---|
| Tên người chơi | DisplayName (dùng Username khi người chơi chưa có tên hiển thị) |
| Cấp | Level, từ 1 trở lên, đúng như server gửi |
| Avatar | Avatar mặc định của bạn. Hiện tại AvatarUrl luôn rỗng |
| Khung avatar | Chưa có gì. Hiện tại AvatarFrameId luôn là null |
UserId là ID tài khoản; không hiện nó.
Khi bị lỗi
| Tình huống | View làm gì | Người chơi thấy gì |
|---|---|---|
| Lần tải đầu thất bại | IsLoading true và có LoadError | Thông báo lỗi tải của bạn kèm Retry |
| Một lần refresh sau đó thất bại | Không làm gì; view giữ hồ sơ đang hiện | Hồ sơ như cũ |
| Người chơi đã đăng xuất | IsLoading true, LoadError là null | Không có gì; game đang chuyển về Login |
Thử lại bằng cách dispose (giải phóng) observation rồi gọi Observe lần nữa,
như OnRetryClicked. Mỗi lần gọi Observe sẽ tải hồ sơ khi cần.
Quy tắc
- Hiện trạng thái đang tải trước khi gọi
Observe; lần gọiRenderđầu tiên có thể đến chậm một chút. - Hiện
Levelđúng như server gửi. Không bao giờ tự suy ra từ tiến trình cục bộ. - Đừng refresh khi vào Lobby.
Observetải hồ sơ khi cần, và thường thì hồ sơ đã có sẵn.
Lỗi thường gặp
- Hiện
LoadErrorcho người chơi. Nó là mã lỗi. - Tải avatar từ
AvatarUrl. Hiện tại nó luôn rỗng; hãy hiện avatar mặc định. - Giữ hồ sơ cũ trên màn sau khi refresh thất bại. View quay về trạng thái
đang tải; hãy vẽ những gì
Renderđưa cho bạn. - Không dispose observation. Giữ
IDisposabletừObservevà dispose nó trongOnDisablehoặcOnDestroy.
Presenter
IProjectVLobbyPresenter là
interface tầng thấp hơn nằm sau screen contract. Các trang thường dùng
IProjectVLobbyScreen; chỉ dùng presenter khi bạn cần thêm chi tiết của nó:
| Member | Trả về | Dùng để |
|---|---|---|
SubscribeAsync(listener) | Task<IDisposable> | ProjectVLobbySnapshot hiện tại, rồi mọi thay đổi sau đó |
RefreshAsync(token) | ProjectVLobbyCommandResult | Tải hồ sơ; các lần gọi chạy lần lượt từng cái một |
Current | ProjectVLobbySnapshot | Trạng thái mới nhất |
Snapshot có Status (Empty, Refreshing, Ready, Failed), Profile,
IsReady và một ProjectVLobbyError
đầy đủ với Category, Code, RequestId và LocalizationKey
(projectv.lobby.<category>). RefreshAsync không throw khi tải thất bại:
IsSuccess là false khi tải thất bại, bị huỷ (PROJECTV_LOBBY_CANCELLED),
hoặc người chơi đăng xuất trong lúc đó.
Listener của presenter có thể chạy ngoài main thread của Unity; hãy chuyển về
main thread (ví dụ await UniTask.SwitchToMainThread()) trước khi đụng vào
object của Unity. Render của màn đã làm việc này cho bạn.