Есть ли способ использовать serializedObject в сценарии EditorWindow? - PullRequest
0 голосов
/ 14 мая 2019

У меня есть скрипт со списком:

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

public class Test : MonoBehaviour
{
    public List<Conversation> conversations = new List<Conversation>();

И при использовании только сценария Editor, а не EditorWindow, я мог бы сделать:

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

[CustomEditor(typeof(Test))]
public class TestTriggerEditor : Editor
{
    private SerializedProperty _conversations;

    private void OnEnable()
    {
        _conversations = serializedObject.FindProperty("conversations");
    }

Но теперь я хочу сделать это вСценарий EditorWindow:

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

public class TestingEditorWindow : EditorWindow
{
    private SerializedProperty _conversations;

    [MenuItem("Testing/Editor")]
    private static void ConversationsSystem()
    {
        const int width = 340;
        const int height = 420;

        var x = (Screen.currentResolution.width - width) / 2;
        var y = (Screen.currentResolution.height - height) / 2;

        GetWindow<TestingEditorWindow>().position = new Rect(x, y, width, height);
    }

    private void OnGUI()
    {
        _conversations = serializedObject.FindProperty("conversations");
    }
}

Но я получаю сообщение об ошибке в строке внутри OnGUI:

_conversations = serializedObject.FindProperty("conversations");

Ошибка в объекте serializedObject:

Имя 'serializedObject 'не существует в текущем контексте

Если я изменяю его на SerializedObject, я получаю ошибку:

Ссылка на объект требуется для нестатического поля, метода илисвойство 'SerializedObject.FindProperty (string)'

Я пытался изменить _conversations на статические, но это не помогло.

Я также пытался сделать:

SerializedObject serializedObject = new SerializedObject(

но не уверен, как с этим работать.Почему в скрипте редактора все работало нормально, а в окне редактора - нет?

1 Ответ

0 голосов
/ 14 мая 2019

Разница в том, что Editor

  1. , как вы можете видеть, явно относится к одному определенному типу в

    [CustomEditor(typeof(Test))]
    
  2. далее и, что более важно, это инспектор для одного определенного экземпляра этого типа, прикрепленного к выбранному в данный момент GameObject.Поэтому вы можете получить доступ к serializedObject экземпляру этого MonoBehaviour (или ScriptableObject)

    см. Editor.serializedObject

    A SerializedObject, представляющегопроверяемый объект или объекты.


С другой стороны EditorWindow означает , а не , относящийся к определенномувведите или для определенного экземпляра или GameObject, но это просто окно, которое будет открыто.Вы можете сказать, что он живет в некой среде static (вместо экземпляра, подобного Editor).

Поэтому просто нет serializedObject, к которому это относится => Это не 'у него нет такого свойства.


Использование SerializedObject конечно не работает, так как это тип, а не экземпляр, а метод FindProperty не является статическим, но требуетНапример, сообщение об ошибке пытается сказать вам.

Я не хочу звучать плохо, но если это то, что вы еще не понимаете, то вам следует немедленно прекратить беспокоиться о EditorScripting и получить некоторые обновления в основномc # кодирование и / или объектно-ориентированное программирование в целом.


Вы можете использовать конструктор

var serializedObject = new SerializedObject(referenceToTest);

если вы можете каким-то образом получить ссылку на один конкретный экземпляр Test.

Вы можете сделать это, например, используя FindObjectOfType

var referenceToTest = FindObjectOfType<Test>();
if(! referenceToTest) return;

Чтобы получить первый активный и включенный экземпляр Test из текущей сцены.

Или, например, использовать Selection.transforms

var selected = Selection.transforms;
Test referenceToTest;
foreach (var item in selected)
{
    referenceToTest = item.GetComponent<Test>();
    if(referenceToTest) break;
}

if(! referenceToTest) return;

, чтобы получить первое столкновение Test из выбранных объектов в окне иерархии сцены.


В качестве альтернативы вы можете открыть это EditorWindow из Инспектора Test вместо того, чтобы открывать его из строки меню static и передать ссылку MonoBehaviour.(Передача serializedObject напрямую будет работать только в том случае, если Инспектор останется открытым, поскольку экземпляр serializedObject, вероятно, будет уничтожен вместе с TestEditor, когда GameObject больше не выбран)

[CustomEditor(typeof(Test))]
public class TestEditor : Editor
{
    public override void OnInpectorGUI ()
    {
        // Draw the default inspector
        DrawDefaultInspector();

        EditorGUILayout.Space();

        // Add a button for opening the EditorWindow and pass in the reference
        if(GUILayout.Button("Open EditorWindow"))
        {
            TestEditorWindow.ConversationsSystem((Test) target);
        }
    }
}

И получено и сохраненоссылка в

public class TestingEditorWindow : EditorWindow
{
    const int width = 340;
    const int height = 420;

    private SerializedProperty _conversations;

    private Test currentTestInstance;

    public static void ConversationsSystem(Test testInstance)
    { 
        var x = (Screen.currentResolution.width - width) / 2;
        var y = (Screen.currentResolution.height - height) / 2;

        var window = GetWindow<TestingEditorWindow>();

        window.position = new Rect(x, y, width, height);

        window.currentTestInstance = testInstance;
    }

    private void OnGUI()
    {
        if(! currentTestInstance)
        {
            EditorGUILayout.HelpBox("No Test instance selected!", MessageType.Error);
            return;
        }

        var serializedObject = new SerializedObject(currentTestInstance);

        _conversations = serializedObject.FindProperty("conversations");
    }
}

Примечание: напечатано на смартфоне, поэтому никаких гарантий, но я надеюсь, что идея проясняется

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