537 lines
18 KiB
C#
537 lines
18 KiB
C#
|
using UnityEngine;
|
|||
|
using UnityEditor;
|
|||
|
using System.IO;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
|
|||
|
public class TiledMapScreenshotTool : EditorWindow
|
|||
|
{
|
|||
|
[Header("相机设置")]
|
|||
|
public Camera targetCamera;
|
|||
|
public LayerMask layerMask = -1;
|
|||
|
|
|||
|
[Header("区域设置")]
|
|||
|
public Vector3 startPosition = new Vector3(-100, 0, -100);
|
|||
|
public Vector3 endPosition = new Vector3(100, 0, 100);
|
|||
|
public float cameraHeight = 100f;
|
|||
|
|
|||
|
[Header("截图设置")]
|
|||
|
public int tileWidth = 2048; // 单个瓦片宽度
|
|||
|
public int tileHeight = 2048; // 单个瓦片高度
|
|||
|
public int antiAliasing = 4; // 抗锯齿
|
|||
|
public float overlapPercent = 5f; // 重叠百分比,避免接缝
|
|||
|
|
|||
|
[Header("网格预览")]
|
|||
|
public bool showGridPreview = true;
|
|||
|
public Color gridColor = Color.yellow;
|
|||
|
|
|||
|
[Header("输出设置")]
|
|||
|
public string fileName = "SuperMapScreenshot";
|
|||
|
public string outputPath = "Assets/Screenshots/";
|
|||
|
public bool saveIndividualTiles = false; // 是否保存单个瓦片
|
|||
|
|
|||
|
private Vector3 originalCameraPosition;
|
|||
|
private Quaternion originalCameraRotation;
|
|||
|
private bool originalOrthographic;
|
|||
|
private float originalOrthographicSize;
|
|||
|
private int originalCullingMask;
|
|||
|
|
|||
|
private int gridWidth, gridHeight;
|
|||
|
private float tileWorldWidth, tileWorldHeight;
|
|||
|
private Vector2 totalWorldSize;
|
|||
|
private int finalImageWidth, finalImageHeight;
|
|||
|
|
|||
|
[MenuItem("Tools/分块地图截图工具")]
|
|||
|
public static void ShowWindow()
|
|||
|
{
|
|||
|
GetWindow<TiledMapScreenshotTool>("分块地图截图工具");
|
|||
|
}
|
|||
|
|
|||
|
void OnEnable()
|
|||
|
{
|
|||
|
SceneView.duringSceneGui += OnSceneGUI;
|
|||
|
CalculateGrid();
|
|||
|
}
|
|||
|
|
|||
|
void OnDisable()
|
|||
|
{
|
|||
|
SceneView.duringSceneGui -= OnSceneGUI;
|
|||
|
}
|
|||
|
|
|||
|
void OnGUI()
|
|||
|
{
|
|||
|
GUILayout.Label("分块地图截图工具", EditorStyles.boldLabel);
|
|||
|
EditorGUILayout.Space();
|
|||
|
|
|||
|
// 相机设置
|
|||
|
EditorGUILayout.LabelField("相机设置", EditorStyles.boldLabel);
|
|||
|
targetCamera = (Camera)EditorGUILayout.ObjectField("目标相机", targetCamera, typeof(Camera), true);
|
|||
|
|
|||
|
if (targetCamera == null)
|
|||
|
{
|
|||
|
EditorGUILayout.HelpBox("请选择一个相机作为截图相机", MessageType.Warning);
|
|||
|
if (GUILayout.Button("使用场景相机"))
|
|||
|
{
|
|||
|
targetCamera = SceneView.lastActiveSceneView?.camera;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
layerMask = EditorGUILayout.MaskField("渲染层级", layerMask, UnityEditorInternal.InternalEditorUtility.layers);
|
|||
|
|
|||
|
EditorGUILayout.Space();
|
|||
|
|
|||
|
// 区域设置
|
|||
|
EditorGUILayout.LabelField("截图区域设置", EditorStyles.boldLabel);
|
|||
|
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
if (GUILayout.Button("设为当前相机位置", GUILayout.Width(120)))
|
|||
|
{
|
|||
|
if (targetCamera != null)
|
|||
|
{
|
|||
|
Vector3 pos = targetCamera.transform.position;
|
|||
|
startPosition = new Vector3(pos.x - 50, startPosition.y, pos.z - 50);
|
|||
|
}
|
|||
|
}
|
|||
|
startPosition = EditorGUILayout.Vector3Field("开始位置 (XZ)", startPosition);
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
if (GUILayout.Button("设为当前相机位置", GUILayout.Width(120)))
|
|||
|
{
|
|||
|
if (targetCamera != null)
|
|||
|
{
|
|||
|
Vector3 pos = targetCamera.transform.position;
|
|||
|
endPosition = new Vector3(pos.x + 50, endPosition.y, pos.z + 50);
|
|||
|
}
|
|||
|
}
|
|||
|
endPosition = EditorGUILayout.Vector3Field("结束位置 (XZ)", endPosition);
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
|
|||
|
cameraHeight = EditorGUILayout.FloatField("相机高度", cameraHeight);
|
|||
|
|
|||
|
EditorGUILayout.Space();
|
|||
|
|
|||
|
// 截图设置
|
|||
|
EditorGUILayout.LabelField("瓦片设置", EditorStyles.boldLabel);
|
|||
|
|
|||
|
EditorGUI.BeginChangeCheck();
|
|||
|
tileWidth = EditorGUILayout.IntField("瓦片宽度", tileWidth);
|
|||
|
tileHeight = EditorGUILayout.IntField("瓦片高度", tileHeight);
|
|||
|
antiAliasing = EditorGUILayout.IntPopup("抗锯齿", antiAliasing, new string[] {"无", "2x", "4x", "8x"}, new int[] {1, 2, 4, 8});
|
|||
|
overlapPercent = EditorGUILayout.Slider("重叠百分比", overlapPercent, 0f, 20f);
|
|||
|
|
|||
|
if (EditorGUI.EndChangeCheck())
|
|||
|
{
|
|||
|
CalculateGrid();
|
|||
|
}
|
|||
|
|
|||
|
EditorGUILayout.Space();
|
|||
|
|
|||
|
// 网格预览
|
|||
|
EditorGUILayout.LabelField("网格预览", EditorStyles.boldLabel);
|
|||
|
showGridPreview = EditorGUILayout.Toggle("显示网格预览", showGridPreview);
|
|||
|
if (showGridPreview)
|
|||
|
{
|
|||
|
gridColor = EditorGUILayout.ColorField("网格颜色", gridColor);
|
|||
|
}
|
|||
|
|
|||
|
EditorGUILayout.Space();
|
|||
|
|
|||
|
// 计算信息显示
|
|||
|
EditorGUILayout.LabelField("计算信息", EditorStyles.boldLabel);
|
|||
|
EditorGUILayout.LabelField($"世界区域大小: {totalWorldSize.x:F1} x {totalWorldSize.y:F1}");
|
|||
|
EditorGUILayout.LabelField($"网格数量: {gridWidth} x {gridHeight} = {gridWidth * gridHeight} 张");
|
|||
|
EditorGUILayout.LabelField($"最终图片尺寸: {finalImageWidth} x {finalImageHeight}");
|
|||
|
EditorGUILayout.LabelField($"预估文件大小: ~{(finalImageWidth * finalImageHeight * 4 / 1024f / 1024f):F1} MB");
|
|||
|
|
|||
|
if (gridWidth * gridHeight > 100)
|
|||
|
{
|
|||
|
EditorGUILayout.HelpBox($"瓦片数量较多({gridWidth * gridHeight}张),截图可能需要较长时间", MessageType.Warning);
|
|||
|
}
|
|||
|
|
|||
|
EditorGUILayout.Space();
|
|||
|
|
|||
|
// 输出设置
|
|||
|
EditorGUILayout.LabelField("输出设置", EditorStyles.boldLabel);
|
|||
|
fileName = EditorGUILayout.TextField("文件名", fileName);
|
|||
|
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
outputPath = EditorGUILayout.TextField("输出路径", outputPath);
|
|||
|
if (GUILayout.Button("选择", GUILayout.Width(50)))
|
|||
|
{
|
|||
|
string selectedPath = EditorUtility.OpenFolderPanel("选择输出文件夹", "Assets", "");
|
|||
|
if (!string.IsNullOrEmpty(selectedPath))
|
|||
|
{
|
|||
|
outputPath = "Assets" + selectedPath.Substring(Application.dataPath.Length) + "/";
|
|||
|
}
|
|||
|
}
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
|
|||
|
saveIndividualTiles = EditorGUILayout.Toggle("保存单个瓦片", saveIndividualTiles);
|
|||
|
|
|||
|
EditorGUILayout.Space();
|
|||
|
|
|||
|
// 操作按钮
|
|||
|
GUI.enabled = targetCamera != null;
|
|||
|
|
|||
|
if (GUILayout.Button("预览第一个瓦片位置", GUILayout.Height(25)))
|
|||
|
{
|
|||
|
PreviewTilePosition(0, 0);
|
|||
|
}
|
|||
|
|
|||
|
if (GUILayout.Button("开始分块截图", GUILayout.Height(40)))
|
|||
|
{
|
|||
|
StartTiledScreenshot();
|
|||
|
}
|
|||
|
|
|||
|
GUI.enabled = true;
|
|||
|
}
|
|||
|
|
|||
|
void CalculateGrid()
|
|||
|
{
|
|||
|
// 计算世界区域大小
|
|||
|
totalWorldSize = new Vector2(
|
|||
|
Mathf.Abs(endPosition.x - startPosition.x),
|
|||
|
Mathf.Abs(endPosition.z - startPosition.z)
|
|||
|
);
|
|||
|
|
|||
|
// 计算每个瓦片对应的世界大小
|
|||
|
float aspectRatio = (float)tileWidth / tileHeight;
|
|||
|
|
|||
|
// 根据重叠百分比调整实际覆盖区域
|
|||
|
float overlapFactor = 1f - (overlapPercent / 100f);
|
|||
|
|
|||
|
// 估算合适的瓦片世界大小
|
|||
|
tileWorldWidth = totalWorldSize.x / Mathf.Ceil(totalWorldSize.x / (totalWorldSize.x / 10f));
|
|||
|
tileWorldHeight = tileWorldWidth / aspectRatio;
|
|||
|
|
|||
|
// 计算网格数量
|
|||
|
gridWidth = Mathf.CeilToInt(totalWorldSize.x / (tileWorldWidth * overlapFactor));
|
|||
|
gridHeight = Mathf.CeilToInt(totalWorldSize.y / (tileWorldHeight * overlapFactor));
|
|||
|
|
|||
|
// 重新计算精确的瓦片世界大小
|
|||
|
tileWorldWidth = totalWorldSize.x / gridWidth;
|
|||
|
tileWorldHeight = totalWorldSize.y / gridHeight;
|
|||
|
|
|||
|
// 计算最终图片尺寸
|
|||
|
finalImageWidth = gridWidth * tileWidth;
|
|||
|
finalImageHeight = gridHeight * tileHeight;
|
|||
|
|
|||
|
// 重绘场景视图以更新网格预览
|
|||
|
SceneView.RepaintAll();
|
|||
|
}
|
|||
|
|
|||
|
void OnSceneGUI(SceneView sceneView)
|
|||
|
{
|
|||
|
if (!showGridPreview) return;
|
|||
|
|
|||
|
Handles.color = gridColor;
|
|||
|
|
|||
|
// 绘制整体区域边界
|
|||
|
Vector3 min = new Vector3(startPosition.x, cameraHeight, startPosition.z);
|
|||
|
Vector3 max = new Vector3(endPosition.x, cameraHeight, endPosition.z);
|
|||
|
|
|||
|
// 绘制外边框
|
|||
|
Handles.DrawLine(new Vector3(min.x, min.y, min.z), new Vector3(max.x, min.y, min.z));
|
|||
|
Handles.DrawLine(new Vector3(max.x, min.y, min.z), new Vector3(max.x, min.y, max.z));
|
|||
|
Handles.DrawLine(new Vector3(max.x, min.y, max.z), new Vector3(min.x, min.y, max.z));
|
|||
|
Handles.DrawLine(new Vector3(min.x, min.y, max.z), new Vector3(min.x, min.y, min.z));
|
|||
|
|
|||
|
// 绘制网格线
|
|||
|
for (int x = 1; x < gridWidth; x++)
|
|||
|
{
|
|||
|
float worldX = startPosition.x + (x * tileWorldWidth);
|
|||
|
Handles.DrawLine(
|
|||
|
new Vector3(worldX, cameraHeight, startPosition.z),
|
|||
|
new Vector3(worldX, cameraHeight, endPosition.z)
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
for (int z = 1; z < gridHeight; z++)
|
|||
|
{
|
|||
|
float worldZ = startPosition.z + (z * tileWorldHeight);
|
|||
|
Handles.DrawLine(
|
|||
|
new Vector3(startPosition.x, cameraHeight, worldZ),
|
|||
|
new Vector3(endPosition.x, cameraHeight, worldZ)
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
// 绘制瓦片中心点
|
|||
|
Handles.color = Color.red;
|
|||
|
for (int x = 0; x < gridWidth; x++)
|
|||
|
{
|
|||
|
for (int z = 0; z < gridHeight; z++)
|
|||
|
{
|
|||
|
Vector3 tileCenter = GetTileWorldPosition(x, z);
|
|||
|
Handles.DrawWireCube(tileCenter, Vector3.one * 2f);
|
|||
|
Handles.Label(tileCenter + Vector3.up * 5f, $"{x},{z}");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Vector3 GetTileWorldPosition(int gridX, int gridZ)
|
|||
|
{
|
|||
|
float worldX = startPosition.x + (gridX + 0.5f) * tileWorldWidth;
|
|||
|
float worldZ = startPosition.z + (gridZ + 0.5f) * tileWorldHeight;
|
|||
|
return new Vector3(worldX, cameraHeight, worldZ);
|
|||
|
}
|
|||
|
|
|||
|
void PreviewTilePosition(int gridX, int gridZ)
|
|||
|
{
|
|||
|
if (targetCamera == null) return;
|
|||
|
|
|||
|
Vector3 tileCenter = GetTileWorldPosition(gridX, gridZ);
|
|||
|
|
|||
|
// 移动场景视图到瓦片位置
|
|||
|
SceneView sceneView = SceneView.lastActiveSceneView;
|
|||
|
if (sceneView != null)
|
|||
|
{
|
|||
|
sceneView.pivot = tileCenter;
|
|||
|
sceneView.rotation = Quaternion.Euler(90, 0, 0);
|
|||
|
sceneView.size = Mathf.Max(tileWorldWidth, tileWorldHeight) / 2f;
|
|||
|
sceneView.orthographic = true;
|
|||
|
sceneView.Repaint();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void StartTiledScreenshot()
|
|||
|
{
|
|||
|
if (targetCamera == null)
|
|||
|
{
|
|||
|
EditorUtility.DisplayDialog("错误", "请先选择一个相机", "确定");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// 确保输出目录存在
|
|||
|
if (!Directory.Exists(outputPath))
|
|||
|
{
|
|||
|
Directory.CreateDirectory(outputPath);
|
|||
|
}
|
|||
|
|
|||
|
EditorCoroutineUtility.StartCoroutine(TakeScreenshotCoroutine(), this);
|
|||
|
}
|
|||
|
|
|||
|
IEnumerator TakeScreenshotCoroutine()
|
|||
|
{
|
|||
|
// 使用二维数组存储瓦片,保持空间位置关系
|
|||
|
Texture2D[,] tileTextures = new Texture2D[gridWidth, gridHeight];
|
|||
|
|
|||
|
// try
|
|||
|
{
|
|||
|
// 保存原始相机设置
|
|||
|
SaveOriginalCameraSettings();
|
|||
|
|
|||
|
// 设置相机为正交模式
|
|||
|
targetCamera.orthographic = true;
|
|||
|
targetCamera.transform.rotation = Quaternion.Euler(90, 0, 0);
|
|||
|
targetCamera.cullingMask = layerMask;
|
|||
|
targetCamera.orthographicSize = Mathf.Max(tileWorldWidth, tileWorldHeight) / 2f;
|
|||
|
targetCamera.nearClipPlane = 0.1f;
|
|||
|
targetCamera.farClipPlane = cameraHeight + 50f;
|
|||
|
|
|||
|
int totalTiles = gridWidth * gridHeight;
|
|||
|
int currentTile = 0;
|
|||
|
|
|||
|
// 逐个拍摄瓦片
|
|||
|
for (int z = 0; z < gridHeight; z++)
|
|||
|
{
|
|||
|
for (int x = 0; x < gridWidth; x++)
|
|||
|
{
|
|||
|
currentTile++;
|
|||
|
float progress = (float)currentTile / totalTiles;
|
|||
|
|
|||
|
if (EditorUtility.DisplayCancelableProgressBar(
|
|||
|
"分块截图中",
|
|||
|
$"正在截图瓦片 {currentTile}/{totalTiles} ({x},{z})",
|
|||
|
progress))
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// 移动相机到瓦片位置
|
|||
|
Vector3 tilePosition = GetTileWorldPosition(x, z);
|
|||
|
targetCamera.transform.position = tilePosition;
|
|||
|
|
|||
|
// 截图
|
|||
|
Texture2D tileTexture = CaptureScreenshot();
|
|||
|
if (tileTexture != null)
|
|||
|
{
|
|||
|
// 存储到对应位置
|
|||
|
tileTextures[x, z] = tileTexture;
|
|||
|
|
|||
|
// 如果需要保存单个瓦片
|
|||
|
if (saveIndividualTiles)
|
|||
|
{
|
|||
|
byte[] bytes = tileTexture.EncodeToPNG();
|
|||
|
string tilePath = Path.Combine(outputPath, $"{fileName}_tile_{x}_{z}.png");
|
|||
|
File.WriteAllBytes(tilePath, bytes);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
yield return null; // 等待一帧
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
EditorUtility.DisplayProgressBar("合成图片", "正在合成最终图片...", 1f);
|
|||
|
|
|||
|
// 合成最终图片
|
|||
|
Texture2D finalTexture = CombineTiles(tileTextures);
|
|||
|
if (finalTexture != null)
|
|||
|
{
|
|||
|
// 保存最终图片
|
|||
|
byte[] finalBytes = finalTexture.EncodeToPNG();
|
|||
|
string finalPath = Path.Combine(outputPath, $"{fileName}_{finalImageWidth}x{finalImageHeight}.png");
|
|||
|
File.WriteAllBytes(finalPath, finalBytes);
|
|||
|
|
|||
|
DestroyImmediate(finalTexture);
|
|||
|
|
|||
|
EditorUtility.DisplayDialog("成功",
|
|||
|
$"超大清晰地图已保存!\n" +
|
|||
|
$"文件: {finalPath}\n" +
|
|||
|
$"尺寸: {finalImageWidth}x{finalImageHeight}\n" +
|
|||
|
$"瓦片数: {totalTiles}", "确定");
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
// catch (System.Exception e)
|
|||
|
// {
|
|||
|
// EditorUtility.DisplayDialog("错误", $"截图失败: {e.Message}", "确定");
|
|||
|
// Debug.LogError($"分块截图失败: {e}");
|
|||
|
// }
|
|||
|
// finally
|
|||
|
{
|
|||
|
// 清理资源
|
|||
|
for (int x = 0; x < gridWidth; x++)
|
|||
|
{
|
|||
|
for (int z = 0; z < gridHeight; z++)
|
|||
|
{
|
|||
|
if (tileTextures[x, z] != null)
|
|||
|
DestroyImmediate(tileTextures[x, z]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RestoreOriginalCameraSettings();
|
|||
|
EditorUtility.ClearProgressBar();
|
|||
|
AssetDatabase.Refresh();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Texture2D CaptureScreenshot()
|
|||
|
{
|
|||
|
// 创建渲染纹理
|
|||
|
RenderTexture renderTexture = new RenderTexture(tileWidth, tileHeight, 24);
|
|||
|
renderTexture.antiAliasing = antiAliasing;
|
|||
|
renderTexture.Create();
|
|||
|
|
|||
|
// 渲染
|
|||
|
RenderTexture originalTarget = targetCamera.targetTexture;
|
|||
|
targetCamera.targetTexture = renderTexture;
|
|||
|
targetCamera.Render();
|
|||
|
|
|||
|
// 读取像素
|
|||
|
RenderTexture.active = renderTexture;
|
|||
|
Texture2D screenshot = new Texture2D(tileWidth, tileHeight, TextureFormat.RGB24, false);
|
|||
|
screenshot.ReadPixels(new Rect(0, 0, tileWidth, tileHeight), 0, 0);
|
|||
|
screenshot.Apply();
|
|||
|
|
|||
|
// 清理
|
|||
|
RenderTexture.active = null;
|
|||
|
targetCamera.targetTexture = originalTarget;
|
|||
|
renderTexture.Release();
|
|||
|
DestroyImmediate(renderTexture);
|
|||
|
|
|||
|
return screenshot;
|
|||
|
}
|
|||
|
|
|||
|
Texture2D CombineTiles(Texture2D[,] tiles)
|
|||
|
{
|
|||
|
Texture2D finalTexture = new Texture2D(finalImageWidth, finalImageHeight, TextureFormat.RGB24, false);
|
|||
|
|
|||
|
// 关键修复:不翻转Z轴,保持原始顺序
|
|||
|
for (int z = 0; z < gridHeight; z++)
|
|||
|
{
|
|||
|
for (int x = 0; x < gridWidth; x++)
|
|||
|
{
|
|||
|
Texture2D tile = tiles[x, z];
|
|||
|
if (tile == null) continue;
|
|||
|
|
|||
|
Color[] pixels = tile.GetPixels();
|
|||
|
|
|||
|
// 修复:直接映射,不进行Y轴翻转
|
|||
|
// 世界坐标系的Z=0对应纹理的Y=0(底部)
|
|||
|
// 世界坐标系的Z=max对应纹理的Y=max(顶部)
|
|||
|
int startX = x * tileWidth;
|
|||
|
int startY = z * tileHeight; // 移除翻转:直接使用z
|
|||
|
|
|||
|
finalTexture.SetPixels(startX, startY, tileWidth, tileHeight, pixels);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
finalTexture.Apply();
|
|||
|
return finalTexture;
|
|||
|
}
|
|||
|
|
|||
|
void SaveOriginalCameraSettings()
|
|||
|
{
|
|||
|
if (targetCamera == null) return;
|
|||
|
|
|||
|
originalCameraPosition = targetCamera.transform.position;
|
|||
|
originalCameraRotation = targetCamera.transform.rotation;
|
|||
|
originalOrthographic = targetCamera.orthographic;
|
|||
|
originalOrthographicSize = targetCamera.orthographicSize;
|
|||
|
originalCullingMask = targetCamera.cullingMask;
|
|||
|
}
|
|||
|
|
|||
|
void RestoreOriginalCameraSettings()
|
|||
|
{
|
|||
|
if (targetCamera == null) return;
|
|||
|
|
|||
|
targetCamera.transform.position = originalCameraPosition;
|
|||
|
targetCamera.transform.rotation = originalCameraRotation;
|
|||
|
targetCamera.orthographic = originalOrthographic;
|
|||
|
targetCamera.orthographicSize = originalOrthographicSize;
|
|||
|
targetCamera.cullingMask = originalCullingMask;
|
|||
|
}
|
|||
|
|
|||
|
void OnDestroy()
|
|||
|
{
|
|||
|
RestoreOriginalCameraSettings();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 编辑器协程工具类
|
|||
|
public static class EditorCoroutineUtility
|
|||
|
{
|
|||
|
public static EditorCoroutine StartCoroutine(IEnumerator routine, object owner)
|
|||
|
{
|
|||
|
return new EditorCoroutine(routine, owner);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class EditorCoroutine
|
|||
|
{
|
|||
|
private IEnumerator routine;
|
|||
|
private object owner;
|
|||
|
|
|||
|
public EditorCoroutine(IEnumerator routine, object owner)
|
|||
|
{
|
|||
|
this.routine = routine;
|
|||
|
this.owner = owner;
|
|||
|
EditorApplication.update += Update;
|
|||
|
}
|
|||
|
|
|||
|
void Update()
|
|||
|
{
|
|||
|
if (routine != null)
|
|||
|
{
|
|||
|
if (!routine.MoveNext())
|
|||
|
{
|
|||
|
EditorApplication.update -= Update;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
EditorApplication.update -= Update;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|