csharp 通用检查器类,它允许您在类文件中而不是在单独的自定义编辑器中实现OnScene / InspectorGUI。它也提供

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 通用检查器类,它允许您在类文件中而不是在单独的自定义编辑器中实现OnScene / InspectorGUI。它也提供相关的知识,希望对你有一定的参考价值。

// ##### ##### ##### ##### ##### ##### ##### #####
// ## ObjectInspectorHelpers.cs (this needs to live outside of the Editor folder)
// ##### ##### ##### ##### ##### ##### ##### #####

using UnityEngine;
using System.Collections;
using System;


/// <summary>
/// implement this empty interface to tell the ObjectInspector that your class should be inspected
/// </summary>
public interface IObjectInspectable
{}


/// <summary>
/// makes any method have a button in the inspector to call it
/// </summary>
[AttributeUsageAttribute( AttributeTargets.Method )]
public class MakeButtonAttribute : Attribute
{}


/// <summary>
/// adds a vector3 editor to the scene GUI if this attribute is on any serialized Vector3, List<Vector3>
/// or Vector3[] fields.
/// </summary>
[AttributeUsageAttribute( AttributeTargets.Field )]
public class Vector3Inspectable : Attribute
{}
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Globalization;


// when implementing this in your MonoBehaviours, wrap your using UnityEditor and
// OnInspectorGUI/OnSceneGUI methods in #if UNITY_EDITOR/#endif


/// <summary>
/// for fields to work with the Vector3 inspector they must either be public or marked with SerializeField and have the Vector3Inspectable
/// attribute.
/// </summary>
[CustomEditor( typeof( UnityEngine.Object ), true )]
[CanEditMultipleObjects]
public class ObjectInspector : Editor
{
	MethodInfo _onInspectorGuiMethod;
	MethodInfo _onSceneGuiMethod;
	List<MethodInfo> _buttonMethods = new List<MethodInfo>();

	// Vector3 editor
	bool _hasVector3Fields = false;
	IEnumerable<FieldInfo> _fields;


	public void OnEnable()
	{
		var type = target.GetType();
		if( !typeof( IObjectInspectable ).IsAssignableFrom( type ) )
			return;

		_onInspectorGuiMethod = target.GetType().GetMethod( "OnInspectorGUI", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
		_onSceneGuiMethod = target.GetType().GetMethod( "OnSceneGUI", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );

		var meths = type.GetMethods( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic )
			.Where( m => m.IsDefined( typeof( MakeButtonAttribute ), false ) );
		foreach( var meth in meths )
		{
			_buttonMethods.Add( meth );
		}

		// the vector3 editor needs to find any fields with the Vector3Inspectable attribute and validate them
		_fields = type.GetFields( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic )
			.Where( f => f.IsDefined( typeof( Vector3Inspectable ), false ) )
			.Where( f => f.IsPublic || f.IsDefined( typeof( SerializeField ), false ) );
		_hasVector3Fields = _fields.Count() > 0;
	}


	public override void OnInspectorGUI()
	{
		DrawDefaultInspector();

		if( _onInspectorGuiMethod != null )
		{
			foreach( var eachTarget in targets )
				_onInspectorGuiMethod.Invoke( eachTarget, new object[0] );
		}


		foreach( var meth in _buttonMethods )
		{
			if( GUILayout.Button( CultureInfo.InvariantCulture.TextInfo.ToTitleCase( Regex.Replace( meth.Name, "(\\B[A-Z])", " $1" ) ) ) )
				foreach( var eachTarget in targets )
					meth.Invoke( eachTarget, new object[0] );
		}
	}


	protected virtual void OnSceneGUI()
	{
		if( _onSceneGuiMethod != null )
			_onSceneGuiMethod.Invoke( target, new object[0] );

		if( _hasVector3Fields )
			vector3OnSceneGUI();
	}


	#region Vector3 editor

	void vector3OnSceneGUI()
	{
		foreach( var field in _fields )
		{
			var value = field.GetValue( target );
			if( value is Vector3 )
			{
				Handles.Label( (Vector3)value, field.Name );
				var newValue = Handles.PositionHandle( (Vector3)value, Quaternion.identity );
				if( GUI.changed )
				{
					GUI.changed = false;
					field.SetValue( target, newValue );
				}
			}
			else if( value is List<Vector3> )
			{
				var list = value as List<Vector3>;
				var label = field.Name + ": ";

				for( var i = 0; i < list.Count; i++ )
				{
					Handles.Label( list[i], label + i );
					list[i] = Handles.PositionHandle( list[i], Quaternion.identity );
				}
				Handles.DrawPolyLine( list.ToArray() );
			}
			else if( value is Vector3[] )
			{
				var list = value as Vector3[];
				var label = field.Name + ": ";

				for( var i = 0; i < list.Length; i++ )
				{
					Handles.Label( list[i], label + i );
					list[i] = Handles.PositionHandle( list[i], Quaternion.identity );
				}
				Handles.DrawPolyLine( list );
			}
		}
	}

	#endregion

}
using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif


public class ExampleUsage : MonoBehaviour
{
  // this attribute will add handles for your Vector3s so that you can drag them around in the scene view
  [Vector3Inspectable]
  List<Vector3> someListOfVectors;
  
  
  // this method will appear as a button in the inspector
  [MakeButton]
  public void someVoidMethod()
  {}
  
  
#if UNITY_EDITOR
	void OnInspectorGUI()
	{
    // do inspector stuff
	}
	
	
	void OnSceneGUI()
	{
	  // do scene stuff
	}
#endif
}

以上是关于csharp 通用检查器类,它允许您在类文件中而不是在单独的自定义编辑器中实现OnScene / InspectorGUI。它也提供的主要内容,如果未能解决你的问题,请参考以下文章

将php代码保存到文件中而不解释它

检查一条消息是不是在 POSIX 消息队列中而没有从队列中删除它?

如何使 std::vector 的 operator[] 编译在 DEBUG 中而不是在 RELEASE 中进行边界检查

C# 将“X”次保存到一个 .txt 文件中而不覆盖最后一个字符串

如何将多个 python 文件组织到一个模块中而不像一个包一样?

Unity 单例管理器类