You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
9.9 KiB
C#
261 lines
9.9 KiB
C#
namespace Fusion.Editor {
|
|
#if FUSION_WEAVER && UNITY_EDITOR
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Photon.Realtime;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using EditorUtility = UnityEditor.EditorUtility;
|
|
|
|
public partial class FusionHubWindow : EditorWindow {
|
|
private const int NavWidth = 256 + 2;
|
|
|
|
private static bool? _ready; // true after InitContent(), reset onDestroy, onEnable, etc.
|
|
|
|
private static Vector2 _windowSize;
|
|
private static Vector2 _windowPosition = new Vector2(100, 100);
|
|
|
|
private int _currentSection;
|
|
|
|
[MenuItem("Tools/Fusion/Fusion Hub &f", false, 0)]
|
|
public static void Open() {
|
|
if (Application.isPlaying) {
|
|
return;
|
|
}
|
|
|
|
var window = GetWindow<FusionHubWindow>(true, Constants.WindowTitle, true);
|
|
window.position = new Rect(_windowPosition, _windowSize);
|
|
window.Show();
|
|
}
|
|
|
|
private static void ReOpen() {
|
|
if (_ready.HasValue && _ready.Value == false) {
|
|
Open();
|
|
}
|
|
|
|
EditorApplication.update -= ReOpen;
|
|
}
|
|
|
|
private void OnEnable() {
|
|
_ready = false;
|
|
_windowSize = new Vector2(800, 540);
|
|
|
|
this.minSize = _windowSize;
|
|
|
|
// Pre-load Release History
|
|
this.PrepareReleaseHistoryText();
|
|
wantsMouseMove = true;
|
|
}
|
|
|
|
private void OnDestroy() {
|
|
_ready = false;
|
|
}
|
|
|
|
private void OnGUI() {
|
|
// skip until ready
|
|
if (InitContent() == false) { return; }
|
|
|
|
GUI.skin = FusionHubSkin;
|
|
|
|
FusionGlobalScriptableObjectUtils.EnsureAssetExists<PhotonAppSettings>();
|
|
FusionGlobalScriptableObjectUtils.EnsureAssetExists<NetworkProjectConfigAsset>();
|
|
|
|
_windowPosition = this.position.position;
|
|
|
|
// full window wrapper
|
|
using (new EditorGUILayout.HorizontalScope(GUI.skin.window)) {
|
|
// Left Nav menu
|
|
using (new EditorGUILayout.VerticalScope(GUILayout.MaxWidth(NavWidth), GUILayout.MinWidth(NavWidth))) {
|
|
DrawHeader();
|
|
DrawLeftNavMenu();
|
|
}
|
|
|
|
// Right Main Content
|
|
using (new EditorGUILayout.VerticalScope()) {
|
|
DrawContent();
|
|
}
|
|
}
|
|
|
|
DrawFooter();
|
|
|
|
// Force repaints while mouse is over the window, to keep Hover graphics working (Unity quirk)
|
|
var timeSinceStartup = Time.realtimeSinceStartupAsDouble;
|
|
if (Event.current.type == EventType.MouseMove && timeSinceStartup > _nextForceRepaint) {
|
|
// Cap the repaint rate a bit since we are forcing repaint on mouse move
|
|
_nextForceRepaint = timeSinceStartup + .05f;
|
|
Repaint();
|
|
}
|
|
}
|
|
|
|
private double _nextForceRepaint;
|
|
private Vector2 _scrollRect;
|
|
|
|
private void DrawContent() {
|
|
var section = _sections[_currentSection];
|
|
GUILayout.Label(section.Description, headerTextStyle);
|
|
|
|
using (new EditorGUILayout.VerticalScope(FusionHubSkin.box)) {
|
|
using (var scrollScope = new EditorGUILayout.ScrollViewScope(_scrollRect)) {
|
|
_scrollRect = scrollScope.scrollPosition;
|
|
section.DrawMethod.Invoke();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawWelcomeSection() {
|
|
// Top Welcome content box
|
|
GUILayout.Label(Constants.WelcomeText);
|
|
GUILayout.Space(16);
|
|
|
|
DrawSetupAppIdBox();
|
|
}
|
|
|
|
private void DrawSetupSection() {
|
|
DrawSetupAppIdBox();
|
|
DrawButtonAction(Icon.FusionIcon, "Fusion Network Project Settings", "Network settings specific to Fusion.",
|
|
callback: () => NetworkProjectConfigUtilities.PingGlobalConfigAsset(true));
|
|
DrawButtonAction(Icon.PhotonCloud, "Photon App Settings", "Network settings specific to the Photon transport.",
|
|
callback: () => {
|
|
EditorGUIUtility.PingObject(Photon.Realtime.PhotonAppSettings.Global);
|
|
Selection.activeObject = Photon.Realtime.PhotonAppSettings.Global;
|
|
});
|
|
}
|
|
|
|
private void DrawDocumentationSection() {
|
|
DrawButtonAction(Icon.Documentation, "Fusion Introduction", "The Fusion Introduction web page.", callback: OpenURL(Constants.UrlFusionIntro));
|
|
DrawButtonAction(Icon.Documentation, "SDK and Release Notes", "Link to the latest Fusion version SDK.", callback: OpenURL(Constants.UrlFusionSDK));
|
|
DrawButtonAction(Icon.Documentation, "API Reference", "The API library reference documentation.", callback: OpenURL(Constants.UrlFusionDocApi));
|
|
}
|
|
|
|
private void DrawSamplesSection() {
|
|
GUILayout.Label("Tutorials", headerLabelStyle);
|
|
DrawButtonAction(Icon.Samples, "Fusion 100 Tutorial", "Fusion Fundamentals Tutorial", callback: OpenURL(Constants.UrlFusion100));
|
|
}
|
|
|
|
private void DrawFusionReleaseSection() {
|
|
GUILayout.Label(fusionReleaseHistory, releaseNotesStyle);
|
|
}
|
|
|
|
private void DrawReleaseHistoryItem(string label, List<string> items) {
|
|
if (items != null && items.Count > 0) {
|
|
GUILayout.BeginVertical();
|
|
{
|
|
GUILayout.Space(5);
|
|
|
|
foreach (string text in items) {
|
|
GUILayout.Label(string.Format("- {0}.", text), textLabelStyle);
|
|
}
|
|
}
|
|
GUILayout.EndVertical();
|
|
}
|
|
}
|
|
|
|
private void DrawSupportSection() {
|
|
GUILayout.BeginVertical();
|
|
GUILayout.Space(5);
|
|
GUILayout.Label(Constants.Support, textLabelStyle);
|
|
GUILayout.EndVertical();
|
|
|
|
GUILayout.Space(15);
|
|
|
|
DrawButtonAction(Icon.Community, Constants.DiscordHeader, Constants.DiscordText, callback: OpenURL(Constants.UrlDashboardProfile));
|
|
DrawButtonAction(Icon.Documentation, Constants.DocumentationHeader, Constants.DocumentationText, callback: OpenURL(Constants.UrlFusionDocsOnline));
|
|
}
|
|
|
|
private void DrawSetupAppIdBox() {
|
|
var realtimeSettings = Photon.Realtime.PhotonAppSettings.Global;
|
|
var realtimeAppId = realtimeSettings.AppSettings.AppIdFusion;
|
|
// Setting up AppId content box.
|
|
using (new EditorGUILayout.VerticalScope(FusionHubSkin.GetStyle("SteelBox") /*contentBoxStyle*/)) {
|
|
GUILayout.Label(Constants.RealtimeAppidSetupInstructions);
|
|
|
|
DrawButtonAction(Icon.PhotonCloud, "Open the Photon Dashboard", callback: OpenURL(Constants.UrlDashboard));
|
|
EditorGUILayout.Space(4);
|
|
|
|
using (new EditorGUILayout.HorizontalScope(FusionHubSkin.GetStyle("SteelBox"))) {
|
|
EditorGUI.BeginChangeCheck();
|
|
GUILayout.Label("Fusion App Id:", GUILayout.Width(120));
|
|
var icon = IsAppIdValid() ? CorrectIcon : EditorGUIUtility.FindTexture("console.erroricon.sml");
|
|
GUILayout.Label(icon, GUILayout.Width(24), GUILayout.Height(24));
|
|
var editedAppId = EditorGUILayout.TextField("", realtimeAppId, FusionHubSkin.textField, GUILayout.Height(24));
|
|
|
|
// Check for changes and validate the AppId
|
|
if (EditorGUI.EndChangeCheck() && Guid.TryParse(editedAppId, out _)) {
|
|
// Update the AppId
|
|
realtimeSettings.AppSettings.AppIdFusion = editedAppId;
|
|
EditorUtility.SetDirty(realtimeSettings);
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawLeftNavMenu() {
|
|
for (var i = 0; i < _sections.Length; ++i) {
|
|
var section = _sections[i];
|
|
if (DrawNavButton(section, _currentSection == i)) {
|
|
_currentSection = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawHeader() {
|
|
GUILayout.Label(GetIcon(Icon.ProductLogo), _navbarHeaderGraphicStyle);
|
|
}
|
|
|
|
private void DrawFooter() {
|
|
GUILayout.BeginHorizontal(FusionHubSkin.window);
|
|
{
|
|
GUILayout.Label("\u00A9 2022, Exit Games GmbH. All rights reserved.");
|
|
}
|
|
GUILayout.EndHorizontal();
|
|
}
|
|
|
|
private bool DrawNavButton(Section section, bool currentSection) {
|
|
var content = new GUIContent() { text = " " + section.Title, image = GetIcon(section.Icon), };
|
|
|
|
var renderStyle = currentSection ? buttonActiveStyle : GUI.skin.button;
|
|
return GUILayout.Button(content, renderStyle);
|
|
}
|
|
|
|
private void DrawButtonAction(Icon icon, string header, string description = null, bool? active = null, Action callback = null, int? width = null) {
|
|
DrawButtonAction(GetIcon(icon), header, description, active, callback, width);
|
|
}
|
|
|
|
private static void DrawButtonAction(Texture2D icon, string header, string description = null, bool? active = null, Action callback = null, int? width = null) {
|
|
var padding = GUI.skin.button.padding.top + GUI.skin.button.padding.bottom;
|
|
var height = icon.height + padding;
|
|
|
|
var renderStyle = active.HasValue && active.Value == true ? buttonActiveStyle : GUI.skin.button;
|
|
// Draw text separately (not part of button guiconent) to have control over the space between the icon and the text.
|
|
var rect = EditorGUILayout.GetControlRect(false, height, width.HasValue ? GUILayout.Width(width.Value) : GUILayout.ExpandWidth(true));
|
|
var clicked = GUI.Button(rect, icon, renderStyle);
|
|
GUI.Label(new Rect(rect) { xMin = rect.xMin + icon.width + 20 },
|
|
description == null ? "<b>" + header + "</b>" : string.Format("<b>{0}</b>\n{1}", header, "<color=#aaaaaa>" + description + "</color>"));
|
|
if (clicked && callback != null) {
|
|
callback.Invoke();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unity handling for post asset processing callback. Checks existence of settings assets every time assets change.
|
|
/// </summary>
|
|
private class FusionHubPostProcessor : AssetPostprocessor {
|
|
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) {
|
|
EnsureAssetExists();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempts enforce existence of singleton. If Editor is not ready, this method will be deferred one editor update and try again until it succeeds.
|
|
/// </summary>
|
|
[UnityEditor.Callbacks.DidReloadScripts]
|
|
private static void EnsureAssetExists() {
|
|
if (!PhotonAppSettings.TryGetGlobal(out var global) || global.AppSettings.AppIdFusion == null) {
|
|
FusionEditorLog.Trace($"Opening HUB due to missing settings.");
|
|
EditorApplication.delayCall += () => { Open(); };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
} |