背景:
最近从cocos那边转过来的unity同事总是吐糟我们unity选中一个资源后都无法清晰的看到他的文件路径,这给他的工作带来了很多的烦恼,于是我想到昨天刚看到一个unity编辑器下的简易协程实现,通过2个接口Selection.activeObject = selectedObject; EditorGUIUtility.PingObject(selectedObject); 可以实现选中一个目标资源并且跳转到该资源,于是我们可以先选中文件的文件夹,然后协程等待一帧然后选中并跳转到选中文件。这样就实现了2边都展开的问题了。所以有时候有个同事问你问题真的是非常好,往往他们能让你产生很多有趣的想法。
运行结果:
1.之前的结果:
2.打开开关后运行结果 可以看到整个左侧的文件路径都暂开了,这样对于ui工作很频繁的同学
就很友好拉,可以节省一点点时间。
前置知识:
unity编辑器下的简易协程EditorCoroutine.cs 下方有代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
public class EditorCoroutine
{
readonly EditorYieldInstruction mRoutine;
public EditorCoroutine(EditorYieldInstruction pRoutine)
{
mRoutine = pRoutine;
}
static public EditorCoroutine StartCoroutine(EditorYieldInstruction pRoutine)
{
var tRoutine = new EditorCoroutine(pRoutine);
tRoutine.Start();
return tRoutine;
}
static public void StopCoroutine(EditorCoroutine pCoroutine)
{
if (pCoroutine != null) pCoroutine.Stop();
}
void Start()
{
EditorApplication.update -= Update;
EditorApplication.update += Update;
}
void Stop()
{
EditorApplication.update -= Update;
}
void Update()
{
if (mRoutine != null && !mRoutine.MoveNext())
{
Stop();
}
}
}
public abstract class EditorYieldInstruction : IEnumerator
{
public abstract object Current { get; }
public abstract bool MoveNext();
public abstract void Reset();
}
public class EditorWaitForSeconds : EditorYieldInstruction
{
readonly long mTicks;
readonly float mSeconds;
readonly Action mCallBack;
public EditorWaitForSeconds(float pSeconds, Action pCallBack)
{
mSeconds = pSeconds;
mCallBack = pCallBack;
mTicks = DateTime.Now.AddSeconds(pSeconds).Ticks;
}
public override object Current { get { return null; } }
public override bool MoveNext()
{
if (DateTime.Now.Ticks >= mTicks)
{
if (mCallBack != null) mCallBack();
return false;
}
return true;
}
public override void Reset()
{
}
}
高亮接口:
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class SelectionTools
{
static SelectionTools()
{
// 监听 Selection 变化事件
Selection.selectionChanged += OnSelectionChanged;
}
private static void OnSelectionChanged()
{
// 开关 如果你不想使用这个功能应该可以关闭
if (!EditorPrefs.GetBool("SelectionTools", true))
{
return;
}
// 获取当前选中的资源
var selectedObject = Selection.activeObject;
if (selectedObject == null)
return;
// 获取资源的路径
string path = AssetDatabase.GetAssetPath(selectedObject);
//目录不要这种操作
if (string.IsNullOrEmpty(path) || System.IO.Directory.Exists(path))
return;
// 获取资源所在的目录
string folderPath = System.IO.Path.GetDirectoryName(path);
var folder = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(folderPath);
if (folder != null)
{
// 将焦点切换到 Project 窗口
//EditorUtility.FocusProjectWindow();
Selection.activeObject = folder;
EditorGUIUtility.PingObject(folder);
//unity编辑下模拟协程
EditorCoroutine.StartCoroutine(new EditorWaitForSeconds(0.00001f, () =>
{
Selection.activeObject = selectedObject;
EditorGUIUtility.PingObject(selectedObject);
}));
// Ping 目录(高亮显示但不会选中它)
}
}
}