Unity 6.3
0 онлайн 78 гостей 3 в системе
Вход

PrefabUtility.ReplacePrefabAssetOfPrefabInstance

Declaration

public static void ReplacePrefabAssetOfPrefabInstance(GameObject prefabInstanceRoot, GameObject prefabAssetRoot, InteractionMode mode);
public static void ReplacePrefabAssetOfPrefabInstance(GameObject prefabInstanceRoot, GameObject prefabAssetRoot, PrefabReplacingSettings settings, InteractionMode mode);

Параметры

Параметр Описание
prefabInstanceRoot Корень экземпляра Префаб, ассет которого Префаб будет заменен.
prefabAssetRoot Новый ассет Префаб используется для экземпляра Префаб.
режим Используемый режим взаимодействия.
настройки Параметры, используемые для управления деталями замены.

Описание

Замените ассет Префаб для экземпляра Префаб, который существует в Scene, или для вложенного экземпляра Префаб внутри другого Префаб.

Эта функция сохранит корневую позицию, вращение и масштаб экземпляра Префаб в Scene, но объединит содержимое из нового ассета Префаб, по умолчанию сохранив как можно больше переопределений и ссылок, используя соответствие по имени. Обратите внимание, что корень GameObject и его компоненты всегда будут повторно использовать эти объекты независимо от ObjectMatchMode, так что ссылки на эти объекты всегда переживут замену. Используйте ObjectMatchMode.ByHierarchy, которые сохранят ссылки, если GameObjects и Компоненты соответствуют полному пути иерархии GameObject, чтобы убедиться, что все братья имеют уникальные имена. При использовании ObjectMatchMode.ByName соответствие объекта выполняется только в том случае, если соответствие имен уникально. Поэтому рекомендуется, чтобы экземпляр Префаб и ассет Префаб имели уникальные имена только в иерархии GameObjects. Соответствие не может быть выполнено для GameObjects с дублирующимися именами.

Переопределения свойств не удаляются из сериализованного состояния экземпляра ассета Prefab, поэтому замена одного ассета Prefab на другой не разрушает переопределения свойств. Когда окончательный экземпляр Prefab будет создан, все неиспользуемые переопределения можно очистить — из окна Hierarchy или из окна Overrides. Добавленные компоненты сохраняются, если найдено совпадение по имени, иначе добавленный компонент удаляется. Добавленный GameObject сохраняется путём добавления в корень нового экземпляра, если для его родительского GameObject не нашлось совпадения по имени. Поскольку у добавленного GameObject может быть под ним целая иерархия, решение о том, есть ли смысл удалять объект, если на новом экземпляре он окажется лишним, мы оставляем за вами. Сделать это можно из окна Hierarchy или из окна Overrides. Для явного контроля над тем, какие переопределения следует очистить, используйте флаги PrefabReplacingSettings.prefabOverridesOptions, найденные в PrefabReplacingSettings.

Дополнительные ресурсы: ReplacePrefabAssetOfPrefabInstances, ConvertToPrefabInstance.

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

class PrefabReplacing { [MenuItem("Assets/Replace Scene Selection with Prefab Asset", false, 32)] static void ReplaceSelectedWithPrefabInstance(MenuCommand menuCommand) { GameObject prefabAsset = null; var listOfInstanceRoots = new List<GameObject>(); var listOfPlainGameObjects = new List<GameObject>(); foreach (var go in Selection.gameObjects) { if (AssetDatabase.Contains(go)) prefabAsset = go; else if (PrefabUtility.IsOutermostPrefabInstanceRoot(go)) listOfInstanceRoots.Add(go); else if (!PrefabUtility.IsPartOfNonAssetPrefabInstance(go)) listOfPlainGameObjects.Add(go); }

if (prefabAsset == null || (listOfInstanceRoots.Count == 0 && listOfPlainGameObjects.Count == 0)) { ShowHelpDialog(prefabAsset); return; }

if (listOfInstanceRoots.Count > 0) { var settings = new PrefabReplacingSettings { logInfo = true, objectMatchMode = ObjectMatchMode.ByHierarchy, prefabOverridesOptions = PrefabOverridesOptions.ClearAllNonDefaultOverrides }; PrefabUtility.ReplacePrefabAssetOfPrefabInstances(listOfInstanceRoots.ToArray(), prefabAsset, settings, InteractionMode.UserAction); }

if (listOfPlainGameObjects.Count > 0) { var settings = new ConvertToPrefabInstanceSettings { logInfo = true, objectMatchMode = ObjectMatchMode.ByHierarchy, }; PrefabUtility.ConvertToPrefabInstances(listOfPlainGameObjects.ToArray(), prefabAsset, settings, InteractionMode.UserAction); } }

[MenuItem("Assets/Replace Scene Selection with Prefab Asset", true, 32)] static bool ValidateReplaceSelectedWithPrefabInstance(MenuCommand menuCommand) { foreach (var go in Selection.gameObjects) { if (AssetDatabase.Contains(go)) return true; }

return false; }

static void ShowHelpDialog(GameObject prefabAsset) { var helptext = "Please make a multiselection with at least one Prefab instance root or plain GameObject in the Scene and one Prefab Asset from the Project Browser. \n\nUse Ctrl/Cmd + Click."; EditorUtility.DisplayDialog("Replace Prefab Asset of Prefab instance", (prefabAsset == null ? "Prefab Asset missing.\n\n" : "Prefab instance missing.\n\n") + helptext, "OK"); } }