[Add] FishNet
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Editing.Beta
|
||||
{
|
||||
public class BetaModeMenu : MonoBehaviour
|
||||
{
|
||||
#region const.
|
||||
private const string STABLE_RECURSIVE_DESPAWNS_DEFINE = "FISHNET_STABLE_RECURSIVE_DESPAWNS";
|
||||
private const string THREADED_TICKSMOOTHERS_DEFINE = "FISHNET_THREADED_TICKSMOOTHERS";
|
||||
private const string THREADED_COLLIDER_ROLLBACK_DEFINE = "FISHNET_THREADED_COLLIDER_ROLLBACK";
|
||||
#endregion
|
||||
|
||||
#region Beta Recursive Despawns
|
||||
#if FISHNET_STABLE_RECURSIVE_DESPAWNS
|
||||
[MenuItem("Tools/Fish-Networking/Beta/Enable Recursive Despawns", false, -1101)]
|
||||
private static void EnableBetaRecursiveDespawns() => SetBetaRecursiveDespawns(useStable: false);
|
||||
#else
|
||||
[MenuItem("Tools/Fish-Networking/Beta/Disable Recursive Despawns", false, -1101)]
|
||||
private static void DisableBetaRecursiveDespawns() => SetBetaRecursiveDespawns(useStable: true);
|
||||
#endif
|
||||
private static void SetBetaRecursiveDespawns(bool useStable)
|
||||
{
|
||||
bool result = DeveloperMenu.RemoveOrAddDefine(STABLE_RECURSIVE_DESPAWNS_DEFINE, removeDefine: !useStable);
|
||||
if (result)
|
||||
Debug.LogWarning($"Beta Recursive Despawns are now {GetBetaEnabledText(useStable)}.");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Beta ThreadedSmothers
|
||||
/* Changes by https://github.com/belplaton
|
||||
* Content: Threaded TickSmoothers
|
||||
* Migrating the network interpolation system for the graphical world to a multithreaded Unity Jobs + Burst implementation. */
|
||||
#if FISHNET_THREADED_TICKSMOOTHERS
|
||||
[MenuItem("Tools/Fish-Networking/Beta/Disable Threaded TickSmoothers", false, -1101)]
|
||||
private static void DisableBetaThreadedSmoothers() => SetBetaThreadedSmoothers(useStable: true);
|
||||
#else
|
||||
[MenuItem("Tools/Fish-Networking/Beta/Enable Threaded TickSmoothers", false, -1101)]
|
||||
private static void EnableBetaThreadedSmoothers()
|
||||
{
|
||||
#if UNITYMATHEMATICS || UNITYMATHEMATICS_131 || UNITYMATHEMATICS_132
|
||||
SetBetaThreadedSmoothers(useStable: false);
|
||||
#else
|
||||
Debug.LogError($"You must install the package com.unity.mathematics to use Beta Threaded TickSmoothers.");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
private static void SetBetaThreadedSmoothers(bool useStable)
|
||||
{
|
||||
bool result = DeveloperMenu.RemoveOrAddDefine(THREADED_TICKSMOOTHERS_DEFINE, removeDefine: useStable);
|
||||
if (result)
|
||||
Debug.LogWarning($"Beta Threaded TickSmoothers are now {GetBetaEnabledText(useStable)}.");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Beta Threaded Collider Rollback
|
||||
/* Changes by https://github.com/belplaton
|
||||
* Content: Threaded Collider Rollback
|
||||
* Migrating collider rollback -- commonly used for hitbox tracing -- to a multithreaded Unity Jobs + Burst implementation. */
|
||||
#if FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
[MenuItem("Tools/Fish-Networking/Beta/Disable Threaded Collider Rollback", false, -1101)]
|
||||
private static void DisableBetaThreadedColliderRollback() => SetBetaThreadedColliderRollback(useStable: true);
|
||||
#else
|
||||
[MenuItem("Tools/Fish-Networking/Beta/Enable Threaded Collider Rollback", false, -1101)]
|
||||
private static void EnableBetaThreadedColliderRollback()
|
||||
{
|
||||
#if UNITYMATHEMATICS || UNITYMATHEMATICS_131 || UNITYMATHEMATICS_132
|
||||
SetBetaThreadedColliderRollback(useStable: false);
|
||||
#else
|
||||
Debug.LogError($"You must install the package com.unity.mathematics to use Beta Threaded Collider Rollhack..");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
private static void SetBetaThreadedColliderRollback(bool useStable)
|
||||
{
|
||||
bool result = DeveloperMenu.RemoveOrAddDefine(THREADED_COLLIDER_ROLLBACK_DEFINE, removeDefine: useStable);
|
||||
if (result)
|
||||
Debug.LogWarning($"Beta Threaded Collider Rollbacks are now {GetBetaEnabledText(useStable)}.");
|
||||
}
|
||||
#endregion
|
||||
|
||||
private static string GetBetaEnabledText(bool useStable)
|
||||
{
|
||||
return useStable ? "disabled" : "enabled";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ecf03df72c983164586a22e695d17905
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/BetaModeMenu.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,146 @@
|
||||
#if UNITY_EDITOR
|
||||
using FishNet.Editing.PrefabCollectionGenerator;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Configuring
|
||||
{
|
||||
public enum StrippingTypes : int
|
||||
{
|
||||
Redirect = 0,
|
||||
Empty_Experimental = 1
|
||||
}
|
||||
|
||||
public enum SearchScopeType : int
|
||||
{
|
||||
EntireProject = 0,
|
||||
SpecificFolders = 1
|
||||
}
|
||||
|
||||
public class CreateNewNetworkBehaviourConfigurations
|
||||
{
|
||||
public string templateDirectoryPath = "Assets";
|
||||
}
|
||||
|
||||
public class PrefabGeneratorConfigurations
|
||||
{
|
||||
public bool Enabled = true;
|
||||
public bool LogToConsole = true;
|
||||
public bool FullRebuild = false;
|
||||
public bool SpawnableOnly = true;
|
||||
public bool SaveChanges = true;
|
||||
public string DefaultPrefabObjectsPath = Path.Combine("Assets", "DefaultPrefabObjects.asset");
|
||||
internal string DefaultPrefabObjectsPath_Platform => Generator.GetPlatformPath(DefaultPrefabObjectsPath);
|
||||
public int SearchScope = (int)SearchScopeType.EntireProject;
|
||||
public List<string> ExcludedFolders = new();
|
||||
public List<string> IncludedFolders = new();
|
||||
}
|
||||
|
||||
public class CodeStrippingConfigurations
|
||||
{
|
||||
public bool IsBuilding = false;
|
||||
public bool IsDevelopment = false;
|
||||
public bool IsHeadless = false;
|
||||
public bool StripReleaseBuilds = false;
|
||||
public int StrippingType = (int)StrippingTypes.Redirect;
|
||||
}
|
||||
|
||||
public class ConfigurationData
|
||||
{
|
||||
// Non serialized doesn't really do anything, its just for me.
|
||||
[NonSerialized]
|
||||
public bool Loaded;
|
||||
public PrefabGeneratorConfigurations PrefabGenerator = new();
|
||||
public CodeStrippingConfigurations CodeStripping = new();
|
||||
public CreateNewNetworkBehaviourConfigurations CreateNewNetworkBehaviour = new();
|
||||
}
|
||||
|
||||
public static class ConfigurationDataExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns if a differs from b.
|
||||
/// </summary>
|
||||
public static bool HasChanged(this ConfigurationData a, ConfigurationData b)
|
||||
{
|
||||
return a.CodeStripping.StripReleaseBuilds != b.CodeStripping.StripReleaseBuilds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies all values from source to target.
|
||||
/// </summary>
|
||||
public static void CopyTo(this ConfigurationData source, ConfigurationData target)
|
||||
{
|
||||
target.CodeStripping.StripReleaseBuilds = source.CodeStripping.StripReleaseBuilds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a configuration data.
|
||||
/// </summary>
|
||||
public static void Write(this ConfigurationData cd, bool refreshAssetDatabase)
|
||||
{
|
||||
/* Why is this a thing you ask? Because Unity makes it VERY difficult to read values from
|
||||
* memory during builds since on some Unity versions the building application is on a different
|
||||
* processor. In result instead of using memory to read configurationdata the values
|
||||
* must be written to disk then load the disk values as needed.
|
||||
*
|
||||
* Fortunatelly the file is extremely small and this does not occur often at all. The disk read
|
||||
* will occur once per script save, and once per assembly when building. */
|
||||
try
|
||||
{
|
||||
string path = Configuration.GetAssetsPath(Configuration.CONFIG_FILE_NAME);
|
||||
XmlSerializer serializer = new(typeof(ConfigurationData));
|
||||
TextWriter writer = new StreamWriter(path);
|
||||
serializer.Serialize(writer, cd);
|
||||
writer.Close();
|
||||
#if UNITY_EDITOR
|
||||
if (refreshAssetDatabase)
|
||||
{
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new($"An error occurred while writing ConfigurationData. Message: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a configuration data.
|
||||
/// </summary>
|
||||
public static void Write(this ConfigurationData cd, string path, bool refreshAssetDatabase)
|
||||
{
|
||||
/* Why is this a thing you ask? Because Unity makes it VERY difficult to read values from
|
||||
* memory during builds since on some Unity versions the building application is on a different
|
||||
* processor. In result instead of using memory to read configurationdata the values
|
||||
* must be written to disk then load the disk values as needed.
|
||||
*
|
||||
* Fortunatelly the file is extremely small and this does not occur often at all. The disk read
|
||||
* will occur once per script save, and once per assembly when building. */
|
||||
try
|
||||
{
|
||||
XmlSerializer serializer = new(typeof(ConfigurationData));
|
||||
TextWriter writer = new StreamWriter(path);
|
||||
serializer.Serialize(writer, cd);
|
||||
writer.Close();
|
||||
#if UNITY_EDITOR
|
||||
if (refreshAssetDatabase)
|
||||
{
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new($"An error occurred while writing ConfigurationData. Message: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4be37e1b0afd29944ad4fa0b92ed8c7e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/ConfigurationData.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,112 @@
|
||||
#if UNITY_EDITOR
|
||||
using FishNet.Editing.PrefabCollectionGenerator;
|
||||
using FishNet.Object;
|
||||
using FishNet.Utility.Extension;
|
||||
using GameKit.Dependencies.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using FishNet.Configuring.EditorCloning;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace FishNet.Editing
|
||||
{
|
||||
public class ConfigurationEditor : EditorWindow
|
||||
{
|
||||
[MenuItem("Tools/Fish-Networking/Configuration", false, 0)]
|
||||
public static void ShowConfiguration()
|
||||
{
|
||||
SettingsService.OpenProjectSettings("Project/Fish-Networking/Configuration");
|
||||
}
|
||||
}
|
||||
|
||||
public class DeveloperMenu : MonoBehaviour
|
||||
{
|
||||
#region const.
|
||||
private const string QOL_ATTRIBUTES_DEFINE = "DISABLE_QOL_ATTRIBUTES";
|
||||
private const string DEVELOPER_ONLY_WARNING = "If you are not a developer or were not instructed to do this by a developer things are likely to break. You have been warned.";
|
||||
#endregion
|
||||
|
||||
#region QOL Attributes
|
||||
#if DISABLE_QOL_ATTRIBUTES
|
||||
[MenuItem("Tools/Fish-Networking/Utility/Quality of Life Attributes/Enable", false, -999)]
|
||||
private static void EnableQOLAttributes()
|
||||
{
|
||||
bool result = RemoveOrAddDefine(QOL_ATTRIBUTES_DEFINE, removeDefine: true);
|
||||
if (result)
|
||||
Debug.LogWarning($"Quality of Life Attributes have been enabled.");
|
||||
}
|
||||
#else
|
||||
[MenuItem("Tools/Fish-Networking/Utility/Quality of Life Attributes/Disable", false, 0)]
|
||||
private static void DisableQOLAttributes()
|
||||
{
|
||||
bool result = RemoveOrAddDefine(QOL_ATTRIBUTES_DEFINE, removeDefine: false);
|
||||
if (result)
|
||||
Debug.LogWarning($"Quality of Life Attributes have been disabled. {DEVELOPER_ONLY_WARNING}");
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
internal static bool RemoveOrAddDefine(string define, bool removeDefine)
|
||||
{
|
||||
#if UNITY_6000_1_OR_NEWER
|
||||
NamedBuildTarget activeTarget = NamedBuildTarget.FromBuildTargetGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||
#endif
|
||||
|
||||
#if UNITY_6000_1_OR_NEWER
|
||||
string currentDefines = PlayerSettings.GetScriptingDefineSymbols(activeTarget);
|
||||
#else
|
||||
string currentDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||
#endif
|
||||
|
||||
HashSet<string> definesHs = new();
|
||||
string[] currentArr = currentDefines.Split(';');
|
||||
|
||||
// Add any define which doesn't contain MIRROR.
|
||||
foreach (string item in currentArr)
|
||||
definesHs.Add(item);
|
||||
|
||||
int startingCount = definesHs.Count;
|
||||
|
||||
if (removeDefine)
|
||||
definesHs.Remove(define);
|
||||
else
|
||||
definesHs.Add(define);
|
||||
|
||||
bool modified = definesHs.Count != startingCount;
|
||||
if (modified)
|
||||
{
|
||||
string changedDefines = string.Join(";", definesHs);
|
||||
#if UNITY_6000_1_OR_NEWER
|
||||
PlayerSettings.SetScriptingDefineSymbols(activeTarget, changedDefines);
|
||||
#else
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, changedDefines);
|
||||
#endif
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
|
||||
public class RefreshDefaultPrefabsMenu : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Rebuilds the DefaultPrefabsCollection file.
|
||||
/// </summary>
|
||||
[MenuItem("Tools/Fish-Networking/Utility/Refresh Default Prefabs", false, 300)]
|
||||
public static void RebuildDefaultPrefabs()
|
||||
{
|
||||
if (!CloneChecker.CanGenerateFiles())
|
||||
{
|
||||
Debug.Log("Skipping prefab generation as clone settings does not allow it.");
|
||||
return;
|
||||
}
|
||||
Debug.Log("Refreshing default prefabs.");
|
||||
Generator.GenerateFull(null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8135b3a4c31cfb74896f1e9e77059c89
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/ConfigurationEditor.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,91 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Compilation;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
|
||||
namespace FishNet.Configuring
|
||||
{
|
||||
public class Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
private static ConfigurationData _configurations;
|
||||
/// <summary>
|
||||
/// ConfigurationData to use.
|
||||
/// </summary>
|
||||
public static ConfigurationData Configurations
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_configurations == null)
|
||||
_configurations = LoadConfigurationData();
|
||||
if (_configurations == null)
|
||||
throw new("Fish-Networking Configurations could not be loaded. Certain features such as code-stripping may not function.");
|
||||
return _configurations;
|
||||
}
|
||||
private set { _configurations = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// File name for configuration disk data.
|
||||
/// </summary>
|
||||
public const string CONFIG_FILE_NAME = "FishNet.Config.XML";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the path for the configuration file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static string GetAssetsPath(string additional = "")
|
||||
{
|
||||
string a = Path.Combine(Directory.GetCurrentDirectory(), "Assets");
|
||||
if (additional != "")
|
||||
a = Path.Combine(a, additional);
|
||||
return a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns FishNetworking ConfigurationData.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static ConfigurationData LoadConfigurationData()
|
||||
{
|
||||
// return new ConfigurationData();
|
||||
if (_configurations == null || !_configurations.Loaded)
|
||||
{
|
||||
string configPath = GetAssetsPath(CONFIG_FILE_NAME);
|
||||
// string configPath = string.Empty;
|
||||
// File is on disk.
|
||||
if (File.Exists(configPath))
|
||||
{
|
||||
FileStream fs = null;
|
||||
try
|
||||
{
|
||||
XmlSerializer serializer = new(typeof(ConfigurationData));
|
||||
fs = new(configPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
_configurations = (ConfigurationData)serializer.Deserialize(fs);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fs?.Close();
|
||||
}
|
||||
_configurations.Loaded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If null then make a new instance.
|
||||
if (_configurations == null)
|
||||
_configurations = new();
|
||||
// Don't unset loaded, if its true then it should have proper info.
|
||||
// _configurationData.Loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
return _configurations;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d05bf07ec9af2c46a1fe6c24871cccb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/Configuring.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,61 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using FishNet.Configuring;
|
||||
using FishNet.Configuring.EditorCloning;
|
||||
using FishNet.Managing;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Editing
|
||||
{
|
||||
/// <summary>
|
||||
/// Contributed by YarnCat! Thank you!
|
||||
/// </summary>
|
||||
[InitializeOnLoad]
|
||||
public class DelayedEditorTasks : EditorWindow
|
||||
{
|
||||
private static double _startTime = double.MinValue;
|
||||
|
||||
static DelayedEditorTasks()
|
||||
{
|
||||
if (CloneChecker.IsMultiplayerClone(out _))
|
||||
return;
|
||||
|
||||
const string startupCheckString = "FishNetDelayedEditorTasks";
|
||||
if (SessionState.GetBool(startupCheckString, false))
|
||||
return;
|
||||
|
||||
_startTime = EditorApplication.timeSinceStartup;
|
||||
EditorApplication.update += CheckRunTasks;
|
||||
|
||||
SessionState.SetBool(startupCheckString, true);
|
||||
}
|
||||
|
||||
private static void CheckRunTasks()
|
||||
{
|
||||
if (EditorApplication.timeSinceStartup - _startTime < 1f)
|
||||
return;
|
||||
|
||||
EditorApplication.update -= CheckRunTasks;
|
||||
|
||||
LogFeedbackLink();
|
||||
|
||||
// First time use, no other actions should be done.
|
||||
if (FishNetGettingStartedEditor.ShowGettingStarted())
|
||||
return;
|
||||
|
||||
ReviewReminderEditor.CheckRemindToReview();
|
||||
}
|
||||
|
||||
private static void LogFeedbackLink()
|
||||
{
|
||||
// Only log the link when editor opens.
|
||||
if (Time.realtimeSinceStartup < 10f)
|
||||
{
|
||||
string msg = $"Thank you for using Fish-Networking! If you have any feedback -- be suggestions, documentation, or performance related, let us know through our anonymous Google feedback form!{Environment.NewLine}" + @"<color=#67d419>https://forms.gle/1g13VY4KKMnEqpkp6</color>";
|
||||
Debug.Log(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb3b5223de134ee41bc1ad462ce897f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/DelayedEditorTasks.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14146fca20e58f94987416948b38d79d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,91 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Configuring.EditorCloning
|
||||
{
|
||||
public static class CloneChecker
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns true if this editor is a multiplayer clone.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsMultiplayerClone(out EditorCloneType editorCloneType)
|
||||
{
|
||||
if (IsUnityMultiplayerModeClone())
|
||||
{
|
||||
editorCloneType = EditorCloneType.UnityMultiplayer;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsParrelSyncClone())
|
||||
{
|
||||
editorCloneType = EditorCloneType.ParrelSync;
|
||||
return true;
|
||||
}
|
||||
|
||||
editorCloneType = EditorCloneType.None;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if ParrelSync clone with file modification enabled, or if not a clone.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool CanGenerateFiles()
|
||||
{
|
||||
//Not a clone.
|
||||
if (!IsMultiplayerClone(out EditorCloneType cloneType))
|
||||
return true;
|
||||
|
||||
//A clone, but not parrelsync.
|
||||
if (cloneType != EditorCloneType.ParrelSync)
|
||||
return false;
|
||||
|
||||
return CanParrelSyncSetData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses preprocessors to determine if ParrelSync and can set data.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static bool CanParrelSyncSetData()
|
||||
{
|
||||
#if PARRELSYNC && UNITY_EDITOR
|
||||
|
||||
bool areSetsBlocked = ParrelSync.Preferences.AssetModPref.Value;
|
||||
|
||||
return !areSetsBlocked;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if is a ParrelSync clone.
|
||||
/// </summary>
|
||||
public static bool IsParrelSyncClone()
|
||||
{
|
||||
#if PARRELSYNC && UNITY_EDITOR
|
||||
|
||||
return ParrelSync.ClonesManager.IsClone();
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if a Unity MultiplayerMode clone.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsUnityMultiplayerModeClone()
|
||||
{
|
||||
return Application.dataPath.ToLower().Contains("library/vp/");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f63e9ae39a4fa65409189b5d587c5197
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/EditorCloning/CloneChecker.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace FishNet.Configuring.EditorCloning
|
||||
{
|
||||
public enum EditorCloneType
|
||||
{
|
||||
None = 0,
|
||||
UnityMultiplayer = 1,
|
||||
ParrelSync = 2,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ef534ed79b320b4c8961e3666159de1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/EditorCloning/EditorCloneType.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,137 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Editing
|
||||
{
|
||||
/// <summary>
|
||||
/// Contributed by YarnCat! Thank you!
|
||||
/// </summary>
|
||||
public class FishNetGettingStartedEditor : EditorWindow
|
||||
{
|
||||
private Texture2D _fishnetLogo, _reviewButtonBg, _reviewButtonBgHover;
|
||||
private GUIStyle _labelStyle, _reviewButtonStyle;
|
||||
private const string SHOWED_GETTING_STARTED = "ShowedFishNetGettingStarted";
|
||||
|
||||
[MenuItem("Tools/Fish-Networking/Getting Started", isValidateFunction: false, 9999)]
|
||||
public static void GettingStartedMenu()
|
||||
{
|
||||
FishNetGettingStartedEditor window = (FishNetGettingStartedEditor)GetWindow(typeof(FishNetGettingStartedEditor));
|
||||
window.position = new(0, 0, 320, 355);
|
||||
Rect mainPos;
|
||||
mainPos = EditorGUIUtility.GetMainWindowPosition();
|
||||
Rect pos = window.position;
|
||||
float w = (mainPos.width - pos.width) * 0.5f;
|
||||
float h = (mainPos.height - pos.height) * 0.5f;
|
||||
pos.x = mainPos.x + w;
|
||||
pos.y = mainPos.y + h;
|
||||
window.position = pos;
|
||||
|
||||
window._fishnetLogo = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/FishNet/Runtime/Editor/Textures/UI/Logo_With_Text.png", typeof(Texture));
|
||||
window._labelStyle = new("label");
|
||||
window._labelStyle.fontSize = 24;
|
||||
window._labelStyle.wordWrap = true;
|
||||
// window.labelStyle.alignment = TextAnchor.MiddleCenter;
|
||||
window._labelStyle.normal.textColor = new Color32(74, 195, 255, 255);
|
||||
|
||||
window._reviewButtonBg = MakeBackgroundTexture(1, 1, new Color32(52, 111, 255, 255));
|
||||
window._reviewButtonBgHover = MakeBackgroundTexture(1, 1, new Color32(99, 153, 255, 255));
|
||||
window._reviewButtonStyle = new("button");
|
||||
window._reviewButtonStyle.fontSize = 18;
|
||||
window._reviewButtonStyle.fontStyle = FontStyle.Bold;
|
||||
window._reviewButtonStyle.normal.background = window._reviewButtonBg;
|
||||
window._reviewButtonStyle.active.background = window._reviewButtonBgHover;
|
||||
window._reviewButtonStyle.focused.background = window._reviewButtonBgHover;
|
||||
window._reviewButtonStyle.onFocused.background = window._reviewButtonBgHover;
|
||||
window._reviewButtonStyle.hover.background = window._reviewButtonBgHover;
|
||||
window._reviewButtonStyle.onHover.background = window._reviewButtonBgHover;
|
||||
window._reviewButtonStyle.alignment = TextAnchor.MiddleCenter;
|
||||
window._reviewButtonStyle.normal.textColor = new(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
internal static bool ShowGettingStarted()
|
||||
{
|
||||
bool shown = EditorPrefs.GetBool(SHOWED_GETTING_STARTED, false);
|
||||
if (!shown)
|
||||
{
|
||||
EditorPrefs.SetBool(SHOWED_GETTING_STARTED, true);
|
||||
ReviewReminderEditor.ResetDateTimeReminded();
|
||||
GettingStartedMenu();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
GUILayout.Box(_fishnetLogo, GUILayout.Width(position.width), GUILayout.Height(128));
|
||||
GUILayout.Space(20);
|
||||
|
||||
GUILayout.Label("Have you considered leaving us a review?", _labelStyle, GUILayout.Width(280));
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
if (GUILayout.Button("Leave us a review!", _reviewButtonStyle))
|
||||
{
|
||||
Application.OpenURL("https://assetstore.unity.com/packages/tools/network/fish-net-networking-evolved-207815");
|
||||
}
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Documentation", GUILayout.Width(position.width * 0.485f)))
|
||||
{
|
||||
Application.OpenURL("https://fish-networking.gitbook.io/docs/");
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Discord", GUILayout.Width(position.width * 0.485f)))
|
||||
{
|
||||
Application.OpenURL("https://discord.gg/Ta9HgDh4Hj");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("FishNet Pro", GUILayout.Width(position.width * 0.485f)))
|
||||
{
|
||||
Application.OpenURL("https://fish-networking.gitbook.io/docs/master/pro");
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Github", GUILayout.Width(position.width * 0.485f)))
|
||||
{
|
||||
Application.OpenURL("https://github.com/FirstGearGames/FishNet");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Pro Downloads", GUILayout.Width(position.width * 0.485f)))
|
||||
{
|
||||
Application.OpenURL("https://www.fish-networking.com/");
|
||||
}
|
||||
|
||||
// if (GUILayout.Button("Examples", GUILayout.Width(this.position.width * 0.485f)))
|
||||
// {
|
||||
// Application.OpenURL("https://fish-networking.gitbook.io/docs/manual/tutorials/example-projects");
|
||||
//}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
//GUILayout.Space(20);
|
||||
//_showOnStartupSelected = EditorGUILayout.Popup("Show on Startup", _showOnStartupSelected, showOnStartupOptions);
|
||||
}
|
||||
//private string[] showOnStartupOptions = new string[] { "Always", "On new version", "Never", };
|
||||
//private int _showOnStartupSelected = 1;
|
||||
|
||||
private static Texture2D MakeBackgroundTexture(int width, int height, Color color)
|
||||
{
|
||||
Color[] pixels = new Color[width * height];
|
||||
for (int i = 0; i < pixels.Length; i++)
|
||||
pixels[i] = color;
|
||||
Texture2D backgroundTexture = new(width, height);
|
||||
backgroundTexture.SetPixels(pixels);
|
||||
backgroundTexture.Apply();
|
||||
return backgroundTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 335aec9a9dce4944994cb57ac704ba5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/FIshNetGettingStartedEditor.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,458 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FishNet.Editing.PrefabCollectionGenerator;
|
||||
using FishNet.Object;
|
||||
using FishNet.Utility.Extension;
|
||||
using GameKit.Dependencies.Utilities;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityScene = UnityEngine.SceneManagement.Scene;
|
||||
using UnitySceneManagement = UnityEngine.SceneManagement;
|
||||
|
||||
namespace FishNet.Editing
|
||||
{
|
||||
/// <summary>
|
||||
/// Contributed by YarnCat! Thank you!
|
||||
/// </summary>
|
||||
public class ReserializeNetworkObjectsEditor : EditorWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// True if currently iterating.
|
||||
/// </summary>
|
||||
[System.NonSerialized]
|
||||
internal static bool IsRunning;
|
||||
|
||||
private enum ReserializeSceneType : int
|
||||
{
|
||||
AllScenes = 0,
|
||||
OpenScenes = 1,
|
||||
SelectedScenes = 2,
|
||||
BuildScenes = 3
|
||||
}
|
||||
|
||||
private struct OpenScene
|
||||
{
|
||||
public UnityScene Scene;
|
||||
public string Path;
|
||||
|
||||
public OpenScene(UnityScene scene)
|
||||
{
|
||||
Scene = scene;
|
||||
Path = scene.path;
|
||||
}
|
||||
}
|
||||
|
||||
private Texture2D _fishnetLogo;
|
||||
private Texture2D _buttonBg;
|
||||
private Texture2D _buttonBgHover;
|
||||
private GUIStyle _upgradeRequiredStyle;
|
||||
private GUIStyle _instructionsStyle;
|
||||
private GUIStyle _buttonStyle;
|
||||
private bool _loaded;
|
||||
private bool _iteratePrefabs;
|
||||
private bool _iterateScenes;
|
||||
private ReserializeSceneType _sceneReserializeType = ReserializeSceneType.OpenScenes;
|
||||
private bool _enabledOnlyBuildScenes = true;
|
||||
private const string UPGRADE_PART_COLOR = "cd61ff";
|
||||
private const string UPGRADE_COMPLETE_COLOR = "32e66e";
|
||||
private const string PREFS_PREFIX = "FishNetReserialize";
|
||||
private static ReserializeNetworkObjectsEditor _window;
|
||||
|
||||
[MenuItem("Tools/Fish-Networking/Utility/Reserialize NetworkObjects", false, 400)]
|
||||
internal static void ReserializeNetworkObjects()
|
||||
{
|
||||
if (ApplicationState.IsPlaying())
|
||||
{
|
||||
Debug.LogError($"NetworkObjects cannot be reserialized while in play mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeWindow();
|
||||
}
|
||||
|
||||
private static void InitializeWindow()
|
||||
{
|
||||
if (_window != null)
|
||||
return;
|
||||
|
||||
_window = (ReserializeNetworkObjectsEditor)GetWindow(typeof(ReserializeNetworkObjectsEditor));
|
||||
_window.position = new(0f, 0f, 550f, 300f);
|
||||
Rect mainPos;
|
||||
mainPos = EditorGUIUtility.GetMainWindowPosition();
|
||||
Rect pos = _window.position;
|
||||
float w = (mainPos.width - pos.width) * 0.5f;
|
||||
float h = (mainPos.height - pos.height) * 0.5f;
|
||||
pos.x = mainPos.x + w;
|
||||
pos.y = mainPos.y + h;
|
||||
_window.position = pos;
|
||||
}
|
||||
|
||||
private static void StyleWindow()
|
||||
{
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
_window._fishnetLogo = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/FishNet/Runtime/Editor/Textures/UI/Logo_With_Text.png", typeof(Texture));
|
||||
_window._upgradeRequiredStyle = new("label");
|
||||
_window._upgradeRequiredStyle.fontSize = 20;
|
||||
_window._upgradeRequiredStyle.wordWrap = true;
|
||||
_window._upgradeRequiredStyle.alignment = TextAnchor.MiddleCenter;
|
||||
_window._upgradeRequiredStyle.normal.textColor = new Color32(255, 102, 102, 255);
|
||||
|
||||
_window._instructionsStyle = new("label");
|
||||
_window._instructionsStyle.fontSize = 14;
|
||||
_window._instructionsStyle.wordWrap = true;
|
||||
_window._instructionsStyle.alignment = TextAnchor.MiddleCenter;
|
||||
_window._instructionsStyle.normal.textColor = new Color32(255, 255, 255, 255);
|
||||
_window._instructionsStyle.hover.textColor = new Color32(255, 255, 255, 255);
|
||||
|
||||
_window._buttonBg = MakeBackgroundTexture(1, 1, new Color32(52, 111, 255, 255));
|
||||
_window._buttonBgHover = MakeBackgroundTexture(1, 1, new Color32(99, 153, 255, 255));
|
||||
_window._buttonStyle = new("button");
|
||||
_window._buttonStyle.fontSize = 18;
|
||||
_window._buttonStyle.fontStyle = FontStyle.Bold;
|
||||
_window._buttonStyle.normal.background = _window._buttonBg;
|
||||
_window._buttonStyle.active.background = _window._buttonBgHover;
|
||||
_window._buttonStyle.focused.background = _window._buttonBgHover;
|
||||
_window._buttonStyle.onFocused.background = _window._buttonBgHover;
|
||||
_window._buttonStyle.hover.background = _window._buttonBgHover;
|
||||
_window._buttonStyle.onHover.background = _window._buttonBgHover;
|
||||
_window._buttonStyle.alignment = TextAnchor.MiddleCenter;
|
||||
_window._buttonStyle.normal.textColor = new(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
// If not yet loaded then set last used values.
|
||||
if (!_loaded)
|
||||
{
|
||||
LoadLastValues();
|
||||
_loaded = true;
|
||||
}
|
||||
|
||||
float thisWidth = position.width;
|
||||
StyleWindow();
|
||||
// Starting values.
|
||||
Vector2 requiredSize = new(position.width, 160f);
|
||||
|
||||
GUILayout.Box(_fishnetLogo, GUILayout.Width(requiredSize.x), GUILayout.Height(requiredSize.y));
|
||||
|
||||
GUILayout.Space(8f);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(5f);
|
||||
CreateInformationLabel("Use this window to refresh serialized values on all NetworkObject prefabs and scene NetworkObjects.");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.Space(8f);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(30f);
|
||||
_iteratePrefabs = EditorGUILayout.Toggle("Reserialize Prefabs", _iteratePrefabs);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
// Some dumb reason Unity moves the checkbox further when using nested settings.
|
||||
float rebuildScenesSpacing = _iterateScenes ? 27f : 30f;
|
||||
GUILayout.Space(rebuildScenesSpacing);
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
_iterateScenes = EditorGUILayout.Toggle("Reserialize Scenes", _iterateScenes);
|
||||
|
||||
if (_iterateScenes)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(15f);
|
||||
_sceneReserializeType = (ReserializeSceneType)EditorGUILayout.EnumPopup("Targeted Scenes", _sceneReserializeType);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
requiredSize.y += 20f;
|
||||
|
||||
if (_sceneReserializeType == ReserializeSceneType.BuildScenes)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(30f);
|
||||
_enabledOnlyBuildScenes = EditorGUILayout.Toggle("Enabled Only", _enabledOnlyBuildScenes);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
requiredSize.y += 18f;
|
||||
}
|
||||
|
||||
if (_sceneReserializeType != ReserializeSceneType.OpenScenes)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(30f);
|
||||
EditorGUILayout.HelpBox("This operation will open and close targeted scene one at a time. Your current open scenes will be closed and re-opened without saving.", MessageType.Warning);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
requiredSize.y += 40f;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
requiredSize.y += 80f;
|
||||
|
||||
GUILayout.Space(8f);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
if (!_iteratePrefabs && !_iterateScenes)
|
||||
GUI.enabled = false;
|
||||
|
||||
if (GUILayout.Button("Run Task"))
|
||||
{
|
||||
IsRunning = true;
|
||||
|
||||
SaveLastValues();
|
||||
|
||||
ReserializeProjectPrefabs();
|
||||
ReserializeScenes();
|
||||
|
||||
LogColoredText($"Task complete.", UPGRADE_COMPLETE_COLOR);
|
||||
|
||||
_iteratePrefabs = false;
|
||||
_iterateScenes = false;
|
||||
|
||||
IsRunning = false;
|
||||
}
|
||||
|
||||
GUI.enabled = true;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
minSize = requiredSize;
|
||||
maxSize = minSize;
|
||||
|
||||
void CreateInformationLabel(string text, FontStyle? style = null)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
FontStyle firstStyle = _instructionsStyle.fontStyle;
|
||||
if (style != null)
|
||||
_instructionsStyle.fontStyle = style.Value;
|
||||
|
||||
GUILayout.Label(text, _instructionsStyle, GUILayout.Width(thisWidth * 0.95f));
|
||||
|
||||
_instructionsStyle.fontStyle = firstStyle;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
requiredSize.y += 55f;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadLastValues()
|
||||
{
|
||||
_iteratePrefabs = EditorPrefs.GetBool($"{PREFS_PREFIX}{nameof(_iteratePrefabs)}", defaultValue: false);
|
||||
_iterateScenes = EditorPrefs.GetBool($"{PREFS_PREFIX}{nameof(_iterateScenes)}", defaultValue: false);
|
||||
_sceneReserializeType = (ReserializeSceneType)EditorPrefs.GetInt($"{PREFS_PREFIX}{nameof(_sceneReserializeType)}", defaultValue: (int)ReserializeSceneType.OpenScenes);
|
||||
_enabledOnlyBuildScenes = EditorPrefs.GetBool($"{PREFS_PREFIX}{nameof(_enabledOnlyBuildScenes)}", defaultValue: true);
|
||||
}
|
||||
|
||||
private void SaveLastValues()
|
||||
{
|
||||
EditorPrefs.SetBool($"{PREFS_PREFIX}{nameof(_iteratePrefabs)}", _iteratePrefabs);
|
||||
EditorPrefs.SetBool($"{PREFS_PREFIX}{nameof(_iterateScenes)}", _iterateScenes);
|
||||
EditorPrefs.SetInt($"{PREFS_PREFIX}{nameof(_sceneReserializeType)}", (int)_sceneReserializeType);
|
||||
EditorPrefs.SetBool($"{PREFS_PREFIX}{nameof(_enabledOnlyBuildScenes)}", _enabledOnlyBuildScenes);
|
||||
}
|
||||
|
||||
private void ReserializeProjectPrefabs()
|
||||
{
|
||||
if (!_iteratePrefabs)
|
||||
return;
|
||||
|
||||
int checkedObjects = 0;
|
||||
int duplicateNetworkObjectsRemoved = 0;
|
||||
|
||||
bool modified = false;
|
||||
|
||||
List<NetworkObject> networkObjects = Generator.GetNetworkObjects(settings: null);
|
||||
foreach (NetworkObject nob in networkObjects)
|
||||
{
|
||||
checkedObjects++;
|
||||
duplicateNetworkObjectsRemoved += nob.RemoveDuplicateNetworkObjects();
|
||||
|
||||
nob.ReserializeEditorSetValues(setWasActiveDuringEdit: true, setSceneId: false);
|
||||
EditorUtility.SetDirty(nob);
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified)
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
Debug.Log($"Reserialized {checkedObjects} NetworkObject prefabs. Removed {duplicateNetworkObjectsRemoved} duplicate NetworkObject components.");
|
||||
}
|
||||
|
||||
private void ReserializeScenes()
|
||||
{
|
||||
if (!_iterateScenes)
|
||||
return;
|
||||
|
||||
int duplicateNetworkObjectsRemoved = 0;
|
||||
int checkedObjects = 0;
|
||||
int checkedScenes = 0;
|
||||
int changedObjects = 0;
|
||||
|
||||
List<OpenScene> openScenes = GetOpenScenes();
|
||||
|
||||
// If running for open scenes only.
|
||||
if (_sceneReserializeType == ReserializeSceneType.OpenScenes)
|
||||
{
|
||||
ReserializeScenes(openScenes, ref checkedScenes, ref checkedObjects, ref changedObjects, ref duplicateNetworkObjectsRemoved);
|
||||
}
|
||||
// Running on multiple scenes.
|
||||
else
|
||||
{
|
||||
// When working on multiple scenes make sure open scenes are not dirty to prevent data loss.
|
||||
foreach (OpenScene os in openScenes)
|
||||
{
|
||||
if (os.Scene.isDirty)
|
||||
{
|
||||
Debug.LogError($"One or more open scenes are dirty. To prevent data loss scene reserialization will not complete. Ensure all open scenes are saved before continuing.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
List<SceneAsset> targetedScenes;
|
||||
if (_sceneReserializeType == ReserializeSceneType.SelectedScenes)
|
||||
{
|
||||
targetedScenes = Selection.GetFiltered<SceneAsset>(SelectionMode.Assets).ToList();
|
||||
}
|
||||
else if (_sceneReserializeType == ReserializeSceneType.AllScenes)
|
||||
{
|
||||
targetedScenes = new();
|
||||
|
||||
string[] scenePaths = Generator.GetProjectFiles("Assets", "unity", new(), recursive: true);
|
||||
foreach (string path in scenePaths)
|
||||
{
|
||||
SceneAsset sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(path);
|
||||
if (sceneAsset != null)
|
||||
targetedScenes.Add(sceneAsset);
|
||||
}
|
||||
}
|
||||
else if (_sceneReserializeType == ReserializeSceneType.BuildScenes)
|
||||
{
|
||||
targetedScenes = new();
|
||||
|
||||
EditorBuildSettingsScene[] buildScenes = EditorBuildSettings.scenes;
|
||||
foreach (EditorBuildSettingsScene bs in buildScenes)
|
||||
{
|
||||
if (_enabledOnlyBuildScenes && !bs.enabled)
|
||||
continue;
|
||||
|
||||
SceneAsset sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(bs.path);
|
||||
if (sceneAsset != null)
|
||||
targetedScenes.Add(sceneAsset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Unsupported {nameof(ReserializeSceneType)} type {_sceneReserializeType}.");
|
||||
return;
|
||||
}
|
||||
|
||||
ReserializeScenes(targetedScenes, ref checkedScenes, ref checkedObjects, ref changedObjects, ref duplicateNetworkObjectsRemoved);
|
||||
|
||||
// Reopen original scenes.
|
||||
for (int i = 0; i < openScenes.Count; i++)
|
||||
{
|
||||
string path = openScenes[i].Path;
|
||||
|
||||
/* Make sure asset exists before trying to reopen scene.
|
||||
* Its possible the dev had a scene open that wasn't saved, which
|
||||
* would otherwise result in an error here. */
|
||||
SceneAsset sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(path);
|
||||
if (sceneAsset != null)
|
||||
{
|
||||
OpenSceneMode mode = i == 0 ? OpenSceneMode.Single : OpenSceneMode.Additive;
|
||||
EditorSceneManager.OpenScene(path, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changedObjects > 0)
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
string saveText = _sceneReserializeType == ReserializeSceneType.OpenScenes && changedObjects > 0 ? " Please save your open scenes." : string.Empty;
|
||||
Debug.Log($"Checked {checkedObjects} NetworkObjects over {checkedScenes} scenes. {changedObjects} sceneIds were generated. {duplicateNetworkObjectsRemoved} duplicate NetworkObject components were removed. {saveText}");
|
||||
|
||||
LogColoredText($"Scene NetworkObjects refreshed.", UPGRADE_PART_COLOR);
|
||||
|
||||
List<OpenScene> GetOpenScenes()
|
||||
{
|
||||
List<OpenScene> result = new();
|
||||
int sceneCount = UnitySceneManagement.SceneManager.sceneCount;
|
||||
for (int i = 0; i < sceneCount; i++)
|
||||
{
|
||||
UnityScene scene = UnitySceneManagement.SceneManager.GetSceneAt(i);
|
||||
if (scene.isLoaded)
|
||||
result.Add(new(scene));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes NetworkObjects for specified scenes.
|
||||
/// </summary>
|
||||
private static void ReserializeScenes(List<SceneAsset> sceneAssets, ref int checkedScenes, ref int checkedObjects, ref int changedObjects, ref int duplicateNetworkObjectsRemoved)
|
||||
{
|
||||
foreach (SceneAsset sa in sceneAssets)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath(sa);
|
||||
UnityScene scene = EditorSceneManager.OpenScene(path, OpenSceneMode.Single);
|
||||
List<NetworkObject> foundNobs = NetworkObject.CreateSceneId(scene, force: true, out int changed);
|
||||
|
||||
foreach (NetworkObject n in foundNobs)
|
||||
{
|
||||
duplicateNetworkObjectsRemoved += n.RemoveDuplicateNetworkObjects();
|
||||
n.ReserializeEditorSetValues(setWasActiveDuringEdit: true, setSceneId: false);
|
||||
}
|
||||
|
||||
EditorSceneManager.SaveScene(scene);
|
||||
|
||||
checkedScenes++;
|
||||
checkedObjects += foundNobs.Count;
|
||||
changedObjects += changed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes NetworkObjects in OpenScenes.
|
||||
/// </summary>
|
||||
private static void ReserializeScenes(List<OpenScene> openScenes, ref int checkedScenes, ref int checkedObjects, ref int changedObjects, ref int duplicateNetworkObjectsRemoved)
|
||||
{
|
||||
foreach (OpenScene os in openScenes)
|
||||
{
|
||||
List<NetworkObject> foundNobs = NetworkObject.CreateSceneId(os.Scene, force: true, out int changed);
|
||||
|
||||
foreach (NetworkObject n in foundNobs)
|
||||
{
|
||||
duplicateNetworkObjectsRemoved += n.RemoveDuplicateNetworkObjects();
|
||||
n.ReserializeEditorSetValues(setWasActiveDuringEdit: true, setSceneId: false);
|
||||
}
|
||||
|
||||
checkedScenes++;
|
||||
checkedObjects += foundNobs.Count;
|
||||
changedObjects += changed;
|
||||
}
|
||||
}
|
||||
|
||||
private static void LogColoredText(string txt, string hexColor)
|
||||
{
|
||||
Debug.Log($"<color=#{hexColor}>{txt}</color>");
|
||||
}
|
||||
|
||||
private static Texture2D MakeBackgroundTexture(int width, int height, Color color)
|
||||
{
|
||||
Color[] pixels = new Color[width * height];
|
||||
for (int i = 0; i < pixels.Length; i++)
|
||||
pixels[i] = color;
|
||||
Texture2D backgroundTexture = new(width, height);
|
||||
backgroundTexture.SetPixels(pixels);
|
||||
backgroundTexture.Apply();
|
||||
return backgroundTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0f2e650746c37949a9dd7b96e7c6f65
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/ReserializeNetworkObjectsEditor.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,165 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using FishNet.Configuring;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Editing
|
||||
{
|
||||
/// <summary>
|
||||
/// Contributed by YarnCat! Thank you!
|
||||
/// </summary>
|
||||
public class ReviewReminderEditor : EditorWindow
|
||||
{
|
||||
private Texture2D _fishnetLogo, _reviewButtonBg, _reviewButtonBgHover;
|
||||
private GUIStyle _labelStyle, _reviewButtonStyle;
|
||||
private const string DATETIME_REMINDED = "ReviewDateTimeReminded";
|
||||
private const string CHECK_REMIND_COUNT = "CheckRemindCount";
|
||||
private const string IS_ENABLED = "ReminderEnabled";
|
||||
private static ReviewReminderEditor _window;
|
||||
|
||||
internal static void CheckRemindToReview()
|
||||
{
|
||||
bool reminderEnabled = EditorPrefs.GetBool(IS_ENABLED, true);
|
||||
if (!reminderEnabled)
|
||||
return;
|
||||
|
||||
/* Require at least two opens and 10 days
|
||||
* to be passed before reminding. */
|
||||
int checkRemindCount = EditorPrefs.GetInt(CHECK_REMIND_COUNT, 0) + 1;
|
||||
EditorPrefs.SetInt(CHECK_REMIND_COUNT, checkRemindCount);
|
||||
|
||||
// Not enough checks.
|
||||
if (checkRemindCount < 2)
|
||||
return;
|
||||
|
||||
string dtStr = EditorPrefs.GetString(DATETIME_REMINDED, string.Empty);
|
||||
// Somehow got cleared. Reset.
|
||||
if (string.IsNullOrWhiteSpace(dtStr))
|
||||
{
|
||||
ResetDateTimeReminded();
|
||||
return;
|
||||
}
|
||||
long binary;
|
||||
//Failed to parse.
|
||||
if (!long.TryParse(dtStr, out binary))
|
||||
{
|
||||
ResetDateTimeReminded();
|
||||
return;
|
||||
}
|
||||
//Not enough time passed.
|
||||
DateTime dt = DateTime.FromBinary(binary);
|
||||
|
||||
if ((DateTime.Now - dt).TotalDays < 10)
|
||||
return;
|
||||
|
||||
//If here then the reminder can be shown.
|
||||
EditorPrefs.SetInt(CHECK_REMIND_COUNT, 0);
|
||||
ResetDateTimeReminded();
|
||||
|
||||
ShowReminder();
|
||||
}
|
||||
|
||||
internal static void ResetDateTimeReminded()
|
||||
{
|
||||
EditorPrefs.SetString(DATETIME_REMINDED, DateTime.Now.ToBinary().ToString());
|
||||
}
|
||||
|
||||
private static void ShowReminder()
|
||||
{
|
||||
InitializeWindow();
|
||||
}
|
||||
|
||||
private static void InitializeWindow()
|
||||
{
|
||||
if (_window != null)
|
||||
return;
|
||||
_window = (ReviewReminderEditor)GetWindow(typeof(ReviewReminderEditor));
|
||||
_window.position = new(0f, 0f, 320f, 300f);
|
||||
Rect mainPos;
|
||||
mainPos = EditorGUIUtility.GetMainWindowPosition();
|
||||
Rect pos = _window.position;
|
||||
float w = (mainPos.width - pos.width) * 0.5f;
|
||||
float h = (mainPos.height - pos.height) * 0.5f;
|
||||
pos.x = mainPos.x + w;
|
||||
pos.y = mainPos.y + h;
|
||||
_window.position = pos;
|
||||
}
|
||||
|
||||
private static void StyleWindow()
|
||||
{
|
||||
InitializeWindow();
|
||||
_window._fishnetLogo = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/FishNet/Runtime/Editor/Textures/UI/Logo_With_Text.png", typeof(Texture));
|
||||
_window._labelStyle = new("label");
|
||||
_window._labelStyle.fontSize = 24;
|
||||
_window._labelStyle.wordWrap = true;
|
||||
//window.labelStyle.alignment = TextAnchor.MiddleCenter;
|
||||
_window._labelStyle.normal.textColor = new Color32(74, 195, 255, 255);
|
||||
|
||||
_window._reviewButtonBg = MakeBackgroundTexture(1, 1, new Color32(52, 111, 255, 255));
|
||||
_window._reviewButtonBgHover = MakeBackgroundTexture(1, 1, new Color32(99, 153, 255, 255));
|
||||
_window._reviewButtonStyle = new("button");
|
||||
_window._reviewButtonStyle.fontSize = 18;
|
||||
_window._reviewButtonStyle.fontStyle = FontStyle.Bold;
|
||||
_window._reviewButtonStyle.normal.background = _window._reviewButtonBg;
|
||||
_window._reviewButtonStyle.active.background = _window._reviewButtonBgHover;
|
||||
_window._reviewButtonStyle.focused.background = _window._reviewButtonBgHover;
|
||||
_window._reviewButtonStyle.onFocused.background = _window._reviewButtonBgHover;
|
||||
_window._reviewButtonStyle.hover.background = _window._reviewButtonBgHover;
|
||||
_window._reviewButtonStyle.onHover.background = _window._reviewButtonBgHover;
|
||||
_window._reviewButtonStyle.alignment = TextAnchor.MiddleCenter;
|
||||
_window._reviewButtonStyle.normal.textColor = new(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
float thisWidth = position.width;
|
||||
StyleWindow();
|
||||
GUILayout.Box(_fishnetLogo, GUILayout.Width(position.width), GUILayout.Height(160f));
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(8f);
|
||||
GUILayout.Label("Have you considered leaving us a review?", _labelStyle, GUILayout.Width(thisWidth * 0.95f));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Don't Ask Again", GUILayout.Width(position.width)))
|
||||
{
|
||||
Close();
|
||||
EditorPrefs.SetBool(IS_ENABLED, false);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Ask Later", GUILayout.Width(position.width)))
|
||||
{
|
||||
Close();
|
||||
//Application.OpenURL("https://discord.gg/Ta9HgDh4Hj");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Leave A Review", GUILayout.Width(position.width)))
|
||||
{
|
||||
Close();
|
||||
EditorPrefs.SetBool(IS_ENABLED, false);
|
||||
Application.OpenURL("https://assetstore.unity.com/packages/tools/network/fish-net-networking-evolved-207815");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
//GUILayout.Space(20);
|
||||
//_showOnStartupSelected = EditorGUILayout.Popup("Show on Startup", _showOnStartupSelected, showOnStartupOptions);
|
||||
}
|
||||
|
||||
private static Texture2D MakeBackgroundTexture(int width, int height, Color color)
|
||||
{
|
||||
Color[] pixels = new Color[width * height];
|
||||
for (int i = 0; i < pixels.Length; i++)
|
||||
pixels[i] = color;
|
||||
Texture2D backgroundTexture = new(width, height);
|
||||
backgroundTexture.SetPixels(pixels);
|
||||
backgroundTexture.Apply();
|
||||
return backgroundTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4260206b6a57e4243b56437f8f283084
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/ReviewReminderEditor.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,85 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using FishNet.Configuring;
|
||||
using UnitySettingsProviderAttribute = UnityEditor.SettingsProviderAttribute;
|
||||
using UnitySettingsProvider = UnityEditor.SettingsProvider;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FishNet.Configuring.Editing
|
||||
{
|
||||
internal static class SettingsProvider
|
||||
{
|
||||
private static Vector2 _scrollView;
|
||||
|
||||
[UnitySettingsProvider]
|
||||
private static UnitySettingsProvider Create()
|
||||
{
|
||||
return new("Project/Fish-Networking/Configuration", SettingsScope.Project)
|
||||
{
|
||||
label = "Configuration",
|
||||
|
||||
guiHandler = OnGUI,
|
||||
|
||||
keywords = new string[]
|
||||
{
|
||||
"Fish",
|
||||
"Networking",
|
||||
"Configuration"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void OnGUI(string searchContext)
|
||||
{
|
||||
ConfigurationData configuration = Configuration.LoadConfigurationData();
|
||||
|
||||
if (configuration == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Unable to load configuration data.", MessageType.Error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
GUIStyle scrollViewStyle = new()
|
||||
{
|
||||
padding = new(10, 10, 10, 10)
|
||||
};
|
||||
|
||||
_scrollView = GUILayout.BeginScrollView(_scrollView, scrollViewStyle);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
GUIStyle toggleStyle = new(EditorStyles.toggle)
|
||||
{
|
||||
richText = true
|
||||
};
|
||||
|
||||
configuration.CodeStripping.StripReleaseBuilds = GUILayout.Toggle(configuration.CodeStripping.StripReleaseBuilds, $"{ObjectNames.NicifyVariableName(nameof(configuration.CodeStripping.StripReleaseBuilds))} <color=yellow>(Pro Only)</color>", toggleStyle);
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (configuration.CodeStripping.StripReleaseBuilds)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
// Stripping Method.
|
||||
List<string> enumStrings = new();
|
||||
foreach (string item in System.Enum.GetNames(typeof(StrippingTypes)))
|
||||
enumStrings.Add(item);
|
||||
configuration.CodeStripping.StrippingType = EditorGUILayout.Popup($"{ObjectNames.NicifyVariableName(nameof(configuration.CodeStripping.StrippingType))}", (int)configuration.CodeStripping.StrippingType, enumStrings.ToArray());
|
||||
|
||||
EditorGUILayout.HelpBox("Development builds will not have code stripped. Additionally, if you plan to run as host disable code stripping.", MessageType.Warning);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
Configuration.Configurations.Write(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3d7d3c45d53dea4e8a0a7da73d64021
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Editor/Configuring/SettingsProvider.cs
|
||||
uploadId: 866910
|
||||
Reference in New Issue
Block a user