Как я могу сравнить prefab и GameObject? - PullRequest
0 голосов
/ 31 августа 2018
prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefab, typeof(GameObject), false);

        GUI.enabled = false;
        var selection = Selection.objects.OfType<GameObject>().ToList();
        for (var i = selection.Count - 1; i >= 0; --i)
        {
            selectedObject = selection[i];
            if (prefab != null && selection.Count > 0
                && prefab != selectedObject)
                GUI.enabled = true;
        }
        if (GUILayout.Button("Replace"))
        {
            selection = Selection.objects.OfType<GameObject>().ToList();

            if (prefab != null && selection.Count > 0)
            {
                for (var i = selection.Count - 1; i >= 0; --i)
                {
                    var selected = selection[i];
                    SceneManager.SetActiveScene(SceneManager.GetSceneByName(selected.scene.name));

                    var prefabType = PrefabUtility.GetPrefabType(prefab);
                    GameObject newObject;

                    if (prefabType == PrefabType.Prefab)
                    {
                        newObject = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
                    }
                    else
                    {
                        newObject = Instantiate(prefab);
                        newObject.name = prefab.name;
                    }

                    if (newObject == null)
                    {
                        Debug.LogError("Error instantiating prefab");
                        break;
                    }

                    Undo.RegisterCreatedObjectUndo(newObject, "Replace With Prefabs");
                    newObject.transform.parent = selected.transform.parent;
                    newObject.transform.localPosition = selected.transform.localPosition;
                    newObject.transform.localRotation = selected.transform.localRotation;
                    newObject.transform.localScale = selected.transform.localScale;
                    newObject.transform.SetSiblingIndex(selected.transform.GetSiblingIndex());
                    Undo.DestroyObjectImmediate(selected);
                }
            }
        }

Я хочу, чтобы кнопка также включала true, только если префаб не совпадает с выбранным объектом (ами).

В первый раз я выбираю один или несколько объектов, затем нажимаю «Заменить», теперь он заменяет выбранные объекты префабом. Но если я снова выберу заменяемые объекты, он все равно активирует кнопку true. Но они должны быть такими же, как и сборные, и не включать истинную кнопку.

Вот сравнение, которое я пытаюсь сделать:

prefab != selectedObject

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

Класс UnityEngine.Component реализует работающий оператор равенства (вам необходимо использовать object.Equals), и мы можем использовать отражение для доступа ко всем компонентам как в префабе, так и в живом экземпляре этого префаба. Можно определить, что изменилось, но это не красиво, и есть много сложных угловых случаев, с которыми приходится иметь дело.

0 голосов
/ 31 августа 2018

Они не одинаковы, потому что != в C #, используемом между двумя ссылочными типами, у которых не перегружен оператор равенства, будет выполнять сравнение ссылок. Это означает, что он проверит, ссылается ли переменная на тот же экземпляр базового объекта. Так что prefab != selectedObject будет только оценивать как ложное, если prefab и selectedObject - это один и тот же экземпляр объекта (iirc проверяет идентификатор объекта на равенство).

Насколько я понимаю, вы хотите, чтобы оно оценивалось как false и, следовательно, активировало кнопку тогда и только тогда, когда выбранные объекты не являются клонами префабов. К счастью, в Unity3D есть способ определить, создан ли GameObject из определенного префаба. Это называется PrefabUtility .GetCorrespondingObjectFromSource . Так что это может соответствовать вашим требованиям:

Изменить эту часть:

for (var i = selection.Count - 1; i >= 0; --i)
{
    selectedObject = selection[i];
    if (prefab != null && selection.Count > 0
        && prefab != selectedObject)
        GUI.enabled = true;
}

К этому:

for (var i = selection.Count - 1; i >= 0; --i)
{
    var selectedObject = selection[i];
    if (prefab != null && selection.Count > 0
        && prefab != PrefabUtility
        .GetCorrespondingObjectFromSource(selectedObject))
        GUI.enabled = true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...