2024-07-14 Unity插件 Odin Inspector2 —— Essential Attributes

文章目录

  • 1 说明
  • 2 重要特性
    • 2.1 AssetsOnly / SceneObjectsOnly
    • 2.2 CustomValueDrawer
    • 2.3 OnValueChanged
    • 2.4 DetailedInfoBox
    • 2.5 EnableGUI
    • 2.6 GUIColor
    • 2.7 HideLabel
    • 2.8 PropertyOrder
    • 2.9 PropertySpace
    • 2.10 ReadOnly
    • 2.11 Required
    • 2.12 RequiredIn(*)
    • 2.13 Searchable
    • 2.14 ShowInInspector
    • 2.15 Title
    • 2.16 TypeFilter
    • 2.17 TypeInfoBox
    • 2.18 ValidateInput
    • 2.19 ValueDropdown

1 说明

​ 本章介绍 Odin Inspector 插件中重要特性的使用方法。

2 重要特性

2.1 AssetsOnly / SceneObjectsOnly

使目标对象在 Inspector 窗口中只能关联资源 / 场景对象,限制拖拽的资源类型。

image-20240715004717713
// SceneAndAssetsOnlyExamplesComponent.csusing Sirenix.OdinInspector;
using System.Collections.Generic;
using UnityEngine;public class SceneAndAssetsOnlyExamplesComponent : MonoBehaviour
{[Title("Assets only")][AssetsOnly]public List<GameObject> OnlyPrefabs;[AssetsOnly]public GameObject SomePrefab;[AssetsOnly]public Material MaterialAsset;[AssetsOnly]public MeshRenderer SomeMeshRendererOnPrefab;[Title("Scene Objects only")][SceneObjectsOnly]public List<GameObject> OnlySceneObjects;[SceneObjectsOnly]public GameObject SomeSceneObject;[SceneObjectsOnly]public MeshRenderer SomeMeshRenderer;
}

2.2 CustomValueDrawer

自定义属性的显示方式。

  • string action

    显示属性的方法名。

image-20240715004812602
  1. action 方法中写 GUI 的显示逻辑,并返回字段的值。
  2. 该特性应用于数组时,将对数组的每个元素应用一次。
  3. 使用该特性时,需要配合 UNITY_EDITOR 指令,用法如下。
// CustomValueDrawerExamplesComponent.csusing Sirenix.OdinInspector;
using System;
using System.Collections.Generic;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.Utilities.Editor;
using UnityEditor;
#endifpublic class CustomValueDrawerExamplesComponent : MonoBehaviour
{public float From = 2, To = 7;[CustomValueDrawer("MyCustomDrawerStatic")]public float CustomDrawerStatic;[CustomValueDrawer("MyCustomDrawerInstance")]public float CustomDrawerInstance;[CustomValueDrawer("MyCustomDrawerAppendRange")]public float AppendRange;[CustomValueDrawer("MyCustomDrawerArrayNoLabel")]public float[] CustomDrawerArrayNoLabel = new float[] { 3f, 5f, 6f };#if UNITY_EDITOR // Editor-related code must be excluded from buildsprivate static float MyCustomDrawerStatic(float value, GUIContent label) {return EditorGUILayout.Slider(label, value, 0f, 10f);}private float MyCustomDrawerInstance(float value, GUIContent label) {return EditorGUILayout.Slider(label, value, this.From, this.To);}private float MyCustomDrawerAppendRange(float value, GUIContent label, Func<GUIContent, bool> callNextDrawer) {SirenixEditorGUI.BeginBox();callNextDrawer(label);var result = EditorGUILayout.Slider(value, this.From, this.To);SirenixEditorGUI.EndBox();return result;}private float MyCustomDrawerArrayNoLabel(float value) {return EditorGUILayout.Slider(value, this.From, this.To);}
#endif
}

2.3 OnValueChanged

在检查器中编辑属性时,延迟对属性应用更改。更改值时,不会应用(黄色显示)。仅更改完成后,才会应用该值。

类似于 Unity 的内置延迟属性,但此特性也可以应用于属性。

