arimger/Unity-Editor-Toolbox

[Feature Request]Reflection based atributes

jinsediaoying opened this issue · 7 comments

To bring this great project to a new level of freedom, we can add a bunch of reflection based attribute.
The basic concept is use field/property/method name as attribute param, and use reflection to retrieve the value and decide how to draw.

For example:

public class DynamicShowIfAttribute : Attribute
{
	public string showMethod;
	public string enableMethod;

	public DynamicShowIfAttribute (string showMethod, string enableMethod = null)
	{
		this.showMethod = showMethod;
	}
}

public class Foo
{
	[DynamicShowIf (nameof (showVal), nameof (EnableValFunc))]
	public int val;

	bool showVal = true;
	bool ShowVal => true;

	bool EnableValFunc ()
	{
		return true;
	}
}

More ideas:

public class DynamicShowIfAttribute : Attribute
{
	public string showMethod;
	public string enableMethod;

	public DynamicShowIfAttribute (string showMethod, string enableMethod = null)
	{
		this.showMethod = showMethod;
		this.enableMethod = enableMethod;//null for always true
	}
}

public class DynamicEnableIfAttribute : Attribute
{
	public string enableMethod;

	public DynamicEnableIfAttribute (string enableMethod)
	{
		this.enableMethod = enableMethod;
	}
}
/// <summary>
/// show help info box with dynamic text and info type
/// hide the info box is the textMethod return null
/// </summary>
public class DynamicInfoAttribute : Attribute
{
	//string type, return null for hide info box
	public string textMethod;
	public UnityMessageType messageType;

	//UnityMessageType type, will override messageType
	public string messageTypeMethod;

	public DynamicInfoAttribute (string textMethod, UnityMessageType messageType = UnityMessageType.Info)
	{
		this.textMethod = textMethod;
		this.messageType = messageType;
	}

	public DynamicInfoAttribute (string textMethod, string messageTypeMethod)
	{
		this.textMethod = textMethod;
		this.messageTypeMethod = messageTypeMethod;
	}
}
public class DynamicLabelAttribute : Attribute
{
	public string labelFunc;

	public DynamicLabelAttribute (string labelFunc)
	{
		this.labelFunc = labelFunc;
	}
}

public class DynamicTitleAttribute : Attribute
{
	public string labelFunc;

	public DynamicTitleAttribute (string labelFunc)
	{
		this.labelFunc = labelFunc;
	}
}

To be honest I wanted to minimize the usage of Reflection-based features but I understand that using properties and methods to stream data to drawers is pretty cool. I will think about it, thank you for this request.

A important use case is handle the class inheritance.
For example, I usually put a help info box on top of my scripts.
Without reflection based features, it is impossible to change that message in derived classes.

Hello,

wanted to say that feature is almost finished, if you are curious you can check the current implementation on the branch.
I need to test it a little bit, and in few days I will try to push it further.

Hello,

from now, all condition drawers (EnableIf, HideIf, etc.) are able to use members of the parent class to pass values:

[DisableIf(nameof(GetFloatValue), 2.0f, Comparison = UnityComparisonMethod.GreaterEqual)]
public int var2;

public float GetFloatValue()
{
	return 1.6f;
}