Add player profile system
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UObject = UnityEngine.Object;
|
||||
|
||||
namespace XGame
|
||||
{
|
||||
public sealed class PlayerProfileModule : MonoBehaviour
|
||||
{
|
||||
private const string HudPrefabPath = "Assets/Game/Art/UI/Prefab/UI_PlayerProfileHud.prefab";
|
||||
private const string PanelPrefabPath = "Assets/Game/Art/UI/Prefab/UI_PlayerProfilePanel.prefab";
|
||||
|
||||
private GameObject hudView;
|
||||
private GameObject detailView;
|
||||
private bool openingHud;
|
||||
private bool openingDetail;
|
||||
private int openVersion;
|
||||
|
||||
private TMP_Text hudNicknameText;
|
||||
private TMP_Text hudLevelText;
|
||||
private TMP_Text hudExpText;
|
||||
private RectTransform hudExpFill;
|
||||
private RectTransform hudExpTrack;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
PlayerProfileStore.Changed += OnProfileChanged;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
PlayerProfileStore.Changed -= OnProfileChanged;
|
||||
}
|
||||
|
||||
public bool IsOpen => hudView != null;
|
||||
|
||||
public IEnumerator OpenAsync()
|
||||
{
|
||||
if (hudView != null || openingHud)
|
||||
{
|
||||
RefreshAll(PlayerProfileStore.Current);
|
||||
yield break;
|
||||
}
|
||||
|
||||
openingHud = true;
|
||||
int version = ++openVersion;
|
||||
UObject loaded = null;
|
||||
yield return XResLoader.coLoadRes(HudPrefabPath, typeof(GameObject), obj => loaded = obj);
|
||||
openingHud = false;
|
||||
|
||||
if (version != openVersion)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
GameObject prefab = loaded as GameObject;
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogError("[PlayerProfileModule] load HUD prefab failed: " + HudPrefabPath);
|
||||
yield break;
|
||||
}
|
||||
|
||||
hudView = Instantiate(prefab);
|
||||
UIManager.AttachTo(UILayer.HUD, hudView);
|
||||
CacheHudControls();
|
||||
BindHudEvents();
|
||||
RefreshHud(PlayerProfileStore.Current);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
openVersion++;
|
||||
openingHud = false;
|
||||
openingDetail = false;
|
||||
if (hudView != null)
|
||||
{
|
||||
Destroy(hudView);
|
||||
}
|
||||
if (detailView != null)
|
||||
{
|
||||
Destroy(detailView);
|
||||
}
|
||||
hudView = null;
|
||||
detailView = null;
|
||||
hudNicknameText = null;
|
||||
hudLevelText = null;
|
||||
hudExpText = null;
|
||||
hudExpFill = null;
|
||||
hudExpTrack = null;
|
||||
}
|
||||
|
||||
private void OnProfileChanged(PlayerProfileData profile)
|
||||
{
|
||||
RefreshAll(profile);
|
||||
}
|
||||
|
||||
private void RefreshAll(PlayerProfileData profile)
|
||||
{
|
||||
RefreshHud(profile);
|
||||
RefreshDetail(profile);
|
||||
}
|
||||
|
||||
private void CacheHudControls()
|
||||
{
|
||||
if (hudView == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
hudNicknameText = FindComponent<TMP_Text>(hudView, "Txt_Nickname");
|
||||
hudLevelText = FindComponent<TMP_Text>(hudView, "Txt_Level");
|
||||
hudExpText = FindComponent<TMP_Text>(hudView, "Txt_Exp");
|
||||
hudExpTrack = FindRect(hudView, "Img_ExpBg");
|
||||
hudExpFill = FindRect(hudView, "Img_ExpFill");
|
||||
}
|
||||
|
||||
private void BindHudEvents()
|
||||
{
|
||||
Button button = FindComponent<Button>(hudView, "Btn_Profile");
|
||||
if (button == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
button.onClick.RemoveAllListeners();
|
||||
button.onClick.AddListener(OpenDetail);
|
||||
}
|
||||
|
||||
private void RefreshHud(PlayerProfileData profile)
|
||||
{
|
||||
if (hudView == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
profile = profile ?? PlayerProfileStore.Current;
|
||||
if (hudNicknameText != null) hudNicknameText.text = profile.Nickname;
|
||||
if (hudLevelText != null) hudLevelText.text = "Lv." + profile.Lv;
|
||||
if (hudExpText != null) hudExpText.text = profile.Exp + "/" + profile.RequiredExp;
|
||||
|
||||
if (hudExpTrack != null && hudExpFill != null)
|
||||
{
|
||||
float width = Mathf.Max(0f, hudExpTrack.rect.width);
|
||||
hudExpFill.sizeDelta = new Vector2(width * profile.Experience01, hudExpFill.sizeDelta.y);
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenDetail()
|
||||
{
|
||||
if (detailView != null || openingDetail)
|
||||
{
|
||||
RefreshDetail(PlayerProfileStore.Current);
|
||||
return;
|
||||
}
|
||||
XWCoroutine.StartCo(CoOpenDetail());
|
||||
}
|
||||
|
||||
private IEnumerator CoOpenDetail()
|
||||
{
|
||||
openingDetail = true;
|
||||
UObject loaded = null;
|
||||
yield return XResLoader.coLoadRes(PanelPrefabPath, typeof(GameObject), obj => loaded = obj);
|
||||
openingDetail = false;
|
||||
|
||||
GameObject prefab = loaded as GameObject;
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogError("[PlayerProfileModule] load detail prefab failed: " + PanelPrefabPath);
|
||||
yield break;
|
||||
}
|
||||
|
||||
detailView = Instantiate(prefab);
|
||||
UIManager.AttachTo(UILayer.Dialog, detailView);
|
||||
BindDetailEvents();
|
||||
RefreshDetail(PlayerProfileStore.Current);
|
||||
}
|
||||
|
||||
private void BindDetailEvents()
|
||||
{
|
||||
BindCloseButton("Btn_Close");
|
||||
BindCloseButton("Img_Mask");
|
||||
}
|
||||
|
||||
private void BindCloseButton(string nodeName)
|
||||
{
|
||||
Button button = FindComponent<Button>(detailView, nodeName);
|
||||
if (button == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
button.onClick.RemoveAllListeners();
|
||||
button.onClick.AddListener(CloseDetail);
|
||||
}
|
||||
|
||||
private void CloseDetail()
|
||||
{
|
||||
if (detailView != null)
|
||||
{
|
||||
Destroy(detailView);
|
||||
}
|
||||
detailView = null;
|
||||
}
|
||||
|
||||
private void RefreshDetail(PlayerProfileData profile)
|
||||
{
|
||||
if (detailView == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
profile = profile ?? PlayerProfileStore.Current;
|
||||
SetText("Txt_Nickname", profile.Nickname);
|
||||
SetText("Txt_Uid", "UID: " + profile.Uid);
|
||||
SetText("Txt_RoleType", profile.RoleType.ToString());
|
||||
SetText("Txt_Gold", profile.Gold.ToString());
|
||||
SetText("Txt_Diamond", profile.Diamond.ToString());
|
||||
SetText("Txt_Lv", profile.Lv.ToString());
|
||||
SetText("Txt_Exp", profile.Exp + "/" + profile.RequiredExp);
|
||||
SetText("Txt_Hp", profile.Hp + "/" + profile.HpMax);
|
||||
SetText("Txt_Mp", profile.Mp + "/" + profile.MpMax);
|
||||
SetText("Txt_Ad", profile.Ad.ToString());
|
||||
SetText("Txt_Ap", profile.Ap.ToString());
|
||||
SetText("Txt_AtkSpeed", profile.AtkSpeed.ToString("0.##"));
|
||||
SetText("Txt_MoveSpeed", profile.MoveSpeed.ToString("0.##"));
|
||||
}
|
||||
|
||||
private void SetText(string nodeName, string value)
|
||||
{
|
||||
TMP_Text text = FindComponent<TMP_Text>(detailView, nodeName);
|
||||
if (text != null)
|
||||
{
|
||||
text.text = value ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private static RectTransform FindRect(GameObject root, string nodeName)
|
||||
{
|
||||
Transform t = root == null ? null : root.transform.FindTransform(nodeName);
|
||||
return t == null ? null : t.GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
private static T FindComponent<T>(GameObject root, string nodeName) where T : Component
|
||||
{
|
||||
Transform t = root == null ? null : root.transform.FindTransform(nodeName);
|
||||
return t == null ? null : t.GetComponent<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user