image-20240715005217404
// DelayedPropertyExampleComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class DelayedPropertyExampleComponent : MonoBehaviour
{// Delayed and DelayedProperty attributes are virtually identical...[Delayed][OnValueChanged("OnValueChanged")]public int DelayedField;// ... but the DelayedProperty can, as the name suggests, also be applied to properties.[ShowInInspector, DelayedProperty][OnValueChanged("OnValueChanged")]public string DelayedProperty { get; set; }private void OnValueChanged() {Debug.Log("Value changed!");}
}

2.4 DetailedInfoBox

为属性设置消息盒。

  • string message

    默认显示的信息。

  • string details

    点击后展开显示的详细信息。

  • InfoMessageType infoMessageType = InfoMessageType.Info

    消息盒种类。

  • string visibleIf = null

    如果表达式为 true,则显示,否则不显示。

image-20240715005253530
// DetailedInfoBoxExampleComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;public class DetailedInfoBoxExampleComponent : MonoBehaviour
{[DetailedInfoBox("Click the DetailedInfoBox...","... to reveal more information!\n" +"This allows you to reduce unnecessary clutter in your editors, and still have all the relavant information available when required.")]public int Field;
}

2.5 EnableGUI

激活 GUI 交互,使得能够在 Inspector 窗口进行编辑。

image-20240715005345457
// EnableGUIExampleComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;public class EnableGUIExampleComponent : MonoBehaviour
{[ShowInInspector]public int GUIDisabledProperty { get { return 10; } }[ShowInInspector, EnableGUI]public int GUIEnabledProperty { get { return 10; } }
}

2.6 GUIColor

为 GUI 上色。

  • float r, float g, float b, float a = 1f

    使用 RGBA 指定颜色。

  • string getColor

    指定颜色名。

image-20240715005438314
// GUIColorExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class GUIColorExamplesComponent : MonoBehaviour
{[GUIColor(0.3f, 0.8f, 0.8f, 1f)]public int ColoredInt1;[GUIColor(0.3f, 0.8f, 0.8f, 1f)]public int ColoredInt2;[GUIColor("#FF0000")]public int Hex1;[GUIColor("#FF000077")]public int Hex2;[GUIColor("RGB(0, 1, 0)")]public int Rgb;[GUIColor("RGBA(0, 1, 0, 0.5)")]public int Rgba;[GUIColor("orange")]public int NamedColors;[ButtonGroup][GUIColor(0, 1, 0)]private void Apply() { }[ButtonGroup][GUIColor(1, 0.6f, 0.4f)]private void Cancel() { }[InfoBox("You can also reference a color member to dynamically change the color of a property.")][GUIColor("GetButtonColor")][Button("I Am Fabulous", ButtonSizes.Gigantic)]private static void IAmFabulous() { }[Button(ButtonSizes.Large)][GUIColor("@Color.Lerp(Color.red, Color.green, Mathf.Abs(Mathf.Sin((float)EditorApplication.timeSinceStartup)))")]private static void Expressive() { }#if UNITY_EDITOR // Editor-related code must be excluded from buildsprivate static Color GetButtonColor() {Sirenix.Utilities.Editor.GUIHelper.RequestRepaint();return Color.HSVToRGB(Mathf.Cos((float)UnityEditor.EditorApplication.timeSinceStartup + 1f) * 0.225f + 0.325f, 1, 1);}
#endif
}

2.7 HideLabel

隐藏属性名。

image-20240715005523963
// HideLabelExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class HideLabelExamplesComponent : MonoBehaviour
{[Title("Wide Colors")][HideLabel][ColorPalette("Fall")]public Color WideColor1;[HideLabel][ColorPalette("Fall")]public Color WideColor2;[Title("Wide Vector")][HideLabel]public Vector3 WideVector1;[HideLabel]public Vector4 WideVector2;[Title("Wide String")][HideLabel]public string WideString;[Title("Wide Multiline Text Field")][HideLabel][MultiLineProperty]public string WideMultilineTextField = "";
}

2.8 PropertyOrder

指定属性显示的顺序。

  • float order

    显示顺序,从小到大排列。

