targetPrefab | 要修改的预制体实例的引用。虽然类型和名称暗示了一个资源,但它应该是作为 GameObject 提供的最外层实例。 |
modifications | 一组定义对目标预制体实例更改的 PropertyModification 对象。 |
将一组 PropertyModification 对象分配给相对于其源预制体资源的目标预制体实例。
务必为此方法提供目标实例层次结构分支中的顶级对象,以避免出现意外结果。为此,请使用 GetOutermostPrefabInstanceRoot。
PropertyModification 预制体覆盖的字段
value
字段始终需要设置的 PropertyModification 成员是修改应用到的 target
对象(即持久预制体资源对象的引用)、要修改的属性的 propertyPath
以及其新的 value
或 objectReference
,如下例所示
void MakePrefabModifications(GameObject gameObject) { // Get the outermost root from the target object GameObject prefabInstanceRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(gameObject); if (prefabInstanceRoot == null) return;
// Get the corresponding prefab asset GameObject prefabAssetRoot = PrefabUtility.GetCorrespondingObjectFromSource(prefabInstanceRoot);
// Create modifications for m_Name and m_LocalScale.x var mods = new[] { new UnityEditor.PropertyModification { value = "NewName", propertyPath = "m_Name", target = prefabAssetRoot }, new UnityEditor.PropertyModification { value = "3", propertyPath = "m_LocalScale.x", target = prefabAssetRoot.transform } };
PrefabUtility.SetPropertyModifications(prefabInstanceRoot, mods); }
以下示例显示了在具有 MeshRenderer 的预制体上使用 PropertyModification.objectReference
的示例
void MakePrefabModificationUsingObjectReference(GameObject gameObject) { // Get the outermost root from the target object GameObject prefabInstanceRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(gameObject); if (prefabInstanceRoot == null) return;
// Get the corresponding prefab asset GameObject prefabAssetRoot = PrefabUtility.GetCorrespondingObjectFromSource(prefabInstanceRoot);
MeshRenderer prefabMeshRenderer = prefabAssetRoot.GetComponent<MeshRenderer>(); // Create a material asset to add to the MeshRenderer Material material = new Material(Shader.Find("Diffuse")); AssetDatabase.CreateAsset(material, "Assets/MyMaterial.mat");
var mods = new[] { new UnityEditor.PropertyModification { target = prefabMeshRenderer, propertyPath = "m_Materials.Array.data[0]", objectReference = material } };
PrefabUtility.SetPropertyModifications(prefabInstanceRoot, mods); }
请注意,对 SetPropertyModifications
的调用将替换之前的修改集。如果目的是累积修改,则使用 GetPropertyModifications 检索当前集,并将它们包含在新集中。
SetPropertyModifications 可用于删除不需要的修改。要仅删除非默认修改,请将其过滤掉并保留默认覆盖,如下所示
List<PropertyModification> defaultMods = new List<PropertyModification>(); PropertyModification[] mods = PrefabUtility.GetPropertyModifications(prefabInstanceRoot); foreach (var mod in mods) { if (PrefabUtility.IsDefaultOverride(mod)) defaultMods.Add(mod); }
PrefabUtility.SetPropertyModifications(prefabInstanceRoot, defaultMods.ToArray());
对于创建覆盖,首选方法是使用 RecordPrefabInstancePropertyModifications 来手动更改属性,或者使用 SerializedObject 和 SerializedProperty,它们将自动生成覆盖。
对于应用和恢复覆盖,请考虑使用以下 API,它们提供了对应用和恢复功能的便捷访问
GetObjectOverrides GetAddedComponents GetRemovedComponents GetAddedGameObjects GetRemovedGameObjects。