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

Unity中为自定义ReferenceManager实现获取指定类型管理器的通用方法

实现思路

方案1:基于现有静态Reference类扩展(最高效,无需依赖ReferenceManager实例)

你当前的静态Reference类用List存储组件,每次查询都要遍历性能较低,替换为字典存储+泛型方法即可直接实现需求:

using System.Collections.Generic;
using System;

public static class Reference
{
    // 替换原有List,用字典存储类型和对应实例的映射
    static Dictionary<Type, ISystemComponent> systemComponentMap = new Dictionary<Type, ISystemComponent>();

    public static void SubscribeSystemComponent(ISystemComponent sC)
    {
        Type compType = sC.GetType();
        // 避免重复注册覆盖,可根据需求调整为覆盖/抛异常
        if (!systemComponentMap.ContainsKey(compType))
        {
            systemComponentMap.Add(compType, sC);
        }
    }

    // 你需要的通用泛型获取方法
    public static T Get<T>() where T : class, ISystemComponent
    {
        Type targetType = typeof(T);
        if (systemComponentMap.TryGetValue(targetType, out var comp))
        {
            return comp as T;
        }
        // 找不到返回null,也可以根据需求加警告日志
        return null;
    }

    // 保留原有接口兼容旧代码
    public static List<ISystemComponent> GetSystemComponents()
    {
        return new List<ISystemComponent>(systemComponentMap.Values);
    }
}

使用方式非常简单,需要获取管理器时直接调用Reference.Get<CameraManager>()即可,不需要再查找ReferenceManager实例,也不用手动维护类型判断逻辑。

方案2:兼容现有References结构体的实现

如果你需要保留结构体的序列化能力(比如要在Inspector里预览所有引用),可以同时优化AssignReferences方法,避免每次新增管理器都要手动写if判断,用反射自动给结构体字段赋值:

using System.Reflection;
using System.Linq;

void AssignReferences()
{
    var allComps = Reference.GetSystemComponents();
    // 获取References结构体的所有可写属性
    var properties = typeof(References).GetProperties();
    foreach (var prop in properties)
    {
        // 找对应类型的组件
        var matchComp = allComps.FirstOrDefault(c => c.GetType() == prop.PropertyType);
        if (matchComp != null)
        {
            prop.SetValue(references, matchComp);
        }
    }
}

同时也可以在ReferenceManager里补充你期望的GetReference方法:

public T GetReference<T>() where T : class, ISystemComponent
{
    return Reference.Get<T>();
}

如果不想引入Linq依赖,把上述代码中的FirstOrDefault替换为手动遍历allComps匹配类型即可。

注意点

  • 要确保管理器的Awake执行顺序早于ReferenceManager的Awake,避免注册顺序问题导致引用为空。你可以在Unity的【Edit】→【Project Settings】→【Script Execution Order】里把ReferenceManager的执行顺序调晚,或者把管理器的注册逻辑放到OnEnable里。
  • 如果有同类型的多个管理器实例,可以给ISystemComponent加个唯一标识字段,扩展Get方法支持按标识查询即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 11:54:01