image-20240715005613267
// PropertyOrderExamplesComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;public class PropertyOrderExamplesComponent : MonoBehaviour
{[PropertyOrder(1)]public int Second;[InfoBox("PropertyOrder is used to change the order of properties in the inspector.")][PropertyOrder(-1)]public int First;
}

2.9 PropertySpace

指定属性显示的间距。

  • float spaceBefore

    上间距。

  • float spaceAfter

    下间距。

image-20240715005654521
// SpaceExampleComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;public class SpaceExampleComponent : MonoBehaviour
{// PropertySpace and Space attributes are virtually identical.[Space][BoxGroup("Space", ShowLabel = false)]public int Space;// You can also control spacing both before and after the PropertySpace attribute.[PropertySpace(SpaceBefore = 30, SpaceAfter = 60)][BoxGroup("BeforeAndAfter", ShowLabel = false)]public int BeforeAndAfter;// The PropertySpace attribute can, as the name suggests, also be applied to properties.[PropertySpace][ShowInInspector, BoxGroup("Property", ShowLabel = false)]public string Property { get; set; }
}

2.10 ReadOnly

只在 Inspector 窗口显示,而不能改变值。

image-20240715005738889
// ReadOnlyExamplesComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;public class ReadOnlyExamplesComponent : MonoBehaviour
{[ReadOnly]public string MyString = "This is displayed as text";[ReadOnly]public int MyInt = 9001;[ReadOnly]public int[] MyIntList = new int[] { 1, 2, 3, 4, 5, 6, 7, };
}

2.11 Required

如果对象没有关联值,则显示信息。

  • string errorMessage

    显示信息。

  • InfoMessageType messageType

    信息类型。

image-20240715005824011
// RequiredExamplesComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;public class RequiredExamplesComponent : MonoBehaviour
{[Required]public GameObject MyGameObject;[Required("Custom error message.")]public Rigidbody MyRigidbody;[InfoBox("Use $ to indicate a member string as message.")][Required("$DynamicMessage")]public GameObject GameObject;public string DynamicMessage = "Dynamic error message";
}

2.12 RequiredIn(*)

说实话,看了半天没看懂。。。

image-20240715005906461
// RequiredInAttributeExamplesComponent.cs
using Sirenix.OdinInspector;
using UnityEngine;public class RequiredInAttributeExamplesComponent : MonoBehaviour
{[RequiredIn(PrefabKind.InstanceInScene, ErrorMessage = "Error messages can be customized. Odin expressions is supported.")]public string InstanceInScene = "Instances of prefabs in scenes";[RequiredIn(PrefabKind.InstanceInPrefab)]public string InstanceInPrefab = "Instances of prefabs nested inside other prefabs";[RequiredIn(PrefabKind.Regular)]public string Regular = "Regular prefab assets";[RequiredIn(PrefabKind.Variant)]public string Variant = "Prefab variant assets";[RequiredIn(PrefabKind.NonPrefabInstance)]public string NonPrefabInstance = "Non-prefab component or gameobject instances in scenes";[RequiredIn(PrefabKind.PrefabInstance)]public string PrefabInstance = "Instances of regular prefabs, and prefab variants in scenes or nested in other prefabs";[RequiredIn(PrefabKind.PrefabAsset)]public string PrefabAsset = "Prefab assets and prefab variant assets";[RequiredIn(PrefabKind.PrefabInstanceAndNonPrefabInstance)]public string PrefabInstanceAndNonPrefabInstance = "Prefab Instances, as well as non-prefab instances";
}

2.13 Searchable

可查询 chiledren 的类型和名称。

  • bool FuzzySearch = true

    是否使用模糊字符串匹配进行搜索。

  • SearchFilterOptions FilterOptions = SearchFilterOptions.All

    搜索方式。

  • bool Recursive = true

    是递归搜索,还是只搜索顶级属性。

