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

如何在函数中高级使用List?Unity对象池通用化实现疑问

问题

我正在用类的静态List实现对象池,想简化/通用化对象池函数来减少重复代码。目前每种资源(比如Iron、Coal)都要单独写Get函数,每次都是复制修改:

public static List<Resources> allResources = new List<Resources>();
public static List<Resources> allIron = new List<Resources>(); // Iron.cs是子类
public static List<Resources> allCoal = new List<Resources>(); // Coal.cs是子类

public Iron GetIron(Vector3 position)
{
    if (allIron.Count > 0)
    {
        for (int i = 0; i < allIron.Count; i++)
        {
            if (!allIron[i].gameObject.activeSelf)
            {
                allIron[i].trans.position = position;
                allIron[i].gameObject.SetActive(true);
                return (Iron)allIron[i];
            }
        }
    }
    Instantiate(prefabIron, position, Quaternion.identity, oreHolder.transform);
    return (Iron)allIron[allIron.Count - 1];
}

我想写一个通用函数替代这些重复代码,写了下面的版本,但没法正常工作——传入的List好像只是副本,没法修改原静态List里的实体。请问能不能实现这种通用函数?必须每种资源单独写函数吗?

注:我可以遍历allResources,但这个List里有10万+元素,遍历性能太差,所以按资源类型拆分List来减少遍历次数。另外我已经自己找到答案了,感谢回复者。

解答

当然可以实现通用函数,你之前的问题不是List传参的问题(C#里List是引用类型,传参时传递的是引用,不是副本),问题出在实例化后没有把新对象添加到对应的静态List里,还有返回值的类型转换可以通过泛型来处理。

这里提供一个基于泛型的通用实现:

// 泛型通用获取函数
public T GetResource<T>(List<Resources> resourceList, Vector3 position, GameObject prefab) where T : Resources
{
    // 遍历找闲置对象
    if (resourceList.Count > 0)
    {
        foreach (var res in resourceList)
        {
            if (!res.gameObject.activeSelf)
            {
                res.trans.position = position;
                res.gameObject.SetActive(true);
                return res as T;
            }
        }
    }

    // 实例化新对象
    var newObj = Instantiate(prefab, position, Quaternion.identity, oreHolder.transform);
    var newResource = newObj.GetComponent<T>();
    
    // 把新对象加入对应的类型List和总List
    resourceList.Add(newResource);
    allResources.Add(newResource);
    
    return newResource;
}

调用的时候就可以这样用:

// 获取Iron
Iron iron = GetResource<Iron>(allIron, position, prefabIron);
// 获取Coal
Coal coal = GetResource<Coal>(allCoal, position, prefabCoal);

关键点说明

  1. 泛型约束:where T : Resources确保传入的类型是Resources的子类,保证类型安全。
  2. 引用类型传参:List是引用类型,函数里对resourceList的操作(比如Add)会直接作用于原静态List,不存在副本问题。
  3. 显式添加实例:之前的代码里调用Instantiate后没有手动添加到对应List,导致resourceList[resourceList.Count - 1]取不到新对象,现在实例化后主动把组件加入List就解决了这个问题。
  4. 性能保持:依然是按类型List遍历,不会影响10万+元素的总List性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 00:35:19