加入很多新内容,这波一块交了
This commit is contained in:
@@ -0,0 +1,415 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class uLevel_skills : MonoBehaviour
|
||||
{
|
||||
public userLevel_skills_SO ulsSO;
|
||||
public Player_SO pso;
|
||||
|
||||
[Header("objs")]
|
||||
public GameObject uSkillBarPrefab;
|
||||
public Transform uSkillBarParent;
|
||||
|
||||
[Header("current selected skill details")]
|
||||
public Image btm_skillImage;
|
||||
public Image skillIcon_Profile;
|
||||
public Text skill_thisSkillName;
|
||||
public Text skill_thisSkillSummary;
|
||||
|
||||
[Header("change")]
|
||||
public Slider need_progress;
|
||||
public Text need_text;
|
||||
public Text need_howmuchCoins;
|
||||
public Button yesChangeButton;
|
||||
public Button noCancelButton;
|
||||
|
||||
private readonly System.Collections.Generic.List<lrPrefab> spawnedBars = new System.Collections.Generic.List<lrPrefab>();
|
||||
private bool hasStarted = false;
|
||||
private int pendingSkillIndex = -1;
|
||||
private Color defaultNeedCoinsColor = Color.white;
|
||||
private const int SkillSwitchCooldownMatches = 3;
|
||||
private const int SkillSwitchMinimumCost = 200;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
hasStarted = true;
|
||||
CacheUiDefaults();
|
||||
RegisterButtons();
|
||||
PlayerSkillService.RegisterSkillAsset(ulsSO);
|
||||
RefreshSkillBars();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
CacheUiDefaults();
|
||||
RegisterButtons();
|
||||
PlayerSkillService.RegisterSkillAsset(ulsSO);
|
||||
if (hasStarted)
|
||||
{
|
||||
RefreshSkillBars();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
UnregisterButtons();
|
||||
}
|
||||
|
||||
public void SetPlayerSo(Player_SO playerSo)
|
||||
{
|
||||
pso = playerSo;
|
||||
}
|
||||
|
||||
public void RefreshSkillBars()
|
||||
{
|
||||
EnsurePlayerSo();
|
||||
|
||||
if (uSkillBarParent == null || uSkillBarPrefab == null || ulsSO == null)
|
||||
return;
|
||||
|
||||
NormalizeSelectionState();
|
||||
ClearExistingBars();
|
||||
spawnedBars.Clear();
|
||||
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry == null)
|
||||
continue;
|
||||
|
||||
GameObject instance = Instantiate(uSkillBarPrefab, uSkillBarParent);
|
||||
instance.SetActive(true);
|
||||
|
||||
lrPrefab bar = instance.GetComponent<lrPrefab>();
|
||||
if (bar == null)
|
||||
continue;
|
||||
|
||||
bar.Bind(this, ulsSO, i, entry, IsSkillUnlocked(entry));
|
||||
spawnedBars.Add(bar);
|
||||
}
|
||||
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
}
|
||||
|
||||
public void ToggleSkill(int index)
|
||||
{
|
||||
if (ulsSO == null || index < 0 || index >= ulsSO.skills.Count)
|
||||
return;
|
||||
|
||||
var entry = ulsSO.skills[index];
|
||||
if (entry == null || !IsSkillUnlocked(entry))
|
||||
return;
|
||||
|
||||
int currentEnabledIndex = GetEnabledSkillIndex();
|
||||
if (index == currentEnabledIndex)
|
||||
{
|
||||
pendingSkillIndex = -1;
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
RefreshStatusesOnly();
|
||||
return;
|
||||
}
|
||||
|
||||
pendingSkillIndex = pendingSkillIndex == index ? -1 : index;
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
RefreshStatusesOnly();
|
||||
}
|
||||
|
||||
public bool IsSkillPreselected(int index)
|
||||
{
|
||||
return pendingSkillIndex >= 0 && pendingSkillIndex == index;
|
||||
}
|
||||
|
||||
public bool IsSkillUnlocked(userLevel_skills_SO.UserLevelSkillEntry entry)
|
||||
{
|
||||
EnsurePlayerSo();
|
||||
|
||||
if (entry == null)
|
||||
return false;
|
||||
|
||||
int currentExp = pso != null ? Mathf.Max(0, pso.player_currentEXP) : 0;
|
||||
return currentExp >= Mathf.Max(0, entry.thisLevelNeedExps);
|
||||
}
|
||||
|
||||
private void RefreshStatusesOnly()
|
||||
{
|
||||
for (int i = 0; i < spawnedBars.Count; i++)
|
||||
{
|
||||
if (spawnedBars[i] == null)
|
||||
continue;
|
||||
|
||||
spawnedBars[i].RefreshVisualState();
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshDetailPanel()
|
||||
{
|
||||
if (ulsSO == null || ulsSO.skills == null || ulsSO.skills.Count == 0)
|
||||
{
|
||||
SetDetailPanel(null);
|
||||
return;
|
||||
}
|
||||
|
||||
int detailIndex = pendingSkillIndex >= 0 ? pendingSkillIndex : GetEnabledSkillIndex();
|
||||
if (detailIndex < 0 || detailIndex >= ulsSO.skills.Count)
|
||||
{
|
||||
SetDetailPanel(null);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDetailPanel(ulsSO.skills[detailIndex]);
|
||||
}
|
||||
|
||||
private void SetDetailPanel(userLevel_skills_SO.UserLevelSkillEntry entry)
|
||||
{
|
||||
if (btm_skillImage != null)
|
||||
{
|
||||
btm_skillImage.sprite = entry != null ? entry.skillIcon : null;
|
||||
}
|
||||
|
||||
if (skillIcon_Profile != null)
|
||||
{
|
||||
skillIcon_Profile.sprite = entry != null ? entry.skillIcon : null;
|
||||
}
|
||||
|
||||
if (skill_thisSkillName != null)
|
||||
{
|
||||
skill_thisSkillName.text = entry != null ? (entry.skillName ?? string.Empty) : string.Empty;
|
||||
}
|
||||
|
||||
if (skill_thisSkillSummary != null)
|
||||
{
|
||||
skill_thisSkillSummary.text = entry != null ? (entry.skillDescription ?? string.Empty) : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshChangeUi()
|
||||
{
|
||||
int cooldownRemaining = PlayerSkillService.GetSkillSwitchCooldownRemainingMatches();
|
||||
int currentEnabledIndex = GetEnabledSkillIndex();
|
||||
bool hasPendingSelection = pendingSkillIndex >= 0 && pendingSkillIndex != currentEnabledIndex;
|
||||
|
||||
if (need_text != null)
|
||||
{
|
||||
need_text.text = cooldownRemaining > 0
|
||||
? $"还需要{cooldownRemaining}场比赛"
|
||||
: "可以切换技能";
|
||||
}
|
||||
|
||||
if (need_progress != null)
|
||||
{
|
||||
need_progress.minValue = 0f;
|
||||
need_progress.maxValue = 1f;
|
||||
need_progress.value = cooldownRemaining > 0
|
||||
? Mathf.Clamp01((float)(SkillSwitchCooldownMatches - cooldownRemaining) / SkillSwitchCooldownMatches)
|
||||
: 1f;
|
||||
}
|
||||
|
||||
int switchCost = GetSkillSwitchCost();
|
||||
bool hasEnoughCoins = HasEnoughCoinsForSwitch(switchCost);
|
||||
|
||||
if (need_howmuchCoins != null)
|
||||
{
|
||||
need_howmuchCoins.text = switchCost.ToString();
|
||||
need_howmuchCoins.color = hasEnoughCoins ? defaultNeedCoinsColor : Color.red;
|
||||
}
|
||||
|
||||
if (yesChangeButton != null)
|
||||
{
|
||||
yesChangeButton.interactable = hasPendingSelection && cooldownRemaining <= 0 && hasEnoughCoins;
|
||||
}
|
||||
|
||||
if (noCancelButton != null)
|
||||
{
|
||||
noCancelButton.interactable = pendingSkillIndex >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int GetSkillSwitchCost()
|
||||
{
|
||||
int currentCoins = Application.isPlaying
|
||||
? PlayerEconomyLedger.EnsureInstance().GetCoins()
|
||||
: (pso != null ? Mathf.Max(0, pso.Coins) : 0);
|
||||
int percentCost = Mathf.CeilToInt(currentCoins * 0.01f);
|
||||
return Mathf.Max(SkillSwitchMinimumCost, percentCost);
|
||||
}
|
||||
|
||||
private bool HasEnoughCoinsForSwitch(int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
return true;
|
||||
|
||||
return Application.isPlaying
|
||||
? PlayerEconomyLedger.EnsureInstance().HasEnoughCoins(amount)
|
||||
: (pso != null && pso.Coins >= amount);
|
||||
}
|
||||
|
||||
private void HandleConfirmSwitchClicked()
|
||||
{
|
||||
int currentEnabledIndex = GetEnabledSkillIndex();
|
||||
if (pendingSkillIndex < 0 || pendingSkillIndex == currentEnabledIndex || ulsSO == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerSkillService.GetSkillSwitchCooldownRemainingMatches() > 0)
|
||||
{
|
||||
RefreshChangeUi();
|
||||
return;
|
||||
}
|
||||
|
||||
int switchCost = GetSkillSwitchCost();
|
||||
bool spent = Application.isPlaying
|
||||
? PlayerEconomyLedger.EnsureInstance().TrySpendCoins(switchCost)
|
||||
: (pso != null && pso.TrySpendCoins(switchCost));
|
||||
if (!spent)
|
||||
{
|
||||
RefreshChangeUi();
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerSkillService.ConfirmSkillSelection(ulsSO, pendingSkillIndex);
|
||||
pendingSkillIndex = -1;
|
||||
MarkSkillsDirty();
|
||||
RefreshStatusesOnly();
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
}
|
||||
|
||||
private void HandleCancelPreselectClicked()
|
||||
{
|
||||
pendingSkillIndex = -1;
|
||||
RefreshStatusesOnly();
|
||||
RefreshDetailPanel();
|
||||
RefreshChangeUi();
|
||||
}
|
||||
|
||||
private void ClearExistingBars()
|
||||
{
|
||||
for (int i = uSkillBarParent.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
Transform child = uSkillBarParent.GetChild(i);
|
||||
if (Application.isPlaying)
|
||||
Destroy(child.gameObject);
|
||||
else
|
||||
DestroyImmediate(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void MarkSkillsDirty()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying && ulsSO != null)
|
||||
UnityEditor.EditorUtility.SetDirty(ulsSO);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void EnsurePlayerSo()
|
||||
{
|
||||
if (pso == null)
|
||||
pso = Resources.Load<Player_SO>("playerdata/playerData_uniqueData");
|
||||
}
|
||||
|
||||
private void CacheUiDefaults()
|
||||
{
|
||||
if (need_howmuchCoins != null)
|
||||
{
|
||||
defaultNeedCoinsColor = need_howmuchCoins.color;
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterButtons()
|
||||
{
|
||||
if (yesChangeButton != null)
|
||||
{
|
||||
yesChangeButton.onClick.RemoveListener(HandleConfirmSwitchClicked);
|
||||
yesChangeButton.onClick.AddListener(HandleConfirmSwitchClicked);
|
||||
}
|
||||
|
||||
if (noCancelButton != null)
|
||||
{
|
||||
noCancelButton.onClick.RemoveListener(HandleCancelPreselectClicked);
|
||||
noCancelButton.onClick.AddListener(HandleCancelPreselectClicked);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnregisterButtons()
|
||||
{
|
||||
if (yesChangeButton != null)
|
||||
{
|
||||
yesChangeButton.onClick.RemoveListener(HandleConfirmSwitchClicked);
|
||||
}
|
||||
|
||||
if (noCancelButton != null)
|
||||
{
|
||||
noCancelButton.onClick.RemoveListener(HandleCancelPreselectClicked);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetEnabledSkillIndex()
|
||||
{
|
||||
if (ulsSO == null || ulsSO.skills == null)
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry != null && entry.isEnabled)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void NormalizeSelectionState()
|
||||
{
|
||||
if (ulsSO == null || ulsSO.skills == null || ulsSO.skills.Count == 0)
|
||||
return;
|
||||
|
||||
int selectedIndex = -1;
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry == null || !entry.isEnabled)
|
||||
continue;
|
||||
|
||||
if (selectedIndex < 0)
|
||||
{
|
||||
selectedIndex = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.isEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedIndex < 0)
|
||||
{
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry == null)
|
||||
continue;
|
||||
|
||||
selectedIndex = i;
|
||||
entry.isEnabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ulsSO.skills.Count; i++)
|
||||
{
|
||||
var entry = ulsSO.skills[i];
|
||||
if (entry == null)
|
||||
continue;
|
||||
|
||||
entry.isEnabled = (i == selectedIndex);
|
||||
}
|
||||
|
||||
MarkSkillsDirty();
|
||||
PlayerSkillService.RegisterSkillAsset(ulsSO);
|
||||
pendingSkillIndex = -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user