Unity扩展编辑器使用整理(一)

准备工作

在Unity工程中新建Editor文件夹存放编辑器脚本,

Unity中其他的特殊文件夹可以参考官方文档链接,如下:

Unity - 手册:保留文件夹名称参考 (unity3d.com)

一、菜单栏扩展

1.增加顶部菜单栏选项

使用MenuItem,包含三个参数,官方文档描述如下:

代码:

   [MenuItem("Tool/test")]public static void test(){Debug.Log("test.....");}

结果:

2.增加右键Create菜单栏选项

使用MenuItem,ItemName需要从"Assets"开始,比如需要在Create菜单栏加一个testFolder的函数

代码:

   [MenuItem("Assets/Create/testFolder")]public static void test2(){Debug.Log("test2....");}

结果:

更多Unity支持的编辑器特性,可查看官方API,地址:

CustomGridBrushAttribute - Unity 脚本 API

3.使用快捷键 

官方文档的MenuItem中使用快捷键描述如下:

官方文档链接:

Unity - 脚本 API:MenuItem (unity3d.com)

热键文本之前必须有一个空格字符:

代码:

    [MenuItem("Tool/testHotKey0 _g")]public static void testHotKey0(){Debug.Log("testHotKeytestHotKey0..........");}

结果:

 

如果不需要特殊的修饰键组合,则可以在下划线后给出键:

代码:

   [MenuItem("Tool/testHotKey #g")]public static void testHotKey(){Debug.Log("testHotKeytestHotKey..........");}[MenuItem("Tool/testHotKey1 #&g")]public static void testHotKey1(){Debug.Log("testHotKeytestHotKey1..........");}

结果:

支持将一些特殊的键盘键(LEFT, RIGHT, UP, DOWN, F1 ..F12、HOME、END、PGUP、PGDN、INS、DEL、BACKSPACE、TAB 和 SPACE)作为热键:

代码:

 [MenuItem("Tool/testHotKey2 #LEFT")]public static void testHotKey2(){Debug.Log("testHotKeytestHotKey2..........");}

结果:

4.弹出一个提示窗口

使用EditorUtility.DisplayDialog显示窗口,第一个参数是弹窗名,第二个参数是提示内容,第三个参数是按钮名字

代码:

    [MenuItem("Tool/testDialog")]public static void DisplayDialog(){EditorUtility.DisplayDialog("Tips", "Hello World", "Completely");}

结果:

二、自定义窗口扩展

1.创建自定义窗口

自定义窗口需要创建的窗口脚本继承子EditorWindow,然后在OnGUI中渲染窗口的实际内容,
新建一个TestWindow脚本,代码如下:

public class TestWindow : EditorWindow
{private void OnGUI(){//渲染窗口的实际内容}
}

编写打开窗口的函数,代码如下:

[MenuItem("CustomWindow/ShowTestWin")]
public static void ShowWindow()
{//显示窗口实例//EditorWindow.GetWindow(typeof(TestWindow));//显示窗口按照自定位置和大小,比如(0,0)点,宽600,长800EditorWindow.GetWindowWithRect<TestWindow>(new Rect(new Vector2(0,0),new Vector2(600,800)));
}

结果:

EditorWindow类中的方法:

官方文档描述如下:

更多方法可参考:Unity - 脚本 API:EditorWindow (unity3d.com)

代码:

public class TestWindow : EditorWindow
{[MenuItem("CustomWindow/ShowTestWin")]public static void ShowWindow(){//显示窗口实例,可以使用鼠标更改大小//EditorWindow.GetWindow(typeof(TestWindow));//显示窗口按照自定位置和大小,比如(0,0)点,宽600,长800,不可以使用鼠标更改大小EditorWindow.GetWindowWithRect<TestWindow>(new Rect(new Vector2(0,0),new Vector2(600,800)));}private void OnEnable(){//在加载脚本或者启用对象时调用Debug.Log("OnEnable");}private void CreateGUI(){//如果Editor未更新,则生成图形用户界面Debug.Log("CreateGUI");}private void Update(){//每帧调用一次以更新脚本的逻辑Debug.Log("Updaete");}private void OnDisable(){//当脚本被禁用或者对象被销毁以完成和清理资源时调用Debug.Log("OnDisable");}private void OnGUI(){//每帧多次调用,用于渲染和处理GUI事件//渲染窗口的实际内容Debug.Log("OnGUI");}
}

结果:

2.增加窗口内容

1.使用EditorGUI类

1.actionKey


使用代码:

