UEDL13——PrefabUtility公共类
UEDL13——PrefabUtility公共类
本章代码关键字
1 | PrefabUtility //提供用于处理 Prefab(预制体或称预设体)的方法的公共类 |
PrefabUtility公共类
它是 Unity 编辑器中的一个公共类,提供了一些用于处理 Prefab(预制体或称预设体)的方法
主要功能包括 实例化预制体、创建预制体、修改预制体 等等
只要你有对预制体操作的相关需求,它可以在编辑器开发的任何地方对其进行使用
关于PrefabUtility相关的更多内容:
- PrefabUtility - Unity 脚本 API(中文文档,缺少部分翻译)
- Unity - Scripting API: PrefabUtility (unity3d.com)(英文文档)
常用API
-
PrefabUtility.SaveAsPrefabAsset()
动态创建预设体文件 路径从Assets/...
开始- 参数一:要保存为本地预设体文件的游戏对象的数据(
GameObject
类型数据) - 参数二:保存路径(需要加上
.prefab
后缀名),该路径是基于工程所在的路径的,路径从Assets/...
开始
注意:需要加上
.prefab
后缀名1
2
3
4
5
6
7
8if (GUILayout.Button("动态创建预设体"))
{
GameObject obj = new GameObject();
obj.AddComponent<Rigidbody>();
obj.AddComponent<BoxCollider>();
PrefabUtility.SaveAsPrefabAsset(obj, "Assets/Resources/TestObj.prefab");
DestroyImmediate(obj); //立刻删除,因为Destory只能在运行模式下的下一帧删除,在编辑器模式下表现就是无法删除并报错
}效果如下:
- 参数一:要保存为本地预设体文件的游戏对象的数据(
-
PrefabUtility.LoadPrefabContents()
加载预制体对象到内存中,路径从Assets/...
开始
(不能用于实例化创建游戏对象,一般只用于修改,会把预设体加载到内存中)这里的加载,本质上其实已经把预设体进行实例化了,因此这里加载的预设体不能用于创建游戏对象
只不过该实例化对象并不是在传统的Scene窗口中(是在一个看不见的独立的场景中,它类似于在编辑器窗口直接打开预设体)
由于这个加载是将预设体实例化了,
因此通过该方法修改预设体,我们可以修改预设体内的游戏对象相关的内容,例如添加对象,创建或修改父子关系等,还可以移除脚本- 参数:要加载的预制体文件路径,该路径是基于工程所在的路径的,路径从
Assets/...
开始
PrefabUtility.UnloadPrefabContents()
释放加载的预设体对象- 参数:要释放的从预制体文件内加载出来的游戏对象
注意:这两个方法需要配对使用,加载了就要在使用完毕后调用释放方法,否则该预设体将一直占用内存!
1
2
3
4
5
6
7
8
9
10
11
12
13if (GUILayout.Button("加载预设体对象"))
{
//加载 到内存中 不能用来实例化 一般加载出来是进行修改预设体的
GameObject testObj = PrefabUtility.LoadPrefabContents("Assets/Resources/TestObj.prefab");
//修改
testObj.AddComponent<MeshRenderer>();
GameObject obj = new GameObject("新建子对象");
obj.transform.parent = testObj.transform;
//将修改保存到本地
PrefabUtility.SaveAsPrefabAsset(testObj, "Assets/Resources/TestObj.prefab");
//释放 一定要配合使用
PrefabUtility.UnloadPrefabContents(testObj);
}效果如下:
- 参数:要加载的预制体文件路径,该路径是基于工程所在的路径的,路径从
-
PrefabUtility.SavePrefabAsset()
修改已有预设体文件,配合AssetDatabase.LoadAssetAtPath
使用注意!不可使用
PrefabUtility.LoadPrefabContents()
加载预制体,因为它加载的预设体会是实例化到另一个不可见场景内的预设体对象
如果PrefabUtility.LoadPrefabContents()
,保存将会报错,它会提示不可对实例化的预设体进行修改1
2
3
4
5
6
7if (GUILayout.Button("修改已有预设体"))
{
GameObject testObj = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Resources/TestObj.prefab");
testObj.AddComponent<BoxCollider>();
PrefabUtility.SavePrefabAsset(testObj, out bool isSuccess);
Debug.Log(isSuccess);
}值得一提的是,上面的方法修改的预设体限于添加脚本,不能修改预设体内游戏对象相关,也不能移除脚本,以及一些需要实例化对象才能完成的操作
效果如下:
-
PrefabUtility.InstantiatePrefab()
实例化预设体- 参数一:从预设体文件对象实例化一个游戏对象到场景上,配合
AssetDatabase.LoadAssetAtPath
使用 - 参数二:(可选)设置实例化出来的对象的父对象
1
2
3
4
5if (GUILayout.Button("实例化预设体"))
{
GameObject testObj = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Resources/TestObj.prefab");
PrefabUtility.InstantiatePrefab(testObj);
}效果如下:
- 参数一:从预设体文件对象实例化一个游戏对象到场景上,配合