运行时如何从prefabs文件夹实例化指定名称的prefab
Unity运行时按名称字符串实例化Prefabs文件夹下预制体实现方案
Unity原生运行时按名称动态加载资源,依赖Resources特殊目录机制,你需要先完成目录配置再写加载逻辑。
第一步:配置资源目录
- 在项目
Assets路径下新建名为Resources的文件夹(名称固定、大小写敏感,不要修改名称) - 在
Resources文件夹内新建Prefabs子文件夹,把所有需要运行时按名称加载的预制体全部放入Assets/Resources/Prefabs路径下
第二步:基础加载实例化代码
直接调用Resources.Load指定路径和类型加载对应预制体,加载完成后调用Instantiate生成实例即可,注意必须做空校验避免空引用报错:
using UnityEngine; public class RuntimePrefabSpawner : MonoBehaviour { // 存储目标预制体名称的字符串,注意不要带.prefab后缀 private string prefabName = "你要加载的预制体名称"; void Start() { // 拼接加载路径:Prefabs为Resources下的子目录名,后面跟预制体名称 GameObject targetPrefab = Resources.Load<GameObject>($"Prefabs/{prefabName}"); if (targetPrefab == null) { Debug.LogError($"加载失败,请检查Assets/Resources/Prefabs路径下是否存在名为{prefabName}的预制体"); return; } // 按需传入实例的位置、旋转、父节点参数即可 Instantiate(targetPrefab, Vector3.zero, Quaternion.identity); } }
可选优化:预制体缓存方案
如果项目里需要频繁按名称生成预制体,不要每次调用Resources.Load重复加载,可以在游戏初始化阶段把所有Prefabs文件夹下的预制体提前加载到字典缓存,运行时直接从缓存取,性能更高:
using System.Collections.Generic; using UnityEngine; public class PrefabManager : MonoBehaviour { public static PrefabManager Instance; private Dictionary<string, GameObject> _prefabCache = new Dictionary<string, GameObject>(); void Awake() { Instance = this; // 初始化时一次性加载所有Prefabs下的预制体入缓存 GameObject[] allPrefabs = Resources.LoadAll<GameObject>("Prefabs"); foreach (GameObject prefab in allPrefabs) { _prefabCache.TryAdd(prefab.name, prefab); } } /// <summary> /// 按名称生成预制体实例 /// </summary> public GameObject SpawnPrefab(string prefabName, Vector3 spawnPos, Quaternion spawnRot, Transform parent = null) { if (!_prefabCache.TryGetValue(prefabName, out GameObject targetPrefab)) { Debug.LogError($"缓存中不存在名为{prefabName}的预制体,请检查名称"); return null; } return Instantiate(targetPrefab, spawnPos, spawnRot, parent); } }
注意事项
- 加载路径不要加
.prefab后缀,Resources.Load只需要传入资源名本身 - 如果预制体放在Prefabs下的多级子目录,比如
Prefabs/Enemy/Boss,加载路径要对应写成$"Prefabs/Enemy/Boss/{prefabName}"
重要提醒:
Resources文件夹下的所有资源打包时会被全量打入包体,和你有没有在代码里用到无关,不要把不需要动态加载的资源丢进这个目录,避免无谓增大包体积。
内容的提问来源于stack exchange,提问作者Domochico
相关产品推荐
相关产品推荐

