Unity Odin从入门到精通(五):自定义处理器

注意事项:如下所示:
1.检视面板根属性为检视面板属性类型创建的字段或者属性,名称默认为$ROOT。
2.检视面板子属性为检视面板根属性的下层属性。
3.检视面板父属性为检视面板子属性的上层属性。
4.检视面板属性包含检视面板根属性和检视面板子属性列表。
5.可以通过PropertyTree类型来使用Odin绘制系统中的所有功能。

定制特性处理器:如下所示:
1.定制特性处理器可以让Odin扩展绘制检视面板属性。如:往检视面板属性上动态添加、修改、删除定制特性等。
2.使用定制特性处理器来扩展绘制检视面板属性时,Odin会自动过滤掉序列化相关的定制特性。
3.定制特性处理器类型有通用版本OdinAttributeProcessor和泛型版本OdinAttributeProcessor<T>两种。其中泛型版本可以约束定制特性处理器类型关联的检视面板属性类型。
4.Odin提供了AttributeListExtension类型来对List<Attribute>对象提供通用辅助函数。
5.定制特性处理器类型中的CanProcessSelfAttributes函数具有以下特性:
5.1.该函数的参数表示检视面板根属性。
5.2.该函数主要用来判定是否可以扩展绘制检视面板根属性。
6.定制特性处理器类型中的ProcessSelfAttributes函数具有以下特性:
6.1.该函数的第一个参数表示检视面板根属性,第二个参数表示定制特性列表。
6.2.该函数主要用来对检视面板根属性使用定制特性列表进行扩展绘制。
7.定制特性处理器类型中的CanProcessChildMemberAttributes函数具有以下特性:
7.1.该函数的第一个参数表示检视面板父属性,第二个参数表示检视面板子属性。
7.2.该函数主要用来判定是否可以扩展绘制检视面板父属性下面的检视面板子属性。
8.定制特性处理器类型中的ProcessChildMemberAttributes函数具有以下特性:
8.1.该函数的第一个参数表示检视面板父属性,第二个参数表示检视面板子属性,第三个参数表示定制特性列表。
8.2.该函数主要用来对检视面板父属性下面的检视面板子属性使用定制特性列表进行扩展绘制。
9.自定义定制特性处理器的流程如下所示:
9.1.首先定义一个检视面板属性类型;然后使用该检视面板属性类型创建一个字段或者属性。参考代码如下所示:

// 自定义检视面板属性类型
[Serializable]
public class MyInspectorPropertyClass
{
    
    
	// 以下字段为检视面板子属性
    public ScaleMode Model;
    public float Size;
}

public class CustomAttributeProcessorExample : MonoBehaviour
{
    
    
	// 通过自定义检视面板属性类型来创建一个字段,该字段就是检视面板根属性
    public MyInspectorPropertyClass Processor1;
	// 通过自定义检视面板属性类型来创建一个属性,该属性就是检视面板根属性
    [ShowInInspector]
    public MyInspectorPropertyClass Processor2
    {
    
    
        get;
        set;
    }
}

9.2.首先创建一个继承自OdinAttributeProcessor<T>类型的自定义定制特性处理器类型,并且将泛型参数设置为自定义检视面板属性类型。此时该自定义定制特性处理器类型就只能处理关联的自定义检视面板属性类型。参考代码如下所示:

public class MyAttributeProcessor : OdinAttributeProcessor<MyInspectorPropertyClass>
{
    
    
}

9.3.首先重写CanProcessSelfAttributes函数来判定是否可以扩展绘制检视面板根属性;然后重写ProcessSelfAttributes函数来对可以扩展绘制的检视面板根属性使用定制特性列表进行扩展绘制。参考代码如下所示:

public override bool CanProcessSelfAttributes(InspectorProperty property)
{
    
    
	// 判定检视面板根属性是否可以使用Odin进行扩展绘制
	return property.Name == "Processor1";
}

public override void ProcessSelfAttributes(InspectorProperty property, List<Attribute> attributes)
{
    
    
	// 使用定制特性列表来扩展绘制检视面板根属性
	attributes.Add(new InfoBoxAttribute("Dynamically added attributes!"));
    attributes.Add(new InlinePropertyAttribute());
}

9.4.首先重写CanProcessChildMemberAttributes函数来判定是否可以扩展绘制检视面板父属性下面的检视面板子属性;然后重写ProcessChildMemberAttributes函数来对可以扩展绘制的检视面板父属性下面的检视面板子属性使用定制特性列表进行扩展绘制。参考代码如下所示:

public override bool CanProcessChildMemberAttributes(InspectorProperty parentProperty, MemberInfo member)
{
    
    
	// 判定检视面板父属性下面的检视面板子属性是否可以使用Odin进行扩展绘制
	return parentProperty.Name == "Processor2";
}

public override void ProcessChildMemberAttributes(InspectorProperty parentProperty, MemberInfo member, List<Attribute> attributes)
{
    
    
	// 使用定制特性列表来扩展绘制检视面板父属性下面的检视面板子属性
	attributes.Add(new HideLabelAttribute());
   	attributes.Add(new BoxGroupAttribute("Box", showLabel: false));
	if (member.Name == "Mode")
	{
    
    
		attributes.Add(new EnumToggleButtonsAttribute());
	}
	else if (member.Name == "Size")
	{
    
    
		attributes.Add(new RangeAttribute(0, 5));
	}
}

