You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
    }
}

关键改动说明

  1. 补全参数传递:新增EStatToChange类型参数,明确要修改的目标属性,解决原代码无法定位属性的问题。
  2. 统一属性读写:拆分GetCurrentStatValue和UpdateStatValue方法,处理int与float类型的自动转换,避免重复代码。
  3. 实现所有计算逻辑:
    • Fixed:直接增减固定数值
    • Persentage:按当前值的百分比修改(传入小数代表比例)
    • Set:直接覆盖为指定数值
    • Second/SecondPersentage:通过协程实现每秒持续修改,适配持续buff需求
  4. 异常防护:对ReloadTime做最小值限制,避免出现负数 reload时间的不合理情况。
  5. 持续效果管理:新增协程列表,支持统一停止所有持续属性修改。

内容的提问来源于stack exchange,提问作者kiefer gaming

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:13:10