Почему я получаю пустую строку при попытке получить готовый путь к активу? - PullRequest
0 голосов
/ 15 февраля 2020
 private void ModifyPrefab(GameObject child)
    {
        var mostPrefabInstanceRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(child);

        // Get the Prefab Asset root GameObject and its asset path.
        string assetPath = AssetDatabase.GetAssetPath(mostPrefabInstanceRoot);

        // Load the contents of the Prefab Asset.
        GameObject contentsRoot = PrefabUtility.LoadPrefabContents(assetPath);

        // Modify Prefab contents.
        DestroyImmediate(child);

        // Save contents back to Prefab Asset and unload contents.
        PrefabUtility.SaveAsPrefabAsset(contentsRoot, assetPath);
        PrefabUtility.UnloadPrefabContents(contentsRoot);
    }

assetPath является пустым

И в редакторе этот объект является префабом:

The prefab in hierarchy

Затем, когда вы делаете на префабе правый клик и выбираете Prefab Asset, это добираемся до этого:

The prefab asset

Но в скрипте строка возвращает ""

Я не могу понять, почему она возвращается пустой string?

Изменить это мой завершенный сценарий сейчас:

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

public class ObjectsReplace : MonoBehaviour
{
    public GameObject prefabToInit;

    // Note your method should probably return something
    public void UpdateOrAddShaderPrefabToDoors()
    {
        GameObject[] doorsLeft = GameObject.FindGameObjectsWithTag("Door_Left");
        GameObject[] doorsRight = GameObject.FindGameObjectsWithTag("Door_Right");

        List<GameObject> allDoors = doorsLeft.Union(doorsRight).ToList();

        allDoors.ForEach(gameObject =>
        {
            Transform childTransform = gameObject.transform.Find("DoorShieldFXLocked Variant");
            GameObject child = childTransform?.gameObject;
            Debug.Log($"Child exist: {child != null}, Name of child: {child?.name}");
            if (child != null)
            {
                ModifyPrefab(child);
            }
        });
    }

    private void ModifyPrefab(GameObject child)
    {
        var mostPrefabInstanceRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(child);

        // Get the Prefab Asset root GameObject and its asset path.
        string assetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(mostPrefabInstanceRoot);

        // Load the contents of the Prefab Asset.
        GameObject contentsRoot = PrefabUtility.LoadPrefabContents(assetPath);

        // Modify Prefab contents.
        DestroyImmediate(child);

        // Save contents back to Prefab Asset and unload contents.
        PrefabUtility.SaveAsPrefabAsset(contentsRoot, assetPath);
        PrefabUtility.UnloadPrefabContents(mostPrefabInstanceRoot);
    }
}

Но все еще получая исключение в редакторе при попытке уничтожить дочерний элемент:

InvalidOperationException: уничтожение GameObject внутри экземпляр Prefab недопустим.

Идея состоит в том, чтобы открыть дочерний префаб, к которому он принадлежит, чтобы уничтожить дочерний элемент, а затем сохранить и закрыть префаб, как в случае переопределения> Применить изменения в редакторе, но из сценария.

1 Ответ

0 голосов
/ 16 февраля 2020

Похоже, mostPrefabInstanceRoot не является активом, и это имеет смысл, поскольку это экземпляр префаба. Используйте PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot вместо AssetDatabase.GetAssetPath.

string assetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(mostPrefabInstanceRoot);

Кроме того, чтобы ваше редактирование работало, вы, вероятно, захотите сохранить mostPrefabInstanceRoot вместо contentRoot, поскольку contentRoot не изменится удалив ребенка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...