【编辑器】脚本实现OpenPrefab界面

前言

2018的Unity中Prefab的显示会跳到另外的一个界面,在prefab的面板上有“Open Prefab”的按钮。这里用脚本实现这个按钮的功能。

效果

在这里插入图片描述

环境

在这里插入图片描述

脚本

using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;

public class PreafabTest : EditorWindow
{
    
    

    [MenuItem("Tool/PreafabTest")]
    private static void Opne()
    {
    
    
        EditorWindow.GetWindow<PreafabTest>("Prefab界面测试");
    }

    private void OnEnable()
    {
    
    
        Selection.selectionChanged += SelectionChangeCallback;
    }

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

    private void OnGUI()
    {
    
    
        GUILayout.BeginHorizontal("helpbox");
        GUILayout.Label(Selection.activeGameObject == null? "当前没有选中任何对象": "当前选中:" + Selection.activeGameObject.name, "box");

        if (Selection.activeGameObject != null)
        {
    
    
            bool isPreviewSceneObject = EditorSceneManager.IsPreviewSceneObject(Selection.activeGameObject);
            GUILayout.Label(isPreviewSceneObject ? "Prefab环境" : "非Prefab环境", "box");
        }
        GUILayout.EndHorizontal();

        if (GUILayout.Button("Open Prefab"))
        {
    
    
            OpenPrefab();
        }

        if (GUILayout.Button("Close Prefab"))
        {
    
    
            OpenMain();
        }
    }

    private void OpenPrefab()
    {
    
    
        GameObject uiPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Prefab/UI.prefab");
        AssetDatabase.OpenAsset(uiPrefab);
    }

    private void OpenMain()
    {
    
    
        StageUtility.GoToMainStage();
    }

    private void SelectionChangeCallback()
    {
    
    
        this.Focus();
    }
}

技术点

  1. 进入Prefab界面并不是切换了一个场景,所以不要使用SceneManger的功能
  2. 在Prefab场景里获取的对象并不是预制体,所以使用PrefabUtility里面的函数进行判断会失败,要使用脚本中的EditorSceneManager。
  3. 判断是否在Prefab场景中直接判断GameObject,而不要用IsPreviewScene。因为真正的previeScene是SceneManager里面的私有对象。

题外

实现的时候一开始没想到这么简单的办法,用了反射调用OpenPrefabMode.OpenPrefab。功能是实现了,但是在Prefab的界面中编译的话,SceneView会报错。原因是里面会创建 StageNavigationManager的单例,这只是临时的对象,并不是Unity中真正的那个对象。所以重编译一切状态就都改变了。看了别的脚本,使用创建单例的办法的地方有很多。当在使用反射创建或改变状态时,编译导致异常的话,有可能就是这个原因。
我使用的是ILSpy反编译UnityEditor.dll得到的脚本,功能真的很强大,调用和引用都能看到。dll的路径:“本地Unity安装路径/Editor/Data/Managed”。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sinat_34870723/article/details/92832399
今日推荐