新增 FlowScope Git 包雏形
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "FlowScope.Editor",
|
||||
"rootNamespace": "FlowScope.Editor",
|
||||
"references": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3ee591f10b84cf7a39d50219698312e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.PackageManager;
|
||||
using UnityEditor.PackageManager.Requests;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FlowScope.Editor
|
||||
{
|
||||
public sealed class FlowScopeDiagnosticsWindow : EditorWindow
|
||||
{
|
||||
private const string PackageRuntimeAsmdefPath = "Packages/com.flowscope.gamecore/Runtime/FlowScope.Runtime.asmdef";
|
||||
private const string PackageAddressablesAsmdefPath = "Packages/com.flowscope.gamecore/Addressables/FlowScope.Addressables.asmdef";
|
||||
private const string AssetsRuntimeAsmdefPath = "Assets/FlowScope/Runtime/FlowScope.Runtime.asmdef";
|
||||
private const string AssetsAddressablesAsmdefPath = "Assets/FlowScope/Addressables/FlowScope.Addressables.asmdef";
|
||||
private const string AssetsMainMenuScenePath = "Assets/FlowScope/Samples/MainMenuP0/Scenes/MainMenuP0.unity";
|
||||
private const string AssetsMainMenuPanelPrefabPath = "Assets/FlowScope/Samples/MainMenuP0/Prefabs/MainMenuPanel.prefab";
|
||||
private const string AddressablesPackageName = "com.unity.addressables";
|
||||
|
||||
private static readonly IReadOnlyList<AssetCheck> AssetChecks = new[]
|
||||
{
|
||||
new AssetCheck("Runtime asmdef", PackageRuntimeAsmdefPath, AssetsRuntimeAsmdefPath),
|
||||
new AssetCheck("Addressables asmdef", PackageAddressablesAsmdefPath, AssetsAddressablesAsmdefPath),
|
||||
new AssetCheck("MainMenuP0 scene", AssetsMainMenuScenePath),
|
||||
new AssetCheck("MainMenuPanel prefab", AssetsMainMenuPanelPrefabPath),
|
||||
};
|
||||
|
||||
private readonly List<DiagnosticResult> _assetResults = new List<DiagnosticResult>();
|
||||
|
||||
private ListRequest _packageListRequest;
|
||||
private DiagnosticResult _addressablesPackageResult = DiagnosticResult.Pending(
|
||||
"Addressables package",
|
||||
"Package status has not been refreshed.");
|
||||
|
||||
private Vector2 _scrollPosition;
|
||||
|
||||
[MenuItem("Tools/FlowScope/Diagnostics")]
|
||||
public static void Open()
|
||||
{
|
||||
FlowScopeDiagnosticsWindow window = GetWindow<FlowScopeDiagnosticsWindow>("FlowScope Diagnostics");
|
||||
window.minSize = new Vector2(520f, 320f);
|
||||
window.RefreshAll();
|
||||
window.Show();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
RefreshAssetChecks();
|
||||
RefreshPackageStatus();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
EditorApplication.update -= PollPackageListRequest;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
using (new EditorGUILayout.VerticalScope())
|
||||
{
|
||||
EditorGUILayout.LabelField("FlowScope Diagnostics", EditorStyles.boldLabel);
|
||||
EditorGUILayout.HelpBox("Read-only diagnostics. This window checks project state and does not create, move, delete, or repair user assets.", MessageType.Info);
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
if (GUILayout.Button("Refresh", GUILayout.Width(96f)))
|
||||
{
|
||||
RefreshAll();
|
||||
}
|
||||
|
||||
GUILayout.Label(
|
||||
_packageListRequest != null && !_packageListRequest.IsCompleted
|
||||
? "Refreshing package status..."
|
||||
: "Package status is complete or has not been requested.",
|
||||
EditorStyles.miniLabel);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
|
||||
DrawResult(_addressablesPackageResult);
|
||||
|
||||
foreach (DiagnosticResult result in _assetResults)
|
||||
{
|
||||
DrawResult(result);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshAll()
|
||||
{
|
||||
RefreshAssetChecks();
|
||||
RefreshPackageStatus();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private void RefreshAssetChecks()
|
||||
{
|
||||
_assetResults.Clear();
|
||||
|
||||
foreach (AssetCheck check in AssetChecks)
|
||||
{
|
||||
string foundPath = FindExistingAssetPath(check.Paths);
|
||||
_assetResults.Add(foundPath != null
|
||||
? DiagnosticResult.Pass(check.Label, foundPath)
|
||||
: DiagnosticResult.Fail(check.Label, string.Join(" or ", check.Paths)));
|
||||
}
|
||||
}
|
||||
|
||||
private static string FindExistingAssetPath(IReadOnlyList<string> paths)
|
||||
{
|
||||
foreach (string path in paths)
|
||||
{
|
||||
if (AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path) != null)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void RefreshPackageStatus()
|
||||
{
|
||||
EditorApplication.update -= PollPackageListRequest;
|
||||
|
||||
_addressablesPackageResult = DiagnosticResult.Pending(
|
||||
"Addressables package",
|
||||
"Querying com.unity.addressables through Unity Package Manager.");
|
||||
|
||||
_packageListRequest = Client.List(true);
|
||||
EditorApplication.update += PollPackageListRequest;
|
||||
}
|
||||
|
||||
private void PollPackageListRequest()
|
||||
{
|
||||
if (_packageListRequest == null || !_packageListRequest.IsCompleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EditorApplication.update -= PollPackageListRequest;
|
||||
|
||||
if (_packageListRequest.Status == StatusCode.Success)
|
||||
{
|
||||
bool found = false;
|
||||
foreach (UnityEditor.PackageManager.PackageInfo packageInfo in _packageListRequest.Result)
|
||||
{
|
||||
if (string.Equals(packageInfo.name, AddressablesPackageName, StringComparison.Ordinal))
|
||||
{
|
||||
found = true;
|
||||
_addressablesPackageResult = DiagnosticResult.Pass(
|
||||
"Addressables package",
|
||||
packageInfo.name + " " + packageInfo.version);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
_addressablesPackageResult = DiagnosticResult.Fail(
|
||||
"Addressables package",
|
||||
"com.unity.addressables was not found in the current Package Manager list.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMessage = _packageListRequest.Error != null
|
||||
? _packageListRequest.Error.message
|
||||
: "Package Manager returned an unknown error.";
|
||||
_addressablesPackageResult = DiagnosticResult.Warning("Addressables package", errorMessage);
|
||||
}
|
||||
|
||||
_packageListRequest = null;
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private static void DrawResult(DiagnosticResult result)
|
||||
{
|
||||
MessageType messageType = ToMessageType(result.Status);
|
||||
|
||||
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
|
||||
{
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.Label(ToStatusText(result.Status), GUILayout.Width(72f));
|
||||
EditorGUILayout.LabelField(result.Label, EditorStyles.boldLabel);
|
||||
}
|
||||
|
||||
EditorGUILayout.HelpBox(result.Detail, messageType);
|
||||
}
|
||||
}
|
||||
|
||||
private static MessageType ToMessageType(DiagnosticStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case DiagnosticStatus.Pass:
|
||||
return MessageType.Info;
|
||||
case DiagnosticStatus.Fail:
|
||||
return MessageType.Error;
|
||||
case DiagnosticStatus.Warning:
|
||||
return MessageType.Warning;
|
||||
default:
|
||||
return MessageType.None;
|
||||
}
|
||||
}
|
||||
|
||||
private static string ToStatusText(DiagnosticStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case DiagnosticStatus.Pass:
|
||||
return "OK";
|
||||
case DiagnosticStatus.Fail:
|
||||
return "Missing";
|
||||
case DiagnosticStatus.Warning:
|
||||
return "Warning";
|
||||
default:
|
||||
return "Pending";
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct AssetCheck
|
||||
{
|
||||
public AssetCheck(string label, params string[] paths)
|
||||
{
|
||||
Label = label;
|
||||
Paths = paths;
|
||||
}
|
||||
|
||||
public string Label { get; }
|
||||
|
||||
public IReadOnlyList<string> Paths { get; }
|
||||
}
|
||||
|
||||
private readonly struct DiagnosticResult
|
||||
{
|
||||
private DiagnosticResult(DiagnosticStatus status, string label, string detail)
|
||||
{
|
||||
Status = status;
|
||||
Label = label;
|
||||
Detail = detail;
|
||||
}
|
||||
|
||||
public DiagnosticStatus Status { get; }
|
||||
|
||||
public string Label { get; }
|
||||
|
||||
public string Detail { get; }
|
||||
|
||||
public static DiagnosticResult Pass(string label, string detail)
|
||||
{
|
||||
return new DiagnosticResult(DiagnosticStatus.Pass, label, detail);
|
||||
}
|
||||
|
||||
public static DiagnosticResult Fail(string label, string detail)
|
||||
{
|
||||
return new DiagnosticResult(DiagnosticStatus.Fail, label, detail);
|
||||
}
|
||||
|
||||
public static DiagnosticResult Warning(string label, string detail)
|
||||
{
|
||||
return new DiagnosticResult(DiagnosticStatus.Warning, label, detail);
|
||||
}
|
||||
|
||||
public static DiagnosticResult Pending(string label, string detail)
|
||||
{
|
||||
return new DiagnosticResult(DiagnosticStatus.Pending, label, detail);
|
||||
}
|
||||
}
|
||||
|
||||
private enum DiagnosticStatus
|
||||
{
|
||||
Pending,
|
||||
Pass,
|
||||
Warning,
|
||||
Fail,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 599ef528ec0c4331a77311f6ef7ef56b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user