10.当自定义定制特性处理器类型应用OdinDontRegisterAttribute定制特性时,虽然该自定义定制特性处理器类型不能直接处理关联的检视面板属性类型,但是可以使用定制特性处理器定位器类型来处理检视面板属性类型。参考代码如下所示:

[OdinDontRegister]
public class MyAttributeProcessor : OdinAttributeProcessor<MyInspectorPropertyClass>
{
    
    
}

属性处理器:如下所示:
1.属性处理器可以让Odin扩展绘制检视面板根属性。如:往检视面板根属性上动态添加、修改、删除检视面板子属性等。
2.属性处理器类型有通用版本OdinPropertyProcessor和泛型版本OdinPropertyProcessor<T>两种。其中泛型版本可以约束属性处理器类型关联的检视面板属性类型。
3.Odin提供了ProcessedMemberPropertyResolverExtensions类型来对List<InspectorPropertyInfo>对象提供通用辅助函数。
4.属性处理器类型中的CanProcessForProperty函数具有以下特性:
4.1.该函数的参数表示检视面板根属性。
4.2.该函数主要用来判定是否可以扩展绘制检视面板根属性。
5.属性处理器类型中的ProcessMemberProperties函数具有以下特性:
5.1.该函数的参数表示检视面板根属性下面的检视面板子属性列表。
5.2.该函数主要用来对检视面板根属性下面的检视面板子属性列表进行扩展绘制。
6.自定义属性处理器的流程如下所示:
6.1.首先定义一个检视面板属性类型;然后使用该检视面板属性类型创建一个字段或者属性。参考代码如下所示:

// 自定义检视面板属性类型
[Serializable]
public class MyInspectorPropertyClass
{
    
    
	// 以下字段为检视面板子属性
    public string Top;
    public string Middle;
    public string Bottom;
    public int Value1;
    public int Value2;
    public int Value3;
}

public class CustomPropertyProcessorExample : MonoBehaviour
{
    
    
	// 通过自定义检视面板属性类型来创建一个字段,该字段就是检视面板根属性
    public MyInspectorPropertyClass Processor1;
	// 通过自定义检视面板属性类型来创建一个属性,该属性就是检视面板根属性
    [ShowInInspector]
    public MyInspectorPropertyClass Processor2
    {
    
    
        get;
        set;
    }
}

6.2.创建一个继承自OdinPropertyProcessor<T>类型的自定义属性处理器类型,并且将泛型参数设置为自定义检视面板属性类型。此时该自定义属性处理器类型就只能处理关联的自定义检视面板属性类型。参考代码如下所示:

public class MyPropertyProcessor : OdinPropertyProcessor<MyInspectorPropertyClass>
{
    
    
}

6.3.首先重写CanProcessForProperty函数来判定是否可以扩展绘制检视面板根属性;然后重写ProcessMemberProperties函数来对可以扩展绘制的检视面板根属性下面的检视面板子属性列表进行扩展绘制。参考代码如下所示:

public override bool CanProcessForProperty(InspectorProperty property)
{
    
    
	// 判定检视面板根属性是否可以使用Odin进行扩展绘制
	return property.Name == "Processor1";
}

public override void ProcessMemberProperties(List<InspectorPropertyInfo> propertyInfos)
{
    
    
	// 将检视面板子属性Bottom移动到检视面板根属性下面的检视面板子属性列表的开头位置
    for (int i = 0; i < propertyInfos.Count; i++)
    {
    
    
		var propertyInfo = propertyInfos[i];
		if (propertyInfo.PropertyName == "Bottom")
		{
    
    
			propertyInfos.Insert(0, propertyInfo);
			propertyInfos.RemoveAt(i + 1);
			break;
		}
	}
        
	// 往检视面板根属性下面的检视面板子属性列表中添加一个名称为HelloFunc且类型为委托的检视面板子属性
	propertyInfos.AddDelegate("HelloFunc", () => {
    
     Debug.Log("Hello");}, new BoxGroupAttribute("Inject"));
	// 往检视面板根属性下面的检视面板子属性列表中添加一个名称为Sum且类型为int的检视面板子属性
	propertyInfos.AddValue("Sum",
	(ref MyInspectorPropertyClass instance) => instance.Value1 + instance.Value2 + instance.Value3,
	(ref MyInspectorPropertyClass instance, int sum) => {
    
     },
	new BoxGroupAttribute("Inject"));
	// 往检视面板根属性下面的检视面板子属性列表中添加一个名称为Enum且类型为MyEnum的检视面板子属性
	propertyInfos.AddValue("Enum",
	(ref MyInspectorPropertyClass instance) => (MyEnum)instance.Value1,
	((ref MyInspectorPropertyClass instance, MyEnum value) => {
    
     instance.Value1 = (int)value;}),
	new EnumToggleButtonsAttribute(),
	new BoxGroupAttribute("Inject"));
	// 从检视面板根属性下面的检视面板子属性列表中删除一个名称为Value1的检视面板子属性
	propertyInfos.Remove("Value1");
}

猜你喜欢

转载自blog.csdn.net/zjz520yy/article/details/125753220
今日推荐