我在显示ScriptableObject的公共字段时遇到问题,ScriptableObject是我正在检查的组件的子代。虽然我可以通过其他方式轻松完成此操作,但我需要使用此方法来处理其他变量。 (ReorderableLists)
我简化了问题,也许我只是做了一些明显的错误,但我看不出我做错了什么。
代码+错误: http://answers.unity3d.com/storage/temp/70243-error.png
class SomeComponent : MonoBehaviour{
public MyScriptable scriptable; //instantiated and saved as asset
}
[Serializable] class MyScriptable : ScriptableObject{
[SerializeField] public float value = 0.1f;
}
[CustomEditor(typeof(SomeComponent))] class SomeComponentEditor : Editor{
public override void OnInspectorGUI() {
if((target as SomeComponent).scriptable==null) (target as SomeComponent).scriptable = ScriptableObject.CreateInstance(typeof(MyScriptable)) as MyScriptable;
EditorGUILayout.PropertyField(serializedObject.FindProperty("scriptable"));
//shows the asset
EditorGUILayout.PropertyField(serializedObject.FindProperty("scriptable").FindPropertyRelative("value"));
//error
}
}
答案 0 :(得分:2)
要修复代码,您可以执行以下操作:
using UnityEditor;
using UnityEngine;
class SomeComponent : MonoBehaviour
{
public MyScriptable myScriptable;
}
class MyScriptable : ScriptableObject
{
public float myChildValue = 0.1f;
}
[CustomEditor(typeof(SomeComponent))]
class SomeComponentEditor : Editor
{
public override void OnInspectorGUI()
{
SomeComponent someComponent = target as SomeComponent;
if (someComponent.myScriptable == null)
someComponent.myScriptable = CreateInstance<MyScriptable>();
SerializedProperty myScriptableProp = serializedObject.FindProperty("myScriptable");
EditorGUILayout.PropertyField(myScriptableProp);
SerializedObject child = new SerializedObject(myScriptableProp.objectReferenceValue);
SerializedProperty myChildValueProp = child.FindProperty("myChildValue");
EditorGUILayout.PropertyField(myChildValueProp);
child.ApplyModifiedProperties();
}
}
要检查子对象,首先需要创建一个 SerializedObject 版本,然后可以像往常一样搜索属性。
此外,从 ScriptableObject 派生的类不需要 Serializable 属性,只有在序列化私有字段时才需要 SerializeField 属性;公共字段在Unity中默认序列化。
在不知道代码的原始上下文的情况下,您的方法对我来说似乎有点特殊。 ScriptableObject 实例旨在用作Unity项目中的资产文件。您是否使用了 CreateAssetMenu 属性?通常,您可以通过菜单手动创建资产,然后将它们插入到组件中。你这样做的方式,它不会被写入磁盘,那么为什么要使用 ScriptableObject 而不仅仅是普通的类呢?但也许这在你的实际环境中都是有意义的,所以不要小心我是不是错了。
答案 1 :(得分:0)
SerializedObject newserobj = new SerializedObject(serializedObject.FindProperty("scriptable").objectReferenceValue );
EditorGUILayout.PropertyField(newserobj.FindProperty("value"));
newserobj.ApplyModifiedProperties();