在Hierarchy窗口选中对象后,场景界面显示自定义的图标

结果

只实现了选中的对象中包含不超过一个的目标对象时显示图标

实现了选中任意个对象并在对应位置显示辨识图标,并且选中父对象时,满足条件的子对象也会显示

起因

我正在编写一个打怪游戏,我通过在地图上放置预制体“刷怪点”来控制对象的生成,使用脚本变量控制刷怪点生成的怪物属性,但是这些刷怪点在场景是没有贴图的,选中后只有线框,我不能整体的预览到怪物分布情况,所以我希望在我选中这些刷怪点时,场景会绘制图标来展示信息

过程

第一版

使用继承了Editor类的编辑器脚本来实现,只能在选中对象中满足条件的对象为单个时显示图标

[CustomEditor(typeof(SMP))]
public class SMPObjectEditor : Editor
{
    public Texture2D icon;

    private void OnSceneGUI()
    {
        // 判断当前是否选中一个SMP脚本挂载的对象
        SMP smp = target as SMP;
        if (smp != null && Selection.activeGameObject == smp.gameObject)
        {
            Handles.BeginGUI();
            GUI.DrawTexture(new Rect(HandleUtility.WorldToGUIPoint(smp.transform.position), new Vector2(32, 32)), icon);
            Handles.EndGUI();
        }
    }
}

第二版

可以选择多个满足条件的对象并在对应位置显示图标

使用[InitializeOnLoad]属性在Unity加载时自动初始化脚本

[InitializeOnLoad]
public class SMPObjectEditor
{
    public static Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/2DBeginnerTutorialResources/Art/Sprites/Characters/EnemyIcon.png");
    static SMPObjectEditor()
    {
        // 注册一个回调函数,在每帧场景视图中绘制SMP对象的Icon
        SceneView.duringSceneGui += OnSceneViewGUI;
    }

    private static void OnSceneViewGUI(SceneView sceneView)
    {
        // 遍历所有被选中的对象
        foreach (GameObject obj in Selection.gameObjects)
        {
            // 如果对象上挂载了SMP组件,就在场景中绘制Icon
            if (obj.GetComponent<SMP>() != null)
            {
                Handles.BeginGUI();
                GUI.DrawTexture(new Rect(HandleUtility.WorldToGUIPoint(obj.transform.position) - new Vector2(32, 32), new Vector2(64, 64)), texture);
                Handles.EndGUI();                
            }
        }
    }
}

最终版

将满足条件的对象都保存在列表里,然后遍历列表绘制图标,要注意BeginGUI和EndGUI要每次遍历都执行,写在外面就只会绘制最后一个

[InitializeOnLoad]
public class SMPObjectEditor
{
    public static Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/2DBeginnerTutorialResources/Art/Sprites/Characters/EnemyIcon.png");
    static SMPObjectEditor()
    {
        // 注册一个回调函数,在每帧场景视图中绘制SMP对象的Icon
        SceneView.duringSceneGui += OnSceneViewGUI;
    }

    private static void OnSceneViewGUI(SceneView sceneView)
    {
        // 遍历所有被选中的对象
        foreach (GameObject obj in Selection.gameObjects)
        {
            // 找出选中对象中挂载了SMP脚本的对象
            SMP[] sMPs = obj.GetComponentsInChildren<SMP>();
            if (sMPs != null)
            {
                foreach (SMP smp in sMPs)
                {
                    Handles.BeginGUI();
                    GUI.DrawTexture(new Rect(HandleUtility.WorldToGUIPoint(smp.transform.position) - new Vector2(32, 32), new Vector2(64, 64)), texture);
                    Handles.EndGUI();
                }
                
            }
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值