当前位置: 首页 > news >正文

Unity3D仿星露谷物语开发14之Custom Property Attribute

1、目标

创建自定义属性特性,类似于[SerializeField]的属性标签。

当用该自定义属性特性标记变量时,可以在Inspector面板中看到相应的效果。

2、Property类

(1)PropertyAttribute类

propertyAttribute是Unity中用于派生自定义属性特性的基类。

它可以用于为脚本变量创建特性,并于自定义PropertyDrawer类一起,以控制具有该特性的脚本变量在Inspector中显示。

举例1:

[SerializeField]

private int age;

上述代码中SerializeField就是PropertyAttribute类,它没有参数。

举例2:

[Range(0,1)]

public int index = 10;

上述代码中Range就是PropertyAttribute类,它有两个参数。

(2)PropertyDrawer类

PropertyDrawer允许我们控制一个属性的Inspector面板的GUI如何绘制。

常用公共方法:

方法名 描述
float GetPropertyHeight(SerializedProperty, GUIContent)重写此方法以指定此字段的GUI的像素高度。
void OnGUI(Rect, SerializedProperty, GUIContent)重写此方法,为属性创建自己的基于IMGUI的GUI

(3)自定义PropertyAttribute的步骤

1)创建自定义属性类

首先,创建一个继承自 PropertyAttribute 的类。例如,创建一个名为 ReadOnlyAttribute 的类:

using UnityEngine;public class ReadOnlyAttribute : PropertyAttribute
{
// 可以添加自定义参数
public ReadOnlyAttribute() { }
}

2)创建自定义属性绘制类

接下来,创建一个继承自 PropertyDrawer 的类,用于定义自定义属性在 Inspector 中的显示方式。例如,创建一个名为 ReadOnlyAttributeDrawer 的类:

using UnityEditor;
using UnityEngine;[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
public class ReadOnlyAttributeDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
GUI.enabled = false; // 禁用编辑
EditorGUI.PropertyField(position, property, label);
GUI.enabled = true; // 恢复编辑
}
}

3)使用自定义属性

最后,在需要的脚本中使用自定义属性。例如:

using UnityEngine;public class Test : MonoBehaviour
{
[ReadOnly]
public int myInt = 10;
}

3、创建步骤

(1)创建PropertyAttribute类

在Assets -> Scripts下创建目录命名为Utilities。

并在此目录下再创建子目录命名为Property Drawers。

在此目录下创建脚本命名为ItemCodeDescriptionAttribute.cs

代码如下:

using UnityEngine;public class ItemCodeDescriptionAttribute : PropertyAttribute
{// No values need to be held for the item code description attribute// so the class can be empty
}

因为是无参特性,所以可以不用定义任何内容。

(2)创建PropertyDrawer类

在Assets -> Scripts -> Utilities -> Property Drawers下创建Editor目录。

在此目录下创建脚本ItemCodeDescriptionDrawer.cs

using UnityEditor;
using UnityEngine;
using System.Collections.Generic;[CustomPropertyDrawer(typeof(ItemCodeDescriptionAttribute))]
public class ItemCodeDescriptionDrawer : PropertyDrawer
{public override float GetPropertyHeight(SerializedProperty property, GUIContent label){// Change the returned property height to be double to cater for the additional item code description that we will drawreturn EditorGUI.GetPropertyHeight(property) * 2;}public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){// Using BeginProperty / EndProperty on the parent property means that prefab override logic works on the entire property.EditorGUI.BeginProperty(position, label, property);if (property.propertyType == SerializedPropertyType.Integer) {EditorGUI.BeginChangeCheck();  // Start of check for changed values// Draw item codevar newValue = EditorGUI.IntField(new Rect(position.x, position.y, position.width, position.height / 2), label, property.intValue);// Draw item descriptionEditorGUI.LabelField(new Rect(position.x, position.y + position.height / 2, position.width, position.height / 2), "Item Description", GetItemDescription(property.intValue));// If item code value has changed, then set value to new valueif (EditorGUI.EndChangeCheck()) {property.intValue = newValue;}}EditorGUI.EndProperty();}private string GetItemDescription(int itemCode){SO_ItemList so_ItemList;so_ItemList = AssetDatabase.LoadAssetAtPath("Assets/Scriptable Object Assets/Item/so_ItemList.asset", typeof(SO_ItemList)) as SO_ItemList;List<ItemDetails> itemDetailsList = so_ItemList.itemDetails;ItemDetails itemDetail = itemDetailsList.Find(x => x.itemCode == itemCode);if (itemDetail != null) {return itemDetail.itemDescription;}else{return "";}}
}

(3)使用PropertyAttribute属性

在Item.cs文件中,给_itemCode变量增加[ItemCodeDescription]

此时再点击Hierarchy -> Items中的道具,可以看到Inspector的Item组件中出现了Item Description属性。


http://www.mrgr.cn/news/82185.html

相关文章:

  • PCA降维算法详细推导
  • 零基础WPF使用NLog记录日志
  • PHP如何删除数组中的特定值?
  • Chrome 浏览器下载安装教程,保姆级教程
  • 探索Docker Compose:轻松管理多容器应用
  • 《一文读懂PyTorch核心模块:开启深度学习之旅》
  • 偏移类窗口函数—— LAG()、LEAD()用法详解
  • 【Kafka 消息队列深度解析与应用】
  • 【Rust自学】8.5. HashMap Pt.1:HashMap的定义、创建、合并与访问
  • 【分布式缓存中间件Memcached原理与应用】
  • 面试题汇总
  • GXUOJ-算法-第四次作业(圆排列、连续邮资、n皇后、符号三角形)
  • 【非关系型数据库Redis 】 入门
  • primevue的<Menu>组件
  • 基于 Node.js 的 ORM(对象关系映射)工具——Sequelize介绍与使用,并举案例分析
  • 【循环神经网络】RNN介绍
  • 【容器化技术 Docker 与微服务部署】详解
  • 基于WSL在Windows下安装Ubuntu
  • C++ 设计模式:组合模式(Composite Pattern)
  • 智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之12 方案再探之3:特定于领域的模板 之2 首次尝试和遗留问题解决
  • 「Mac畅玩鸿蒙与硬件50」UI互动应用篇27 - 水果掉落小游戏
  • libvirt学习
  • 【Compose multiplatform教程24】导航与路由
  • 智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之11 方案再探之2 项目文件(修改稿1)
  • Linux2.4.20顶层Makefile文件分析
  • 我的Java-Web进阶--Spring