mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-11-12 00:58:16 +00:00
提交Unity 联机Pro
This commit is contained in:
101
JNFrame2/Assets/Plugins/SRDebugger/Scripts/Editor/ApiSignup.cs
Normal file
101
JNFrame2/Assets/Plugins/SRDebugger/Scripts/Editor/ApiSignup.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
#if !DISABLE_SRDEBUGGER
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Cache;
|
||||
using System.Text;
|
||||
using SRF;
|
||||
using UnityEngine;
|
||||
using SRDebugger.Internal;
|
||||
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
static class ApiSignup
|
||||
{
|
||||
public delegate void ApiSignupResultCallback(bool success, string apiKey, string email, string error);
|
||||
|
||||
public static void SignUp(string email, string invoiceNo, ApiSignupResultCallback resultCallback)
|
||||
{
|
||||
var requestData = new Hashtable();
|
||||
requestData["emailAddress"] = email;
|
||||
requestData["transactionNumber"] = invoiceNo;
|
||||
|
||||
try
|
||||
{
|
||||
var request = SendRequest(SRDebugApi.EndPoint + "/user/create", requestData, WebRequestMethods.Http.Post);
|
||||
|
||||
string result;
|
||||
|
||||
var didSucceed = SRDebugApiUtil.ReadResponse(request, out result);
|
||||
|
||||
if (didSucceed)
|
||||
{
|
||||
var jsonTable = (Dictionary<string, object>) Json.Deserialize(result);
|
||||
|
||||
resultCallback(true, (string) jsonTable["apiKey"], (string) jsonTable["emailAddress"], null);
|
||||
}
|
||||
else
|
||||
{
|
||||
resultCallback(false, null, null, SRDebugApiUtil.ParseErrorResponse(result));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
resultCallback(false, null, null, "Internal Error (" + e.Message + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public static string Verify(string apiKey)
|
||||
{
|
||||
var request = SendRequest(SRDebugApi.EndPoint + "/user/test", null, apiKey: apiKey);
|
||||
|
||||
string result;
|
||||
|
||||
SRDebugApiUtil.ReadResponse(request, out result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static HttpWebRequest SendRequest(string endpoint, Hashtable data,
|
||||
string method = WebRequestMethods.Http.Get, string apiKey = null)
|
||||
{
|
||||
var request = (HttpWebRequest) WebRequest.Create(endpoint);
|
||||
request.Timeout = 15000;
|
||||
request.Method = method;
|
||||
|
||||
request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.BypassCache);
|
||||
|
||||
request.ContentType = "application/json";
|
||||
request.Accept = "application/json";
|
||||
|
||||
if (!string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
request.Headers.Add("X-ApiKey", apiKey);
|
||||
}
|
||||
|
||||
request.KeepAlive = false;
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
var requestJson = Json.Serialize(data);
|
||||
|
||||
using (var requestStream = request.GetRequestStream())
|
||||
{
|
||||
using (var writer = new StreamWriter(requestStream, Encoding.UTF8))
|
||||
{
|
||||
writer.Write(requestJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c678ba20e05678942905f13f1f42c8e1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,42 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
class ApiSignupTermsWindow : EditorWindow
|
||||
{
|
||||
public static void Open()
|
||||
{
|
||||
GetWindowWithRect<ApiSignupTermsWindow>(new Rect(0, 0, 430, 345), true, "SRDebugger - Bug Reporter TOS",
|
||||
true);
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
GUILayout.Label("Terms and Conditions", SRInternalEditorUtil.Styles.HeaderLabel);
|
||||
|
||||
GUILayout.Label(
|
||||
"The Bug Reporter service is provided free of charge to owners of SRDebugger. One valid license key of SRDebugger allows one account to be registered. You must not share your API key with another party. Stompy Robot LTD reserves the right to terminate your bug reporter account if your API key is shared with another party.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
GUILayout.Label(
|
||||
"Stompy Robot LTD reserves the right to cancel the bug report service at any time without notice.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
GUILayout.Label(
|
||||
"By signing up for the Bug Reporter service you grant Stompy Robot LTD permission to gather non-identifying information from users when submitting reports. You attest that your users are aware of the data collection and give their consent.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
GUILayout.Label(
|
||||
"THE SERVICE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button("Close"))
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58b4c2d8acab3b747a2a90abd77b1132
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
abstract class IntegrityIssue
|
||||
{
|
||||
private readonly string _title;
|
||||
private readonly string _description;
|
||||
private List<Fix> _fixes;
|
||||
|
||||
public string Title
|
||||
{
|
||||
get { return _title; }
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get { return _description; }
|
||||
}
|
||||
|
||||
public IList<Fix> GetFixes()
|
||||
{
|
||||
if (_fixes == null)
|
||||
{
|
||||
_fixes = CreateFixes().ToList();
|
||||
}
|
||||
|
||||
return _fixes;
|
||||
}
|
||||
|
||||
protected IntegrityIssue(string title, string description)
|
||||
{
|
||||
_title = title;
|
||||
_description = description;
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<Fix> CreateFixes();
|
||||
}
|
||||
|
||||
abstract class Fix
|
||||
{
|
||||
private readonly string _name;
|
||||
private readonly string _description;
|
||||
private readonly bool _isAutoFix;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get { return _description; }
|
||||
}
|
||||
|
||||
public bool IsAutoFix
|
||||
{
|
||||
get { return _isAutoFix; }
|
||||
}
|
||||
|
||||
protected Fix(string name, string description, bool isAutoFix)
|
||||
{
|
||||
_name = name;
|
||||
_description = description;
|
||||
_isAutoFix = isAutoFix;
|
||||
}
|
||||
|
||||
public abstract void Execute();
|
||||
}
|
||||
|
||||
class DelegateFix : Fix
|
||||
{
|
||||
private readonly Action _fixMethod;
|
||||
|
||||
public DelegateFix(string name, string description, Action fixMethod) : base(name, description, true)
|
||||
{
|
||||
_fixMethod = fixMethod;
|
||||
}
|
||||
|
||||
public override void Execute()
|
||||
{
|
||||
_fixMethod();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fab9c606533743f6bfcb59f8392b1a0c
|
||||
timeCreated: 1611921984
|
||||
123
JNFrame2/Assets/Plugins/SRDebugger/Scripts/Editor/Migrations.cs
Normal file
123
JNFrame2/Assets/Plugins/SRDebugger/Scripts/Editor/Migrations.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using SRF;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
#pragma warning disable 162
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
static class Migrations
|
||||
{
|
||||
static Migrations()
|
||||
{
|
||||
RunMigrations();
|
||||
}
|
||||
|
||||
private const bool EnableLog = false;
|
||||
|
||||
public class Migration
|
||||
{
|
||||
public readonly string Id;
|
||||
public readonly string[] ObsoleteFiles;
|
||||
|
||||
public Migration(string id, string[] obsoleteFiles)
|
||||
{
|
||||
Id = id;
|
||||
ObsoleteFiles = obsoleteFiles;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Migration> AvailableMigrations = new List<Migration>()
|
||||
{
|
||||
new Migration("DeleteOldEditorResources", new[]
|
||||
{
|
||||
"Editor/Resources/SRDebugger/BG_Dark.png",
|
||||
"Editor/Resources/SRDebugger/BG_Light.png",
|
||||
"Editor/Resources/SRDebugger/DemoSprite.png",
|
||||
"Editor/Resources/SRDebugger/Logo_DarkBG.png",
|
||||
"Editor/Resources/SRDebugger/Logo_LightBG.png",
|
||||
"Editor/Resources/SRDebugger/WelcomeLogo_DarkBG.png",
|
||||
"Editor/Resources/SRDebugger/WelcomeLogo_LightBG.png",
|
||||
"Editor/Resources/SRDebugger/Icons/Dark/console-25.png",
|
||||
"Editor/Resources/SRDebugger/Icons/Dark/options-25.png",
|
||||
"Editor/Resources/SRDebugger/Icons/Dark/profiler-25.png",
|
||||
"Editor/Resources/SRDebugger/Icons/Light/console-25.png",
|
||||
"Editor/Resources/SRDebugger/Icons/Light/options-25.png",
|
||||
"Editor/Resources/SRDebugger/Icons/Light/profiler-25.png",
|
||||
})
|
||||
};
|
||||
|
||||
public static void RunMigrations(bool forceRun = false)
|
||||
{
|
||||
if(EnableLog)
|
||||
Debug.Log("[SRDebugger] Running Migrations...");
|
||||
|
||||
foreach (var m in AvailableMigrations)
|
||||
{
|
||||
var key = GetProjectPrefsKey(m.Id);
|
||||
|
||||
if (!forceRun && EditorPrefs.GetBool(key, false))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
EditorPrefs.SetBool(key, true);
|
||||
RunMigration(m);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RunMigration(Migration migration)
|
||||
{
|
||||
if (EnableLog)
|
||||
Debug.Log("Running Migration: " + migration.Id);
|
||||
|
||||
var assetPaths = AssetDatabase.GetAllAssetPaths();
|
||||
var root = new DirectoryInfo(SRInternalEditorUtil.GetRootPath());
|
||||
|
||||
if(EnableLog)
|
||||
Debug.Log("Using Root Path: " + root.FullName);
|
||||
|
||||
var obsoleteAssets = migration.ObsoleteFiles.Select(p => root + "/" + p).ToList();
|
||||
var deleteQueue = assetPaths.Where(assetPath => obsoleteAssets.Contains(assetPath)).ToList();
|
||||
|
||||
if (deleteQueue.Count == 0)
|
||||
return;
|
||||
|
||||
var message = "The following files used by a previous version of SRDebugger are obsolete and can be safely deleted: \n\n" +
|
||||
deleteQueue.Aggregate((s1, s2) => s1 + "\n" + s2);
|
||||
|
||||
Debug.Log(message);
|
||||
|
||||
message += "\n\nIt is recommended to delete these files.";
|
||||
|
||||
if (EditorUtility.DisplayDialog("SRDebugger Migration Assistant",
|
||||
message, "Delete Now", "Ignore"))
|
||||
{
|
||||
foreach (var s in deleteQueue)
|
||||
{
|
||||
Debug.Log("[SRDebugger] Deleting Asset {0}".Fmt(s));
|
||||
|
||||
if (!AssetDatabase.DeleteAsset(s))
|
||||
{
|
||||
Debug.LogWarning("[SRDebugger] Error deleting asset {0}".Fmt(s));
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log("[SRDebugger] Migration Complete");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("SRDebugger Migration Assitant",
|
||||
"You can run this migration check again via the \"Run Migrations\" button in the advanced tab of the SRDebugger settings window.", "OK");
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetProjectPrefsKey(string key)
|
||||
{
|
||||
return "SRDebugger_Migration_" + Application.dataPath + "_" + key;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b80f539792faff4187cbd7fb1113d67
|
||||
timeCreated: 1451840376
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,4 @@
|
||||
/*
|
||||
* This file has been deleted.
|
||||
* This empty file is left here to ensure it is properly overwritten when importing a new version of the package over an old version.
|
||||
*/
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c38092124e5b1114d9f037f64769dc5f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
public partial class SRDebugEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets compiler define <paramref name="define"/> to be enabled/disabled on all build targets.
|
||||
/// </summary>
|
||||
static void SetCompileDefine(string define, bool enabled)
|
||||
{
|
||||
foreach (BuildTargetGroup targetGroup in GetAllBuildTargetGroups())
|
||||
{
|
||||
// Use hash set to remove duplicates.
|
||||
List<string> defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup).Split(';').ToList();
|
||||
|
||||
bool alreadyExists = false;
|
||||
|
||||
for (var i = 0; i < defines.Count; i++)
|
||||
{
|
||||
if (string.Equals(define, defines[i], StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
alreadyExists = true;
|
||||
if (!enabled)
|
||||
{
|
||||
defines.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyExists && enabled)
|
||||
{
|
||||
defines.Add(define);
|
||||
}
|
||||
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup, string.Join(";", defines.ToArray()));
|
||||
}
|
||||
}
|
||||
static void ForceRecompile()
|
||||
{
|
||||
AssetDatabase.ImportAsset(SRInternalEditorUtil.GetAssetPath("StompyRobot.SRDebugger.asmdef"), ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
static IEnumerable<BuildTargetGroup> GetAllBuildTargetGroups()
|
||||
{
|
||||
Type enumType = typeof(BuildTargetGroup);
|
||||
string[] names = Enum.GetNames(enumType);
|
||||
Array values = Enum.GetValues(enumType);
|
||||
|
||||
for (var i = 0; i < names.Length; i++)
|
||||
{
|
||||
string name = names[i];
|
||||
BuildTargetGroup value = (BuildTargetGroup)values.GetValue(i);
|
||||
|
||||
if (value == BuildTargetGroup.Unknown) continue;
|
||||
|
||||
MemberInfo[] member = enumType.GetMember(name);
|
||||
MemberInfo entry = member.FirstOrDefault(p => p.DeclaringType == enumType);
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
Debug.LogErrorFormat(
|
||||
"[SRDebugger] Unhandled build target: {0}. SRDebugger disabled state may not be applied correctly to this platform.",
|
||||
name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.GetCustomAttributes(typeof(ObsoleteAttribute), true).Length != 0)
|
||||
{
|
||||
// obsolete, ignore.
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9adb2a4b8a61fe47ba3c6717de5f78b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
public partial class SRDebugEditor
|
||||
{
|
||||
internal const string DisabledDirectoryPostfix = "_DISABLED~";
|
||||
|
||||
// Paths to enable/disable (relative to SRDebugger root directory)
|
||||
private static readonly string[] _resourcePaths = new[]
|
||||
{
|
||||
"Resources",
|
||||
"usr",
|
||||
"UI/Prefabs"
|
||||
};
|
||||
|
||||
static void SetResourcesEnabled(bool enable)
|
||||
{
|
||||
AssetDatabase.StartAssetEditing();
|
||||
|
||||
foreach (ResourceDirectory d in GetResourcePaths())
|
||||
{
|
||||
d.SetDirectoryEnabled(enable);
|
||||
}
|
||||
|
||||
AssetDatabase.StopAssetEditing();
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
AssetDatabase.ImportAsset(SRInternalEditorUtil.GetRootPath(
|
||||
), ImportAssetOptions.ImportRecursive | ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
internal static IEnumerable<ResourceDirectory> GetResourcePaths()
|
||||
{
|
||||
foreach (string resourcePath in _resourcePaths)
|
||||
{
|
||||
string enabledPath = Path.Combine(SRInternalEditorUtil.GetRootPath(), resourcePath);
|
||||
string disabledPath = Path.Combine(SRInternalEditorUtil.GetRootPath(), resourcePath) + DisabledDirectoryPostfix;
|
||||
|
||||
yield return new ResourceDirectory(enabledPath, disabledPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class ResourceDirectory
|
||||
{
|
||||
public readonly string EnabledPath;
|
||||
public readonly string DisabledPath;
|
||||
|
||||
public readonly string EnabledPathMetaFile;
|
||||
public readonly string DisabledPathMetaFile;
|
||||
public readonly string DisabledPathBackupMetaFile;
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get { return Directory.Exists(EnabledPath); }
|
||||
}
|
||||
|
||||
public bool IsDisabled
|
||||
{
|
||||
get { return Directory.Exists(DisabledPath); }
|
||||
}
|
||||
|
||||
public ResourceDirectory(string enabledPath, string disabledPath)
|
||||
{
|
||||
EnabledPath = enabledPath;
|
||||
DisabledPath = disabledPath;
|
||||
|
||||
EnabledPathMetaFile = enabledPath + ".meta";
|
||||
DisabledPathMetaFile = disabledPath + ".meta";
|
||||
DisabledPathBackupMetaFile = disabledPath + ".meta.bak~";
|
||||
}
|
||||
|
||||
public void SetDirectoryEnabled(bool enable)
|
||||
{
|
||||
if (IsEnabled && enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsDisabled && !enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsEnabled && IsDisabled)
|
||||
{
|
||||
// TODO
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
string title = string.Format("SRDebugger - {0} Resources", enable ? "Enable" : "Disable");
|
||||
|
||||
string oldPath = enable ? DisabledPath : EnabledPath;
|
||||
string newPath = enable ? EnabledPath : DisabledPath;
|
||||
bool useAssetDatabase = !enable;
|
||||
|
||||
string error = null;
|
||||
|
||||
if (useAssetDatabase)
|
||||
{
|
||||
error = AssetDatabase.MoveAsset(oldPath, newPath);
|
||||
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog(title, GetErrorMessage(enable, error), "Force Move", "Abort"))
|
||||
{
|
||||
useAssetDatabase = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!useAssetDatabase)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Move(oldPath, newPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Error moving directory");
|
||||
Debug.LogException(e);
|
||||
error = "Exception occurred, see console for details.";
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
{
|
||||
string message = string.Format(
|
||||
"An error occurred while attempting to {3} SRDebugger resource directory.\n\n Old Path: {0}\n New Path: {1}\n\n Error: \n{2}",
|
||||
EnabledPath, DisabledPath, error, enable ? "enable" : "disable");
|
||||
|
||||
EditorUtility.DisplayDialog(title, message, "Continue");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enable)
|
||||
{
|
||||
// Disable meta files
|
||||
if (File.Exists(DisabledPathMetaFile))
|
||||
{
|
||||
if (File.Exists(DisabledPathBackupMetaFile))
|
||||
{
|
||||
File.Delete(DisabledPathBackupMetaFile);
|
||||
}
|
||||
|
||||
File.Move(DisabledPathMetaFile, DisabledPathBackupMetaFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enable backed up meta files
|
||||
if (File.Exists(DisabledPathBackupMetaFile))
|
||||
{
|
||||
if (File.Exists(EnabledPathMetaFile))
|
||||
{
|
||||
File.Delete(EnabledPathMetaFile);
|
||||
}
|
||||
|
||||
File.Move(DisabledPathBackupMetaFile, EnabledPathMetaFile);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private string GetErrorMessage(bool enable, string error)
|
||||
{
|
||||
return string.Format(
|
||||
"An error occurred while attempting to {3} SRDebugger resources. \n\n Old Path: {0}\n New Path: {1}\n\n Error: \n{2}",
|
||||
EnabledPath, DisabledPath, error, enable ? "enable" : "disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d6ba6f98fe1a9c4e8c082aa4aed6922
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,308 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
public static partial class SRDebugEditor
|
||||
{
|
||||
internal const string DisableSRDebuggerCompileDefine = "DISABLE_SRDEBUGGER";
|
||||
|
||||
/// <summary>
|
||||
/// Is SRDebugger currently enabled or disabled.
|
||||
/// </summary>
|
||||
public static readonly bool IsEnabled =
|
||||
#if DISABLE_SRDEBUGGER
|
||||
false
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
;
|
||||
|
||||
/// <summary>
|
||||
/// Set SRDebugger to be enabled or disabled.
|
||||
/// This is a synchronous operation, which means calling this as part of a build pipeline should be possible.
|
||||
/// </summary>
|
||||
/// <param name="enable"></param>
|
||||
public static void SetEnabled(bool enable)
|
||||
{
|
||||
if (EditorApplication.isPlaying || EditorApplication.isCompiling)
|
||||
{
|
||||
Debug.LogError(
|
||||
"[SRDebugger.SetEnabled] Can't change SRDebugger enabled state while in play mode or compiling scripts.");
|
||||
throw new InvalidOperationException(
|
||||
"Can't change SRDebugger enabled state while in play mode or compiling scripts.");
|
||||
}
|
||||
|
||||
#if !DISABLE_SRDEBUGGER
|
||||
AssetDatabase.SaveAssets(); // In case any pending changes to files about to be moved
|
||||
|
||||
// Try and unload the settings asset to prevent errors later (harmless error, but annoying)
|
||||
SRInternalEditorUtil.EditorSettings.ClearCache();
|
||||
GC.Collect();
|
||||
EditorUtility.UnloadUnusedAssetsImmediate(true);
|
||||
#endif
|
||||
|
||||
AssetDatabase.ReleaseCachedFileHandles();
|
||||
|
||||
SetCompileDefine(DisableSRDebuggerCompileDefine, !enable);
|
||||
SetResourcesEnabled(enable);
|
||||
|
||||
ForceRecompile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs through a series of integrity checks that are fast to perform.
|
||||
/// </summary>
|
||||
internal static IEnumerable<IntegrityIssue> QuickIntegrityCheck()
|
||||
{
|
||||
int enabledCount = 0;
|
||||
int disabledCount = 0;
|
||||
|
||||
foreach (ResourceDirectory directory in GetResourcePaths())
|
||||
{
|
||||
if (directory.IsEnabled && directory.IsDisabled)
|
||||
{
|
||||
yield return new SomeResourcesAreEnabledAndDisabledIntegrityIssue();
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (directory.IsEnabled) enabledCount++;
|
||||
if (directory.IsDisabled) disabledCount++;
|
||||
}
|
||||
|
||||
if (enabledCount > 0 && disabledCount > 0)
|
||||
{
|
||||
#if DISABLE_SRDEBUGGER
|
||||
yield return new SomeResourcesEnabledIntegrityIssue();
|
||||
#else
|
||||
yield return new SomeResourcesDisabledIntegrityIssue();
|
||||
#endif
|
||||
yield break; // Don't do any further resource-related checks.
|
||||
}
|
||||
|
||||
if (!IsEnabled && enabledCount > 0)
|
||||
{
|
||||
yield return new ScriptsDisabledButResourcesEnabled();
|
||||
}
|
||||
|
||||
if (IsEnabled && disabledCount > 0)
|
||||
{
|
||||
yield return new ScriptsEnabledButResourcesDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DrawDisabledWindowGui(ref bool isWorking)
|
||||
{
|
||||
SRInternalEditorUtil.BeginDrawBackground();
|
||||
SRInternalEditorUtil.DrawLogo(SRInternalEditorUtil.GetLogo());
|
||||
SRInternalEditorUtil.EndDrawBackground();
|
||||
|
||||
// Draw header/content divider
|
||||
EditorGUILayout.BeginVertical(SRInternalEditorUtil.Styles.SettingsHeaderBoxStyle);
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
GUILayout.Label("SRDebugger Disabled", SRInternalEditorUtil.Styles.InspectorHeaderStyle);
|
||||
|
||||
GUILayout.Label(
|
||||
"SRDebugger is currently disabled. SRDebugger must be enabled in order to access editor features.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
EditorGUILayout.HelpBox("Enabling SRDebugger will result in the tools being included in all builds of your game until it is disabled again.", MessageType.Warning);
|
||||
|
||||
GUILayout.Label("• "+ DisableSRDebuggerCompileDefine + " compiler define will be removed from all build configurations.", SRInternalEditorUtil.Styles.ListBulletPoint);
|
||||
GUILayout.Label("• Disabled SRDebugger folders will be renamed so Unity imports them.", SRInternalEditorUtil.Styles.ListBulletPoint);
|
||||
GUILayout.Label("• You can disable SRDebugger again at any time.", SRInternalEditorUtil.Styles.ListBulletPoint);
|
||||
|
||||
if (isWorking && !EditorApplication.isCompiling && !EditorApplication.isUpdating)
|
||||
{
|
||||
isWorking = false;
|
||||
}
|
||||
|
||||
if (isWorking)
|
||||
{
|
||||
using (new EditorGUI.DisabledGroupScope(true))
|
||||
{
|
||||
GUILayout.Button("Working...");
|
||||
}
|
||||
}
|
||||
else if (GUILayout.Button("Enable SRDebugger"))
|
||||
{
|
||||
isWorking = true;
|
||||
try
|
||||
{
|
||||
SetEnabled(true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
isWorking = false;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DISABLE_SRDEBUGGER
|
||||
class SomeResourcesEnabledIntegrityIssue : IntegrityIssue
|
||||
{
|
||||
private new const string Title = "Some SRDebugger resources are enabled.";
|
||||
|
||||
private new const string Description =
|
||||
"SRDebugger is disabled, but some SRDebugger resource directories are enabled. \n\n" +
|
||||
"This can occur if an unhandled error occurs while SRDebugger is being enabled or disabled, or if the resource directories are modified by hand.";
|
||||
|
||||
public SomeResourcesEnabledIntegrityIssue() : base(Title, Description)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override IEnumerable<Fix> CreateFixes()
|
||||
{
|
||||
yield return new DelegateFix(
|
||||
"Disable all SRDebugger resources",
|
||||
"All resource directories will be disabled.",
|
||||
() => { SetResourcesEnabled(false); });
|
||||
yield return new DelegateFix(
|
||||
"Enable SRDebugger",
|
||||
"Fully enable SRDebugger (activate scripts and enable resources).",
|
||||
() => { SetEnabled(true); });
|
||||
}
|
||||
}
|
||||
#else
|
||||
class SomeResourcesDisabledIntegrityIssue : IntegrityIssue
|
||||
{
|
||||
private new const string Title = "Some SRDebugger resources are disabled.";
|
||||
|
||||
private new const string Description =
|
||||
"SRDebugger is enabled, but some SRDebugger resource directories are disabled. \n\n" +
|
||||
"This can occur if an unhandled error occurs while SRDebugger is being enabled or disabled, or if the resource directories are modified by hand.";
|
||||
|
||||
public SomeResourcesDisabledIntegrityIssue() : base(Title, Description)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override IEnumerable<Fix> CreateFixes()
|
||||
{
|
||||
yield return new DelegateFix(
|
||||
"Enable all SRDebugger resources",
|
||||
"All resource directories will be enabled.",
|
||||
() => { SetResourcesEnabled(true); });
|
||||
|
||||
yield return new DelegateFix(
|
||||
"Disable SRDebugger",
|
||||
"Fully disable SRDebugger (deactivate scripts, exclude all resources from builds of your game).",
|
||||
() => { SetEnabled(false); });
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
class SomeResourcesAreEnabledAndDisabledIntegrityIssue : IntegrityIssue
|
||||
{
|
||||
private new const string Title = "Duplicate SRDebugger resource directories";
|
||||
|
||||
private new const string Description =
|
||||
"Some SRDebugger resource directories exist in both an enabled and disabled state. \n\n" +
|
||||
"This can occur if a new version of SRDebugger is installed while SRDebugger is disabled, or if an unhandled error occurs while SRDebugger is being enabled/disabled.";
|
||||
|
||||
public SomeResourcesAreEnabledAndDisabledIntegrityIssue() : base(Title, Description)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override IEnumerable<Fix> CreateFixes()
|
||||
{
|
||||
if (!IsEnabled)
|
||||
{
|
||||
var deletePaths = GetResourcePaths().Where(p => p.IsDisabled && p.IsEnabled).ToList();
|
||||
string paths = " - " + string.Join("\n - ", deletePaths
|
||||
.SelectMany(p => new string[] { p.DisabledPath, p.DisabledPathBackupMetaFile }).ToArray());
|
||||
|
||||
yield return new DelegateFix(
|
||||
"Keep enabled resources, disable SRDebugger",
|
||||
"If you have just installed a new version of SRDebugger, this will keep the most up-to-date resources from the imported package. SRDebugger will be disabled after the old resources are deleted. \n\n The following paths will be deleted: \n\n" + paths,
|
||||
() =>
|
||||
{
|
||||
foreach (ResourceDirectory rd in GetResourcePaths())
|
||||
{
|
||||
if (rd.IsEnabled && rd.IsDisabled)
|
||||
{
|
||||
Debug.Log("[SRDebugger] Delete Path: " + rd.DisabledPath);
|
||||
Directory.Delete(rd.DisabledPath, true);
|
||||
|
||||
Debug.Log("[SRDebugger] Delete File: " + rd.DisabledPathBackupMetaFile);
|
||||
File.Delete(rd.DisabledPathBackupMetaFile);
|
||||
}
|
||||
}
|
||||
|
||||
SetEnabled(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptsDisabledButResourcesEnabled : IntegrityIssue
|
||||
{
|
||||
private new const string Title = "SRDebugger resources are enabled while scripts are disabled";
|
||||
|
||||
private new const string Description =
|
||||
"SRDebugger's resources directories are enabled, but SRDebugger scripts are disabled. \n" +
|
||||
"This can occur if the resource directories or if the C# compile defines are modified manually.";
|
||||
|
||||
public ScriptsDisabledButResourcesEnabled() : base(Title, Description)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<Fix> CreateFixes()
|
||||
{
|
||||
yield return new DelegateFix(
|
||||
"Enable SRDebugger scripts",
|
||||
"Remove compiler define (" + DisableSRDebuggerCompileDefine + ") SRDebugger can be disabled again from the settings menu.",
|
||||
() =>
|
||||
{
|
||||
SetCompileDefine(DisableSRDebuggerCompileDefine, false);
|
||||
});
|
||||
yield return new DelegateFix(
|
||||
"Disable SRDebugger resources",
|
||||
"Resources will no longer be included in builds of your game (you can enable SRDebugger from the settings menu later)",
|
||||
() =>
|
||||
{
|
||||
SetResourcesEnabled(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptsEnabledButResourcesDisabled : IntegrityIssue
|
||||
{
|
||||
private new const string Title = "SRDebugger scripts are enabled while resources are disabled.";
|
||||
|
||||
private new const string Description =
|
||||
"SRDebugger resources directories are disabled, but SRDebugger scripts are still enabled. \n" +
|
||||
"This can occur if the resource directories or C# compile defines are modified manually.";
|
||||
|
||||
public ScriptsEnabledButResourcesDisabled() : base(Title, Description)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<Fix> CreateFixes()
|
||||
{
|
||||
yield return new DelegateFix(
|
||||
"Disable SRDebugger scripts",
|
||||
"Add compiler define (" + DisableSRDebuggerCompileDefine + ") to disable SRDebugger scripts (you can re-enable SRDebugger from the settings menu later)",
|
||||
() =>
|
||||
{
|
||||
SetCompileDefine(DisableSRDebuggerCompileDefine, true);
|
||||
});
|
||||
yield return new DelegateFix(
|
||||
"Enable SRDebugger resources",
|
||||
"Resources will be included in builds of your game (you can disable SRDebugger from the settings menu later)",
|
||||
() =>
|
||||
{
|
||||
SetResourcesEnabled(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca60d3f1302b47e1a3c6f43ed06dedcf
|
||||
timeCreated: 1611413144
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
static class SRDebugEditorPaths
|
||||
{
|
||||
public const string EditorLogoPath = "UI/Sprites/Default/Logo.psd";
|
||||
|
||||
public const string SettingsMenuItemPath = "Window/SRDebugger/Settings Window";
|
||||
public const string WelcomeItemPath = "Window/SRDebugger/Welcome Guide";
|
||||
public const string SROptionsMenuItemPath = "Window/SRDebugger/SROptions Window";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6eeabd6854ed440ab38998300a297c0b
|
||||
timeCreated: 1611414784
|
||||
@@ -0,0 +1,43 @@
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
class SRDebugEditorStrings
|
||||
{
|
||||
public static readonly SRDebugEditorStrings Current = new SRDebugEditorStrings();
|
||||
|
||||
public readonly string SettingsIsEnabledTooltip =
|
||||
"If false, SRDebugger.Init prefab will not load SRDebugger. Manual calls to SRDebug.Instance.ShowDebugPanel() will still work.";
|
||||
|
||||
public readonly string SettingsAutoLoadTooltip =
|
||||
"Automatically load SRDebugger when the game loads, even if SRDebugger.Init prefab is not present.";
|
||||
|
||||
public readonly string SettingsDefaultTabTooltip =
|
||||
"Visible tab when panel is first opened.";
|
||||
|
||||
public readonly string SettingsKeyboardShortcutsTooltip =
|
||||
"Enable Keyboard Shortcuts";
|
||||
|
||||
public readonly string SettingsCloseOnEscapeTooltip =
|
||||
"Close debug panel when Escape is pressed.";
|
||||
|
||||
public readonly string SettingsKeyboardModifersTooltip =
|
||||
"Modifier keys that must be held for keyboard shortcuts to execute.";
|
||||
|
||||
public readonly string SettingsDebugCameraTooltip =
|
||||
"UI will render to a camera instead of overlaying the entire scene.";
|
||||
|
||||
public readonly string SettingsRateBoxContents =
|
||||
"If you like SRDebugger, please consider leaving a rating on the Asset Store.";
|
||||
|
||||
public readonly string SettingsWebSiteUrl = "https://www.stompyrobot.uk/tools/srdebugger";
|
||||
|
||||
public readonly string SettingsAssetStoreUrl = "http://u3d.as/aZc";
|
||||
|
||||
public readonly string SettingsDocumentationUrl = "https://www.stompyrobot.uk/tools/srdebugger/documentation";
|
||||
|
||||
public readonly string SettingsSupportUrl =
|
||||
"http://forum.unity3d.com/threads/srdebugger-debug-and-tweak-your-game-while-on-device-released.296403/";
|
||||
|
||||
public readonly string SettingsEnabledTabsDescription =
|
||||
"Deselect any tabs that you do not wish to be available in the debug panel.";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd05741ba3454346864f3c28fcdce56f
|
||||
timeCreated: 1611414505
|
||||
@@ -0,0 +1,183 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
class SRIntegrityCheckWindow : EditorWindow
|
||||
{
|
||||
private List<IntegrityIssue> _results;
|
||||
private Vector2 _scrollPosition;
|
||||
|
||||
private bool _applyingFix;
|
||||
private static bool _isOpen;
|
||||
|
||||
static SRIntegrityCheckWindow()
|
||||
{
|
||||
// Delay call to prevent any UI stalls after compile complete.
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
if (!_isOpen && SRDebugEditor.QuickIntegrityCheck().Any())
|
||||
{
|
||||
Debug.Log("[SRDebugger] Some issues have been detected with SRDebugger, opening integrity check window.");
|
||||
Open();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void Open()
|
||||
{
|
||||
var window = GetWindow<SRIntegrityCheckWindow>(true, "SRDebugger Integrity Check", true);
|
||||
window.minSize = new Vector2(640, 400);
|
||||
window.Show();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_isOpen = true;
|
||||
RefreshIntegrityCheck();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_isOpen = false;
|
||||
}
|
||||
|
||||
public void RefreshIntegrityCheck()
|
||||
{
|
||||
_results = SRDebugEditor.QuickIntegrityCheck().ToList();
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
// Draw header area
|
||||
SRInternalEditorUtil.BeginDrawBackground();
|
||||
SRInternalEditorUtil.DrawLogo(SRInternalEditorUtil.GetLogo());
|
||||
SRInternalEditorUtil.EndDrawBackground();
|
||||
|
||||
// Draw header/content divider
|
||||
EditorGUILayout.BeginVertical(SRInternalEditorUtil.Styles.SettingsHeaderBoxStyle);
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
GUILayout.Label(
|
||||
"SRDebugger automatically scans your project to find common issues with the SRDebugger installation.");
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// TODO: Enable button when there are some more 'expensive' integrity checks. For now no point as alt the checks are really quick
|
||||
if (GUILayout.Button("Refresh"))
|
||||
{
|
||||
RefreshIntegrityCheck();
|
||||
}
|
||||
|
||||
if (_applyingFix)
|
||||
{
|
||||
if (!EditorApplication.isCompiling && !EditorApplication.isUpdating)
|
||||
{
|
||||
_applyingFix = false;
|
||||
RefreshIntegrityCheck();
|
||||
}
|
||||
|
||||
EditorGUI.BeginDisabledGroup(_applyingFix);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (_results == null)
|
||||
{
|
||||
_results = new List<IntegrityIssue>();
|
||||
}
|
||||
|
||||
EditorGUILayout.TextArea("Issues Detected: " + _results.Count, EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (_results.Count == 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("No issues have been found!", MessageType.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("It is highly recommended to backup your project before using this tool.", MessageType.Warning);
|
||||
|
||||
_scrollPosition = GUILayout.BeginScrollView(_scrollPosition, false, false,
|
||||
GUILayout.Width(position.width));
|
||||
|
||||
DrawIssuesList();
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
}
|
||||
|
||||
if (_applyingFix)
|
||||
{
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawIssuesList()
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
for (var i = 0; i < _results.Count; i++)
|
||||
{
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
|
||||
GUILayout.Label(_results[i].Title, EditorStyles.boldLabel);
|
||||
GUILayout.Label(_results[i].Description, SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
var fixes = _results[i].GetFixes();
|
||||
if (fixes.Count > 0)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
GUILayout.Label("Possible Fixes:", EditorStyles.miniBoldLabel);
|
||||
|
||||
foreach (Fix fix in fixes)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
GUILayout.Space(10);
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
GUILayout.Label(fix.Name, EditorStyles.boldLabel);
|
||||
|
||||
GUILayout.Label(fix.Description, SRInternalEditorUtil.Styles.ParagraphLabelItalic);
|
||||
|
||||
if (fix.IsAutoFix && GUILayout.Button("Apply Fix", GUILayout.Width(90)))
|
||||
{
|
||||
fix.Execute();
|
||||
_applyingFix = true;
|
||||
}
|
||||
|
||||
GUILayout.Space(2);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d3667acfb91436880aa7f35bcc5fe43
|
||||
timeCreated: 1611919957
|
||||
@@ -0,0 +1,707 @@
|
||||
using SRF;
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
static class SRInternalEditorUtil
|
||||
{
|
||||
// Path to this file from the root path
|
||||
private const string TestPath = "SRDebugger/README.txt";
|
||||
|
||||
private static GUIStyle _bgStyle;
|
||||
private static Texture2D _logoTexture;
|
||||
private static Texture2D _welcomeLogoTexture;
|
||||
private static Texture2D _bgTexture;
|
||||
private static GUIStyle _middleAlign;
|
||||
|
||||
/// <summary>
|
||||
/// Finds the path to the SRDebugger installation folder (e.g. Assets/StompyRobot/SRDebugger)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetRootPath()
|
||||
{
|
||||
// Find assets that match this file name
|
||||
var potentialAssets = AssetDatabase.FindAssets("README");
|
||||
|
||||
foreach (var potentialAsset in potentialAssets)
|
||||
{
|
||||
var path = AssetDatabase.GUIDToAssetPath(potentialAsset);
|
||||
|
||||
if (path.Contains(TestPath))
|
||||
{
|
||||
var rootPath = Path.GetDirectoryName(path);
|
||||
return rootPath;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("Unable to find SRDebugger root path. Please ensure the README file in StompyRobot/SRDebugger still exists.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the path to an SRDebugger asset relative to the installation root.
|
||||
/// </summary>
|
||||
/// <param name="relativeToRoot"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetAssetPath(string relativeToRoot)
|
||||
{
|
||||
if (!relativeToRoot.StartsWith("/"))
|
||||
{
|
||||
relativeToRoot = "/" + relativeToRoot;
|
||||
}
|
||||
|
||||
var p = GetRootPath() + relativeToRoot;
|
||||
return p;
|
||||
}
|
||||
|
||||
public static T LoadResource<T>(string path) where T : UnityEngine.Object
|
||||
{
|
||||
var p = GetAssetPath(path);
|
||||
//Debug.Log("[SRDebugger] Loading " + p);
|
||||
var asset = AssetDatabase.LoadAssetAtPath(p, typeof(T));
|
||||
return asset as T;
|
||||
}
|
||||
|
||||
|
||||
#if !DISABLE_SRDEBUGGER
|
||||
|
||||
public enum SettingsResult
|
||||
{
|
||||
Cache,
|
||||
Loaded,
|
||||
Waiting,
|
||||
Error
|
||||
}
|
||||
|
||||
public static class EditorSettings
|
||||
{
|
||||
internal const string SettingsFilePath = "/usr/Resources/SRDebugger/Settings.asset";
|
||||
|
||||
internal const string DisabledSettingsFilePath = "/usr" + SRDebugEditor.DisabledDirectoryPostfix + "/Resources/SRDebugger/Settings.asset";
|
||||
|
||||
private static Settings _instance;
|
||||
|
||||
public static SettingsResult TryGetOrCreate(out Settings instance, out string message)
|
||||
{
|
||||
if (_instance != null)
|
||||
{
|
||||
instance = _instance;
|
||||
message = string.Empty;
|
||||
return SettingsResult.Cache;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SettingsResult result = InternalTryGetOrCreateSettings(out _instance, out message);
|
||||
instance = _instance;
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
instance = null;
|
||||
message = e.ToString();
|
||||
return SettingsResult.Error;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearCache()
|
||||
{
|
||||
Settings.ClearCache(); // Just in case runtime settings are loaded.
|
||||
|
||||
if (_instance == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var instance = _instance;
|
||||
_instance = null;
|
||||
|
||||
Resources.UnloadAsset(instance);
|
||||
instance = null;
|
||||
GC.Collect();
|
||||
|
||||
EditorUtility.UnloadUnusedAssetsImmediate();
|
||||
Resources.UnloadUnusedAssets();
|
||||
}
|
||||
|
||||
private static SettingsResult InternalTryGetOrCreateSettings(out Settings instance, out string message)
|
||||
{
|
||||
instance = null;
|
||||
message = null;
|
||||
|
||||
if (EditorApplication.isPlaying || EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
message = "Settings can only be modified while in edit-mode. Exit play mode to make changes to SRDebugger settings.";
|
||||
return SettingsResult.Waiting;
|
||||
}
|
||||
|
||||
// If compiling, wait for that to finish. We might be disabling/enabling SRDebugger and don't want to recreate the settings while that is in progress.
|
||||
if (EditorApplication.isCompiling || EditorApplication.isUpdating)
|
||||
{
|
||||
message = "Waiting for Unity to finish compiling/updating...";
|
||||
return SettingsResult.Waiting;
|
||||
}
|
||||
|
||||
// Check if there is a 'disabled' settings file, we don't want to create a new settings file if a disabled one exists.
|
||||
string disabledSettingsFile = SRInternalEditorUtil.GetAssetPath(DisabledSettingsFilePath);
|
||||
if (File.Exists(disabledSettingsFile))
|
||||
{
|
||||
message = "A settings file already exists but is disabled. Please ensure SRDebugger is correctly enabled or disabled.";
|
||||
return SettingsResult.Error;
|
||||
}
|
||||
|
||||
// Get resources folder path
|
||||
var settingsAssetPath = SRInternalEditorUtil.GetAssetPath(SettingsFilePath);
|
||||
|
||||
// Load existing asset.
|
||||
if (File.Exists(settingsAssetPath))
|
||||
{
|
||||
instance = AssetDatabase.LoadAssetAtPath<Settings>(settingsAssetPath);
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
message = "Error loading settings asset.";
|
||||
return SettingsResult.Error;
|
||||
}
|
||||
|
||||
return SettingsResult.Loaded;
|
||||
}
|
||||
|
||||
Debug.Log("[SRDebugger] Creating settings asset at {0}".Fmt(settingsAssetPath));
|
||||
|
||||
instance = ScriptableObject.CreateInstance<Settings>();
|
||||
|
||||
string containingDirectory = Path.GetDirectoryName(settingsAssetPath);
|
||||
if (containingDirectory == null)
|
||||
{
|
||||
message = "Error finding target settings directory.";
|
||||
return SettingsResult.Error;
|
||||
}
|
||||
|
||||
// Create directory if it doesn't exist
|
||||
Directory.CreateDirectory(containingDirectory);
|
||||
|
||||
// Save instance if in editor
|
||||
AssetDatabase.CreateAsset(instance, settingsAssetPath);
|
||||
|
||||
return SettingsResult.Loaded;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public static Texture2D GetLogo()
|
||||
{
|
||||
if (_logoTexture != null)
|
||||
{
|
||||
return _logoTexture;
|
||||
}
|
||||
|
||||
return
|
||||
_logoTexture =
|
||||
LoadResource<Texture2D>("Editor/Logo_" + (EditorGUIUtility.isProSkin ? "DarkBG" : "LightBG") +
|
||||
".png");
|
||||
}
|
||||
|
||||
public static Texture2D GetWelcomeLogo()
|
||||
{
|
||||
if (_welcomeLogoTexture != null)
|
||||
{
|
||||
return _welcomeLogoTexture;
|
||||
}
|
||||
|
||||
return
|
||||
_welcomeLogoTexture =
|
||||
LoadResource<Texture2D>("Editor/WelcomeLogo_" +
|
||||
(EditorGUIUtility.isProSkin ? "DarkBG" : "LightBG") + ".png");
|
||||
}
|
||||
|
||||
public static Texture2D GetBackground()
|
||||
{
|
||||
if (_bgTexture != null)
|
||||
{
|
||||
return _bgTexture;
|
||||
}
|
||||
|
||||
return
|
||||
_bgTexture =
|
||||
LoadResource<Texture2D>("Editor/BG_" + (EditorGUIUtility.isProSkin ? "Dark" : "Light") + ".png");
|
||||
}
|
||||
|
||||
public static void DrawLogo(Texture2D logo)
|
||||
{
|
||||
if (logo == null)
|
||||
{
|
||||
Debug.LogError("Error loading SRDebugger logo");
|
||||
return;
|
||||
}
|
||||
|
||||
#if !DISABLE_SRDEBUGGER
|
||||
var rect =
|
||||
#endif
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
GUILayout.Space(15);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUI.DrawTexture(
|
||||
GUILayoutUtility.GetRect(logo.width, logo.width, logo.height, logo.height, GUILayout.ExpandHeight(false),
|
||||
GUILayout.ExpandWidth(false)),
|
||||
logo);
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(15);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
#if !DISABLE_SRDEBUGGER
|
||||
var size = EditorStyles.miniLabel.CalcSize(new GUIContent(SRDebug.Version));
|
||||
GUI.Label(new Rect(rect.xMax - size.x, rect.yMax - size.y, size.x, size.y), SRDebug.Version,
|
||||
EditorStyles.miniLabel);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool DrawInspectorFoldout(bool isVisible, string content)
|
||||
{
|
||||
isVisible = EditorGUILayout.Foldout(isVisible, content, Styles.InspectorHeaderFoldoutStyle);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
return isVisible;
|
||||
}
|
||||
|
||||
public static void BeginDrawBackground()
|
||||
{
|
||||
if (_bgStyle == null)
|
||||
{
|
||||
_bgStyle = new GUIStyle();
|
||||
_bgStyle.margin = _bgStyle.padding = new RectOffset(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
var rect = EditorGUILayout.BeginVertical(_bgStyle);
|
||||
|
||||
DrawTextureTiled(rect, GetBackground());
|
||||
}
|
||||
|
||||
public static void EndDrawBackground()
|
||||
{
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
public static void DrawTextureTiled(Rect rect, Texture2D tex)
|
||||
{
|
||||
GUI.BeginGroup(rect);
|
||||
|
||||
var tilesX = Mathf.Max(1, Mathf.CeilToInt(rect.width / tex.width));
|
||||
var tilesY = Mathf.Max(1, Mathf.CeilToInt(rect.height / tex.height));
|
||||
|
||||
for (var x = 0; x < tilesX; x++)
|
||||
{
|
||||
for (var y = 0; y < tilesY; y++)
|
||||
{
|
||||
var pos = new Rect(x * tex.width, y * tex.height, tex.width, tex.height);
|
||||
pos.x += rect.x;
|
||||
pos.y += rect.y;
|
||||
|
||||
GUI.DrawTexture(pos, tex, ScaleMode.ScaleAndCrop);
|
||||
}
|
||||
}
|
||||
|
||||
GUI.EndGroup();
|
||||
}
|
||||
|
||||
public static bool ClickableLabel(string text, GUIStyle style)
|
||||
{
|
||||
var rect = EditorGUILayout.BeginVertical(Styles.NoPaddingNoMargin);
|
||||
|
||||
GUILayout.Label(text, style);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
if (Event.current.type == EventType.MouseUp && rect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !DISABLE_SRDEBUGGER
|
||||
public static void DrawLayoutPreview(Rect rect, Settings settings)
|
||||
{
|
||||
const int profilerWidth = 120;
|
||||
const int profilerHeight = 70;
|
||||
const int optionsWidth = 150;
|
||||
const int optionsHeight = 36;
|
||||
|
||||
if (_middleAlign == null)
|
||||
{
|
||||
_middleAlign = new GUIStyle(EditorStyles.helpBox);
|
||||
_middleAlign.alignment = TextAnchor.MiddleCenter;
|
||||
}
|
||||
|
||||
var iconPath = "Editor/Icons/" + (EditorGUIUtility.isProSkin ? "Light" : "Dark");
|
||||
|
||||
const float consoleHeight = 90;
|
||||
|
||||
GUI.Box(rect, "", EditorStyles.helpBox);
|
||||
|
||||
var consoleAlignment = settings.ConsoleAlignment;
|
||||
|
||||
var consoleRect = new Rect(rect.x,
|
||||
consoleAlignment == ConsoleAlignment.Top ? rect.y : rect.yMax - consoleHeight, rect.width,
|
||||
consoleHeight);
|
||||
|
||||
GUI.Box(consoleRect, new GUIContent(LoadResource<Texture2D>(iconPath + "/console-25.png"), "Console"),
|
||||
_middleAlign);
|
||||
|
||||
var workRect = rect;
|
||||
|
||||
if (consoleAlignment == ConsoleAlignment.Top)
|
||||
{
|
||||
workRect.yMin += consoleHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
workRect.yMax -= consoleHeight;
|
||||
}
|
||||
|
||||
var opAlignment = settings.OptionsAlignment;
|
||||
var proAlignment = settings.ProfilerAlignment;
|
||||
|
||||
GUI.Box(GetAlignedRect(profilerWidth, profilerHeight, proAlignment, workRect),
|
||||
new GUIContent(LoadResource<Texture2D>(iconPath + "/profiler-25.png"), "Profiler"), _middleAlign);
|
||||
|
||||
var optionsRect = workRect;
|
||||
|
||||
if ((opAlignment == PinAlignment.TopCenter && proAlignment == PinAlignment.TopLeft) || (opAlignment == PinAlignment.BottomCenter && proAlignment == PinAlignment.BottomLeft))
|
||||
{
|
||||
optionsRect.x += profilerWidth;
|
||||
optionsRect.width -= profilerWidth;
|
||||
}
|
||||
else if ((opAlignment == PinAlignment.TopCenter && proAlignment == PinAlignment.TopRight) ||
|
||||
opAlignment == PinAlignment.BottomCenter && proAlignment == PinAlignment.BottomRight)
|
||||
{
|
||||
optionsRect.width -= profilerWidth;
|
||||
}
|
||||
|
||||
GUI.Box(GetAlignedRect(optionsWidth, optionsHeight, opAlignment, optionsRect),
|
||||
new GUIContent(LoadResource<Texture2D>(iconPath + "/options-25.png"), "Pinned Options"), _middleAlign);
|
||||
|
||||
if (settings.EnableTrigger != Settings.TriggerEnableModes.Off)
|
||||
{
|
||||
GUI.Box(GetAlignedRect(25, 25, settings.TriggerPosition, rect),
|
||||
new GUIContent("", "Entry Trigger"),
|
||||
_middleAlign);
|
||||
}
|
||||
}
|
||||
|
||||
private static Rect GetAlignedRect(int width, int height, PinAlignment alignment, Rect workRect)
|
||||
{
|
||||
var rect = new Rect(0, 0, width, height);
|
||||
|
||||
if (alignment == PinAlignment.BottomLeft || alignment == PinAlignment.BottomRight || alignment == PinAlignment.BottomCenter)
|
||||
{
|
||||
rect.position = new Vector2(0, workRect.height - rect.height);
|
||||
}
|
||||
else if (alignment == PinAlignment.CenterLeft || alignment == PinAlignment.CenterRight)
|
||||
{
|
||||
rect.position = new Vector2(0, workRect.height / 2 - rect.height / 2);
|
||||
}
|
||||
|
||||
if (alignment == PinAlignment.TopRight || alignment == PinAlignment.BottomRight || alignment == PinAlignment.CenterRight)
|
||||
{
|
||||
rect.position += new Vector2(workRect.width - rect.width, 0);
|
||||
}
|
||||
else if (alignment == PinAlignment.TopCenter || alignment == PinAlignment.BottomCenter)
|
||||
{
|
||||
rect.position += new Vector2(workRect.width / 2 - rect.width / 2, 0);
|
||||
}
|
||||
|
||||
rect.position += workRect.position;
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
#endif
|
||||
public static void RenderGif(Rect pos, Texture2D map, int frameNo, int frameWidth, int frameHeight, int perLine,
|
||||
int paddingX = 0, int paddingY = 0)
|
||||
{
|
||||
var x = frameNo % perLine;
|
||||
var y = Mathf.FloorToInt((float)frameNo / perLine);
|
||||
|
||||
var xCoord = x * (frameWidth + paddingX);
|
||||
var yCoord = (y + 1) * (frameHeight + paddingY);
|
||||
|
||||
var texCoords = new Rect(
|
||||
xCoord / (float)map.width,
|
||||
(map.height - yCoord) / (float)map.height,
|
||||
(frameWidth) / (float)map.width,
|
||||
(frameHeight) / (float)map.height);
|
||||
|
||||
GUI.DrawTextureWithTexCoords(pos, map, texCoords);
|
||||
|
||||
//Debug.Log(texCoords);
|
||||
//Debug.Log("x: " + x + ", y: " + y);
|
||||
}
|
||||
|
||||
public static void DrawFooterLayout(float width)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
var margin = (EditorStyles.miniButton.padding.left) / 2f;
|
||||
width = width - margin * 2;
|
||||
|
||||
if (GUILayout.Button("Web Site", GUILayout.Width(width / 2f - margin)))
|
||||
{
|
||||
Application.OpenURL(SRDebugEditorStrings.Current.SettingsWebSiteUrl);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Asset Store Page", GUILayout.Width(width / 2f - margin)))
|
||||
{
|
||||
Application.OpenURL(SRDebugEditorStrings.Current.SettingsAssetStoreUrl);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
if (GUILayout.Button("Documentation", GUILayout.Width(width / 2f - margin)))
|
||||
{
|
||||
Application.OpenURL(SRDebugEditorStrings.Current.SettingsDocumentationUrl);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Support", GUILayout.Width(width / 2f - margin)))
|
||||
{
|
||||
Application.OpenURL(
|
||||
SRDebugEditorStrings.Current.SettingsSupportUrl);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public static class Styles
|
||||
{
|
||||
private static GUIStyle _inspectorHeaderStyle;
|
||||
private static GUIStyle _inspectorHeaderFoldoutStyle;
|
||||
private static GUIStyle _settingsHeaderBoxStyle;
|
||||
private static GUIStyle _headerLabel;
|
||||
private static GUIStyle _paragraphLabel;
|
||||
private static GUIStyle _paragraphLabelItalic;
|
||||
private static GUIStyle _radioButtonDescription;
|
||||
private static GUIStyle _radioButton;
|
||||
private static GUIStyle _leftToggleButton;
|
||||
private static GUIStyle _noPaddingNoMargin;
|
||||
private static GUIStyle _richTextLabel;
|
||||
private static GUIStyle _listBulletPoint;
|
||||
|
||||
public static string LinkColour
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
{
|
||||
return "#7C8CB9";
|
||||
}
|
||||
|
||||
return "#0032E6";
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle InspectorHeaderStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_inspectorHeaderStyle == null)
|
||||
{
|
||||
_inspectorHeaderStyle = new GUIStyle(EditorStyles.boldLabel);
|
||||
_inspectorHeaderStyle.fontSize = 12;
|
||||
}
|
||||
|
||||
return _inspectorHeaderStyle;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle InspectorHeaderFoldoutStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_inspectorHeaderFoldoutStyle == null)
|
||||
{
|
||||
_inspectorHeaderFoldoutStyle = new GUIStyle(EditorStyles.foldout);
|
||||
_inspectorHeaderFoldoutStyle.fontSize = 12;
|
||||
_inspectorHeaderFoldoutStyle.fontStyle = FontStyle.Bold;
|
||||
}
|
||||
|
||||
return _inspectorHeaderFoldoutStyle;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle SettingsHeaderBoxStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_settingsHeaderBoxStyle == null)
|
||||
{
|
||||
_settingsHeaderBoxStyle = new GUIStyle("OL Title");
|
||||
_settingsHeaderBoxStyle.padding = new RectOffset(0, 0, 0, 0);
|
||||
_settingsHeaderBoxStyle.margin = new RectOffset(0, 0, 0, 0);
|
||||
_settingsHeaderBoxStyle.clipping = TextClipping.Clip;
|
||||
_settingsHeaderBoxStyle.overflow = new RectOffset(0, 0, 0, 0);
|
||||
//_settingsHeaderBoxStyle.border = new RectOffset(1, 1, 1, 1);
|
||||
_settingsHeaderBoxStyle.fixedHeight = 0.5f;
|
||||
}
|
||||
|
||||
return _settingsHeaderBoxStyle;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle HeaderLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_headerLabel == null)
|
||||
{
|
||||
_headerLabel = new GUIStyle(EditorStyles.largeLabel);
|
||||
_headerLabel.fontSize = 18;
|
||||
_headerLabel.fontStyle = FontStyle.Normal;
|
||||
_headerLabel.margin = new RectOffset(5, 5, 5, 5);
|
||||
}
|
||||
|
||||
return _headerLabel;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle ParagraphLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_paragraphLabel == null)
|
||||
{
|
||||
_paragraphLabel = new GUIStyle(EditorStyles.label);
|
||||
_paragraphLabel.margin = new RectOffset(5, 5, 5, 5);
|
||||
_paragraphLabel.wordWrap = true;
|
||||
_paragraphLabel.richText = true;
|
||||
}
|
||||
|
||||
return _paragraphLabel;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle ParagraphLabelItalic
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_paragraphLabelItalic == null)
|
||||
{
|
||||
_paragraphLabelItalic = new GUIStyle(EditorStyles.label);
|
||||
_paragraphLabelItalic.margin = new RectOffset(5, 5, 5, 5);
|
||||
_paragraphLabelItalic.wordWrap = true;
|
||||
_paragraphLabelItalic.richText = true;
|
||||
_paragraphLabelItalic.fontStyle = FontStyle.Italic;
|
||||
}
|
||||
|
||||
return _paragraphLabelItalic;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle LeftToggleButton
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_leftToggleButton == null)
|
||||
{
|
||||
_leftToggleButton = new GUIStyle(EditorStyles.label);
|
||||
_leftToggleButton.contentOffset = new Vector2(_leftToggleButton.contentOffset.x + 5,
|
||||
_leftToggleButton.contentOffset.y);
|
||||
}
|
||||
|
||||
return _leftToggleButton;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle RadioButton
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_radioButton == null)
|
||||
{
|
||||
_radioButton = new GUIStyle(EditorStyles.radioButton);
|
||||
_radioButton.contentOffset = new Vector2(_radioButton.contentOffset.x + 5,
|
||||
_radioButton.contentOffset.y);
|
||||
}
|
||||
|
||||
return _radioButton;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle RadioButtonDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_radioButtonDescription == null)
|
||||
{
|
||||
_radioButtonDescription = new GUIStyle(ParagraphLabel);
|
||||
_radioButtonDescription.padding.left = (int)RadioButton.contentOffset.x +
|
||||
RadioButton.padding.left;
|
||||
}
|
||||
|
||||
return _radioButtonDescription;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle NoPaddingNoMargin
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_noPaddingNoMargin == null)
|
||||
{
|
||||
_noPaddingNoMargin = new GUIStyle();
|
||||
_noPaddingNoMargin.margin = new RectOffset(0, 0, 0, 0);
|
||||
_noPaddingNoMargin.padding = new RectOffset(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
return _noPaddingNoMargin;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle RichTextLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_richTextLabel == null)
|
||||
{
|
||||
_richTextLabel = new GUIStyle(EditorStyles.label);
|
||||
_richTextLabel.richText = true;
|
||||
_richTextLabel.margin = new RectOffset(2, 2, 0, 0);
|
||||
}
|
||||
|
||||
return _richTextLabel;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIStyle ListBulletPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_listBulletPoint == null)
|
||||
{
|
||||
_listBulletPoint = new GUIStyle(EditorStyles.miniBoldLabel);
|
||||
_listBulletPoint.wordWrap = true;
|
||||
_listBulletPoint.margin = new RectOffset(6, 2, 0, 0);
|
||||
}
|
||||
|
||||
return _listBulletPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f05cd73b58c9481593f90b04c3084b15
|
||||
timeCreated: 1611414371
|
||||
@@ -0,0 +1,455 @@
|
||||
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SRF;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.ComponentModel;
|
||||
using SRF.Helpers;
|
||||
#if !DISABLE_SRDEBUGGER
|
||||
using Internal;
|
||||
using SRDebugger.Services;
|
||||
using UI.Controls.Data;
|
||||
#endif
|
||||
|
||||
class SROptionsWindow : EditorWindow
|
||||
{
|
||||
[MenuItem(SRDebugEditorPaths.SROptionsMenuItemPath)]
|
||||
public static void Open()
|
||||
{
|
||||
var window = GetWindow<SROptionsWindow>(false, "SROptions", true);
|
||||
window.minSize = new Vector2(100, 100);
|
||||
window.Show();
|
||||
}
|
||||
|
||||
#if DISABLE_SRDEBUGGER
|
||||
private bool _isWorking;
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
SRDebugEditor.DrawDisabledWindowGui(ref _isWorking);
|
||||
}
|
||||
#else
|
||||
[Serializable]
|
||||
private class CategoryState
|
||||
{
|
||||
public string Name;
|
||||
public bool IsOpen;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private List<CategoryState> _categoryStates = new List<CategoryState>();
|
||||
|
||||
private Dictionary<Type, Action<OptionDefinition>> _typeLookup;
|
||||
private Dictionary<string, List<OptionDefinition>> _options;
|
||||
|
||||
private Vector2 _scrollPosition;
|
||||
private bool _queueRefresh;
|
||||
private bool _isDirty;
|
||||
|
||||
|
||||
[NonSerialized] private GUIStyle _divider;
|
||||
[NonSerialized] private GUIStyle _foldout;
|
||||
|
||||
private IOptionsService _activeOptionsService;
|
||||
|
||||
public void OnInspectorUpdate()
|
||||
{
|
||||
if (EditorApplication.isPlaying && (_options == null || _isDirty))
|
||||
{
|
||||
Populate();
|
||||
_queueRefresh = true;
|
||||
_isDirty = false;
|
||||
}
|
||||
else if (!EditorApplication.isPlaying && _options != null)
|
||||
{
|
||||
Clear();
|
||||
_queueRefresh = true;
|
||||
}
|
||||
|
||||
if (_queueRefresh)
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
|
||||
_queueRefresh = false;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void PopulateTypeLookup()
|
||||
{
|
||||
_typeLookup = new Dictionary<Type, Action<OptionDefinition>>()
|
||||
{
|
||||
{typeof(int), OnGUI_Int},
|
||||
{typeof(float), OnGUI_Float},
|
||||
{typeof(double), OnGUI_Double},
|
||||
{typeof(string), OnGUI_String},
|
||||
{typeof(bool), OnGUI_Boolean },
|
||||
{typeof(uint), OnGUI_AnyInteger},
|
||||
{typeof(ushort), OnGUI_AnyInteger},
|
||||
{typeof(short), OnGUI_AnyInteger},
|
||||
{typeof(sbyte), OnGUI_AnyInteger},
|
||||
{typeof(byte), OnGUI_AnyInteger},
|
||||
{typeof(long), OnGUI_AnyInteger},
|
||||
};
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
_options = null;
|
||||
_isDirty = false;
|
||||
|
||||
if (_activeOptionsService != null)
|
||||
{
|
||||
_activeOptionsService.OptionsUpdated -= OnOptionsUpdated;
|
||||
}
|
||||
|
||||
_activeOptionsService = null;
|
||||
}
|
||||
|
||||
void Populate()
|
||||
{
|
||||
if (_typeLookup == null)
|
||||
{
|
||||
PopulateTypeLookup();
|
||||
}
|
||||
|
||||
if (_activeOptionsService != null)
|
||||
{
|
||||
_activeOptionsService.OptionsUpdated -= OnOptionsUpdated;
|
||||
}
|
||||
|
||||
if (_options != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, List<OptionDefinition>> kv in _options)
|
||||
{
|
||||
foreach (var option in kv.Value)
|
||||
{
|
||||
if (option.IsProperty)
|
||||
{
|
||||
option.Property.ValueChanged -= OnOptionPropertyValueChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_options = new Dictionary<string, List<OptionDefinition>>();
|
||||
|
||||
foreach (var option in Service.Options.Options)
|
||||
{
|
||||
List<OptionDefinition> list;
|
||||
|
||||
if (!_options.TryGetValue(option.Category, out list))
|
||||
{
|
||||
list = new List<OptionDefinition>();
|
||||
_options[option.Category] = list;
|
||||
}
|
||||
|
||||
list.Add(option);
|
||||
|
||||
if (option.IsProperty)
|
||||
{
|
||||
option.Property.ValueChanged += OnOptionPropertyValueChanged;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var kv in _options)
|
||||
{
|
||||
kv.Value.Sort((d1, d2) => d1.SortPriority.CompareTo(d2.SortPriority));
|
||||
}
|
||||
|
||||
_activeOptionsService = Service.Options;
|
||||
_activeOptionsService.OptionsUpdated += OnOptionsUpdated;
|
||||
}
|
||||
|
||||
private void OnOptionPropertyValueChanged(PropertyReference property)
|
||||
{
|
||||
_queueRefresh = true;
|
||||
}
|
||||
|
||||
private void OnOptionsUpdated(object sender, EventArgs e)
|
||||
{
|
||||
_isDirty = true;
|
||||
_queueRefresh = true;
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (!EditorApplication.isPlayingOrWillChangePlaymode || _options == null)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label("SROptions can only be edited in play-mode.");
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_divider == null)
|
||||
{
|
||||
_divider = new GUIStyle(GUI.skin.box);
|
||||
_divider.stretchWidth = true;
|
||||
_divider.fixedHeight = 2;
|
||||
}
|
||||
|
||||
if (_foldout == null)
|
||||
{
|
||||
_foldout = new GUIStyle(EditorStyles.foldout);
|
||||
_foldout.fontStyle = FontStyle.Bold;
|
||||
}
|
||||
|
||||
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
|
||||
|
||||
foreach (var kv in _options)
|
||||
{
|
||||
var state = _categoryStates.FirstOrDefault(p => p.Name == kv.Key);
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
state = new CategoryState()
|
||||
{
|
||||
Name = kv.Key,
|
||||
IsOpen = true
|
||||
};
|
||||
_categoryStates.Add(state);
|
||||
}
|
||||
|
||||
state.IsOpen = EditorGUILayout.Foldout(state.IsOpen, kv.Key, _foldout);
|
||||
|
||||
if (!state.IsOpen)
|
||||
continue;
|
||||
|
||||
EditorGUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins);
|
||||
OnGUI_Category(kv.Value);
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
void OnGUI_Category(List<OptionDefinition> options)
|
||||
{
|
||||
for (var i = 0; i < options.Count; i++)
|
||||
{
|
||||
var op = options[i];
|
||||
|
||||
if (op.Property != null)
|
||||
{
|
||||
OnGUI_Property(op);
|
||||
} else if (op.Method != null)
|
||||
{
|
||||
OnGUI_Method(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_Method(OptionDefinition op)
|
||||
{
|
||||
if (GUILayout.Button(op.Name))
|
||||
{
|
||||
op.Method.Invoke(null);
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_Property(OptionDefinition op)
|
||||
{
|
||||
Action<OptionDefinition> method;
|
||||
|
||||
if (op.Property.PropertyType.IsEnum)
|
||||
{
|
||||
method = OnGUI_Enum;
|
||||
}
|
||||
else if (!_typeLookup.TryGetValue(op.Property.PropertyType, out method))
|
||||
{
|
||||
OnGUI_Unsupported(op);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!op.Property.CanWrite)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
}
|
||||
|
||||
method(op);
|
||||
|
||||
if (!op.Property.CanWrite)
|
||||
{
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_String(OptionDefinition op)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var newValue = EditorGUILayout.TextField(op.Name, (string) op.Property.GetValue());
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
op.Property.SetValue(Convert.ChangeType(newValue, op.Property.PropertyType));
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_Boolean(OptionDefinition op)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var newValue = EditorGUILayout.Toggle(op.Name, (bool) op.Property.GetValue());
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
op.Property.SetValue(Convert.ChangeType(newValue, op.Property.PropertyType));
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_Enum(OptionDefinition op)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var newValue = EditorGUILayout.EnumPopup(op.Name, (Enum)op.Property.GetValue());
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
op.Property.SetValue(Convert.ChangeType(newValue, op.Property.PropertyType));
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_Int(OptionDefinition op)
|
||||
{
|
||||
var range = op.Property.GetAttribute<NumberRangeAttribute>();
|
||||
|
||||
int newValue;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
if (range != null)
|
||||
{
|
||||
newValue = EditorGUILayout.IntSlider(op.Name, (int)op.Property.GetValue(), (int)range.Min, (int)range.Max);
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = EditorGUILayout.IntField(op.Name, (int) op.Property.GetValue());
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
op.Property.SetValue(Convert.ChangeType(newValue, op.Property.PropertyType));
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_Float(OptionDefinition op)
|
||||
{
|
||||
var range = op.Property.GetAttribute<NumberRangeAttribute>();
|
||||
|
||||
float newValue;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
if (range != null)
|
||||
{
|
||||
newValue = EditorGUILayout.Slider(op.Name, (float)op.Property.GetValue(), (float)range.Min, (float)range.Max);
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = EditorGUILayout.FloatField(op.Name, (float) op.Property.GetValue());
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
op.Property.SetValue(Convert.ChangeType(newValue, op.Property.PropertyType));
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_Double(OptionDefinition op)
|
||||
{
|
||||
var range = op.Property.GetAttribute<NumberRangeAttribute>();
|
||||
|
||||
double newValue;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
if (range != null && range.Min > float.MinValue && range.Max < float.MaxValue)
|
||||
{
|
||||
newValue = EditorGUILayout.Slider(op.Name, (float)op.Property.GetValue(), (float)range.Min, (float)range.Max);
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = EditorGUILayout.DoubleField(op.Name, (double) op.Property.GetValue());
|
||||
|
||||
if (range != null)
|
||||
{
|
||||
if (newValue > range.Max)
|
||||
{
|
||||
newValue = range.Max;
|
||||
} else if (newValue < range.Min)
|
||||
{
|
||||
newValue = range.Min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
op.Property.SetValue(Convert.ChangeType(newValue, op.Property.PropertyType));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnGUI_AnyInteger(OptionDefinition op)
|
||||
{
|
||||
NumberControl.ValueRange range;
|
||||
|
||||
if (!NumberControl.ValueRanges.TryGetValue(op.Property.PropertyType, out range))
|
||||
{
|
||||
Debug.LogError("Unknown integer type: " + op.Property.PropertyType);
|
||||
return;
|
||||
}
|
||||
|
||||
var userRange = op.Property.GetAttribute<NumberRangeAttribute>();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var oldValue = (long)Convert.ChangeType(op.Property.GetValue(), typeof(long));
|
||||
var newValue = EditorGUILayout.LongField(op.Name, oldValue);
|
||||
|
||||
if (newValue > range.MaxValue)
|
||||
{
|
||||
newValue = (long)range.MaxValue;
|
||||
} else if (newValue < range.MinValue)
|
||||
{
|
||||
newValue = (long)range.MinValue;
|
||||
}
|
||||
|
||||
if (userRange != null)
|
||||
{
|
||||
if (newValue > userRange.Max)
|
||||
{
|
||||
newValue = (long)userRange.Max;
|
||||
} else if (newValue < userRange.Min)
|
||||
{
|
||||
newValue = (long) userRange.Min;
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
op.Property.SetValue(Convert.ChangeType(newValue, op.Property.PropertyType));
|
||||
}
|
||||
}
|
||||
|
||||
void OnGUI_Unsupported(OptionDefinition op)
|
||||
{
|
||||
EditorGUILayout.PrefixLabel(op.Name);
|
||||
EditorGUILayout.LabelField("Unsupported Type: {0}".Fmt(op.Property.PropertyType));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c10ec5c3e9f1e404ba655cbc07340b94
|
||||
timeCreated: 1465649914
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
#if !DISABLE_SRDEBUGGER
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
[CustomEditor(typeof (Settings))]
|
||||
class SettingsEditor : UnityEditor.Editor
|
||||
{
|
||||
private bool _override;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
SRInternalEditorUtil.DrawLogo(SRInternalEditorUtil.GetLogo());
|
||||
|
||||
GUILayout.Label(
|
||||
"This asset contains the runtime settings used by SRDebugger. It is recommended that this asset be edited only via the SRDebugger Settings window.",
|
||||
EditorStyles.wordWrappedLabel);
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (GUILayout.Button("Open SRDebugger Settings Window"))
|
||||
{
|
||||
SRDebuggerSettingsWindow.Open();
|
||||
}
|
||||
|
||||
if (!_override)
|
||||
{
|
||||
if (GUILayout.Button("Override Warning"))
|
||||
{
|
||||
_override = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label(
|
||||
"You have been warned...",
|
||||
EditorStyles.wordWrappedLabel);
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (_override)
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6304f38f53dfcc44f9265410f0f14050
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
1026
JNFrame2/Assets/Plugins/SRDebugger/Scripts/Editor/SettingsWindow.cs
Normal file
1026
JNFrame2/Assets/Plugins/SRDebugger/Scripts/Editor/SettingsWindow.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a6cf957f3eda7b429dd0eae2cfbb40c
|
||||
timeCreated: 1441902550
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "StompyRobot.SRDebugger.Editor",
|
||||
"references": [
|
||||
"StompyRobot.SRDebugger",
|
||||
"StompyRobot.SRF"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07ab30a82c1032d45ad726f7216628e8
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,194 @@
|
||||
#if !DISABLE_SRDEBUGGER
|
||||
using SRF;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRDebugger.Editor
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
class WelcomeWindow : EditorWindow
|
||||
{
|
||||
private const string WelcomeWindowPlayerPrefsKey = "SRDEBUGGER_WELCOME_SHOWN_VERSION";
|
||||
private Texture2D _demoSprite;
|
||||
private Vector2 _scrollPosition;
|
||||
|
||||
static WelcomeWindow()
|
||||
{
|
||||
EditorApplication.update += OpenUpdate;
|
||||
}
|
||||
|
||||
private static void OpenUpdate()
|
||||
{
|
||||
if (ShouldOpen())
|
||||
{
|
||||
Open();
|
||||
}
|
||||
|
||||
EditorApplication.update -= OpenUpdate;
|
||||
}
|
||||
|
||||
[MenuItem(SRDebugEditorPaths.WelcomeItemPath)]
|
||||
public static void Open()
|
||||
{
|
||||
GetWindowWithRect<WelcomeWindow>(new Rect(0, 0, 449, 500), true, "SRDebugger - Welcome", true);
|
||||
}
|
||||
|
||||
private static bool ShouldOpen()
|
||||
{
|
||||
var settings = Settings.GetInstance();
|
||||
if (settings != null)
|
||||
{
|
||||
if (settings.DisableWelcomePopup)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var hasKey = EditorPrefs.HasKey(WelcomeWindowPlayerPrefsKey);
|
||||
|
||||
if (!hasKey)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var value = EditorPrefs.GetString(WelcomeWindowPlayerPrefsKey);
|
||||
|
||||
if (value != SRDebug.Version)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
EditorPrefs.SetString(WelcomeWindowPlayerPrefsKey, SRDebug.Version);
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
// Draw header area
|
||||
SRInternalEditorUtil.BeginDrawBackground();
|
||||
SRInternalEditorUtil.DrawLogo(SRInternalEditorUtil.GetWelcomeLogo());
|
||||
SRInternalEditorUtil.EndDrawBackground();
|
||||
|
||||
// Draw header/content divider
|
||||
EditorGUILayout.BeginVertical(SRInternalEditorUtil.Styles.SettingsHeaderBoxStyle);
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
|
||||
|
||||
GUILayout.Label("Welcome", SRInternalEditorUtil.Styles.HeaderLabel);
|
||||
|
||||
GUILayout.Label(
|
||||
"Thank you for purchasing SRDebugger, your support is very much appreciated and we hope you find it useful for your project. " +
|
||||
"This window contains a quick guide to get to help get you started with SRDebugger.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
if (SRInternalEditorUtil.ClickableLabel(
|
||||
"Note: For more detailed information <color={0}>click here</color> to visit the online documentation."
|
||||
.Fmt(SRInternalEditorUtil.Styles.LinkColour),
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel))
|
||||
{
|
||||
Application.OpenURL(SRDebugEditorStrings.Current.SettingsDocumentationUrl);
|
||||
}
|
||||
|
||||
GUILayout.Label("Quick Start", SRInternalEditorUtil.Styles.HeaderLabel);
|
||||
GUILayout.Label(
|
||||
"Now that you have imported the package, you should find the trigger available in the top-left of your game window when in play mode. " +
|
||||
"Triple-clicking this trigger will bring up the debug panel. The trigger is hidden until clicked.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
GUILayout.Label(
|
||||
"By default, SRDebugger loads automatically when your game starts. " +
|
||||
"You can change this behaviour from the SRDebugger Settings window.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
DrawVideo();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
GUILayout.Label("Customization", SRInternalEditorUtil.Styles.HeaderLabel);
|
||||
|
||||
if (SRInternalEditorUtil.ClickableLabel(
|
||||
"Many features of SRDebugger can be configured from the <color={0}>SRDebugger Settings</color> window."
|
||||
.Fmt(
|
||||
SRInternalEditorUtil.Styles.LinkColour), SRInternalEditorUtil.Styles.ParagraphLabel))
|
||||
{
|
||||
SRDebuggerSettingsWindow.Open();
|
||||
}
|
||||
|
||||
GUILayout.Label(
|
||||
"From the settings window you can configure loading behaviour, trigger position, docked tools layout, and more. " +
|
||||
"You can enable the bug reporter service by using the sign-up form to get a free API key.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
GUILayout.Label("What Next?", SRInternalEditorUtil.Styles.HeaderLabel);
|
||||
|
||||
if (SRInternalEditorUtil.ClickableLabel(
|
||||
"For more detailed information about SRDebugger's features or details about the Options Tab and script API, check the <color={0}>online documentation</color>."
|
||||
.Fmt(SRInternalEditorUtil.Styles.LinkColour), SRInternalEditorUtil.Styles.ParagraphLabel))
|
||||
{
|
||||
Application.OpenURL(SRDebugEditorStrings.Current.SettingsDocumentationUrl);
|
||||
}
|
||||
|
||||
GUILayout.Label(
|
||||
"Thanks again for purchasing SRDebugger. " +
|
||||
"If you find it useful please consider leaving a rating or review on the Asset Store page as this helps us continue to provide updates and support to our users. ",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
GUILayout.Label(
|
||||
"If you have any questions or concerns please do not hesitate to get in touch with us via email or the Unity forums.",
|
||||
SRInternalEditorUtil.Styles.ParagraphLabel);
|
||||
|
||||
SRInternalEditorUtil.DrawFooterLayout(position.width - 15);
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private void DrawVideo()
|
||||
{
|
||||
if (_demoSprite == null)
|
||||
{
|
||||
_demoSprite = SRInternalEditorUtil.LoadResource<Texture2D>("Editor/DemoSprite.png");
|
||||
}
|
||||
|
||||
if (_demoSprite == null)
|
||||
return;
|
||||
|
||||
var frameWidth = 400;
|
||||
var frameHeight = 300;
|
||||
var framePadding = 0;
|
||||
var extraFramesStart = 5;
|
||||
var extraFramesEnd = 20;
|
||||
var totalFrames = 29;
|
||||
var fps = 16f;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
var rect = GUILayoutUtility.GetRect(400*0.75f, 300*0.75f, GUILayout.ExpandHeight(false),
|
||||
GUILayout.ExpandWidth(false));
|
||||
|
||||
var frame = ((int) (EditorApplication.timeSinceStartup*fps))%
|
||||
(totalFrames + extraFramesStart + extraFramesEnd);
|
||||
frame -= extraFramesStart;
|
||||
|
||||
var actualFrame = Mathf.Clamp(frame, 0, totalFrames);
|
||||
|
||||
SRInternalEditorUtil.RenderGif(rect, _demoSprite, actualFrame, frameWidth, frameHeight, 5, framePadding,
|
||||
framePadding);
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e35f7047e81c2247ae9a5bfd682e156
|
||||
timeCreated: 1442417928
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user