csharp 在检查器中显示ScriptableObject的字段

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 在检查器中显示ScriptableObject的字段相关的知识,希望对你有一定的参考价值。

// Developed by Tom Kail at Inkle
// Released under the MIT Licence as held at https://opensource.org/licenses/MIT

// Must be placed within a folder named "Editor"
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

/// <summary>
/// Extends how ScriptableObject object references are displayed in the inspector
/// Shows you all values under the object reference
/// Also provides a button to create a new ScriptableObject if property is null.
/// </summary>
[CustomPropertyDrawer(typeof(ScriptableObject), true)]
public class ExtendedScriptableObjectDrawer : PropertyDrawer {
	
	public override float GetPropertyHeight (SerializedProperty property, GUIContent label) {
		float totalHeight = EditorGUIUtility.singleLineHeight;
		if(property.isExpanded) {
			var data = property.objectReferenceValue as ScriptableObject;
			if( data == null ) return EditorGUIUtility.singleLineHeight;
			SerializedObject serializedObject = new SerializedObject(data);
			SerializedProperty prop = serializedObject.GetIterator();
			if (prop.NextVisible(true)) {
				do {
					if(prop.name == "m_Script") continue;
					var subProp = serializedObject.FindProperty(prop.name);
					float height = EditorGUI.GetPropertyHeight(subProp, null, true) + EditorGUIUtility.standardVerticalSpacing;
					totalHeight += height;
				}
				while (prop.NextVisible(false));
			}
			// Add a tiny bit of height if open for the background
			totalHeight += EditorGUIUtility.standardVerticalSpacing;
		}
		return totalHeight;
	}

	public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
		EditorGUI.BeginProperty (position, label, property);
		if(property.objectReferenceValue != null) {
			property.isExpanded = EditorGUI.Foldout(new Rect(position.x, position.y, EditorGUIUtility.labelWidth, EditorGUIUtility.singleLineHeight), property.isExpanded, property.displayName, true);
			EditorGUI.PropertyField(new Rect(EditorGUIUtility.labelWidth + 14, position.y, position.width - EditorGUIUtility.labelWidth, EditorGUIUtility.singleLineHeight), property, GUIContent.none, true);
			if (GUI.changed) property.serializedObject.ApplyModifiedProperties();
			if(property.objectReferenceValue == null) EditorGUIUtility.ExitGUI();

			if(property.isExpanded) {
				// Draw a background that shows us clearly which fields are part of the ScriptableObject
				GUI.Box(new Rect(0, position.y + EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing - 1, Screen.width, position.height - EditorGUIUtility.singleLineHeight - EditorGUIUtility.standardVerticalSpacing), "");

				EditorGUI.indentLevel++;
				var data = (ScriptableObject)property.objectReferenceValue;
				SerializedObject serializedObject = new SerializedObject(data);
				
				// Iterate over all the values and draw them
				SerializedProperty prop = serializedObject.GetIterator();
				float y = position.y + EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
				if (prop.NextVisible(true)) {
					do {
						// Don't bother drawing the class file
						if(prop.name == "m_Script") continue;
						float height = EditorGUI.GetPropertyHeight(prop, new GUIContent(prop.displayName), true);
						EditorGUI.PropertyField(new Rect(position.x, y, position.width, height), prop, true);
						y += height + EditorGUIUtility.standardVerticalSpacing;
					}
					while (prop.NextVisible(false));
				}
				if (GUI.changed)
					serializedObject.ApplyModifiedProperties();

				EditorGUI.indentLevel--;
			}
		} else {
			EditorGUI.ObjectField(new Rect(position.x, position.y, position.width - 60, EditorGUIUtility.singleLineHeight), property);
			if(GUI.Button(new Rect(position.x + position.width - 58, position.y, 58, EditorGUIUtility.singleLineHeight), "Create")) {
				string selectedAssetPath = "Assets";
				if(property.serializedObject.targetObject is MonoBehaviour) {
					MonoScript ms = MonoScript.FromMonoBehaviour((MonoBehaviour)property.serializedObject.targetObject);
					selectedAssetPath = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath( ms ));
				}
				Type type = fieldInfo.FieldType;
				if(type.IsArray) type = type.GetElementType();
				else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) type = type.GetGenericArguments()[0];
				property.objectReferenceValue = CreateAssetWithSavePrompt(type, selectedAssetPath);
			}
		}
		property.serializedObject.ApplyModifiedProperties();
		EditorGUI.EndProperty ();
	}

	// Creates a new ScriptableObject via the default Save File panel
	ScriptableObject CreateAssetWithSavePrompt (Type type, string path) {
		path = EditorUtility.SaveFilePanelInProject("Save ScriptableObject", "New "+type.Name+".asset", "asset", "Enter a file name for the ScriptableObject.", path);
		if (path == "") return null;
		ScriptableObject asset = ScriptableObject.CreateInstance(type);
		AssetDatabase.CreateAsset (asset, path);
		AssetDatabase.SaveAssets ();
		AssetDatabase.Refresh();
		AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
		EditorGUIUtility.PingObject(asset);
		return asset;
	}
}

以上是关于csharp 在检查器中显示ScriptableObject的字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Chrome 检查器中显示完整的标尺线?

在 IDE 对象检查器中动态显示/隐藏属性?

是否可以找到导致规则在 Chrome 检查器中显示为灰色值的父 CSS?

我的 Prefab 上的 Canvas Environment 在 Unity 检查器中显示为灰色,我做了啥?

如何在 Unity3d 检查器中显示锯齿状数组?

检查/记录远程系统的网络利用率(显示在任务管理器中)