Chuyển tới nội dung chính

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ùngNó cho bạn
IProjectVLobbyScreenScreen contract: theo dõi thẻ hồ sơ
ProjectVLobbyViewNhững gì cần vẽ: trạng thái đang tải và hồ sơ
ProjectVLobbyProfileTê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:

MemberTypeDùng để
IsLoadingboolTrue 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
LoadErrorstring?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
ProfileProjectVLobbyProfile?Hồ sơ; null khi IsLoading

lobby.Current chứa cùng view đó.

Với ProjectVLobbyProfile:

Để hiệnĐọc
Tên người chơiDisplayName (dùng Username khi người chơi chưa có tên hiển thị)
CấpLevel, từ 1 trở lên, đúng như server gửi
AvatarAvatar mặc định của bạn. Hiện tại AvatarUrl luôn rỗng
Khung avatarChư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ốngView làm gìNgười chơi thấy gì
Lần tải đầu thất bạiIsLoading true và có LoadErrorThông báo lỗi tải của bạn kèm Retry
Một lần refresh sau đó thất bạiKhông làm gì; view giữ hồ sơ đang hiệnHồ sơ như cũ
Người chơi đã đăng xuấtIsLoading true, LoadError là nullKhô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ọi Render đầ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. Observe tải hồ sơ khi cần, và thường thì hồ sơ đã có sẵn.

Lỗi thường gặp​

  • Hiện LoadError cho 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ữ IDisposable từ Observe và dispose nó trong OnDisable hoặc OnDestroy.

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ó:

MemberTrả vềDùng để
SubscribeAsync(listener)Task<IDisposable>ProjectVLobbySnapshot hiện tại, rồi mọi thay đổi sau đó
RefreshAsync(token)ProjectVLobbyCommandResultTải hồ sơ; các lần gọi chạy lần lượt từng cái một
CurrentProjectVLobbySnapshotTrạ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.