Unity玩家属性计算器功能完善求助:按枚举类型修改对应属性值
Unity玩家属性计算功能完善方案
以下是修改后的PlayerStatCalculator脚本,完全适配现有代码结构,实现所有枚举类型的属性计算逻辑:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerStatCalculator : MonoBehaviour { public CardSO collectedCard; public PlayerStats playerStatToChange; // 存储持续生效的属性修改任务,用于后续统一管理 private List<Coroutine> ongoingStatCoroutines = new List<Coroutine>(); public void OnCardCollected() { foreach (var statChanges in collectedCard.StatChanges) { // 传入目标属性、数值、计算类型 SetStats(statChanges.statName, statChanges.statChangeAmount, statChanges.changeType); } } void SetStats(EStatToChange statName, float amount, EStatChangeType type) { float currentValue = GetCurrentStatValue(statName); switch (type) { case EStatChangeType.Fixed: // 固定增减:当前值 + 数值 UpdateStatValue(statName, currentValue + amount); break; case EStatChangeType.Persentage: // 百分比增减:当前值 × (1 + 百分比小数),例:0.2代表+20% UpdateStatValue(statName, currentValue * (1 + amount)); break; case EStatChangeType.Set: // 直接赋值:覆盖为指定数值 UpdateStatValue(statName, amount); break; case EStatChangeType.Second: // 每秒固定增减:开启协程持续生效 var secondCoroutine = StartCoroutine(ApplyPerSecondFixed(statName, amount)); ongoingStatCoroutines.Add(secondCoroutine); break; case EStatChangeType.SecondPersentage: // 每秒百分比增减:开启协程持续生效 var secondPercentCoroutine = StartCoroutine(ApplyPerSecondPercentage(statName, amount)); ongoingStatCoroutines.Add(secondPercentCoroutine); break; } } // 获取指定属性的当前值 float GetCurrentStatValue(EStatToChange statName) { switch (statName) { case EStatToChange.Hp: return playerStatToChange.Hp; case EStatToChange.Damage: return playerStatToChange.Damage; case EStatToChange.ReloadTime: return playerStatToChange.ReloadTime; default: Debug.LogWarning($"未处理的属性类型:{statName}"); return 0; } } // 更新指定属性值,处理int/float类型转换 void UpdateStatValue(EStatToChange statName, float newValue) { switch (statName) { case EStatToChange.Hp: playerStatToChange.Hp = Mathf.RoundToInt(newValue); break; case EStatToChange.Damage: playerStatToChange.Damage = Mathf.RoundToInt(newValue); break; case EStatToChange.ReloadTime: // 防止 reload时间出现负数 playerStatToChange.ReloadTime = Mathf.Max(newValue, 0); break; default: Debug.LogWarning($"未处理的属性类型:{statName}"); break; } } // 协程:每秒执行一次固定增减 IEnumerator ApplyPerSecondFixed(EStatToChange statName, float amountPerSecond) { while (true) { float currentValue = GetCurrentStatValue(statName); UpdateStatValue(statName, currentValue + amountPerSecond); yield return new WaitForSeconds(1f); } } // 协程:每秒执行一次百分比增减 IEnumerator ApplyPerSecondPercentage(EStatToChange statName, float percentPerSecond) { while (true) { float currentValue = GetCurrentStatValue(statName); UpdateStatValue(statName, currentValue * (1 + percentPerSecond)); yield return new WaitForSeconds(1f); } } // 可选:停止所有持续属性修改(比如角色死亡时调用) public void StopAllOngoingStatChanges() { foreach (var coroutine in ongoingStatCoroutines) { StopCoroutine(coroutine); } ongoingStatCoroutines.Clear(); } }
关键改动说明
- 补全参数传递:新增
EStatToChange类型参数,明确要修改的目标属性,解决原代码无法定位属性的问题。 - 统一属性读写:拆分
GetCurrentStatValue和UpdateStatValue方法,处理int与float类型的自动转换,避免重复代码。 - 实现所有计算逻辑:
- Fixed:直接增减固定数值
- Persentage:按当前值的百分比修改(传入小数代表比例)
- Set:直接覆盖为指定数值
- Second/SecondPersentage:通过协程实现每秒持续修改,适配持续buff需求
- 异常防护:对
ReloadTime做最小值限制,避免出现负数 reload时间的不合理情况。 - 持续效果管理:新增协程列表,支持统一停止所有持续属性修改。
内容的提问来源于stack exchange,提问作者kiefer gaming
相关产品推荐
相关产品推荐

