加入很多新内容,这波一块交了

This commit is contained in:
FloatGaming
2026-04-08 20:53:41 +08:00
parent d9376833b6
commit 85dfff28dd
128 changed files with 14546 additions and 474 deletions
@@ -0,0 +1,296 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2099462153568767799
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 665396819362690529}
- component: {fileID: 3192217589302937993}
- component: {fileID: 5556623676502886536}
m_Layer: 5
m_Name: levelID
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &665396819362690529
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2099462153568767799}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 9152270112823009895}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -107.33, y: 0}
m_SizeDelta: {x: 25.792, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3192217589302937993
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2099462153568767799}
m_CullTransparentMesh: 1
--- !u!114 &5556623676502886536
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2099462153568767799}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 12800000, guid: 8b8373b0af11dca46b89be60dbe469f8, type: 3}
m_FontSize: 20
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 2
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 10
--- !u!1 &2343926165364488871
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 9152270112823009895}
- component: {fileID: 4801688296739999581}
- component: {fileID: 4501378674247754304}
m_Layer: 5
m_Name: btm
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &9152270112823009895
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2343926165364488871}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2290428063649654242}
- {fileID: 665396819362690529}
m_Father: {fileID: 2460305581810160109}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 250, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4801688296739999581
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2343926165364488871}
m_CullTransparentMesh: 1
--- !u!114 &4501378674247754304
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2343926165364488871}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: -52179173452712981, guid: be120bf969ae2c84fa997ecca6dd28e6, type: 3}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 2
--- !u!1 &3339470438795980614
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2290428063649654242}
- component: {fileID: 4129409205783608839}
- component: {fileID: 534678815217464394}
m_Layer: 5
m_Name: skillName
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2290428063649654242
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3339470438795980614}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 9152270112823009895}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 1.4, y: 0}
m_SizeDelta: {x: 187.733, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4129409205783608839
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3339470438795980614}
m_CullTransparentMesh: 1
--- !u!114 &534678815217464394
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3339470438795980614}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 12800000, guid: dfa10de3e2846524089b5073175cd151, type: 3}
m_FontSize: 20
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 2
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: "\u5076\u50CF\u5927\u5E08\uFF1A\u8D5B\u540E\u611F\u609F"
--- !u!1 &4419549278339915466
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2460305581810160109}
- component: {fileID: 7517620086478948793}
m_Layer: 5
m_Name: levelRewardPrefab
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2460305581810160109
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4419549278339915466}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 9152270112823009895}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 450, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &7517620086478948793
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4419549278339915466}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 427d68583c7d9ab4588888b68dc7a8d2, type: 3}
m_Name:
m_EditorClassIdentifier:
enableSprite: {fileID: -52179173452712981, guid: be120bf969ae2c84fa997ecca6dd28e6, type: 3}
availableSprite: {fileID: 2561534620446350566, guid: 23a48ca1e983a4c47971fcf7eab26b89, type: 3}
lockedSprite: {fileID: -1936355827857895663, guid: fa360ec6245a3dd43bfbae1ac1093a6e, type: 3}
unknownSprite: {fileID: 21300000, guid: 931f6455943555649a61ed7f1c76cbf6, type: 3}
preSelectSprite: {fileID: 7919194353434859991, guid: b35fcaa46fa9f3e49b71c103f69df698, type: 3}
levelName: {fileID: 5556623676502886536}
statusImg: {fileID: 4501378674247754304}
thisSkillName: {fileID: 534678815217464394}
descriptionPrefab: {fileID: 2219571326304505587, guid: bde76837f913f3943836d4f83292618b, type: 3}
descriptionOffsetX: 150
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 26d681beab8631442ac57714a80f1f37
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+184
View File
@@ -0,0 +1,184 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class lrPrefab : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
[Header("sprite")]
public Sprite enableSprite;
public Sprite availableSprite;
public Sprite lockedSprite;
public Sprite unknownSprite;
public Sprite preSelectSprite;
[Header("uis")]
public Text levelName;
public Image statusImg;
public Text thisSkillName;
[Header("desOBJ")]
public GameObject descriptionPrefab;
public float descriptionOffsetX = 80f;
private uLevel_skills owner;
private userLevel_skills_SO ownerSo;
private userLevel_skills_SO.UserLevelSkillEntry boundEntry;
private int boundIndex = -1;
private bool isUnlocked = false;
private Coroutine hoverCoroutine;
private GameObject spawnedDescription;
public void Bind(uLevel_skills ownerController, userLevel_skills_SO sourceSo, int index, userLevel_skills_SO.UserLevelSkillEntry entry, bool unlocked)
{
owner = ownerController;
ownerSo = sourceSo;
boundIndex = index;
boundEntry = entry;
isUnlocked = unlocked;
if (levelName != null)
levelName.text = entry != null ? entry.userLevel.ToString() : string.Empty;
RefreshVisualState();
}
public void RefreshVisualState()
{
if (owner != null && boundEntry != null)
isUnlocked = owner.IsSkillUnlocked(boundEntry);
if (boundEntry == null)
return;
bool revealLockedSkills = PlayerSkillService.IsSkillEnabled(7);
bool shouldHideLockedSkillInfo = !isUnlocked && !revealLockedSkills;
if (thisSkillName != null)
{
thisSkillName.text = shouldHideLockedSkillInfo
? "?????"
: (boundEntry.skillName ?? string.Empty);
}
if (statusImg == null)
return;
if (owner != null && owner.IsSkillPreselected(boundIndex))
statusImg.sprite = preSelectSprite != null ? preSelectSprite : availableSprite;
else if (boundEntry.isEnabled)
statusImg.sprite = enableSprite;
else if (isUnlocked)
statusImg.sprite = availableSprite;
else if (shouldHideLockedSkillInfo)
statusImg.sprite = unknownSprite != null ? unknownSprite : lockedSprite;
else
statusImg.sprite = lockedSprite;
}
public void OnPointerEnter(PointerEventData eventData)
{
if (boundEntry == null || descriptionPrefab == null)
return;
if (!isUnlocked && !PlayerSkillService.IsSkillEnabled(7))
return;
if (hoverCoroutine != null)
StopCoroutine(hoverCoroutine);
hoverCoroutine = StartCoroutine(ShowDescriptionAfterDelay());
}
public void OnPointerExit(PointerEventData eventData)
{
if (hoverCoroutine != null)
{
StopCoroutine(hoverCoroutine);
hoverCoroutine = null;
}
HideDescription();
}
public void OnPointerClick(PointerEventData eventData)
{
if (owner == null || boundIndex < 0)
return;
owner.ToggleSkill(boundIndex);
}
private IEnumerator ShowDescriptionAfterDelay()
{
yield return new WaitForSeconds(0.5f);
hoverCoroutine = null;
ShowDescription();
}
private void ShowDescription()
{
if (spawnedDescription != null || descriptionPrefab == null || boundEntry == null)
return;
RectTransform root = ResolveDescriptionRoot();
if (root == null)
return;
spawnedDescription = Instantiate(descriptionPrefab, root);
spawnedDescription.SetActive(true);
spawnedDescription.transform.SetAsLastSibling();
esDesPrefab detail = spawnedDescription.GetComponent<esDesPrefab>();
if (detail != null)
detail.Bind(boundEntry.skillName, boundEntry.skillIcon, boundEntry.skillDescription, boundEntry.skillSummary);
RectTransform spawnedRect = spawnedDescription.GetComponent<RectTransform>();
if (spawnedRect == null)
return;
Canvas canvas = root.GetComponentInParent<Canvas>();
Camera eventCamera = null;
if (canvas != null && canvas.renderMode != RenderMode.ScreenSpaceOverlay)
eventCamera = canvas.worldCamera;
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(root, Input.mousePosition, eventCamera, out localPoint);
localPoint.x += descriptionOffsetX;
spawnedRect.anchoredPosition = localPoint;
}
private RectTransform ResolveDescriptionRoot()
{
Canvas canvas = GetComponentInParent<Canvas>();
if (canvas == null)
return null;
Canvas rootCanvas = canvas.rootCanvas != null ? canvas.rootCanvas : canvas;
return rootCanvas.transform as RectTransform;
}
private void HideDescription()
{
if (spawnedDescription == null)
return;
if (Application.isPlaying)
Destroy(spawnedDescription);
else
DestroyImmediate(spawnedDescription);
spawnedDescription = null;
}
private void OnDisable()
{
if (hoverCoroutine != null)
{
StopCoroutine(hoverCoroutine);
hoverCoroutine = null;
}
HideDescription();
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 427d68583c7d9ab4588888b68dc7a8d2
@@ -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;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 522d48b038e44bd4289b57ea155ae0b9
+92
View File
@@ -0,0 +1,92 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 19a25568f1e1a8b4093dce8a6753be0e, type: 3}
m_Name: ulsSO
m_EditorClassIdentifier:
skills:
- userLevel: 0
skillName: "\u8D5B\u524D\u51C6\u5907"
skillDescription: "\u4F60\u5DF2\u6765\u5230\u672C\u7D22\u5C3C\u514B\u4E16\u754C\u3002\u8D5B\u524D\u51C6\u5907\u65F6\uFF0C\u4F60\u53EF\u4EE5\u65E0\u9650\u5236\u5730\u8FDB\u5165\u65B0\u624B\u6559\u7A0B\u3002"
skillSummary: "\u5378\u4E0B\u5B83\u65F6\u4F60\u5DF2\u4E0D\u518D\u662F\u65B0\u624B"
isEnabled: 1
skillIcon: {fileID: 0}
thisLevelNeedExps: 0
- userLevel: 1
skillName: "\u8BB0\u5FC6\u8D2D\u4E70\u8BA1\u5212"
skillDescription: "\u5141\u8BB8\u4F60\u4EE510\u91D1\u5E01\u8D2D\u4E701\u4E2A\u8BB0\u5FC6\u788E\u7247\u3002\u88C5\u5907\u6B64\u6280\u80FD\u65F6\u53EF\u4E8E\u5546\u5E97\u89E3\u9501\u4E00\u4E2A\u8D2D\u4E70\u9009\u9879\u3002"
skillSummary: "\u4ECE\u8001\u5E08\u90A3\u91CC\u65B0\u5B66\u4E86\u4EC0\u4E48\uFF1F"
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 200
- userLevel: 2
skillName: "\u8BB0\u5FC6\u5F52\u8FD8\u8BA1\u5212"
skillDescription: "\u5141\u8BB8\u4F60\u5C061\u4E2A\u8BB0\u5FC6\u788E\u7247\u4EE54\u91D1\u5E01\u552E\u51FA\u3002\u88C5\u5907\u6B64\u6280\u80FD\u65F6\u53EF\u4E8E\u5546\u5E97\u89E3\u9501\u4E00\u4E2A\u8D2D\u4E70\u9009\u9879\u3002"
skillSummary: "\u8001\u5E08\u6559\u7ED9\u4F60\u7684\u53C8\u8FD8\u56DE\u53BB\u4E86\u5417\uFF1F"
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 300
- userLevel: 3
skillName: "\u6311\u6218\u8005\u6A21\u578B"
skillDescription: "\u5141\u8BB8\u8BBE\u7F6E\u4E00\u4E2A\u81EA\u5B9A\u7684\u767E\u5206\u6BD4\u9ED1\u5E55\u6765\u906E\u4F4F\u8F68\u9053\u3002\u6700\u5C11\u906E\u632120%\uFF0C\u6700\u591A\u906E\u632190%\u3002\u6BCF\u906E\u63211%\uFF0C\u63D0\u4F9B1.5%\u7ED3\u7B97\u5956\u52B1\u52A0\u6210\u3002"
skillSummary: "\u9AD8\u98CE\u9669\u9AD8\u56DE\u62A5\uFF0C\u597D\u5947\u5FC3\u5BB3\u6B7B\u732B\u3002"
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 400
- userLevel: 4
skillName: "\u8D5B\u540E\u611F\u609F"
skillDescription: "\u6BCF\u8FDB\u884C10\u573A\u6BD4\u8D5B\u53EF\u83B7\u5F97\u4E00\u4EF6\u968F\u673A\u7C7B\u578B\u968F\u673A\u5C5E\u6027\u7684\u8BB0\u5FC6\u3002\u5728\u66F4\u6362\u6280\u80FD\u65F6\u6E05\u96F6\u8BA1\u6570\u5668\u3002"
skillSummary:
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 500
- userLevel: 5
skillName: "\u6211\u7231\u53D1\u660E"
skillDescription: "\u4F60\u7684\u8BB0\u5FC6\u878D\u5408\u548C\u52A0\u901F\u6240\u9700\u7684\u8D27\u5E01\u51CF\u534A\u3002"
skillSummary:
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 600
- userLevel: 6
skillName: "\u8FFD\u68A6\u4E4B\u8DEF"
skillDescription: "\u7ED3\u7B97\u65F6\uFF0C\u83B7\u5F97\u5076\u50CF\u5206\u65701\u2030\u7684\u8BB0\u5FC6\u788E\u7247\u3002"
skillSummary:
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 700
- userLevel: 7
skillName: "\u6D1E\u5BDF"
skillDescription: "\u4F60\u53EF\u4EE5\u770B\u5230\u89D2\u8272\u672A\u89E3\u9501\u7684\u6280\u80FD\u53CA\u5176\u4ECB\u7ECD\u3002"
skillSummary: "\u4F60\u7684\u76EE\u5149\u6781\u5177\u6218\u7565\u524D\u77BB\u6027\u3002"
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 800
- userLevel: 8
skillName: "95\u6298"
skillDescription: "\u6D88\u8D39\u8BB0\u5FC6\u788E\u7247\u548Ccoins\u65F6\u767E\u5206\u6BD4\u8FD4\u8FD8\u3002\u4F60\u6BCF\u62E5\u6709\u4E00\u4E2A\u5076\u50CF\uFF0C\u589E\u52A0\u6D88\u8D39\u8FD4\u8FD8\u7684\u6BD4\u4F8B0.5%\u3002\u6700\u591A\u5408\u8BA1\u8FD4\u8FD85%\u3002"
skillSummary:
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 900
- userLevel: 9
skillName: "\u5229\u6DA6\u63D0\u53D6\u5668"
skillDescription: "\u7ED3\u7B97\u65F6\uFF0C\u83B7\u5F97\u5076\u50CF\u5206\u65702\u2030\u7684\u91D1\u5E01\u3002"
skillSummary: "\u6B7B\u4E0E\u7A0E"
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 1100
- userLevel: 10
skillName: "\u9876\u5CF0\u76F8\u89C1"
skillDescription: "\u6E38\u620F\u4E2D\u4F60\u7684\u89C6\u89D2\u9AD8\u5EA6\u63D0\u9AD810%\u3002"
skillSummary: "\u611F\u6069\u6559\u7EC3\u3002"
isEnabled: 0
skillIcon: {fileID: 0}
thisLevelNeedExps: 1500
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: acf1a85d46975694aba2cdc12b9b3dfb
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
using UnityEngine;
using System.Collections.Generic;
[CreateAssetMenu(fileName = "userLevel_skills", menuName = "Player/UserLevel Skills SO")]
public class userLevel_skills_SO : ScriptableObject
{
[System.Serializable]
public class UserLevelSkillEntry
{
public int userLevel;
public string skillName;
[TextArea(3, 10)] public string skillDescription;
public string skillSummary;
public bool isEnabled;
public Sprite skillIcon;
public int thisLevelNeedExps;
}
public List<UserLevelSkillEntry> skills = new List<UserLevelSkillEntry>();
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 19a25568f1e1a8b4093dce8a6753be0e