UEDL5——Selection公共类

本章代码关键字

1
2
3
4
5
6
7
8
9
10
11
Selection.activeObject            //获取当前选择的单个Object
Selection.activeGameObject //获取当前选择的单个GameObject
Selection.activeTransform //获取当前选择的单个Transform
Selection.objects //获取当前选择的所有Object
Selection.gameObjects //获取当前选择的所有GameObject
Selection.transforms //获取当前选择的所有Transform
Selection.count //获取当前选择的对象数
Selection.Contains() //可以判断某个对象是否在编辑器窗口内被选中,传入要判断的对象
Selection.GetFiltered<>() //从当前选择对象中,筛选出想要的内容,返回筛选出来的Object数组
SelectionMode //筛选模式枚举
Selection.selectionChanged //当选中对象变化时会调用的委托

Selection

Selection​主要用来获取当前在Unity编辑器中选择的对象,只能用于编辑器开发中

关于Selection​的具体内容,详见:Selection - Unity 脚本 API

Selection常用静态属性

  1. 当前选择的Object

    我们可以通过Selection.activeObject​,来获取当前在面板上选择的游戏物体Object​,未选择则返回null
    选择多个则返回第一个选择的游戏物体

    我们可以判断对象的类型,根据不同的类型来做不同的处理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    private StringBuilder str1 = new StringBuilder("没有选择");
    private void OnGUI()
    {
    if (GUILayout.Button("获取当前选择的Object的名字"))
    {
    if (Selection.activeObject != null)
    {
    str1.Clear();
    str1.Append(Selection.activeObject.name);
    if (Selection.activeObject is GameObject)
    Debug.Log("它是游戏对象");
    else if (Selection.activeObject is Texture)
    Debug.Log("它是一张纹理");
    else if (Selection.activeObject is TextAsset)
    Debug.Log("它是一个文本");
    else
    Debug.Log("它是其他类型的资源");
    }
    else
    {
    str1.Clear();
    str1.Append("没有选择");
    }
    }
    EditorGUILayout.LabelField("当前选择的对象", str1.ToString());
    }

    如果选择了游戏对象:image
    输出如下:image

    如果选择了贴图资源:image
    输出如下:image

  2. 当前选择的GameObject

    Selection.activeGameObject​可获取当前在面板上选择的游戏物体GameObject​,未选择或选择的不是GameObject​则返回null
    选择多个则返回第一个选择的游戏物体

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    private StringBuilder str2 = new StringBuilder("没有选择");

    private void OnGUI()
    {
    if (GUILayout.Button("获取当前选择的GameObject的名字"))
    {
    if (Selection.activeGameObject != null)
    {
    str2.Clear();
    str2.Append(Selection.activeGameObject.name);
    }
    else
    {
    str2.Clear();
    str2.Append("没有选择");
    }
    }
    EditorGUILayout.LabelField("当前选择的GameObject", str2.ToString());
    }

    显示效果:image

  3. 当前选择的Transform

    Selection.activeTransform​可获取当前在面板上选择的游戏物体的Transform​,未选择则返回null
    选择多个则返回第一个选择的游戏物体,只能获取到场景中的对象的****​Transform​,不能获取预设体的Transform

    因此,在获取到Transform​后我们可以操控对象的位置,旋转,缩放

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    private StringBuilder str3 = new StringBuilder("没有选择");

    private void OnGUI()
    {
    if (GUILayout.Button("获取当前选择的Transform的名字"))
    {
    if (Selection.activeTransform != null)
    {
    str3.Clear();
    str3.Append(Selection.activeTransform.name);
    Selection.activeTransform.position = new Vector3(10, 10, 10);
    }
    else
    {
    str3.Clear();
    str3.Append("没有选择");
    }
    }
    EditorGUILayout.LabelField("当前选择的Transform", str3.ToString());
    }

    显示效果:
    image

    image

    选择预设体则不生效:image

  4. 当前选择的所有Object

    Selection.objects​可获取当前在面板上选择的物体数组,未选择则返回null​,便于我们进行批量的处理

    注意:如果没有选择任何对象,Selection.gameObjects​不会返回null​,而是返回空的数组,
    因此我们不能以判断null​来判断是否选择了对象,而是应该以判断数组长度是否为0来判断是否选择了对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    private StringBuilder str4 = new StringBuilder("没有选择");

    private void OnGUI()
    {
    if (GUILayout.Button("获取当前选择的所有Object的名字"))
    {
    if (Selection.objects.Length != 0)
    {
    str4.Clear();
    for (int i = 0; i < Selection.objects.Length; i++)
    {
    str4.Append(Selection.objects[i].name + "; ");
    }
    }
    else
    {
    str4.Clear();
    str4.Append("没有选择");
    }
    }
    EditorGUILayout.LabelField("当前选择的所有对象", str4.ToString());
    }

    显示效果:image

  5. 当前选择的所有GameObject

    Selection.gameObjects​可获取当前在面板上选择的游戏物体或Project中预设体 GameObject​ 数组,未选择则返回null
    可以遍历获取所有信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    private StringBuilder str5 = new StringBuilder("没有选择");

    private void OnGUI()
    {
    if (GUILayout.Button("获取当前选择的所有GameObject的名字"))
    {
    if (Selection.gameObjects.Length != 0)
    {
    str5.Clear();
    for (int i = 0; i < Selection.gameObjects.Length; i++)
    {
    str5.Append(Selection.gameObjects[i].name + "; ");
    }
    }
    else
    {
    str5.Clear();
    str5.Append("没有选择");
    }
    }
    EditorGUILayout.LabelField("选择的所有GameObject", str5.ToString());
    }

    显示效果:image

  6. 当前选择的所有Transform

    Selection.transforms​可获取当前在面板上选择的游戏物体Transform​数组,未选择则返回null
    可以遍历获取所有信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    if (GUILayout.Button("获取当前选择的所有的Transform的名字"))
    {
    if (Selection.transforms.Length != 0)
    {
    str6.Clear();
    for (int i = 0; i < Selection.transforms.Length; i++)
    {
    str6.Append(Selection.transforms[i].name + "; ");
    }
    }
    else
    {
    str6.Clear();
    str6.Append("没有选择");
    }
    }
    EditorGUILayout.LabelField("选择的所有Transform", str6.ToString());

    显示效果:image

  7. 返回当前所选的对象数

    Selection.count​可以返回当前所选的对象数,在判断是否选择对象时,可以使用该属性用来替代判空或者判断数组长度

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int num = 0;

    private void OnGUI()
    {
    if (GUILayout.Button("获取当前选择的对象数量"))
    {
    num = Selection.count;
    }
    EditorGUILayout.LabelField("当前选择的对象数量", num.ToString());
    }

    显示效果:image

