案例一
【Searchable、ListDrawerSettings、LabelText
】
public class PracticeAssets : ScriptableObject
{
[SerializeField]
[Searchable]
[ListDrawerSettings(ShowIndexLabels = true)]
[LabelText("练习版数据列表")]
public List<PracticeData> Practicies = new List<PracticeData>();
}
1. SerializeField
- 用途:此特性允许
Practicies
字段在 Unity 编辑器中可见并可序列化,即使它是一个private
字段也能被 Inspector 显示出来。 - 效果:使得程序员在脚本中定义的某个字段(在这里是
Practicies
)能够在 Unity 编辑器的 Inspector 面板中进行赋值和编辑。
2. [Searchable]
- 用途:这个特性通常用于自定义类或框架中的数据结构,允许在 Inspector 中搜索列表。这意味着在该列表中可以快速找到特定的
PracticeData
。 - 效果:增强 UX(用户体验),使得在大量数据项中快速定位特定项变得容易。
3. [ListDrawerSettings(ShowIndexLabels = true)]
- 用途:使用这个特性可以自定义列表在 Inspector 中的显示方式。这里的
ShowIndexLabels
设置为true
,表示在列表的每一项前面显示它们的索引标签(如 0, 1, 2...)。 - 效果:使列表更加易于理解和管理,尤其在处理多个
PracticeData
实例时,索引能够帮助用户快速识别和访问特定项。
4. [LabelText("练习版数据列表")]
- 用途:此特性用于指定在 Unity 编辑器 Inspector 中显示的标签。这允许您为
Practicies
列表设置一个更具描述性的名称而非默认的字段名称。 - 效果:在 Inspector 中显示为“练习版数据列表”,提高可读性,并提供有意义的上下文信息,帮助开发者理解这个字段的用途。
5. public List<PracticeData> Practicies = new List<PracticeData>();
- 用途:这是字段的声明。它定义了一个
public
类型的列表,列表中是PracticeData
类型的对象。 - 效果:允许将多个
PracticeData
实例存储在Practicies
列表中,同时由于是public
,可以在其它类中直接访问此列表。
案例二
【ListDrawerSettings
】
public class IndustryAssets : ScriptableObject
{
[SerializeField]
[Searchable]
[ListDrawerSettings(ListElementLabelName = "GetClassName")]
[LabelText("行业列表")]
public List<IndustryData> Industry = new List<IndustryData>();
}
1.[ListDrawerSettings(ListElementLabelName = "GetClassName")]
- 用途:此特性用于配置列表的显示方式。在这里,
ListElementLabelName
指定使用GetClassName
方法返回的值作为每个列表项的标签。 - 效果:使得在 Inspector 中查看
Industry
列表时,每个IndustryData
实例将使用其GetClassName()
方法的返回值作为标签,使得列表更具可读性和可管理性。
案例三
【ReadOnly
、GUIColor
】
[ReadOnly]
[GUIColor("red")]
[LabelText("数据验证:")]
public string ErrorMessage;
1.[ReadOnly]
- 用途:表示该字段在 Unity Inspector 中为只读,不允许用户编辑。
- 效果:防止用户在 Inspector 中修改该字段的值,确保程序逻辑控制该字段。
2.[GUIColor("red")]
- 用途:为该字段指定一个颜色,这里设置为红色。
- 效果:在 Inspector 中显示该字段时,以红色突出显示,通常用于表示错误或警告消息。
案例四
【OnStateUpdate
、ListDrawerSettings
】
[Space]
[Searchable]
[OnStateUpdate("CheckList")]
[ListDrawerSettings(ShowIndexLabels = true)]
[LabelText("隐患点数据列表")]
public List<DataConfigStruct> DataList = new List<DataConfigStruct>();
1.[Space]
- 用途:在 Inspector 中创建一个空间,用于分隔不同的部分。
- 效果:使变量的布局更清晰,不会拥挤在一起。
2.[OnStateUpdate("CheckList")]
- 用途:在状态更新时自动调用
CheckList
方法。 - 效果:每当数据发生改变或进入检查状态时,
CheckList
方法会被自动调用,以验证数据的完整性。
3.[ListDrawerSettings(ShowIndexLabels = true)]
- 用途:配置列表在 Inspector 中的显示方式,显示每个元素的索引标签。
- 效果:使得用户可以看到列表中每一项的位置编号,便于管理和引用特定项。
方法 CheckList
private void CheckList()
{
// 检查应用程序是否正在运行,如果是,则不执行验证逻辑
if (Application.isPlaying)
return;
// 创建一个用于存储所有 ID 的列表
List<uint> idList = new List<uint>();
// 遍历 DataList 列表,提取每个 DataConfigStruct 对象的 ID
for (int i = 0; i < DataList.Count; i++)
{
// 将每个对象的 ID 添加到 idList 列表中
idList.Add(DataList[i].ID);
}
// 使用 LINQ 查询查找重复的 ID 值
var duplicates = idList.GroupBy(n => n) // 根据 ID 分组
.Where(g => g.Count() > 1) // 只选择计数大于 1 的组,即重复的 ID
.Select(g => g.Key); // 选择每个重复组的 ID
// 检查是否存在重复的 ID
if (duplicates.Count() > 0)
{
// 如果发现重复 ID,更新错误信息
foreach (var number in duplicates)
{
// 设置错误信息,包含找到的重复 ID
ErrorMessage = string.Format("验证不通过,存在相同的唯一ID: {0}", number);
}
}
else
{
// 如果没有重复 ID,设置验证通过的消息
ErrorMessage = string.Format("验证通过");
}
}
案例五
【HideIf、ShowIf
】
[SerializeField][LabelText("显示目标位置点")] private bool ShowTarget;
[LabelText("目标位置")]
[SerializeField, HideIf("ShowTarget")]
public Vector3 pos;
[LabelText("目标角度")]
[SerializeField, HideIf("ShowTarget")]
public Vector3 rot;
[LabelText("目标位置点")]
[SerializeField, ShowIf("ShowTarget")]
public Transform Target;
1.[HideIf("ShowTarget")]
:
- 这是一个 Odin 特性,用于在
ShowTarget
为true
时隐藏该字段。也就是说,如果ShowTarget
被勾选(为true
),pos
字段将隐藏。这使得pos
字段能够与ShowTarget
逻辑相适应。
2.[ShowIf("ShowTarget")]
:
- 当
ShowTarget
为true
时,显示Target
字段。这使得只有在用户需要时才显示这个字段
案例六
[FilePath(ParentFolder = "Assets/Resources/Assets",Extensions = ".asset",IncludeFileExtension = false)]
[Multiline(3)]
[LabelText("相关条款Pdf路径")]
public string PdfPath;
[FilePath(ParentFolder = "Assets/Resources/Prefabs",Extensions = ".prefab",IncludeFileExtension = false)]
[LabelText("教学版模型路径")]
public string TeachingModelPath;
-
ParentFolder:
指定搜索文件时的根目录。例如"Assets/Resources/Assets"
,意味着只能选择该目录下的文件。 -
Extensions:
允许的文件扩展名,如".asset"
或".prefab"
。编辑器中只能选中这些后缀的文件。 -
IncludeFileExtension:
是否在输入的字符串路径中包含文件扩展名。false
表示路径中不包含扩展名(即只写文件名,不写后缀)。true
则包含扩展名。
PdfPath
:表示一个字符串字段,用来存储“相关条款”(比如合同条款或协议条款)对应的 PDF 文件路径。- 这个路径限定从项目里的
Assets/Resources/Assets
文件夹开始查找。 - 文件扩展名为
.asset
,但显示时不包含文件扩展名。 - 该字段在编辑器里显示为多行文本输入框(3行高)。
- 标签名称显示为“相关条款Pdf路径”,方便用户理解这个字段表示什么。
TeachingModelPath
是一个字符串字段,用于存储“教学版模型”的预制体路径。- 路径限定从
Assets/Resources/Prefabs
文件夹开始。 - 文件扩展名为
.prefab
,显示时不包含扩展名。 - 标签显示为“教学版模型路径”。