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

Unity+C#下批量计算相似但逻辑不同值的通用优化方案问询

模块化解决方案:用ScriptableObject封装独立计算单元

针对你遇到的List计算逻辑管理混乱问题,这里提供一套基于Unity ScriptableObject的实现方案,既能拆分独立计算逻辑,又能避免大量零散脚本的维护负担:

核心设计思路

把每个List元素的目标索引、计算逻辑、依赖数据监听封装成单个ScriptableObject实例,通过统一管理器来触发计算和绑定事件,兼顾模块化和可维护性。

1. 定义计算单元基类

先写一个抽象ScriptableObject基类,封装通用逻辑,子类只需要实现具体计算和依赖监听:

using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;

public abstract class CalculationUnitSO : ScriptableObject
{
    public int targetIndex; // 对应ExampleList的目标索引
    public UnityEvent onDataChanged; // 依赖数据变更时触发的事件

    // 子类必须实现的计算方法,直接更新目标List
    public abstract void CalculateAndUpdate(List<int> targetList);

    // 子类重写此方法绑定依赖数据的变更事件
    protected virtual void OnEnable() {}

    // 子类重写此方法解绑事件,防止内存泄漏
    protected virtual void OnDisable() {}
}

2. 实现具体计算单元

每个计算逻辑对应一个轻量子类,可按功能分组放在同一个文件里,不用每个都单独建脚本:

// 示例:计算原料A的用量上限
[CreateAssetMenu(fileName = "RawMaterialACalculator", menuName = "Calculators/RawMaterialA")]
public class RawMaterialACalculator : CalculationUnitSO
{
    public IngredientData ingredientAData;
    public SomeOtherIngredientData otherData;

    public override void CalculateAndUpdate(List<int> targetList)
    {
        // 这里写具体的计算逻辑
        int result = ingredientAData.baseAmount * otherData.efficiencyRate;
        targetList[targetIndex] = result;
    }

    protected override void OnEnable()
    {
        // 监听依赖数据的变更事件,触发计算更新
        ingredientAData.onValueChanged.AddListener(onDataChanged.Invoke);
        otherData.onValueChanged.AddListener(onDataChanged.Invoke);
    }

    protected override void OnDisable()
    {
        // 解绑事件
        ingredientAData.onValueChanged.RemoveListener(onDataChanged.Invoke);
        otherData.onValueChanged.RemoveListener(onDataChanged.Invoke);
    }
}

3. 统一管理器

写一个简单的管理器,负责初始化List、触发首次计算,以及绑定所有计算单元的变更事件:

using UnityEngine;
using System.Collections.Generic;

public class ListCalculatorManager : MonoBehaviour
{
    public List<int> ExampleList;
    public List<CalculationUnitSO> calculationUnits; // 在Inspector里拖入所有计算单元

    private void Start()
    {
        // 初始化List为100个0
        ExampleList = new List<int>(new int[100]);
        // 启动时全量计算一次
        RefreshAllCalculations();
        // 绑定每个计算单元的变更事件
        foreach (var unit in calculationUnits)
        {
            unit.onDataChanged.AddListener(() => unit.CalculateAndUpdate(ExampleList));
        }
    }

    // 手动触发全量刷新的方法
    public void RefreshAllCalculations()
    {
        foreach (var unit in calculationUnits)
        {
            unit.CalculateAndUpdate(ExampleList);
        }
    }
}

方案优势

  • 避免臃肿:每个计算逻辑独立封装,不会出现单个脚本塞100个方法的情况
  • 减少冗余:基类搞定通用的事件绑定/解绑,子类只需要写核心计算逻辑
  • 可视化配置:在Inspector里直接给每个计算单元配置目标索引、依赖数据,不用硬编码
  • 易维护:计算单元可按功能分类存放,通过管理器统一管控,不会出现零散脚本找不到的情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:25:26