68 lines
1.8 KiB
C#
68 lines
1.8 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
/// <summary>
|
||
/// 在多 SceneView 窗口下安全地添加/移除临时回调。
|
||
/// 原理:Templist 存放需在下一帧执行的回调,OnSceneGUI 将会把 Templist 转移到 list 来执行。
|
||
/// </summary>
|
||
public class UXCustomSceneView
|
||
{
|
||
static private List<Action<SceneView>> list = new List<Action<SceneView>>();
|
||
static private List<Action<SceneView>> Templist = new List<Action<SceneView>>();
|
||
|
||
[InitializeOnLoadMethod]
|
||
static void Init()
|
||
{
|
||
list.Clear();
|
||
Templist.Clear();
|
||
SceneView.duringSceneGui -= OnSceneGUI;
|
||
SceneView.duringSceneGui += OnSceneGUI;
|
||
}
|
||
|
||
static public void AddDelegate(Action<SceneView> method)
|
||
{
|
||
if (method == null) return;
|
||
// 去重
|
||
if (!Templist.Contains(method))
|
||
Templist.Add(method);
|
||
}
|
||
|
||
static public void RemoveDelegate(Action<SceneView> method)
|
||
{
|
||
if (method == null) return;
|
||
var idx = Templist.FindIndex(i => i == method);
|
||
if (idx >= 0) Templist.RemoveAt(idx);
|
||
}
|
||
|
||
static public void OnSceneGUI(SceneView sceneView)
|
||
{
|
||
// 执行上一帧注册的 list
|
||
foreach (Action<SceneView> method in list)
|
||
{
|
||
try
|
||
{
|
||
method.Invoke(sceneView);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogException(e);
|
||
}
|
||
}
|
||
|
||
list.Clear();
|
||
|
||
// 将 Templist 拷贝到 list,并在下一帧执行,这样可以避免在枚举时修改集合的问题
|
||
foreach (Action<SceneView> method in Templist)
|
||
{
|
||
if (!list.Contains(method))
|
||
list.Add(method);
|
||
}
|
||
}
|
||
|
||
static public void ClearDelegate()
|
||
{
|
||
Templist.Clear();
|
||
}
|
||
} |