image-20240715010054683
// SearchablePerksExampleComponent.csusing Sirenix.OdinInspector;
using System;
using System.Collections.Generic;
using UnityEngine;public class SearchablePerksExampleComponent : MonoBehaviour
{[Searchable]public List<Perk> Perks = new List<Perk>() {new Perk() {Name = "Old Sage",Effects = new List<Effect>() {new Effect() { Skill = Skill.Wisdom, Value       = 2, },new Effect() { Skill = Skill.Intelligence, Value = 1, },new Effect() { Skill = Skill.Strength, Value     = -2 },},},new Perk() {Name = "Hardened Criminal",Effects = new List<Effect>() {new Effect() { Skill = Skill.Dexterity, Value = 2, },new Effect() { Skill = Skill.Strength, Value  = 1, },new Effect() { Skill = Skill.Charisma, Value  = -2 },},},new Perk() {Name = "Born Leader",Effects = new List<Effect>() {new Effect() { Skill = Skill.Charisma, Value     = 2, },new Effect() { Skill = Skill.Intelligence, Value = -3 },},},new Perk() {Name = "Village Idiot",Effects = new List<Effect>() {new Effect() { Skill = Skill.Charisma, Value     = 4, },new Effect() { Skill = Skill.Constitution, Value = 2, },new Effect() { Skill = Skill.Intelligence, Value = -3 },new Effect() { Skill = Skill.Wisdom, Value       = -3 },},},};[Serializable]public class Perk{public string Name;[TableList]public List<Effect> Effects;}[Serializable]public class Effect{public Skill Skill;public float Value;}public enum Skill{Strength,Dexterity,Constitution,Intelligence,Wisdom,Charisma,}
}

2.14 ShowInInspector

在 Inspector 窗口中显示任意成员。

注意:

​ ShowInInspector 不会序列化成员,仅使用该特性不会保存任何改动。

image-20240715010414020
// ShowPropertiesInTheInspectorExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class ShowPropertiesInTheInspectorExamplesComponent : MonoBehaviour
{[SerializeField, HideInInspector]private int evenNumber;[ShowInInspector]public int EvenNumber {get { return this.evenNumber; }set { this.evenNumber = value - (value % 2); }}
}

2.15 Title

在属性上方显示标题。

  • string title

    标题名。

  • string subtitle = null

    副标题。

  • TitleAlignments titleAlignment = TitleAlignments.Left

    对齐方式。

  • bool horizontalLine = true

    是否显示水平线。

  • bool bold = true

    标题是否加粗显示。

image-20240715010618848
// TitleExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;public class TitleExamplesComponent : MonoBehaviour
{[Title("Titles and Headers")]public string MyTitle = "My Dynamic Title";public string MySubtitle = "My Dynamic Subtitle";[Title("Static title")]public int C;public int D;[Title("Static title", "Static subtitle")]public int E;public int F;[Title("$MyTitle", "$MySubtitle")]public int G;public int H;[Title("Non bold title", "$MySubtitle", bold: false)]public int I;public int J;[Title("Non bold title", "With no line seperator", horizontalLine: false, bold: false)]public int K;public int L;[Title("$MyTitle", "$MySubtitle", TitleAlignments.Right)]public int M;public int N;[Title("$MyTitle", "$MySubtitle", TitleAlignments.Centered)]public int O;public int P;[Title("@DateTime.Now.ToString(\"dd:MM:yyyy\")", "@DateTime.Now.ToString(\"HH:mm:ss\")")]public int Expression;[ShowInInspector][Title("Title on a Property")]public int S { get; set; }[Title("Title on a Method")][Button]public void DoNothing() { }
}

2.16 TypeFilter

依据类型显示属性。

  • string filterGetter

    获取显示属性的方法。

