我有一个带有列表的脚本:
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>();
当仅使用编辑器脚本而不使用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(
但不确定如何使用它。为什么在Editor脚本中可以正常工作,但在EditorWindow中却不能呢?
答案 0 :(得分:0)
不同之处在于Editor
您可以看到
显然与其中一种特定类型有关[CustomEditor(typeof(Test))]
更重要的是,它是附加到当前所选GameObject的一个特定实例的检查器。因此,您可以访问该serializedObject
(或MonoBehaviour
)的ScriptableObject
实例
SerializedObject
代表要检查的一个或多个对象。
EditorWindow
的另一面与特定实例或GameObject 无关不相关,而只是将要打开的窗口。您可以说它生活在一种static
环境中(而不是像Editor
这样的实例化环境)。
因此,根本就没有serializedObject
它与=>有关。它没有这样的属性。
使用SerializedObject
当然是行不通的,因为这不是一个实例类型,并且方法FindProperty
不是静态的,但由于错误消息试图告诉您,因此需要一个实例。
我不想听起来很糟糕,但是如果那是您还不了解的事情,那么您应该立即停止担心EditorScripting,并从基本的C#编码和/或一般面向对象的编程中获得一些刷新。 / p>
您可以使用constructor
var serializedObject = new SerializedObject(referenceToTest);
如果,您将以某种方式获得对Test
某个实例的引用。
您可以使用FindObjectOfType
var referenceToTest = FindObjectOfType<Test>();
if(! referenceToTest) return;
要从当前场景中获取第一个活动并启用的Test
实例。
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
引用。 (仅当Inspector保持打开状态时,直接传递serializedObject
才有效,因为当不再选择GameObject时,serializedObject实例可能与TestEditor
一起被销毁了)
[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");
}
}
注意:在智能手机上键入内容,因此没有保修,但我希望这个主意会清楚