  private void OnGUI(){//渲染窗口的实际内容if (EditorGUI.actionKey){//是否按住了平台相关的“action”修改键?(只读),该键在 macOS 上为 Command,在 Windows 上为 ControlDebug.Log("按下了actionKey");}}

结果:

2.indentLevel

 使用代码:

    private void OnGUI(){//渲染窗口的实际内容//使用indentLevel缩进文本EditorGUI.indentLevel++;EditorGUILayout.LabelField("P1:");EditorGUI.indentLevel++;EditorGUILayout.LabelField("P2:");EditorGUI.indentLevel++;EditorGUILayout.LabelField("P3:");EditorGUI.indentLevel--;EditorGUI.indentLevel--;EditorGUILayout.LabelField("P1:");EditorGUI.indentLevel++;EditorGUILayout.LabelField("P2:");}

结果:

3.showMixedValue

具体作用可以看下面两篇文章

EditorGUI.showMixedValue 什么都不做?- Unity 引擎 - Unity 讨论

Unity - 脚本 API:EditorGUI.showMixedValue (unity3d.com)

就是可以让在 GUI 中以非标准方式表示值,同时支持多对象编辑,也就是通过设置此值为true,让枚举值没有在面板选择值时显示为

代码:

    private void OnGUI(){//渲染窗口的实际内容EditorGUI.showMixedValue = true;// 将isFast布尔值转换为enum值SpeedOption speedOptionEnumValue = SpeedOption.Fast;// 在下拉菜单中显示枚举值:speedOptionEnumValue = (SpeedOption)EditorGUILayout.EnumPopup("Speed", speedOptionEnumValue);// 将showMixedValue设置为false,这样它就不会影响以下控件(如果有的话):EditorGUI.showMixedValue = false;}

结果:

4.BeginChangeCheck,EndChangeCheck

EndChangeCheck返回值如下

代码:

float value = 0; 
private void OnGUI()
{//渲染窗口的实际内容EditorGUI.BeginChangeCheck();value = EditorGUILayout.Slider(value, 0, 1);if (EditorGUI.EndChangeCheck()){this.ShowTips("变量检查成功!");}
}

结果:

5.BeginDisabledGroup,EndDisabledGroup

 BeginChangeCheck参数如下:

 使用这两个API可以禁用执行在其中间的多个组件。

代码:

    private void OnGUI(){//渲染窗口的实际内容EditorGUI.BeginDisabledGroup(false);EditorGUI.TextField(new Rect(new Vector2(0,150),new Vector2(300,50)), "TestDisabledGroup");EditorGUI.DropdownButton(new Rect(new Vector2(300, 150), new Vector2(100, 50)),this.titleContent,FocusType.Keyboard);EditorGUI.EndDisabledGroup();}

结果:

当BeginDisabledGroup传入值为false时,

当BeginDisabledGroup传入值为true时,

6.BeginFoldoutHeaderGroup,EndFoldoutHeaderGroup

BeginFoldoutHeaderGroup参数如下:

代码:

public void TestFoldoutHeaderGroup()
{isShow = EditorGUI.BeginFoldoutHeaderGroup(new Rect(new Vector2(0, 200), new Vector2(120, 50)), isShow, "TEST Folder", null, ShowHeaderContextMenu);if (isShow){if (Selection.activeTransform){Selection.activeTransform.position = EditorGUI.Vector3Field(new Rect(0, 220, 200, 100), "Position", Selection.activeTransform.position);}else{EditorGUI.LabelField(new Rect(0, 220, 200, 20),"请先选中一个物体!");}}EditorGUI.EndFoldoutHeaderGroup();
}Color mColor;
void ShowHeaderContextMenu(Rect position)
{isShow = !isShow;GenericMenu menu = new GenericMenu();menu.AddItem(new GUIContent("RGB/Red"), mColor.Equals(Color.red), (color) =>{ mColor = (Color)color; },Color.red);menu.AddItem(new GUIContent("RGB/Black"), mColor.Equals(Color.black), (color) => { mColor = (Color)color; }, Color.black);menu.AddItem(new GUIContent("RGB/White"), mColor.Equals(Color.white), (color) => { mColor = (Color)color; }, Color.white);menu.ShowAsContext();
}

结果:


生成上图中的一个UI元素,左边的可以通过foldout控制,控制显示下面需要显示的信息

右边可以选择执行方法,比如上述代码中,点击就可以显示一个菜单,如下:

7.BeginProperty,EndProperty

 BeginProperty参数如下:

8.文本字段(xxxField)

以下API都是在面板中创建一个字段显示,故放在一起整理:

BoundsField

BoundsIntField

ColorField

CurveField

EnumFlagsField

DoubleField,FloatField,IntField,LongField
描述:创建一个用于输入双精度浮点数、单精度浮点数、整数、长整数的字段

LabelField

LayerField

GradientField

MaskField

MultiFloatField

MultiIntField

MultiPropertyField

注:使用此方法必须在使用前获取一下 SerializedProperty,否则会报错如下:

ObjectField

PasswordField

PropertyField

RectField

RectIntField

TagField

TextField

Vector2Field

Vector2IntField

Vector3Field

Vector3IntField

Vector4Field

DelayedDoubleField

DelayedFloatField

DelayedIntField

DelayedTextField

代码:

    private void OnEnable(){//在加载脚本或者启用对象时调用MonsterData m = ScriptableObject.CreateInstance<MonsterData>();mMonsterData = new UnityEditor.SerializedObject(m);mAtt = mMonsterData.FindProperty("att1");mObj = mMonsterData.FindProperty("obj");AttData m1 = ScriptableObject.CreateInstance<AttData>();mAttData = new UnityEditor.SerializedObject(m1);mAtt1 = mAttData.FindProperty("a1");}    [Serializable]public class Attribute{public float hp;public float maxhp;public float mp;public float maxmp;}[Serializable]public class MonsterData : ScriptableObject{public Attribute att1;public GameObject obj;public MonsterData(){this.att1 = new Attribute();}}SerializedObject mMonsterData;SerializedObject mAttData;[Serializable]public class AttData : ScriptableObject{public int a1 = 1;public int a2 = 2;public int a3 = 3;public int a4 = 4;}SerializedProperty mAtt;SerializedProperty mAtt1;SerializedProperty mObj;public void TestField(){//BoundsField 用于输入Bounds的Center和Extents字段EditorGUI.BoundsField(new Rect(0,300,250,50), "BoundsField", new Bounds(Vector3.zero,Vector3.one));//BoundsIntField 用于输入BoundsInt的Position和Size字段EditorGUI.BoundsIntField(new Rect(0,360,250,50), "BoundsIntField", new BoundsInt(Vector3Int.zero,Vector3Int.one));//ColorField 用于选择Color字段EditorGUI.ColorField(new Rect(0,430,100,20), "ColorField ", Color.white);//CurveField 用于编辑AnimationCurve的字段EditorGUI.CurveField(new Rect(0,460,250,20), "CurveField", new AnimationCurve());//EnumFlagsField EditorGUI.EnumFlagsField(new Rect(0,490,200,20), "EnumFlagsField", SpeedOption.Fast);//DoubleField 用于输入双精度浮点数的字段EditorGUI.DoubleField(new Rect(0,520,200,20), "DoubleField", 0);//FloatField 用于输入浮点数的文本字段EditorGUI.FloatField(new Rect(0,550,200,20), "FloatField", 0);//IntField 用于输入整数的字段EditorGUI.IntField(new Rect(0,580,200,20), "IntField", 0);//LongField 用于输入长整数的字段EditorGUI.LongField(new Rect(0, 610, 200, 20), "LongField", 0);//LabelField 创建一个标签字段EditorGUI.LabelField(new Rect(0, 640, 100, 20), "这是一个标签");//LayerField 创建一个层选择字段EditorGUI.LayerField(new Rect(0, 670, 250, 20), "LayerField", 0);//GradientField 创建一个用于编辑Gradient的字段EditorGUI.GradientField(new Rect(0, 700, 250, 20), "GradientField", new Gradient());//MaskField 创建一个掩码字段EditorGUI.MaskField(new Rect(0,730,100,20), "MaskField", 0,new string[] {"player","enemy","npc"});//MultiFloatField 同一行输入多个浮点值EditorGUI.MultiFloatField(new Rect(0, 760, 200, 20),new GUIContent("MultiFloatField"), new GUIContent[] {new GUIContent("第一个"),new GUIContent("第二个")}, new float[] {2.5f,3.0f});//MultiIntField 同一行输入多个整数EditorGUI.MultiIntField(new Rect(0, 810, 200, 20),new GUIContent[] { new GUIContent("第一个"), new GUIContent("第二个") }, new int[] { 6, 100 });//MultiPropertyField 同一行包含多个属性,标签数组决定显示的属性数量。使用的属性不应超过4个mAtt1 = mAttData.FindProperty("a1");//mAtt = mMonsterData.FindProperty("att1");EditorGUI.MultiPropertyField(new Rect(0,830,300,20), new GUIContent[] { new GUIContent("第一个"), new GUIContent("第二个"), new GUIContent("第三个"), new GUIContent("第四个") },mAtt1, new GUIContent("MultiPropertyField"));//ObjectField 创建一个对象字段,可以通过拖放对象或者使用对象选择器选择对象来分配对象EditorGUI.ObjectField(new Rect(0,870,250,20),mObj);//PasswordField 创建一个输入密码的字段EditorGUI.PasswordField(new Rect(0,900,250,20),"这是一个密码","ssssss");//PropertyField 针对SerializedProperty 创建一个字段EditorGUI.PropertyField(new Rect(0,930,200,20),mAtt,new GUIContent("这是一个属性字段"),true);//RectField 创建用于输入Rect的xywh的字段EditorGUI.RectField(new Rect(300,880,200,20),"这是一个Rect字段",new Rect(0,0,200.0f,200.0f));//RectIntField 创建用于输入RectInt的xywh的字段EditorGUI.RectIntField(new Rect(300,810,200,20),"这是一个RectInt字段",new RectInt(0,0,200,200));//TagField 创建标签选择字段EditorGUI.TagField(new Rect(600,880,250,20),"这是一个标签选择字段","player");//TextField 创建一个文本字段EditorGUI.TextField(new Rect(600,810,250,20),"这是一个文本字段","请输入。。。");//Vector2Field 输入Vector2的xy字段EditorGUI.Vector2Field(new Rect(0, 1030, 200, 20), "这是一个Vector2字段", Vector2.zero);//Vector2IntField 输入Vector2Int的xy字段EditorGUI.Vector2IntField(new Rect(0, 1070, 200, 20), "这是一个Vector2Int字段", Vector2Int.zero);//Vector3Field 输入Vector3的xyz字段EditorGUI.Vector3Field(new Rect(0, 1110, 200, 20), "这是一个Vector3字段", Vector3.zero);//Vector3IntField 输入Vector3Intd的xyz字段EditorGUI.Vector3IntField(new Rect(0, 1150, 200, 20), "这是一个Vector3Int字段", Vector3Int.zero);//Vector4Field 输入Vector4的xyzw字段EditorGUI.Vector4Field(new Rect(0, 1190, 200, 20), "这是一个Vector4字段", Vector4.zero);//DelayedDoubleField 创建一个用于输入双精度浮点数的延迟文本字段EditorGUI.DelayedDoubleField(new Rect(300,990,200,20),"这是一个Double延迟文本字段",20);//DelayedFloatField 创建一个用于输入浮点数的延迟文本字段 EditorGUI.DelayedFloatField(new Rect(300, 1030, 200, 20), "这是一个Float延迟文本字段", 20);//DelayedIntField 创建一个用于输入整数的延迟文本字段EditorGUI.DelayedIntField(new Rect(300, 1070, 200, 20), "这是一个Int延迟文本字段", 20);//DelayedTextField 创建一个用于输入延迟文本字段EditorGUI.DelayedTextField(new Rect(300, 1110, 200, 20), "这是一个文本延迟文本字段", "");}

结果:

9.CanCacheInspectorGUI
10.DrawPreviewTexture

代码:

    Texture texture;private void OnEnable(){//在加载脚本或者启用对象时调用texture = AssetDatabase.LoadAssetAtPath<Texture>("Assets/Art/bg_window.png");}public void TestDrawPreviewTexture(){EditorGUI.LabelField(new Rect(600, 880, 200, 200), "在矩形内绘制纹理");//在矩形内绘制纹理EditorGUI.DrawPreviewTexture(new Rect(600, 990, 200, 200), texture);}

结果:

11.DrawRect

代码:

    public void TestDrawRect(){EditorGUI.LabelField(new Rect(900, 880, 250, 200), "在窗口指定位置绘制一个指定颜色的矩形");//在窗口指定位置绘制一个指定颜色的矩形EditorGUI.DrawRect(new Rect(900, 990, 200, 200),Color.red);}

 结果:

12.DrawTextureAlpha

代码:

    Texture texture;private void OnEnable(){//在加载脚本或者启用对象时调用texture = AssetDatabase.LoadAssetAtPath<Texture>("Assets/Art/bg_window.png");}   public void TestDrawTextureAlpha(){//在矩形内绘制纹理的Alpha通道EditorGUI.LabelField(new Rect(300, 480, 200, 200), "在矩形内绘制纹理的Alpha通道");EditorGUI.DrawTextureAlpha(new Rect(300, 590, 200, 200),texture);}

结果:

13.DropdownButton

代码:

    public void TestDropdownButton(){//用于显示自己的下拉菜单内容if(EditorGUI.DropdownButton(new Rect(900, 590, 200, 200),new GUIContent("TEST"), FocusType.Keyboard)){GenericMenu genericMenu = new GenericMenu();genericMenu.AddItem(new GUIContent("test1"), true, () => { });genericMenu.AddItem(new GUIContent("test2"), false, () => { });genericMenu.AddItem(new GUIContent("test3"), false, () => { });genericMenu.AddItem(new GUIContent("test4"), false, () => { });genericMenu.AddItem(new GUIContent("test5"), false, () => { });genericMenu.DropDown(new Rect(950,410, 400, 200));}}

 结果:

14.DropShadowLabel

代码:

    public void TestDropShadowLabel(){//绘制带有投影的标签EditorGUI.DropShadowLabel(new Rect(900, 650, 200, 200),"这是一个阴影文字",new GUIStyle() { fontSize = 30});}

结果:

15.EnumPopup,IntPopup,Popup
创建一个枚举、整型、通用弹出字段

代码:

    public enum PopUpEnum{first,second, third, fourth,}public void TestPopup(){EditorGUI.EnumPopup(new Rect(300,200,200,20),PopUpEnum.fourth);EditorGUI.IntPopup(new Rect(300,230,200,20),0,new GUIContent[] {new GUIContent("第一个"),new GUIContent("第二个")},new int[] {0,1}); ;EditorGUI.Popup(new Rect(300, 260, 200, 20),0, new GUIContent[] { new GUIContent("One"), new GUIContent("Two") });}

结果:

16.FocusTextInControl
17.Foldout

代码:

    bool _isShow = false;public void TestFoldout(){_isShow = EditorGUI.Foldout(new Rect(300, 290, 200, 20), _isShow, "testFoldout");if (_isShow){if (Selection.activeTransform){Selection.activeTransform.position = EditorGUI.Vector3Field(new Rect(300, 310, 200, 100), "Position", Selection.activeTransform.position);}else{EditorGUI.LabelField(new Rect(300, 310, 200, 20), "请先选中一个物体!");}}}

结果:

18.GetPropertyHeight

代码:

    public void TestGetPropertyHeight(){//获取 PropertyField 控件所需的高度。float h = EditorGUI.GetPropertyHeight(mAtt, true);}

 结果:

19.HandlePrefixLabel

代码:

 public void TestHandlePrefixLabel(){//EditorGUI.LabelField(new Rect(300, 322, 200, 10),"testLabel");EditorGUI.HandlePrefixLabel(new Rect(300, 520, 200, 20), new Rect(300, 322, 200, 20), new GUIContent("testHandlePrefixLabel"));}

结果:

 

20.PrefixLabel

参数:

代码:

 public void TestPrefixLabel(){EditorGUI.PrefixLabel(new Rect(600, 180, 200, 20), new GUIContent("testPrefixLabel"));}

结果: 

21.HelpBox

代码:

  public void TestHelpBox(){EditorGUI.HelpBox(new Rect(300, 350, 200, 20),"测试HelpBox",MessageType.Warning);}

结果:

22.InspectorTitlebar
23.IntSlider,Slider,MinMaxSlider(已弃用)
创建一个滑动条,用户可以进行拖动以在最小值和最大值之间更改整数值。

代码:

    int valueInt = 0;float valueFloat = 50.8f;public void TestSlider(){valueInt = EditorGUI.IntSlider(new Rect(300, 410, 200, 20),valueInt,0,100);valueFloat = EditorGUI.Slider(new Rect(300, 440, 200, 20), valueFloat, 0, 100);//弃用的//EditorGUI.MinMaxSlider();}

结果:

24.LinkButton

代码:

    public void TestLinkButton(){if(EditorGUI.LinkButton(new Rect(900, 200, 200, 20), "TestLinkButton")){Application.OpenURL("Www.baidu.com");}}

结果:
 

25.ProgressBar

代码:

    float processValue = 0;public void TestProgressBar(){EditorGUI.ProgressBar(new Rect(600, 200, 200, 20),processValue, "testProgressBar");}

结果:

26.SelectableLabel

代码:

   public void TestSelectableLabel(){EditorGUI.SelectableLabel(new Rect(600, 230, 200, 20), "testSelectableLabel");}

结果:
 

27.TextArea

代码:

    string inputTxt = "请输入。。。";public void TestTextArea(){inputTxt = EditorGUI.TextArea(new Rect(600, 260, 200, 20), inputTxt);}

 结果:

28.Toggle,ToggleLeft

创建一个开关

代码:

    bool toglevalue = false;bool toggleLeftValue = false;public void TestToggle(){toglevalue = EditorGUI.Toggle(new Rect(600, 290, 200, 20), "testToggle", toglevalue);toggleLeftValue = EditorGUI.ToggleLeft(new Rect(600, 320, 200, 20), "testToggleLeft", toggleLeftValue);}

结果:

2.使用EditorGUILayout类

与EditorGUI不相同的API部分:

相同的部分:

与EditorGUI类中的方法用法一致。

3.使用GUI类:

4.使用GUILayaout类:

三、自定义Inspectors面板扩展

1.建立一个脚本面板扩展的编辑器脚本

新建一个TestEditorInspector脚本,用于自定义物体上的TestData脚本的Inspector面板

TestEditorInspector需要继承自Editor类,通过CustomEditor特性将编辑器脚本与脚本组件关联

代码:

[CustomEditor(typeof(TestData))]
public class TestEditorInspector : Editor
{public override void OnInspectorGUI(){base.OnInspectorGUI();//自定义Inspector内容}
}

2.增加面板内容

1.使用EditorGUI类(同上)

2.使用EditorGUILayout类(同上)

3.使用GUI类(同上)

4.使用GUILayaout类(同上)

参考:

《Extending Unity with Editor Scripting》

扩展编辑器 - Unity 手册 (unity3d.com)

EditorWindow - Unity 脚本 API

Unity - 手动:使用 C# 脚本创建自定义 Editor 窗口 (unity3d.com)

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

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

相关文章

Vue3+codemirror6实现公式(规则)编辑器

实现截图 实现/带实现功能 插入标签 插入公式 提示补全 公式验证 公式计算 需要的依赖 "codemirror/autocomplete": "^6.18.4","codemirror/lang-javascript": "^6.2.2","codemirror/state": "^6.5.2","cod…

4.PPT:日月潭景点介绍【18】

目录 NO1、2、3、4​ NO5、6、7、8 ​ ​NO9、10、11、12 ​ 表居中或者水平/垂直居中单元格内容居中或者水平/垂直居中 NO1、2、3、4 新建一个空白演示文稿&#xff0c;命名为“PPT.pptx”&#xff08;“.pptx”为扩展名&#xff09;新建幻灯片 开始→版式“PPT_素材.doc…

开源项目介绍-词云生成

开源词云项目是一个利用开源技术生成和展示词云的工具或框架&#xff0c;广泛应用于文本分析、数据可视化等领域。以下是几个与开源词云相关的项目及其特点&#xff1a; Stylecloud Stylecloud 是一个由 Maximilianinir 创建和维护的开源项目&#xff0c;旨在通过扩展 wordclou…

Redis双写一致性(数据库与redis数据一致性)

一 什么是双写一致性&#xff1f; 当修改了数据库&#xff08;MySQL&#xff09;中的数据&#xff0c;也要同时更新缓存&#xff08;redis&#xff09;中的数据&#xff0c;缓存中的数据要和数据库中的数据保持一致 双写一致性&#xff0c;根据业务对时间上的要求&#xff0c;…

C32.【C++ Cont】静态实现双向链表及STL库的list

目录 1.知识回顾 2.静态实现演示图 3.静态实现代码 1.初始双向链表 2.头插 3.遍历链表 4.查找某个值 4.任意位置之后插入元素 5.任意位置之前插入元素 6.删除任意位置的元素 4.STL库的list 1.知识回顾 96.【C语言】数据结构之双向链表的初始化,尾插,打印和尾删 97.【C…

二级C语言题解:矩阵主、反对角线元素之和,二分法求方程根,处理字符串中 * 号

目录 一、程序填空&#x1f4dd; --- 矩阵主、反对角线元素之和 题目&#x1f4c3; 分析&#x1f9d0; 二、程序修改&#x1f6e0;️ --- 二分法求方程根 题目&#x1f4c3; 分析&#x1f9d0; 三、程序设计&#x1f4bb; --- 处理字符串中 * 号 题目&#x1f…

采用idea中的HTTP Client插件测试

1.安装插件 采用idea中的HTTP Client插件进行接口测试,好处是不用打开post/swagger等多个软件,并且可以保存测试时的参数,方便后续继续使用. 高版本(2020版本以上)的idea一般都自带这个插件,如果没有也可以单独安装. 2.使用 插件安装完成(或者如果idea自带插件),会在每个Con…

探讨如何在AS上构建webrtc(2)从sdk/android/Build.gn开始

全文七千多字&#xff0c;示例代码居多别担心&#xff0c;没有废话&#xff0c;不建议跳读。 零、梦开始的地方 要发美梦得先入睡&#xff0c;要入睡得找能躺平的地方。那么能躺平编译webrtc-android的地方在哪&#xff1f;在./src/sdk/android/Build.gn。Build.gn是Build.nin…

Linux firewalld开启日志审计功能(2)

在Firewalld防火墙中启用和配置logdenied选项&#xff0c;记录被拒绝的数据包&#xff08;等同于开启日志功能&#xff09; 效果展示&#xff1a; 1.开启日志记录功能 firewall-cmd --set-log-deniedunicast #重新加载生效配置 firewall-cmd --reload 2.配置rsyslog捕获日志…

Spring Web MVC项目的创建及使用

一、什么是Spring Web MVC&#xff1f; Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;从⼀开始就包含在 Spring 框架中&#xff0c;通常被称为Spring MVC。 1.1 MVC的定义 MVC 是 Model View Controller 的缩写&#xff0c;它是软件工程中的一种软件架构…

oracle:索引(B树索引,位图索引,分区索引,主键索引,唯一索引,联合索引/组合索引,函数索引)

索引通过存储列的排序值来加快对表中数据的访问速度&#xff0c;帮助数据库系统快速定位到所需数据&#xff0c;避免全表扫描 B树索引(B-Tree Index) B树索引是一种平衡树结构&#xff0c;适合处理范围查询和精确查找。它的设计目标是保持数据有序&#xff0c;并支持高效的插入…

android 适配 api 35(android 15) 遇到的问题

首先升级 targetSdkVersion 和 compileSdkVersion 到 35&#xff0c;升级后发生的报错 一、 解决方案: 升级 gradle 和 gradle 插件版本 com.android.tools.build:gradle -> 8.3.0-alpha02 gradle-wrapper.properties : distributionUrl -> gradle-8.6-bin.zip htt…

@Value属性读取系统变量错误

Value属性读取配置属性错误 场景 在测试Value读取yml配置文件属性时&#xff0c;发现系统配置属性优先级高于配置文件&#xff0c;导致注入异常值&#xff1a; 配置文件: user:name: yanxin测试类: RestController RequestMapping("/books") public class BookC…

BFS算法——广度优先搜索,探索未知的旅程(下)

文章目录 前言一. N叉树的层序遍历1.1 题目链接&#xff1a;https://leetcode.cn/problems/n-ary-tree-level-order-traversal/description/1.2 题目分析&#xff1a;1.3 思路讲解&#xff1a;1.4 代码实现&#xff1a; 二. 二叉树的锯齿形层序遍历2.1 题目链接&#xff1a;htt…

【Ubuntu】ARM交叉编译开发环境解决“没有那个文件或目录”问题

【Ubuntu】ARM交叉编译开发环境解决“没有那个文件或目录”问题 零、起因 最近在使用Ubuntu虚拟机编译ARM程序&#xff0c;解压ARM的GCC后想要启动&#xff0c;报“没有那个文件或目录”&#xff0c;但是文件确实存在&#xff0c;环境配置也检查过了没问题&#xff0c;本文记…

清理服务器/docker容器

清理服务器 服务器或docker容器清理空间。 清理conda环境 删除不用的conda虚拟环境&#xff1a; conda env remove --name python38 conda env remove --name python310清理临时目录&#xff1a;/tmp du -sh /tmp # 查看/tmp目录的大小/tmp 目录下的文件通常是可以直接删除…

康谋方案 | BEV感知技术:多相机数据采集与高精度时间同步方案

随着自动驾驶技术的快速发展&#xff0c;车辆准确感知周围环境的能力变得至关重要。BEV&#xff08;Birds-Eye-View&#xff0c;鸟瞰图&#xff09;感知技术&#xff0c;以其独特的视角和强大的数据处理能力&#xff0c;正成为自动驾驶领域的一大研究热点。 一、BEV感知技术概…

HarmonyOS 5.0应用开发——ContentSlot的使用

【高心星出品】 文章目录 ContentSlot的使用使用方法案例运行结果 完整代码 ContentSlot的使用 用于渲染并管理Native层使用C-API创建的组件同时也支持ArkTS创建的NodeContent对象。 支持混合模式开发&#xff0c;当容器是ArkTS组件&#xff0c;子组件在Native侧创建时&#…

脚本一键生成管理下游k8s集群的kubeconfig

一、场景 1.1 需要管理下游k8s集群的场景。 1.2 不希望使用默认的cluster-admin权限的config. 二、脚本 **重点参数&#xff1a; 2.1 配置变量。 1、有单独namespace的权限和集群只读权限。 2、自签名的CA证书位置要正确。 2.2 如果配置错误&#xff0c;需要重新…

windows安装linux子系统【ubuntu】操作步骤

1.在windows系统中开启【适用于Linux的Windows子系统】 控制面板—程序—程序和功能—启用或关闭Windows功能—勾选适用于Linux的Windows子系统–确定 2.下载安装Linux Ubuntu 22.04.5 LTS系统 Ununtu下载链接 3.安装完Ununtu系统后更新系统 sudo apt update4.进入/usr/l…