image-20240715010719942
// TypeFilterExamplesComponent.cs
using Sirenix.OdinInspector;
using Sirenix.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;public class TypeFilterExamplesComponent : SerializedMonoBehaviour
{[TypeFilter("GetFilteredTypeList")]public BaseClass A, B;[TypeFilter("GetFilteredTypeList")]public BaseClass[] Array = new BaseClass[3];public IEnumerable<Type> GetFilteredTypeList(){var q = typeof(BaseClass).Assembly.GetTypes().Where(x => !x.IsAbstract)                                          // Excludes BaseClass.Where(x => !x.IsGenericTypeDefinition)                             // Excludes C1<>.Where(x => typeof(BaseClass).IsAssignableFrom(x));                 // Excludes classes not inheriting from BaseClass// Adds various C1<T> type variants.q = q.AppendWith(typeof(C1<>).MakeGenericType(typeof(GameObject)));q = q.AppendWith(typeof(C1<>).MakeGenericType(typeof(AnimationCurve)));q = q.AppendWith(typeof(C1<>).MakeGenericType(typeof(List<float>)));return q;}public abstract class BaseClass{public int BaseField;}public class A1 : BaseClass { public int _A1; }public class A2 : A1 { public int _A2; }public class A3 : A2 { public int _A3; }public class B1 : BaseClass { public int _B1; }public class B2 : B1 { public int _B2; }public class B3 : B2 { public int _B3; }public class C1<T> : BaseClass { public T C; }
}

2.17 TypeInfoBox

在类型的每个示例顶部绘制一个信息框。

  • string message

    绘制的信息。

image-20240715010844080
// TypeInfoBoxExampleComponent.csusing Sirenix.OdinInspector;
using System;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endifpublic class TypeInfoBoxExampleComponent : MonoBehaviour
{public MyType MyObject = new MyType();#if UNITY_EDITOR // MyScriptyScriptableObject is an example type and only exists in the editor[InfoBox("Click the pen icon to open a new inspector for the Scripty object.")][InlineEditor]public MyScriptyScriptableObject Scripty;
#endif[Serializable][TypeInfoBox("The TypeInfoBox attribute can be put on type definitions and will result in an InfoBox being drawn at the top of a property.")]public class MyType{public int Value;}#if UNITY_EDITOR // Editor-related code must be excluded from builds[OnInspectorInit]private void CreateData() {Scripty = ExampleHelper.GetScriptableObject<MyScriptyScriptableObject>("Scripty");}[OnInspectorDispose]private void CleanupData() {if (Scripty != null) UnityEngine.Object.DestroyImmediate(Scripty);}
#endif
}

2.18 ValidateInput

允许检查 Inspector 窗口中拖拽关联值是否正确。

  • string condition

    判断是否正确的方法。

  • string defaultMessage

    显示信息。

  • InfoMessageType messageType

    信息类型。

image-20240715011220919
// ValidateInputExamplesComponent.csusing Sirenix.OdinInspector;
using UnityEngine;#if UNITY_EDITOR // Editor namespaces can only be used in the editor.
using Sirenix.OdinInspector.Editor.Examples;
#endifpublic class ValidateInputExamplesComponent : MonoBehaviour
{
#if UNITY_EDITOR // MyScriptyScriptableObject is an example type and only exists in the editor[HideLabel][Title("Default message", "You can just provide a default message that is always used")][ValidateInput("MustBeNull", "This field should be null.")]public MyScriptyScriptableObject DefaultMessage;
#endif[Space(12), HideLabel][Title("Dynamic message", "Or the validation method can dynamically provide a custom message")][ValidateInput("HasMeshRendererDynamicMessage", "Prefab must have a MeshRenderer component")]public GameObject DynamicMessage;[Space(12), HideLabel][Title("Dynamic message type", "The validation method can also control the type of the message")][ValidateInput("HasMeshRendererDynamicMessageAndType", "Prefab must have a MeshRenderer component")]public GameObject DynamicMessageAndType;[Space(8), HideLabel][InfoBox("Change GameObject value to update message type", InfoMessageType.None)]public InfoMessageType MessageType;[Space(12), HideLabel][Title("Dynamic default message", "Use $ to indicate a member string as default message")][ValidateInput("AlwaysFalse", "$Message", InfoMessageType.Warning)]public string Message = "Dynamic ValidateInput message";#if UNITY_EDITOR // Editor-related code must be excluded from buildsprivate bool AlwaysFalse(string value) {return false;}private bool MustBeNull(MyScriptyScriptableObject scripty) {return scripty == null;}private bool HasMeshRendererDefaultMessage(GameObject gameObject) {if (gameObject == null) return true;return gameObject.GetComponentInChildren<MeshRenderer>() != null;}private bool HasMeshRendererDynamicMessage(GameObject gameObject, ref string errorMessage) {if (gameObject == null) return true;if (gameObject.GetComponentInChildren<MeshRenderer>() == null) {// If errorMessage is left as null, the default error message from the attribute will be usederrorMessage = "\"" + gameObject.name + "\" must have a MeshRenderer component";return false;}return true;}private bool HasMeshRendererDynamicMessageAndType(GameObject gameObject, ref string errorMessage, ref InfoMessageType? messageType) {if (gameObject == null) return true;if (gameObject.GetComponentInChildren<MeshRenderer>() == null) {// If errorMessage is left as null, the default error message from the attribute will be usederrorMessage = "\"" + gameObject.name + "\" should have a MeshRenderer component";// If messageType is left as null, the default message type from the attribute will be usedmessageType = this.MessageType;return false;}return true;}
#endif
}

2.19 ValueDropdown

创建下拉列表,以供在 Inspector 面板上选择对应的值。

  • string valuesGetter

    获取下拉列表可选值的方法。返回值可以是数组,或者 ValueDropdownList<T> 的 IEnumerable。

    ValueDropdownList 的成员为 ValueDropdownItem,其成员 Text 为显示在 Inspector 窗口上对应值 Value 的信息。

  • bool AppendNextDrawer = false

    如果为 true,则改为用小按钮开启下拉列表,而不是用宽按钮。

  • bool DisableGUIInAppendedDrawer = false

    是否可以在 Inspector 窗口上编辑值。

  • bool ExpandAllMenuItems = false

    如果为 true,则下拉菜单呈现树状图,用 ‘/’ 号表示父子关系。

  • bool DrawDropdownForListElements = true

    如果对象为列表,则需禁用此属性,以正常显示子元素。

  • bool IsUniqueList = false

    对象为列表时,其内容是否唯一,不可重复。

  • bool ExcludeExistingValuesInList = false

    如果对象为列表,且 IsUniqueList 为 true,则启用此属性将排除现有值;

    否则,将显示一个复选框,指示该项是否已包含。

image-20240715011330407
// ValueDropdownExamplesComponent.csusing Sirenix.OdinInspector;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;public class ValueDropdownExamplesComponent : MonoBehaviour
{[ValueDropdown("TextureSizes")]public int SomeSize1;[ValueDropdown("FriendlyTextureSizes")]public int SomeSize2;[ValueDropdown("FriendlyTextureSizes", AppendNextDrawer = true, DisableGUIInAppendedDrawer = true)]public int SomeSize3;[ValueDropdown("GetListOfMonoBehaviours", AppendNextDrawer = true)]public MonoBehaviour SomeMonoBehaviour;[ValueDropdown("KeyCodes")]public KeyCode FilteredEnum;[ValueDropdown("TreeViewOfInts", ExpandAllMenuItems = true)]public List<int> IntTreview = new List<int>() { 1, 2, 7 };[ValueDropdown("GetAllSceneObjects", IsUniqueList = true)]public List<GameObject> UniqueGameobjectList;[ValueDropdown("GetAllSceneObjects", IsUniqueList = true, DropdownTitle = "Select Scene Object", DrawDropdownForListElements = false, ExcludeExistingValuesInList = true)]public List<GameObject> UniqueGameobjectListMode2;#if UNITY_EDITOR        // Editor-related code must be excluded from builds
#pragma warning disable // And these members are in fact being used, though the compiler cannot tell. Let's not have bothersome warnings.private IEnumerable TreeViewOfInts = new ValueDropdownList<int>() {{ "Node 1/Node 1.1", 1 },{ "Node 1/Node 1.2", 2 },{ "Node 2/Node 2.1", 3 },{ "Node 3/Node 3.1", 4 },{ "Node 3/Node 3.2", 5 },{ "Node 1/Node 3.1/Node 3.1.1", 6 },{ "Node 1/Node 3.1/Node 3.1.2", 7 },};private IEnumerable<MonoBehaviour> GetListOfMonoBehaviours() {return GameObject.FindObjectsOfType<MonoBehaviour>();}private static IEnumerable<KeyCode> KeyCodes = Enumerable.Range((int)KeyCode.Alpha0, 10).Cast<KeyCode>();private static IEnumerable GetAllSceneObjects() {Func<Transform, string> getPath = null;getPath = x => (x ? getPath(x.parent) + "/" + x.gameObject.name : "");return GameObject.FindObjectsOfType<GameObject>().Select(x => new ValueDropdownItem(getPath(x.transform), x));}private static IEnumerable GetAllScriptableObjects() {return UnityEditor.AssetDatabase.FindAssets("t:ScriptableObject").Select(x => UnityEditor.AssetDatabase.GUIDToAssetPath(x)).Select(x => new ValueDropdownItem(x, UnityEditor.AssetDatabase.LoadAssetAtPath<ScriptableObject>(x)));}private static IEnumerable GetAllSirenixAssets() {var root = "Assets/Plugins/Sirenix/";return UnityEditor.AssetDatabase.GetAllAssetPaths().Where(x => x.StartsWith(root)).Select(x => x.Substring(root.Length)).Select(x => new ValueDropdownItem(x, UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(root + x)));}private static IEnumerable FriendlyTextureSizes = new ValueDropdownList<int>() {{ "Small", 256 },{ "Medium", 512 },{ "Large", 1024 },};private static int[] TextureSizes = new int[] { 256, 512, 1024 };
#endif
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/46306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器人相关工科专业课程体系

机器人相关工科专业课程体系 前言传统工科专业机械工程自动化/控制工程计算机科学与技术 新兴工科专业智能制造人工智能机器人工程 总结Reference: 前言 机器人工程专业是一个多领域交叉的前沿学科&#xff0c;涉及自然科学、工程技术、社会科学、人文科学等相关学科的理论、方…

Linux编程(三)—makefile快速编译

起因 linux环境下&#xff0c;编译c程序很麻烦&#xff0c;后面g -o demo demo.cpp ……往往跟了许多许多东西&#xff0c;这些每次编译的时候都要书写&#xff0c;所以就产生了makefile快速编译方式&#xff0c;具体操作如下。 怎么用makefile? 第一步&#xff1a;下载 m…

WPF学习(2) -- 样式基础

一、代码 <Window x:Class"学习.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008&…

MySQL 聚簇索引和非聚簇索引有什么区别?

聚簇索引&#xff08;主键索引&#xff09;、非聚簇索引&#xff08;二级索引&#xff09;。 这两者之间的最主要的区别是 B 树的叶子节点存放的内容不同&#xff1a; 聚簇索引的 B 树叶子节点存放的是主键值完整的记录&#xff1b;非聚簇索引的 B 树叶子节点存放的是索引值主…

【面试八股总结】C++内存管理:内存分区、内存泄漏、new和delete、malloc和free

参考资料&#xff1a;代码随想录、阿秀 一、内存分区 &#xff08;1&#xff09;栈区 在执行函数时&#xff0c;函数内部局部变量的存储单元都可以在栈上创建&#xff0c;函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中&#xff0c;效率很高&am…

Postman下载及使用说明

Postman使用说明 Postman是什么&#xff1f; ​ Postman是一款接口对接工具【接口测试工具】 接口&#xff08;前端接口&#xff09;是什么&#xff1f; ​ 前端发送的请求普遍被称为接口 ​ 通常有网页的uri参数格式json/key-value请求方式post/get响应请求的格式json 接…

关闭Ubuntu烦人的apport

先来看让人绷不住的&#xff08;恼&#xff09; 我查半天apport是啥玩意发现就一错误报告弹窗&#xff0c;十秒钟给我弹一次一天给我内存弹爆了 就算我程序就算真的不停崩溃&#xff0c;也没你这傻比apport杀伤性强啊&#xff1f;&#xff1f;&#xff1f; 原则上是不建议关闭…

牛客周赛 Round 51 解题报告 | 珂学家

前言 题解 典题场&#xff0c; EF都有很多种解法 A. 小红的同余 性质: 相邻两数互质 x ( m 1 ) / 2 x (m1)/2 x(m1)/2 m int(input())print ((m 1) // 2)B. 小红的三倍数 性质: 各个位数之和是3的倍数&#xff0c;可被3整除 和数的组合顺序无关 n int(input()) arr…

MySQL高级面试点

Explain语句结果中各个字段分别代表什么 id&#xff1a;查询语句没出现一个select关键字&#xff0c;MySQL就会给他分配一个唯一id select_type&#xff1a; select关键字对应哪个查询的类型 simple&#xff1a;简单的查询 不包含任何子查询 primary&#xff1a;查询中如果…

网络安全设备——EDR

网络安全中的EDR&#xff08;Endpoint Detection and Response&#xff0c;端点检测与响应&#xff09;是一种主动式的端点安全解决方案&#xff0c;它专注于监控、检测和响应计算机和终端设备上的安全威胁。以下是EDR的详细解释&#xff1a; 一、定义与功能 EDR是一种网络安…

repo sync同步出错解决

当出现下面提示时 e list of known hosts. Fetching: 100% (1167/1167), done in 44.619s info: A new version of repo is available warning: repo is not tracking a remote branch, so it will not receive updates Repo command failed: RepoUnhandledExceptionError …

Zabbix6.0使用自带模板(Redis by Zabbix agent 2)监控Redis数据库

注意&#xff1a;Zabbix6.0使用Redis by Zabbix agent 2 模板可直接监控Redis数据。 1、添加Redis账号密码信息(如果Redis没有设置密码可省略此步骤) vim zabbix_agent2.confPlugins.Redis.Sessions.redis.Uritcp://redis.huayunworld.com:6379 Plugins.Redis.Sessions.redis…

025-GeoGebra中级篇-曲线(1)_显式曲线、隐式曲线、参数曲线

写到曲线这一章节&#xff0c;不得不先梳理一下数学中关于曲线这一部分的内容&#xff0c;我们常见的曲线有显式曲线、隐式曲线、参数曲线&#xff0c;当然还有极坐标曲线、参数化曲面、分段函数曲线、分形曲线、复数平面上的曲线、随机曲线、和非线性动力系统的轨迹&#xff0…

在 PostgreSQL 里如何实现数据的分布式事务的回滚和补偿机制?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 里如何实现数据的分布式事务的回滚和补偿机制一、分布式事务的概念与挑战&#xff08;一…

STM32智能农田监测系统教程

目录 引言环境准备智能农田监测系统基础代码实现&#xff1a;实现智能农田监测系统 4.1 数据采集模块 4.2 数据处理与分析模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;农田监测与管理问题解决方案与优化收尾与总结 1. 引言 智能农田监测系统通…

【LeetCode 链表合集】

文章目录 1. LeetCode 206 反转链表2. NC40 链表相加 1. LeetCode 206 反转链表 题目链接&#x1f517; 解题思路&#xff1a; &#x1f50d; &#x1f427;创建一个新的节点&#xff0c;使用链表头插的方法&#xff1b; 2. NC40 链表相加 题目链接&#x1f517; 解题思路…

WPF MVVM框架 Caliburn.Micro的Action绑定

WPF MVVM框架 Caliburn.Micro的Action绑定 通过命名约定来绑定Action View <Window x:Class"WpfApp1.Views.AboutView"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml…

spring boot 基础特性

Spring Boot 特性&#xff1a; SpringBoot Starter&#xff08;场景启动器&#xff09;&#xff1a;将常用的依赖分组进行了整合&#xff0c;将其合并到一个依赖中&#xff0c;这样就可以一次性添加到项目的Maven或Gradle构建中。使编码变得简单&#xff0c;SpringBoot采用 Ja…

Django 删除所有数据

1&#xff0c;添加模型 Test/app11/models.py from django.db import modelsclass Post(models.Model):title models.CharField(max_length200)content models.TextField()pub_date models.DateTimeField(date published)class Book(models.Model):title models.CharFiel…

论文翻译:Rethinking Interpretability in the Era of Large Language Models

https://arxiv.org/abs/2402.01761 在大型语言模型时代的可解释性再思考 摘要 在过去十年中&#xff0c;随着越来越大的数据集和深度神经网络的兴起&#xff0c;可解释机器学习领域的兴趣迅速增长。同时&#xff0c;大型语言模型&#xff08;LLMs&#xff09;在广泛的任务中…