Selection常用静态方法

  • 判断某个对象是否被选中

    顾名思义,可以判断某个对象是否在编辑器窗口内被选中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    private Object obj;

    private void OnGUI()
    {
    obj = EditorGUILayout.ObjectField("用于判断是否被选中的对象", obj, typeof(GameObject)
    if (GUILayout.Button("判断对象是否被选中"))
    {
    if (Selection.Contains(obj))
    Debug.Log("对象有被选中");
    else
    Debug.Log("对象未被选中");
    }
    }

    显示效果:image

  • 筛选对象

    从当前选择对象中,筛选出想要的内容,类型参数可用泛型或者不用泛型,返回Object​数组

    • Selection.GetFiltered(类型, 筛选模式)
    • Selection.GetFiltered<类型>(筛选模式)

    筛选模式 SelectionMode​ 枚举包括:

    • Unfiltered​:不过滤
    • TopLevel​:只获取最上层对象,子对象不获取
    • Deep​:父对象、子对象都获取
    • ExcludePrefab​:排除预设体
    • Editable​:只选择可编辑的对象
    • OnlyUserModifiable​:仅用户可修改的内容
    • Assets​:只返回资源文件夹下的内容
    • DeepAssets​:如果存在子文件夹,其中的内容也获取

    筛选模式如果要混用,使用位或|​即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    private void OnGUI()
    {
    if (GUILayout.Button("筛选所有对象"))
    {
    //筛选Assets文件夹下的所有内容,选中的文件若包括子文件夹,则子文件夹内的内容也获取
    Object[] objs = Selection.GetFiltered<Object>(SelectionMode.DeepAssets | SelectionMode.Assets);
    for (int i = 0; i < objs.Length; i++)
    {
    Debug.Log(objs[i].name);
    }
    }
    }

    显示效果(选择Editor文件夹下的内容筛选):
    image

    输出结果:image

  • 当选中变化时会调用的委托

    Selection​有一个委托变量selectionChanged​,我们可用向里边添加在编辑器窗口选中对象变化时会调用的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private void OnEnable()
    {
    Selection.selectionChanged += SelectionChanged;
    }

    private void OnDestroy()
    {
    Selection.selectionChanged -= SelectionChanged;
    }

    private void SelectionChanged()
    {
    Debug.Log($"选择的对象变化了,变化为{Selection.activeObject.name}");
    }

    点击Project窗口上Assets下的不同对象(点到Package文件夹会报错):

    image