first commit
This commit is contained in:
BIN
Assets/Photon/PhotonUnityNetworking/Code/Editor/CopyIcon.png
Normal file
BIN
Assets/Photon/PhotonUnityNetworking/Code/Editor/CopyIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 131 B |
@ -0,0 +1,116 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1228d93299ce47a8a5ac1a33513aeaf
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: iPhone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Assets/Photon/PhotonUnityNetworking/Code/Editor/CopyIconPro.png
Normal file
BIN
Assets/Photon/PhotonUnityNetworking/Code/Editor/CopyIconPro.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,116 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81b8e0c5ffa3345b7aa3af3a2c0257ce
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: iPhone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
855
Assets/Photon/PhotonUnityNetworking/Code/Editor/PhotonEditor.cs
Normal file
855
Assets/Photon/PhotonUnityNetworking/Code/Editor/PhotonEditor.cs
Normal file
@ -0,0 +1,855 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonEditor.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// MenuItems and in-Editor scripts for PhotonNetwork.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEditor.Compilation;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
using Realtime;
|
||||
|
||||
|
||||
public class PunWizardText
|
||||
{
|
||||
public string WindowTitle = "PUN Wizard";
|
||||
public string SetupWizardWarningTitle = "Warning";
|
||||
public string SetupWizardWarningMessage = "You have not yet run the Photon setup wizard! Your game won't be able to connect. See Windows -> Photon Unity Networking.";
|
||||
public string MainMenuButton = "Main Menu";
|
||||
public string SetupWizardTitle = "PUN Setup";
|
||||
public string SetupWizardInfo = "Thanks for importing Photon Unity Networking.\nThis window should set you up.\n\n<b>-</b> To use an existing Photon Cloud App, enter your AppId.\n<b>-</b> To register an account or access an existing one, enter the account's mail address.\n<b>-</b> To use Photon OnPremise, skip this step.";
|
||||
public string EmailOrAppIdLabel = "AppId or Email";
|
||||
public string AlreadyRegisteredInfo = "The email is registered so we can't fetch your AppId (without password).\n\nPlease login online to get your AppId and paste it above.";
|
||||
public string SkipRegistrationInfo = "Skipping? No problem:\nEdit your server settings in the PhotonServerSettings file.";
|
||||
public string RegisteredNewAccountInfo = "We created a (free) account and fetched you an AppId.\nWelcome. Your PUN project is setup.";
|
||||
public string AppliedToSettingsInfo = "Your AppId is now applied to this project.";
|
||||
public string SetupCompleteInfo = "<b>Done!</b>\nAll connection settings can be edited in the <b>PhotonServerSettings</b> now.\nHave a look.";
|
||||
public string CloseWindowButton = "Close";
|
||||
public string SkipButton = "Skip";
|
||||
public string SetupButton = "Setup Project";
|
||||
public string CancelButton = "Cancel";
|
||||
public string PUNWizardLabel = "PUN Wizard";
|
||||
public string SettingsButton = "Settings:";
|
||||
public string SetupServerCloudLabel = "Setup wizard for setting up your own server or the cloud.";
|
||||
public string WarningPhotonDisconnect = "Disconnecting PUN due to recompile. Exit PlayMode.";
|
||||
public string StartButton = "Start";
|
||||
public string LocateSettingsButton = "Locate PhotonServerSettings";
|
||||
public string SettingsHighlightLabel = "Highlights the used photon settings file in the project.";
|
||||
public string DocumentationLabel = "Documentation:";
|
||||
public string OpenPDFText = "Reference PDF";
|
||||
public string OpenPDFTooltip = "Opens the local documentation pdf.";
|
||||
public string OpenDevNetText = "Doc Pages / Manual";
|
||||
public string OpenDevNetTooltip = "Online documentation for Photon.";
|
||||
public string OpenCloudDashboardText = "Cloud Dashboard Login";
|
||||
public string OpenCloudDashboardTooltip = "Review Cloud App information and statistics.";
|
||||
public string OpenForumText = "Open Forum";
|
||||
public string OpenForumTooltip = "Online support for Photon.";
|
||||
public string OkButton = "Ok";
|
||||
public string OwnHostCloudCompareLabel = "How 'my own host' compares to 'cloud'.";
|
||||
public string ComparisonPageButton = "Cloud versus OnPremise";
|
||||
public string ConnectionTitle = "Connecting";
|
||||
public string ConnectionInfo = "Connecting to the account service...";
|
||||
public string ErrorTextTitle = "Error";
|
||||
public string IncorrectRPCListTitle = "Warning: RPC-list becoming incompatible!";
|
||||
public string IncorrectRPCListLabel = "Your project's RPC-list is full, so we can't add some RPCs just compiled.\n\nBy removing outdated RPCs, the list will be long enough but incompatible with older client builds!\n\nMake sure you change the game version where you use PhotonNetwork.ConnectUsingSettings().";
|
||||
public string RemoveOutdatedRPCsLabel = "Remove outdated RPCs";
|
||||
public string FullRPCListTitle = "Warning: RPC-list is full!";
|
||||
public string FullRPCListLabel = "Your project's RPC-list is too long for PUN.\n\nYou can change PUN's source to use short-typed RPC index. Look for comments 'LIMITS RPC COUNT'\n\nAlternatively, remove some RPC methods (use more parameters per RPC maybe).\n\nAfter a RPC-list refresh, make sure you change the game version where you use PhotonNetwork.ConnectUsingSettings().";
|
||||
public string SkipRPCListUpdateLabel = "Skip RPC-list update";
|
||||
public string PUNNameReplaceTitle = "Warning: RPC-list Compatibility";
|
||||
public string PUNNameReplaceLabel = "PUN replaces RPC names with numbers by using the RPC-list. All clients must use the same list for that.\n\nClearing it most likely makes your client incompatible with previous versions! Change your game version or make sure the RPC-list matches other clients.";
|
||||
public string RPCListCleared = "Clear RPC-list";
|
||||
public string ServerSettingsCleanedWarning = "Cleared the PhotonServerSettings.RpcList, which breaks compatibility with older builds. You should update the \"App Version\" in the PhotonServerSettings to avoid issues.";
|
||||
public string WizardMainWindowInfo = "This window should help you find important settings for PUN, as well as documentation.";
|
||||
}
|
||||
|
||||
|
||||
public class PhotonEditor : EditorWindow
|
||||
{
|
||||
protected static Type WindowType = typeof(PhotonEditor);
|
||||
|
||||
protected Vector2 scrollPos = Vector2.zero;
|
||||
|
||||
private readonly Vector2 preferredSize = new Vector2(350, 400);
|
||||
|
||||
private static Texture2D BackgroundImage;
|
||||
|
||||
public static PunWizardText CurrentLang = new PunWizardText();
|
||||
|
||||
/// <summary>
|
||||
/// third parties custom token
|
||||
/// </summary>
|
||||
public static string CustomToken = null;
|
||||
|
||||
/// <summary>
|
||||
/// third parties custom context
|
||||
/// </summary>
|
||||
public static string CustomContext = null;
|
||||
|
||||
protected static string DocumentationLocation = "Assets/Photon/PhotonNetworking-Documentation.pdf";
|
||||
|
||||
protected static string UrlFreeLicense = "https://dashboard.photonengine.com/en-US/SelfHosted";
|
||||
|
||||
public const string UrlDevNet = "https://doc.photonengine.com/en-us/pun/v2";
|
||||
|
||||
protected static string UrlForum = "https://forum.photonengine.com";
|
||||
|
||||
protected static string UrlCompare = "https://doc.photonengine.com/en-us/realtime/current/getting-started/onpremise-or-saas";
|
||||
|
||||
protected static string UrlHowToSetup = "https://doc.photonengine.com/en-us/onpremise/current/getting-started/photon-server-in-5min";
|
||||
|
||||
protected static string UrlAppIDExplained = "https://doc.photonengine.com/en-us/realtime/current/getting-started/obtain-your-app-id";
|
||||
|
||||
public const string UrlCloudDashboard = "https://dashboard.photonengine.com/en-US/account/signin?email=";
|
||||
|
||||
public const string UrlPunSettings = "https://doc.photonengine.com/en-us/pun/v2/getting-started/initial-setup"; // the SeverSettings class has this url directly in it's HelpURL attribute.
|
||||
|
||||
private enum PhotonSetupStates
|
||||
{
|
||||
MainUi,
|
||||
|
||||
RegisterForPhotonCloud,
|
||||
|
||||
EmailAlreadyRegistered,
|
||||
|
||||
GoEditPhotonServerSettings,
|
||||
|
||||
EmailRegistrationPending
|
||||
}
|
||||
|
||||
private bool isSetupWizard = false;
|
||||
|
||||
private PhotonSetupStates photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
|
||||
|
||||
|
||||
private bool minimumInput = false;
|
||||
private bool useMail = false;
|
||||
private bool useAppId = false;
|
||||
private bool useSkip = false;
|
||||
private bool highlightedSettings = false;
|
||||
private bool close = false;
|
||||
private string mailOrAppId = string.Empty;
|
||||
|
||||
|
||||
private static double lastWarning = 0;
|
||||
private static bool postInspectorUpdate;
|
||||
|
||||
|
||||
|
||||
[MenuItem("Window/Photon Unity Networking/PUN Wizard &p", false, 0)]
|
||||
protected static void MenuItemOpenWizard()
|
||||
{
|
||||
PhotonEditor win = GetWindow<PhotonEditor>(false, CurrentLang.WindowTitle, true);
|
||||
if (win == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
win.photonSetupState = PhotonSetupStates.MainUi;
|
||||
win.isSetupWizard = false;
|
||||
}
|
||||
|
||||
[MenuItem("Window/Photon Unity Networking/Highlight Server Settings %#&p", false, 1)]
|
||||
protected static void MenuItemHighlightSettings()
|
||||
{
|
||||
HighlightSettings();
|
||||
}
|
||||
|
||||
|
||||
|
||||
[UnityEditor.InitializeOnLoadMethod]
|
||||
public static void InitializeOnLoadMethod()
|
||||
{
|
||||
//Debug.Log("InitializeOnLoadMethod()");
|
||||
EditorApplication.delayCall += OnDelayCall;
|
||||
}
|
||||
|
||||
|
||||
// used to register for various events (post-load)
|
||||
private static void OnDelayCall()
|
||||
{
|
||||
//Debug.Log("OnDelayCall()");
|
||||
|
||||
postInspectorUpdate = true;
|
||||
|
||||
EditorApplication.playModeStateChanged -= PlayModeStateChanged;
|
||||
EditorApplication.playModeStateChanged += PlayModeStateChanged;
|
||||
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
CompilationPipeline.compilationStarted -= OnCompileStarted21;
|
||||
CompilationPipeline.compilationStarted += OnCompileStarted21;
|
||||
#else
|
||||
CompilationPipeline.assemblyCompilationStarted -= OnCompileStarted;
|
||||
CompilationPipeline.assemblyCompilationStarted += OnCompileStarted;
|
||||
#endif
|
||||
|
||||
#if (UNITY_2018 || UNITY_2018_1_OR_NEWER)
|
||||
EditorApplication.projectChanged -= OnProjectChanged;
|
||||
EditorApplication.projectChanged += OnProjectChanged;
|
||||
#else
|
||||
EditorApplication.projectWindowChanged -= OnProjectChanged;
|
||||
EditorApplication.projectWindowChanged += OnProjectChanged;
|
||||
#endif
|
||||
|
||||
|
||||
if (!EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
OnProjectChanged(); // call this initially from here, as the project change events happened earlier (on start of the Editor)
|
||||
PhotonEditor.UpdateRpcList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// called in editor, opens wizard for initial setup, keeps scene PhotonViews up to date and closes connections when compiling (to avoid issues)
|
||||
private static void OnProjectChanged()
|
||||
{
|
||||
PhotonEditorUtils.ProjectChangedWasCalled = true;
|
||||
|
||||
|
||||
// Prevent issues with Unity Cloud Builds where ServerSettings are not found.
|
||||
// Also, within the context of a Unity Cloud Build, ServerSettings is already present anyway.
|
||||
#if UNITY_CLOUD_BUILD
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (PhotonNetwork.PhotonServerSettings == null || PhotonNetwork.PhotonServerSettings.AppSettings == null || string.IsNullOrEmpty(PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime))
|
||||
{
|
||||
PhotonNetwork.LoadOrCreateSettings(true);
|
||||
}
|
||||
|
||||
if (PhotonNetwork.PhotonServerSettings == null)
|
||||
{
|
||||
// the PhotonServerSettings are loaded or created. If both fails, the Editor should probably not run (anymore).
|
||||
return;
|
||||
}
|
||||
|
||||
PunSceneSettings.SanitizeSceneSettings();
|
||||
|
||||
|
||||
// serverSetting is null when the file gets deleted. otherwise, the wizard should only run once and only if hosting option is not (yet) set
|
||||
if (!PhotonNetwork.PhotonServerSettings.DisableAutoOpenWizard)
|
||||
{
|
||||
ShowRegistrationWizard();
|
||||
PhotonNetwork.PhotonServerSettings.DisableAutoOpenWizard = true;
|
||||
PhotonEditor.SaveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_2021_1_OR_NEWER
|
||||
private static void OnCompileStarted21(object obj)
|
||||
{
|
||||
OnCompileStarted(obj as string);
|
||||
}
|
||||
#endif
|
||||
|
||||
private static void OnCompileStarted(string obj)
|
||||
{
|
||||
if (PhotonNetwork.IsConnected)
|
||||
{
|
||||
// log warning, unless there was one recently
|
||||
if (EditorApplication.timeSinceStartup - lastWarning > 3)
|
||||
{
|
||||
Debug.LogWarning(CurrentLang.WarningPhotonDisconnect);
|
||||
lastWarning = EditorApplication.timeSinceStartup;
|
||||
}
|
||||
|
||||
PhotonNetwork.Disconnect();
|
||||
PhotonNetwork.NetworkingClient.LoadBalancingPeer.DispatchIncomingCommands();
|
||||
#if UNITY_2019_4_OR_NEWER && UNITY_EDITOR
|
||||
EditorApplication.ExitPlaymode();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[DidReloadScripts]
|
||||
private static void OnDidReloadScripts()
|
||||
{
|
||||
//Debug.Log("OnDidReloadScripts() postInspectorUpdate: "+postInspectorUpdate + " isPlayingOrWillChangePlaymode: "+EditorApplication.isPlayingOrWillChangePlaymode);
|
||||
if (postInspectorUpdate && !EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
PhotonEditor.UpdateRpcList(); // could be called when compilation finished (instead of when reload / compile starts)
|
||||
}
|
||||
}
|
||||
|
||||
private static void PlayModeStateChanged(PlayModeStateChange state)
|
||||
{
|
||||
//Debug.Log("PlayModeStateChanged");
|
||||
if (EditorApplication.isPlaying || !EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime) && !PhotonNetwork.PhotonServerSettings.AppSettings.IsMasterServerAddress)
|
||||
{
|
||||
EditorUtility.DisplayDialog(CurrentLang.SetupWizardWarningTitle, CurrentLang.SetupWizardWarningMessage, CurrentLang.OkButton);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region GUI and Wizard
|
||||
|
||||
|
||||
// setup per window
|
||||
public PhotonEditor()
|
||||
{
|
||||
this.minSize = this.preferredSize;
|
||||
}
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
// check if some appid is set. if so, we can avoid registration calls.
|
||||
if (PhotonNetwork.PhotonServerSettings != null && PhotonNetwork.PhotonServerSettings.AppSettings != null && !string.IsNullOrEmpty(PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime))
|
||||
{
|
||||
this.mailOrAppId = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Creates an Editor window, showing the cloud-registration wizard for Photon (entry point to setup PUN).</summary>
|
||||
protected static void ShowRegistrationWizard()
|
||||
{
|
||||
PhotonEditor win = GetWindow(WindowType, false, CurrentLang.WindowTitle, true) as PhotonEditor;
|
||||
if (win == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
win.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
|
||||
win.isSetupWizard = true;
|
||||
}
|
||||
|
||||
// Window Update() callback. On-demand, when Window is open
|
||||
protected void Update()
|
||||
{
|
||||
if (this.close)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnGUI()
|
||||
{
|
||||
if (BackgroundImage == null)
|
||||
{
|
||||
string[] paths = AssetDatabase.FindAssets("PunGradient t:Texture2D");
|
||||
if (paths != null && paths.Length > 0)
|
||||
{
|
||||
BackgroundImage = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(paths[0]));
|
||||
}
|
||||
}
|
||||
|
||||
PhotonSetupStates oldGuiState = this.photonSetupState; // used to fix an annoying Editor input field issue: wont refresh until focus is changed.
|
||||
|
||||
GUI.SetNextControlName(string.Empty);
|
||||
this.scrollPos = GUILayout.BeginScrollView(this.scrollPos);
|
||||
|
||||
|
||||
if (this.photonSetupState == PhotonSetupStates.MainUi)
|
||||
{
|
||||
this.UiMainWizard();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(this.photonSetupState == PhotonSetupStates.EmailRegistrationPending);
|
||||
this.UiSetupApp();
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
if (oldGuiState != this.photonSetupState)
|
||||
{
|
||||
GUI.FocusControl(string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private string emailSentToAccount;
|
||||
private bool emailSentToAccountIsRegistered;
|
||||
|
||||
|
||||
protected virtual void UiSetupApp()
|
||||
{
|
||||
GUI.skin.label.wordWrap = true;
|
||||
if (!this.isSetupWizard)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(CurrentLang.MainMenuButton, GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.MainUi;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
// setup header
|
||||
this.UiTitleBox(CurrentLang.SetupWizardTitle, BackgroundImage);
|
||||
|
||||
// setup info text
|
||||
GUI.skin.label.richText = true;
|
||||
GUILayout.Label(CurrentLang.SetupWizardInfo);
|
||||
|
||||
// input of appid or mail
|
||||
EditorGUILayout.Separator();
|
||||
GUILayout.Label(CurrentLang.EmailOrAppIdLabel);
|
||||
this.minimumInput = false;
|
||||
this.useMail = false;
|
||||
this.useAppId = false;
|
||||
this.mailOrAppId = EditorGUILayout.TextField(this.mailOrAppId);
|
||||
if (!string.IsNullOrEmpty(this.mailOrAppId))
|
||||
{
|
||||
this.mailOrAppId = this.mailOrAppId.Trim(); // note: we trim all input
|
||||
if (AccountService.IsValidEmail(this.mailOrAppId))
|
||||
{
|
||||
// input should be a mail address
|
||||
this.useMail = true;
|
||||
|
||||
// check if the current input equals earlier input, which is known to be registered already
|
||||
this.minimumInput = !this.mailOrAppId.Equals(this.emailSentToAccount) || !this.emailSentToAccountIsRegistered;
|
||||
}
|
||||
else if (ServerSettings.IsAppId(this.mailOrAppId))
|
||||
{
|
||||
// this should be an appId
|
||||
this.minimumInput = true;
|
||||
this.useAppId = true;
|
||||
}
|
||||
}
|
||||
|
||||
// button to skip setup
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(CurrentLang.SkipButton, GUILayout.Width(100)))
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.GoEditPhotonServerSettings;
|
||||
this.useSkip = true;
|
||||
this.useMail = false;
|
||||
this.useAppId = false;
|
||||
}
|
||||
|
||||
// SETUP button
|
||||
EditorGUI.BeginDisabledGroup(!this.minimumInput);
|
||||
if (GUILayout.Button(CurrentLang.SetupButton, GUILayout.Width(100)))
|
||||
{
|
||||
this.useSkip = false;
|
||||
GUIUtility.keyboardControl = 0;
|
||||
if (this.useMail)
|
||||
{
|
||||
this.RegisterWithEmail(this.mailOrAppId); // sets state
|
||||
}
|
||||
else if (this.useAppId)
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.GoEditPhotonServerSettings;
|
||||
Undo.RecordObject(PhotonNetwork.PhotonServerSettings, "Update PhotonServerSettings for PUN");
|
||||
PhotonNetwork.PhotonServerSettings.UseCloud(this.mailOrAppId);
|
||||
PhotonEditor.SaveSettings();
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
// existing account needs to fetch AppId online
|
||||
if (this.photonSetupState == PhotonSetupStates.EmailAlreadyRegistered)
|
||||
{
|
||||
// button to open dashboard and get the AppId
|
||||
GUILayout.Space(15);
|
||||
GUILayout.Label(CurrentLang.AlreadyRegisteredInfo);
|
||||
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(new GUIContent(CurrentLang.OpenCloudDashboardText, CurrentLang.OpenCloudDashboardTooltip), GUILayout.Width(205)))
|
||||
{
|
||||
Application.OpenURL(string.Concat(UrlCloudDashboard, Uri.EscapeUriString(this.mailOrAppId)));
|
||||
this.mailOrAppId = string.Empty;
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
else if (this.photonSetupState == PhotonSetupStates.GoEditPhotonServerSettings)
|
||||
{
|
||||
if (!this.highlightedSettings)
|
||||
{
|
||||
this.highlightedSettings = true;
|
||||
HighlightSettings();
|
||||
}
|
||||
|
||||
GUILayout.Space(15);
|
||||
if (this.useSkip)
|
||||
{
|
||||
GUILayout.Label(CurrentLang.SkipRegistrationInfo);
|
||||
}
|
||||
else if (this.useMail)
|
||||
{
|
||||
GUILayout.Label(CurrentLang.RegisteredNewAccountInfo);
|
||||
}
|
||||
else if (this.useAppId)
|
||||
{
|
||||
GUILayout.Label(CurrentLang.AppliedToSettingsInfo);
|
||||
}
|
||||
|
||||
|
||||
// setup-complete info
|
||||
GUILayout.Space(15);
|
||||
GUILayout.Label(CurrentLang.SetupCompleteInfo);
|
||||
|
||||
|
||||
// close window (done)
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(CurrentLang.CloseWindowButton, GUILayout.Width(205)))
|
||||
{
|
||||
this.close = true;
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
GUI.skin.label.richText = false;
|
||||
}
|
||||
|
||||
private void UiTitleBox(string title, Texture2D bgIcon)
|
||||
{
|
||||
GUIStyle bgStyle = EditorGUIUtility.isProSkin ? new GUIStyle(GUI.skin.GetStyle("Label")) : new GUIStyle(GUI.skin.GetStyle("WhiteLabel"));
|
||||
bgStyle.padding = new RectOffset(10, 10, 10, 10);
|
||||
bgStyle.fontSize = 22;
|
||||
bgStyle.fontStyle = FontStyle.Bold;
|
||||
if (bgIcon != null)
|
||||
{
|
||||
bgStyle.normal.background = bgIcon;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
Rect scale = GUILayoutUtility.GetLastRect();
|
||||
scale.height = 44;
|
||||
|
||||
GUI.Label(scale, title, bgStyle);
|
||||
GUILayout.Space(scale.height + 5);
|
||||
}
|
||||
|
||||
protected virtual void UiMainWizard()
|
||||
{
|
||||
GUILayout.Space(15);
|
||||
|
||||
// title
|
||||
this.UiTitleBox(CurrentLang.PUNWizardLabel, BackgroundImage);
|
||||
|
||||
EditorGUILayout.BeginVertical(new GUIStyle() { padding = new RectOffset(10, 10, 10, 10) });
|
||||
|
||||
// wizard info text
|
||||
GUILayout.Label(CurrentLang.WizardMainWindowInfo, new GUIStyle("Label") { wordWrap = true });
|
||||
GUILayout.Space(15);
|
||||
|
||||
|
||||
// settings button
|
||||
GUILayout.Label(CurrentLang.SettingsButton, EditorStyles.boldLabel);
|
||||
|
||||
if (GUILayout.Button(new GUIContent(CurrentLang.LocateSettingsButton, CurrentLang.SettingsHighlightLabel)))
|
||||
{
|
||||
HighlightSettings();
|
||||
}
|
||||
if (GUILayout.Button(new GUIContent(CurrentLang.OpenCloudDashboardText, CurrentLang.OpenCloudDashboardTooltip)))
|
||||
{
|
||||
Application.OpenURL(UrlCloudDashboard + Uri.EscapeUriString(this.mailOrAppId));
|
||||
}
|
||||
if (GUILayout.Button(new GUIContent(CurrentLang.SetupButton, CurrentLang.SetupServerCloudLabel)))
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
|
||||
}
|
||||
|
||||
GUILayout.Space(15);
|
||||
|
||||
|
||||
// documentation
|
||||
GUILayout.Label(CurrentLang.DocumentationLabel, EditorStyles.boldLabel);
|
||||
|
||||
if (GUILayout.Button(new GUIContent(CurrentLang.OpenPDFText, CurrentLang.OpenPDFTooltip)))
|
||||
{
|
||||
EditorUtility.OpenWithDefaultApp(DocumentationLocation);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(new GUIContent(CurrentLang.OpenDevNetText, CurrentLang.OpenDevNetTooltip)))
|
||||
{
|
||||
Application.OpenURL(UrlDevNet);
|
||||
}
|
||||
|
||||
GUI.skin.label.wordWrap = true;
|
||||
GUILayout.Label(CurrentLang.OwnHostCloudCompareLabel);
|
||||
if (GUILayout.Button(CurrentLang.ComparisonPageButton))
|
||||
{
|
||||
Application.OpenURL(UrlCompare);
|
||||
}
|
||||
|
||||
|
||||
if (GUILayout.Button(new GUIContent(CurrentLang.OpenForumText, CurrentLang.OpenForumTooltip)))
|
||||
{
|
||||
Application.OpenURL(UrlForum);
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private AccountService serviceClient;
|
||||
protected virtual void RegisterWithEmail(string email)
|
||||
{
|
||||
List<ServiceTypes> types = new List<ServiceTypes>();
|
||||
types.Add(ServiceTypes.Pun);
|
||||
if (PhotonEditorUtils.HasChat)
|
||||
{
|
||||
types.Add(ServiceTypes.Chat);
|
||||
}
|
||||
if (PhotonEditorUtils.HasVoice)
|
||||
{
|
||||
types.Add(ServiceTypes.Voice);
|
||||
}
|
||||
|
||||
|
||||
if (this.serviceClient == null)
|
||||
{
|
||||
this.serviceClient = new AccountService();
|
||||
this.serviceClient.CustomToken = CustomToken;
|
||||
this.serviceClient.CustomContext = CustomContext;
|
||||
}
|
||||
else
|
||||
{
|
||||
// while RegisterByEmail will check RequestPendingResult below, it would also display an error message. no needed in this case
|
||||
if (this.serviceClient.RequestPendingResult)
|
||||
{
|
||||
Debug.LogWarning("Registration request is pending a response. Please wait.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.emailSentToAccount = email;
|
||||
this.emailSentToAccountIsRegistered = false;
|
||||
|
||||
if (this.serviceClient.RegisterByEmail(email, types, RegisterWithEmailSuccessCallback, RegisterWithEmailErrorCallback, "PUN"+PhotonNetwork.PunVersion))
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.EmailRegistrationPending;
|
||||
EditorUtility.DisplayProgressBar(CurrentLang.ConnectionTitle, CurrentLang.ConnectionInfo, 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.DisplayErrorMessage("Email registration request could not be sent. Retry again or check error logs and contact support.");
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterWithEmailSuccessCallback(AccountServiceResponse res)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
this.emailSentToAccountIsRegistered = true; // email is either registered now, or was already
|
||||
|
||||
if (res.ReturnCode == AccountServiceReturnCodes.Success)
|
||||
{
|
||||
string key = ((int) ServiceTypes.Pun).ToString();
|
||||
string appId;
|
||||
if (res.ApplicationIds.TryGetValue(key, out appId))
|
||||
{
|
||||
this.mailOrAppId = appId;
|
||||
PhotonNetwork.PhotonServerSettings.UseCloud(this.mailOrAppId, null);
|
||||
key = ((int) ServiceTypes.Chat).ToString();
|
||||
if (res.ApplicationIds.TryGetValue(key, out appId))
|
||||
{
|
||||
PhotonNetwork.PhotonServerSettings.AppSettings.AppIdChat = appId;
|
||||
}
|
||||
else if (PhotonEditorUtils.HasChat)
|
||||
{
|
||||
Debug.LogWarning("Registration successful but no Chat AppId returned");
|
||||
}
|
||||
key = ((int) ServiceTypes.Voice).ToString();
|
||||
if (res.ApplicationIds.TryGetValue(key, out appId))
|
||||
{
|
||||
PhotonNetwork.PhotonServerSettings.AppSettings.AppIdVoice = appId;
|
||||
}
|
||||
else if (PhotonEditorUtils.HasVoice)
|
||||
{
|
||||
Debug.LogWarning("Registration successful but no Voice AppId returned");
|
||||
}
|
||||
PhotonEditor.SaveSettings();
|
||||
this.photonSetupState = PhotonSetupStates.GoEditPhotonServerSettings;
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayErrorMessage("Registration successful but no PUN AppId returned");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PhotonEditor.SaveSettings();
|
||||
|
||||
if (res.ReturnCode == AccountServiceReturnCodes.EmailAlreadyRegistered)
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.EmailAlreadyRegistered;
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayErrorMessage(res.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterWithEmailErrorCallback(string error)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
DisplayErrorMessage(error);
|
||||
}
|
||||
|
||||
private void DisplayErrorMessage(string error)
|
||||
{
|
||||
EditorUtility.DisplayDialog(CurrentLang.ErrorTextTitle, error, CurrentLang.OkButton);
|
||||
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
|
||||
}
|
||||
|
||||
// Pings PhotonServerSettings and makes it selected (show in Inspector)
|
||||
private static void HighlightSettings()
|
||||
{
|
||||
ServerSettings serverSettings = (ServerSettings)Resources.Load(PhotonNetwork.ServerSettingsFileName, typeof(ServerSettings));
|
||||
Selection.objects = new UnityEngine.Object[] { serverSettings };
|
||||
EditorGUIUtility.PingObject(serverSettings);
|
||||
}
|
||||
|
||||
// Marks settings object as dirty, so it gets saved.
|
||||
// unity 5.3 changes the usecase for SetDirty(). but here we don't modify a scene object! so it's ok to use
|
||||
private static void SaveSettings()
|
||||
{
|
||||
EditorUtility.SetDirty(PhotonNetwork.PhotonServerSettings);
|
||||
}
|
||||
|
||||
#region RPC List Handling
|
||||
|
||||
|
||||
public static void UpdateRpcList()
|
||||
{
|
||||
//Debug.Log("UpdateRpcList()");
|
||||
|
||||
if (PhotonNetwork.PhotonServerSettings == null)
|
||||
{
|
||||
Debug.LogWarning("UpdateRpcList() wasn not able to access the PhotonServerSettings. Not updating the RPCs.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// check all "script assemblies" for methods with PunRPC attribute
|
||||
List<string> additionalRpcs = new List<string>(); // not yet listed rpc-method names go here
|
||||
List<string> allRpcs = new List<string>();
|
||||
|
||||
|
||||
#if UNITY_2019_2_OR_NEWER
|
||||
|
||||
// we can make use of the new TypeCache to find methods with PunRPC attribute
|
||||
var extractedMethods = TypeCache.GetMethodsWithAttribute<PunRPC>();
|
||||
foreach (var methodInfo in extractedMethods)
|
||||
{
|
||||
allRpcs.Add(methodInfo.Name);
|
||||
if (!PhotonNetwork.PhotonServerSettings.RpcList.Contains(methodInfo.Name) && !additionalRpcs.Contains(methodInfo.Name))
|
||||
{
|
||||
additionalRpcs.Add(methodInfo.Name);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies().Where(a => !(a.ManifestModule is System.Reflection.Emit.ModuleBuilder)).ToArray();
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
if (!assembly.Location.Contains("ScriptAssemblies") || assembly.FullName.StartsWith("Assembly-CSharp-Editor"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var types = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(MonoBehaviour)));
|
||||
var methodInfos = types.SelectMany(t => t.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
|
||||
var methodNames = methodInfos.Where(m => m.IsDefined(typeof(PunRPC), false)).Select(mi => mi.Name).ToArray();
|
||||
var additional = methodNames.Where(n => !PhotonNetwork.PhotonServerSettings.RpcList.Contains(n) && !additionalRpcs.Contains(n));
|
||||
|
||||
allRpcs.AddRange(methodNames);
|
||||
additionalRpcs.AddRange(additional);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
if (additionalRpcs.Count <= 0)
|
||||
{
|
||||
//Debug.Log("UpdateRPCs did not found new.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (additionalRpcs.Count + PhotonNetwork.PhotonServerSettings.RpcList.Count >= byte.MaxValue)
|
||||
{
|
||||
if (allRpcs.Count <= byte.MaxValue)
|
||||
{
|
||||
bool clearList = EditorUtility.DisplayDialog(CurrentLang.IncorrectRPCListTitle, CurrentLang.IncorrectRPCListLabel, CurrentLang.RemoveOutdatedRPCsLabel, CurrentLang.CancelButton);
|
||||
if (clearList)
|
||||
{
|
||||
PhotonNetwork.PhotonServerSettings.RpcList.Clear();
|
||||
additionalRpcs = allRpcs.Distinct().ToList(); // we add all unique names
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog(CurrentLang.FullRPCListTitle, CurrentLang.FullRPCListLabel, CurrentLang.SkipRPCListUpdateLabel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
additionalRpcs.Sort();
|
||||
Undo.RecordObject(PhotonNetwork.PhotonServerSettings, "RPC-list update of PUN.");
|
||||
PhotonNetwork.PhotonServerSettings.RpcList.AddRange(additionalRpcs);
|
||||
EditorUtility.SetDirty(PhotonNetwork.PhotonServerSettings);
|
||||
|
||||
//Debug.Log("Updated RPCs. Added: "+additionalRpcs.Count);
|
||||
}
|
||||
|
||||
|
||||
public static void ClearRpcList()
|
||||
{
|
||||
bool clearList = EditorUtility.DisplayDialog(CurrentLang.PUNNameReplaceTitle, CurrentLang.PUNNameReplaceLabel, CurrentLang.RPCListCleared, CurrentLang.CancelButton);
|
||||
if (clearList)
|
||||
{
|
||||
ServerSettings serverSettings = PhotonNetwork.PhotonServerSettings;
|
||||
|
||||
Undo.RecordObject(serverSettings, "RPC-list cleared for PUN.");
|
||||
serverSettings.RpcList.Clear();
|
||||
EditorUtility.SetDirty(serverSettings);
|
||||
|
||||
Debug.LogWarning(CurrentLang.ServerSettingsCleanedWarning);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dabbbed2a74eac44dac281f20d706ba8
|
||||
labels:
|
||||
- ExitGames
|
||||
- PUN
|
||||
- Photon
|
||||
- Networking
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
363
Assets/Photon/PhotonUnityNetworking/Code/Editor/PhotonGUI.cs
Normal file
363
Assets/Photon/PhotonUnityNetworking/Code/Editor/PhotonGUI.cs
Normal file
@ -0,0 +1,363 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonGUI.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// GUI scripts for the Editor.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
public class PhotonGUI
|
||||
{
|
||||
#region Styles
|
||||
|
||||
static GUIStyle m_DefaultTitleStyle;
|
||||
|
||||
public static GUIStyle DefaultTitleStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_DefaultTitleStyle == null)
|
||||
{
|
||||
m_DefaultTitleStyle = new GUIStyle();
|
||||
m_DefaultTitleStyle.border = new RectOffset(2, 2, 2, 1);
|
||||
m_DefaultTitleStyle.margin = new RectOffset(5, 5, 5, 0);
|
||||
m_DefaultTitleStyle.padding = new RectOffset(5, 5, 0, 0);
|
||||
m_DefaultTitleStyle.alignment = TextAnchor.MiddleLeft;
|
||||
m_DefaultTitleStyle.normal.background = ReorderableListResources.texTitleBackground;
|
||||
m_DefaultTitleStyle.normal.textColor = EditorGUIUtility.isProSkin
|
||||
? new Color(0.8f, 0.8f, 0.8f)
|
||||
: new Color(0.2f, 0.2f, 0.2f);
|
||||
}
|
||||
|
||||
return m_DefaultTitleStyle;
|
||||
}
|
||||
}
|
||||
|
||||
static GUIStyle m_DefaultContainerStyle;
|
||||
|
||||
public static GUIStyle DefaultContainerStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_DefaultContainerStyle == null)
|
||||
{
|
||||
m_DefaultContainerStyle = new GUIStyle();
|
||||
m_DefaultContainerStyle.border = new RectOffset(2, 2, 1, 2);
|
||||
m_DefaultContainerStyle.margin = new RectOffset(5, 5, 5, 5);
|
||||
m_DefaultContainerStyle.padding = new RectOffset(1, 1, 2, 2);
|
||||
m_DefaultContainerStyle.normal.background = ReorderableListResources.texContainerBackground;
|
||||
}
|
||||
|
||||
return m_DefaultContainerStyle;
|
||||
}
|
||||
}
|
||||
|
||||
static GUIStyle m_DefaultAddButtonStyle;
|
||||
|
||||
public static GUIStyle DefaultAddButtonStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_DefaultAddButtonStyle == null)
|
||||
{
|
||||
m_DefaultAddButtonStyle = new GUIStyle();
|
||||
m_DefaultAddButtonStyle.fixedWidth = 30;
|
||||
m_DefaultAddButtonStyle.fixedHeight = 16;
|
||||
m_DefaultAddButtonStyle.normal.background = ReorderableListResources.texAddButton;
|
||||
m_DefaultAddButtonStyle.active.background = ReorderableListResources.texAddButtonActive;
|
||||
}
|
||||
|
||||
return m_DefaultAddButtonStyle;
|
||||
}
|
||||
}
|
||||
|
||||
static GUIStyle m_DefaultRemoveButtonStyle;
|
||||
|
||||
public static GUIStyle DefaultRemoveButtonStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_DefaultRemoveButtonStyle == null)
|
||||
{
|
||||
m_DefaultRemoveButtonStyle = new GUIStyle();
|
||||
m_DefaultRemoveButtonStyle.fixedWidth = 30;
|
||||
m_DefaultRemoveButtonStyle.fixedHeight = 20;
|
||||
m_DefaultRemoveButtonStyle.active.background = ReorderableListResources.CreatePixelTexture("Dark Pixel (List GUI)", new Color32(18, 18, 18, 255));
|
||||
m_DefaultRemoveButtonStyle.imagePosition = ImagePosition.ImageOnly;
|
||||
m_DefaultRemoveButtonStyle.alignment = TextAnchor.MiddleCenter;
|
||||
}
|
||||
|
||||
return m_DefaultRemoveButtonStyle;
|
||||
}
|
||||
}
|
||||
|
||||
static GUIStyle m_DefaultContainerRowStyle;
|
||||
|
||||
public static GUIStyle DefaultContainerRowStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_DefaultContainerRowStyle == null)
|
||||
{
|
||||
m_DefaultContainerRowStyle = new GUIStyle();
|
||||
m_DefaultContainerRowStyle.border = new RectOffset(2, 2, 2, 2);
|
||||
|
||||
m_DefaultContainerRowStyle.margin = new RectOffset(5, 5, 5, 5);
|
||||
m_DefaultContainerRowStyle.padding = new RectOffset(1, 1, 2, 2);
|
||||
m_DefaultContainerRowStyle.normal.background = ReorderableListResources.texContainerBackground;
|
||||
}
|
||||
|
||||
return m_DefaultContainerRowStyle;
|
||||
}
|
||||
}
|
||||
|
||||
static GUIStyle m_FoldoutBold;
|
||||
|
||||
public static GUIStyle FoldoutBold
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_FoldoutBold == null)
|
||||
{
|
||||
m_FoldoutBold = new GUIStyle(EditorStyles.foldout);
|
||||
m_FoldoutBold.fontStyle = FontStyle.Bold;
|
||||
}
|
||||
|
||||
return m_FoldoutBold;
|
||||
}
|
||||
}
|
||||
|
||||
static GUIStyle m_RichLabel;
|
||||
|
||||
public static GUIStyle RichLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_RichLabel == null)
|
||||
{
|
||||
m_RichLabel = new GUIStyle(GUI.skin.label);
|
||||
m_RichLabel.richText = true;
|
||||
m_RichLabel.wordWrap = true;
|
||||
}
|
||||
|
||||
return m_RichLabel;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
internal static string GetIconPath(string iconFileName)
|
||||
{
|
||||
string _thisIconPath = PhotonNetwork.FindAssetPath ("PhotonGUI");
|
||||
|
||||
if (string.IsNullOrEmpty(_thisIconPath))
|
||||
{
|
||||
_thisIconPath = "Assets/Photon/PhotonUnityNetworking/Code/Editor/"+iconFileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
_thisIconPath = _thisIconPath.Replace("PhotonGUI.cs", iconFileName);
|
||||
}
|
||||
|
||||
return _thisIconPath;
|
||||
}
|
||||
|
||||
static Texture2D m_HelpIcon;
|
||||
|
||||
public static Texture2D HelpIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_HelpIcon == null)
|
||||
{
|
||||
m_HelpIcon = AssetDatabase.LoadAssetAtPath(GetIconPath("help.png"), typeof(Texture2D)) as Texture2D;
|
||||
}
|
||||
|
||||
|
||||
return m_HelpIcon;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Texture2D m_CopyIcon;
|
||||
static Texture2D m_CopyIconPro;
|
||||
|
||||
public static Texture2D CopyIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
{
|
||||
if (m_CopyIconPro == null)
|
||||
{
|
||||
m_CopyIconPro = AssetDatabase.LoadAssetAtPath(GetIconPath("CopyIconPro.png"), typeof(Texture2D)) as Texture2D;
|
||||
}
|
||||
|
||||
return m_CopyIconPro;
|
||||
}
|
||||
|
||||
if (m_CopyIcon == null)
|
||||
{
|
||||
m_CopyIcon = AssetDatabase.LoadAssetAtPath(GetIconPath("CopyIcon.png"), typeof(Texture2D)) as Texture2D;
|
||||
}
|
||||
|
||||
return m_CopyIcon;
|
||||
}
|
||||
}
|
||||
|
||||
#region Interface
|
||||
|
||||
public static void ContainerHeader(string headline)
|
||||
{
|
||||
DoContainerHeader(headline, 27, 0);
|
||||
}
|
||||
|
||||
public static bool ContainerHeaderToggle(string headline, bool toggle)
|
||||
{
|
||||
return DoContainerHeaderToggle(headline, toggle);
|
||||
}
|
||||
|
||||
public static bool ContainerHeaderFoldout(string headline, bool foldout, System.Action buttonAction = null, string buttonName = null)
|
||||
{
|
||||
return DoContainerHeaderFoldout(headline, foldout, buttonAction, buttonName);
|
||||
}
|
||||
|
||||
public static Rect ContainerBody(float height)
|
||||
{
|
||||
return DoContainerBody(height);
|
||||
}
|
||||
|
||||
public static bool AddButton()
|
||||
{
|
||||
Rect controlRect = EditorGUILayout.GetControlRect(false, DefaultAddButtonStyle.fixedHeight - 5);
|
||||
controlRect.yMin -= 5;
|
||||
controlRect.yMax -= 5;
|
||||
|
||||
Rect addButtonRect = new Rect(controlRect.xMax - DefaultAddButtonStyle.fixedWidth,
|
||||
controlRect.yMin,
|
||||
DefaultAddButtonStyle.fixedWidth,
|
||||
DefaultAddButtonStyle.fixedHeight);
|
||||
|
||||
return GUI.Button(addButtonRect, "", DefaultAddButtonStyle);
|
||||
}
|
||||
|
||||
public static void DrawSplitter(Rect position)
|
||||
{
|
||||
ReorderableListResources.DrawTexture(position, ReorderableListResources.texItemSplitter);
|
||||
}
|
||||
|
||||
public static void DrawGizmoOptions(
|
||||
Rect position,
|
||||
string label,
|
||||
SerializedProperty gizmoEnabledProperty,
|
||||
SerializedProperty gizmoColorProperty,
|
||||
SerializedProperty gizmoTypeProperty,
|
||||
SerializedProperty gizmoSizeProperty)
|
||||
{
|
||||
float height = EditorGUIUtility.singleLineHeight;
|
||||
float flexibleWidth = Mathf.Max(40, position.width - EditorGUIUtility.labelWidth - 20 - 75 - 5 - 40 - 5);
|
||||
|
||||
Rect labelRect = new Rect(position.xMin, position.yMin, EditorGUIUtility.labelWidth, height);
|
||||
GUI.Label(labelRect, label);
|
||||
|
||||
Rect enabledRect = new Rect(labelRect.xMax, labelRect.yMin, 20, height);
|
||||
EditorGUI.PropertyField(enabledRect, gizmoEnabledProperty, GUIContent.none);
|
||||
|
||||
bool oldGUIEnabled = GUI.enabled;
|
||||
GUI.enabled = gizmoEnabledProperty.boolValue;
|
||||
|
||||
Rect colorRect = new Rect(enabledRect.xMax + 5, labelRect.yMin, 70, height);
|
||||
EditorGUI.PropertyField(colorRect, gizmoColorProperty, GUIContent.none);
|
||||
|
||||
Rect typeRect = new Rect(colorRect.xMax + 5, labelRect.yMin, flexibleWidth * 0.7f, height);
|
||||
EditorGUI.PropertyField(typeRect, gizmoTypeProperty, GUIContent.none);
|
||||
|
||||
Rect sizeLabelRect = new Rect(typeRect.xMax + 10, labelRect.yMin, 30, height);
|
||||
GUI.Label(sizeLabelRect, "Size");
|
||||
|
||||
Rect sizeRect = new Rect(sizeLabelRect.xMax + 5, labelRect.yMin, flexibleWidth * 0.3f, height);
|
||||
EditorGUI.PropertyField(sizeRect, gizmoSizeProperty, GUIContent.none);
|
||||
|
||||
GUI.enabled = oldGUIEnabled;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation
|
||||
|
||||
static Rect DoContainerBody(float height)
|
||||
{
|
||||
Rect controlRect = EditorGUILayout.GetControlRect(false, height);
|
||||
controlRect.yMin -= 3;
|
||||
controlRect.yMax -= 2;
|
||||
|
||||
int controlID = GUIUtility.GetControlID(FocusType.Passive, controlRect);
|
||||
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
PhotonGUI.DefaultContainerStyle.Draw(controlRect, GUIContent.none, controlID);
|
||||
}
|
||||
|
||||
return controlRect;
|
||||
}
|
||||
|
||||
static bool DoContainerHeaderToggle(string headline, bool toggle)
|
||||
{
|
||||
Rect rect = DoContainerHeader(headline, 27, 15);
|
||||
Rect toggleRect = new Rect(rect.xMin + 5, rect.yMin + 5, EditorGUIUtility.labelWidth, rect.height);
|
||||
|
||||
return EditorGUI.Toggle(toggleRect, toggle);
|
||||
}
|
||||
|
||||
|
||||
static bool DoContainerHeaderFoldout(string headline, bool foldout, System.Action buttonAction = null, string buttonLabel = null, float buttonWidth = 48)
|
||||
{
|
||||
bool showButton = buttonAction != null;
|
||||
|
||||
Rect rect = DoContainerHeader("", 27, 0f);
|
||||
|
||||
// Shorten foldout label if button is present, so it doesn't interfere with clicking.
|
||||
float foldoutWidth = rect.width - (showButton ? 15 + buttonWidth: 15);
|
||||
Rect foldoutRect = new Rect(rect.xMin + 15, rect.yMin + 5, foldoutWidth, 16);
|
||||
|
||||
bool expanded = EditorGUI.Foldout(foldoutRect, foldout, headline, FoldoutBold);
|
||||
|
||||
// If a button is defined show it, and invoke action on click.
|
||||
if (showButton && GUI.Button(new Rect(foldoutRect) { x = foldoutRect.xMax, height = 17, width = buttonWidth - 4 }, buttonLabel == null ? "" : buttonLabel))
|
||||
{
|
||||
buttonAction.Invoke();
|
||||
}
|
||||
|
||||
return expanded;
|
||||
}
|
||||
|
||||
static Rect DoContainerHeader(string headline, float height, float contentOffset)
|
||||
{
|
||||
GUILayout.Space(5);
|
||||
Rect controlRect = EditorGUILayout.GetControlRect(false, height);
|
||||
|
||||
int controlID = GUIUtility.GetControlID(FocusType.Passive, controlRect);
|
||||
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
PhotonGUI.DefaultTitleStyle.Draw(controlRect, GUIContent.none, controlID);
|
||||
|
||||
Rect labelRect = new Rect(controlRect.xMin + 5 + contentOffset, controlRect.yMin + 5, controlRect.width, controlRect.height);
|
||||
GUI.Label(labelRect, headline, EditorStyles.boldLabel);
|
||||
}
|
||||
|
||||
return controlRect;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d2cadb1ccf05074e8ce96b1393846cf
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "PhotonUnityNetworking.Editor",
|
||||
"references": [
|
||||
"PhotonRealtime",
|
||||
"PhotonUnityNetworking"
|
||||
],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4025d00f1ce60da4ea2d0830acf5ebfb
|
||||
timeCreated: 1537863428
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,191 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonViewHandler.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// This is a Editor script to initialize PhotonView components.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Realtime;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
|
||||
[InitializeOnLoad]
|
||||
public class PhotonViewHandler : EditorWindow
|
||||
{
|
||||
static PhotonViewHandler()
|
||||
{
|
||||
// called once per change (per key-press in inspectors) and once after play-mode ends.
|
||||
#if (UNITY_2018 || UNITY_2018_1_OR_NEWER)
|
||||
EditorApplication.hierarchyChanged += OnHierarchyChanged;
|
||||
#else
|
||||
EditorApplication.hierarchyWindowChanged += OnHierarchyChanged;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
internal static void OnHierarchyChanged()
|
||||
{
|
||||
// set prefabs to viewID 0 if needed
|
||||
// organize resource PVs in a list per viewID
|
||||
|
||||
// process the lists: if more than one photonView is in a list, we have to resolve the clash
|
||||
// check if only one view had the viewId earlier
|
||||
// apply a new viewID to the others
|
||||
|
||||
// update the cached list of instances and their viewID
|
||||
|
||||
|
||||
//Debug.LogWarning("OnHierarchyChanged(). isPlaying: " + Application.isPlaying);
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PhotonView[] photonViewResources = Resources.FindObjectsOfTypeAll<PhotonView>();
|
||||
List<PhotonView> photonViewInstances = new List<PhotonView>();
|
||||
Dictionary<int, List<PhotonView>> viewInstancesPerViewId = new Dictionary<int, List<PhotonView>>();
|
||||
List<PhotonView> photonViewsToReassign = new List<PhotonView>();
|
||||
|
||||
foreach (PhotonView view in photonViewResources)
|
||||
{
|
||||
if (PhotonEditorUtils.IsPrefab(view.gameObject))
|
||||
{
|
||||
// prefabs should use 0 as ViewID and sceneViewId
|
||||
if (view.ViewID != 0 || view.sceneViewId != 0)
|
||||
{
|
||||
view.ViewID = 0;
|
||||
view.sceneViewId = 0;
|
||||
EditorUtility.SetDirty(view);
|
||||
}
|
||||
|
||||
continue; // skip prefabs in further processing
|
||||
}
|
||||
|
||||
photonViewInstances.Add(view);
|
||||
|
||||
|
||||
// assign a new viewID if the viewId is lower than the minimum for this scene
|
||||
if (!IsViewIdOkForScene(view))
|
||||
{
|
||||
photonViewsToReassign.Add(view);
|
||||
continue; // this view definitely gets cleaned up, so it does not count versus duplicates, checked below
|
||||
}
|
||||
|
||||
|
||||
// organize the viewInstances into lists per viewID, so we know duplicate usage
|
||||
if (!viewInstancesPerViewId.ContainsKey(view.sceneViewId))
|
||||
{
|
||||
viewInstancesPerViewId[view.sceneViewId] = new List<PhotonView>();
|
||||
}
|
||||
viewInstancesPerViewId[view.sceneViewId].Add(view);
|
||||
}
|
||||
|
||||
//Debug.Log("PreviousAssignments: "+PunSceneViews.Instance.Views.Count);
|
||||
|
||||
foreach (List<PhotonView> list in viewInstancesPerViewId.Values)
|
||||
{
|
||||
if (list.Count <= 1)
|
||||
{
|
||||
continue; // skip lists with just one entry (the viewID is unique)
|
||||
}
|
||||
|
||||
|
||||
PhotonView previousAssignment = null;
|
||||
bool wasAssigned = PunSceneViews.Instance.Views.TryGetValue(list[0].sceneViewId, out previousAssignment);
|
||||
|
||||
foreach (PhotonView view in list)
|
||||
{
|
||||
if (wasAssigned && view.Equals(previousAssignment))
|
||||
{
|
||||
// previously, we cached the used viewID as assigned to the current view. we don't change this.
|
||||
continue;
|
||||
}
|
||||
|
||||
//Debug.LogWarning("View to reassign due to viewID: "+view, view.gameObject);
|
||||
photonViewsToReassign.Add(view);
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
foreach (PhotonView view in photonViewsToReassign)
|
||||
{
|
||||
i = MinSceneViewId(view);
|
||||
while (viewInstancesPerViewId.ContainsKey(i))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
view.sceneViewId = i;
|
||||
viewInstancesPerViewId.Add(i, null); // we don't need the lists anymore but we care about getting the viewIDs listed
|
||||
EditorUtility.SetDirty(view);
|
||||
}
|
||||
|
||||
|
||||
// update the "semi persistent" list of viewIDs and their PhotonViews
|
||||
PunSceneViews.Instance.Views.Clear();
|
||||
foreach (PhotonView view in photonViewInstances)
|
||||
{
|
||||
if (PunSceneViews.Instance.Views.ContainsKey(view.sceneViewId))
|
||||
{
|
||||
Debug.LogError("ViewIDs should no longer have duplicates! "+view.sceneViewId, view);
|
||||
continue;
|
||||
}
|
||||
|
||||
PunSceneViews.Instance.Views[view.sceneViewId] = view;
|
||||
}
|
||||
|
||||
//Debug.Log("photonViewsToReassign.Count: "+photonViewsToReassign.Count + " count of viewIDs in use: "+viewInstancesPerViewId.Values.Count);
|
||||
//Debug.Log("PreviousAssignments now counts: "+PunSceneViews.Instance.Views.Count);
|
||||
}
|
||||
|
||||
|
||||
private static int MinSceneViewId(PhotonView view)
|
||||
{
|
||||
int result = PunSceneSettings.MinViewIdForScene(view.gameObject.scene.name);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool IsViewIdOkForScene(PhotonView view)
|
||||
{
|
||||
return view.sceneViewId >= MinSceneViewId(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a PhotonView instances per viewId (key). Instance is used as cache storage in-Editor.
|
||||
/// </summary>
|
||||
public class PunSceneViews : ScriptableObject
|
||||
{
|
||||
[SerializeField]
|
||||
public Dictionary<int, PhotonView> Views = new Dictionary<int, PhotonView>();
|
||||
|
||||
private static PunSceneViews instanceField;
|
||||
public static PunSceneViews Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instanceField != null)
|
||||
{
|
||||
return instanceField;
|
||||
}
|
||||
|
||||
instanceField = GameObject.FindObjectOfType<PunSceneViews>();
|
||||
if (instanceField == null)
|
||||
{
|
||||
instanceField = ScriptableObject.CreateInstance<PunSceneViews>();
|
||||
}
|
||||
|
||||
return instanceField;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57b538e62a0ca6248bfd354def935e57
|
||||
labels:
|
||||
- ExitGames
|
||||
- PUN
|
||||
- Photon
|
||||
- Networking
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,394 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonViewInspector.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Custom inspector for the PhotonView component.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
using Photon.Realtime;
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
[CustomEditor(typeof(PhotonView))]
|
||||
[CanEditMultipleObjects]
|
||||
internal class PhotonViewInspector : Editor
|
||||
{
|
||||
private PhotonView m_Target;
|
||||
|
||||
private static GUIContent ownerTransferGuiContent = new GUIContent("Ownership Transfer", "Determines how ownership changes may be initiated.");
|
||||
private static GUIContent syncronizationGuiContent = new GUIContent("Synchronization", "Determines how sync updates are culled and sent.");
|
||||
private static GUIContent observableSearchGuiContent = new GUIContent("Observable Search", "When set to Auto, On Awake, Observables on this GameObject (and child GameObjects) will be found and populate the Observables List." +
|
||||
"\n\nNested PhotonViews (children with a PhotonView) and their children will not be included in the search.");
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
this.m_Target = (PhotonView)this.target;
|
||||
|
||||
if (!Application.isPlaying)
|
||||
m_Target.FindObservables();
|
||||
}
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
|
||||
|
||||
this.m_Target = (PhotonView)this.target;
|
||||
bool isProjectPrefab = PhotonEditorUtils.IsPrefab(this.m_Target.gameObject);
|
||||
bool multiSelected = Selection.gameObjects.Length > 1;
|
||||
|
||||
if (this.m_Target.ObservedComponents == null)
|
||||
{
|
||||
this.m_Target.ObservedComponents = new System.Collections.Generic.List<Component>();
|
||||
}
|
||||
|
||||
if (this.m_Target.ObservedComponents.Count == 0)
|
||||
{
|
||||
this.m_Target.ObservedComponents.Add(null);
|
||||
}
|
||||
|
||||
GUILayout.Space(5);
|
||||
|
||||
EditorGUILayout.BeginVertical((GUIStyle)"HelpBox");
|
||||
// View ID - Hide if we are multi-selected
|
||||
if (!multiSelected)
|
||||
{
|
||||
if (isProjectPrefab)
|
||||
{
|
||||
EditorGUILayout.LabelField("View ID", "<i>Set at runtime</i>", new GUIStyle("Label") { richText = true });
|
||||
}
|
||||
else if (EditorApplication.isPlaying)
|
||||
{
|
||||
EditorGUILayout.LabelField("View ID", this.m_Target.ViewID.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is an object in a scene, modified at edit-time. we can store this as sceneViewId
|
||||
int idValue = EditorGUILayout.IntField("View ID [1.." + (PhotonNetwork.MAX_VIEW_IDS - 1) + "]", this.m_Target.sceneViewId);
|
||||
if (this.m_Target.sceneViewId != idValue)
|
||||
{
|
||||
Undo.RecordObject(this.m_Target, "Change PhotonView viewID");
|
||||
this.m_Target.sceneViewId = idValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Locally Controlled
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
string masterClientHint = PhotonNetwork.IsMasterClient ? " (master)" : "";
|
||||
EditorGUILayout.LabelField("IsMine:", this.m_Target.IsMine.ToString() + masterClientHint);
|
||||
Room room = PhotonNetwork.CurrentRoom;
|
||||
int cretrId = this.m_Target.CreatorActorNr;
|
||||
Player cretr = (room != null) ? room.GetPlayer(cretrId) : null;
|
||||
Player owner = this.m_Target.Owner;
|
||||
Player ctrlr = this.m_Target.Controller;
|
||||
EditorGUILayout.LabelField("Controller:", (ctrlr != null ? ("[" + ctrlr.ActorNumber + "] '" + ctrlr.NickName + "' " + (ctrlr.IsMasterClient ? " (master)" : "")) : "[0] <null>"));
|
||||
EditorGUILayout.LabelField("Owner:", (owner != null ? ("[" + owner.ActorNumber + "] '" + owner.NickName + "' " + (owner.IsMasterClient ? " (master)" : "")) : "[0] <null>"));
|
||||
EditorGUILayout.LabelField("Creator:", (cretr != null ? ("[" +cretrId + "] '" + cretr.NickName + "' " + (cretr.IsMasterClient ? " (master)" : "")) : "[0] <null>"));
|
||||
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUI.BeginDisabledGroup(Application.isPlaying);
|
||||
|
||||
GUILayout.Space(5);
|
||||
|
||||
// Ownership section
|
||||
|
||||
EditorGUILayout.LabelField("Ownership", (GUIStyle)"BoldLabel");
|
||||
|
||||
OwnershipOption own = (OwnershipOption)EditorGUILayout.EnumPopup(ownerTransferGuiContent, this.m_Target.OwnershipTransfer/*, GUILayout.MaxWidth(68), GUILayout.MinWidth(68)*/);
|
||||
if (own != this.m_Target.OwnershipTransfer)
|
||||
{
|
||||
// jf: fixed 5 and up prefab not accepting changes if you quit Unity straight after change.
|
||||
// not touching the define nor the rest of the code to avoid bringing more problem than solving.
|
||||
EditorUtility.SetDirty(this.m_Target);
|
||||
|
||||
Undo.RecordObject(this.m_Target, "Change PhotonView Ownership Transfer");
|
||||
this.m_Target.OwnershipTransfer = own;
|
||||
}
|
||||
|
||||
|
||||
GUILayout.Space(5);
|
||||
|
||||
// Observables section
|
||||
|
||||
EditorGUILayout.LabelField("Observables", (GUIStyle)"BoldLabel");
|
||||
|
||||
EditorGUILayout.PropertyField(this.serializedObject.FindProperty("Synchronization"), syncronizationGuiContent);
|
||||
|
||||
if (this.m_Target.Synchronization == ViewSynchronization.Off)
|
||||
{
|
||||
// Show warning if there are any observables. The null check is because the list allows nulls.
|
||||
var observed = m_Target.ObservedComponents;
|
||||
if (observed.Count > 0)
|
||||
{
|
||||
for (int i = 0, cnt = observed.Count; i < cnt; ++i)
|
||||
if (observed[i] != null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Synchronization is set to Off. Select a Synchronization setting in order to sync the listed Observables.", MessageType.Warning);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PhotonView.ObservableSearch autoFindObservables = (PhotonView.ObservableSearch)EditorGUILayout.EnumPopup(observableSearchGuiContent, m_Target.observableSearch);
|
||||
|
||||
if (m_Target.observableSearch != autoFindObservables)
|
||||
{
|
||||
Undo.RecordObject(this.m_Target, "Change Auto Find Observables Toggle");
|
||||
m_Target.observableSearch = autoFindObservables;
|
||||
}
|
||||
|
||||
m_Target.FindObservables();
|
||||
|
||||
if (!multiSelected)
|
||||
{
|
||||
bool disableList = Application.isPlaying || autoFindObservables != PhotonView.ObservableSearch.Manual;
|
||||
|
||||
if (disableList)
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
|
||||
this.DrawObservedComponentsList(disableList);
|
||||
|
||||
if (disableList)
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
// Cleanup: save and fix look
|
||||
if (GUI.changed)
|
||||
{
|
||||
PhotonViewHandler.OnHierarchyChanged(); // TODO: check if needed
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int GetObservedComponentsCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < this.m_Target.ObservedComponents.Count; ++i)
|
||||
{
|
||||
if (this.m_Target.ObservedComponents[i] != null)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find Observables, and then baking them into the serialized object.
|
||||
/// </summary>
|
||||
private void EditorFindObservables()
|
||||
{
|
||||
Undo.RecordObject(serializedObject.targetObject, "Find Observables");
|
||||
var property = serializedObject.FindProperty("ObservedComponents");
|
||||
|
||||
// Just doing a Find updates the Observables list, but Unity fails to save that change.
|
||||
// Instead we do the find, and then iterate the found objects into the serialize property, then apply that.
|
||||
property.ClearArray();
|
||||
m_Target.FindObservables(true);
|
||||
for(int i = 0; i < m_Target.ObservedComponents.Count; ++i)
|
||||
{
|
||||
property.InsertArrayElementAtIndex(i);
|
||||
property.GetArrayElementAtIndex(i).objectReferenceValue = m_Target.ObservedComponents[i];
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void DrawObservedComponentsList(bool disabled = false)
|
||||
{
|
||||
SerializedProperty listProperty = this.serializedObject.FindProperty("ObservedComponents");
|
||||
|
||||
if (listProperty == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float containerElementHeight = 22;
|
||||
float containerHeight = listProperty.arraySize * containerElementHeight;
|
||||
|
||||
string foldoutLabel = "Observed Components (" + this.GetObservedComponentsCount() + ")";
|
||||
bool isOpen = PhotonGUI.ContainerHeaderFoldout(foldoutLabel, this.serializedObject.FindProperty("ObservedComponentsFoldoutOpen").boolValue, () => EditorFindObservables(), "Find");
|
||||
this.serializedObject.FindProperty("ObservedComponentsFoldoutOpen").boolValue = isOpen;
|
||||
|
||||
if (isOpen == false)
|
||||
{
|
||||
containerHeight = 0;
|
||||
}
|
||||
|
||||
//Texture2D statsIcon = AssetDatabase.LoadAssetAtPath( "Assets/Photon Unity Networking/Editor/PhotonNetwork/PhotonViewStats.png", typeof( Texture2D ) ) as Texture2D;
|
||||
|
||||
Rect containerRect = PhotonGUI.ContainerBody(containerHeight);
|
||||
|
||||
|
||||
bool wasObservedComponentsEmpty = this.m_Target.ObservedComponents.FindAll(item => item != null).Count == 0;
|
||||
if (isOpen == true)
|
||||
{
|
||||
for (int i = 0; i < listProperty.arraySize; ++i)
|
||||
{
|
||||
Rect elementRect = new Rect(containerRect.xMin, containerRect.yMin + containerElementHeight * i, containerRect.width, containerElementHeight);
|
||||
{
|
||||
Rect texturePosition = new Rect(elementRect.xMin + 6, elementRect.yMin + elementRect.height / 2f - 1, 9, 5);
|
||||
ReorderableListResources.DrawTexture(texturePosition, ReorderableListResources.texGrabHandle);
|
||||
|
||||
Rect propertyPosition = new Rect(elementRect.xMin + 20, elementRect.yMin + 3, elementRect.width - 45, 16);
|
||||
|
||||
// keep track of old type to catch when a new type is observed
|
||||
Type _oldType = listProperty.GetArrayElementAtIndex(i).objectReferenceValue != null ? listProperty.GetArrayElementAtIndex(i).objectReferenceValue.GetType() : null;
|
||||
|
||||
EditorGUI.PropertyField(propertyPosition, listProperty.GetArrayElementAtIndex(i), new GUIContent());
|
||||
|
||||
// new type, could be different from old type
|
||||
Type _newType = listProperty.GetArrayElementAtIndex(i).objectReferenceValue != null ? listProperty.GetArrayElementAtIndex(i).objectReferenceValue.GetType() : null;
|
||||
|
||||
// the user dropped a Transform, we must change it by adding a PhotonTransformView and observe that instead
|
||||
if (_oldType != _newType)
|
||||
{
|
||||
if (_newType == typeof(PhotonView))
|
||||
{
|
||||
listProperty.GetArrayElementAtIndex(i).objectReferenceValue = null;
|
||||
Debug.LogError("PhotonView Detected you dropped a PhotonView, this is not allowed. \n It's been removed from observed field.");
|
||||
|
||||
}
|
||||
else if (_newType == typeof(Transform))
|
||||
{
|
||||
|
||||
// try to get an existing PhotonTransformView ( we don't want any duplicates...)
|
||||
PhotonTransformView _ptv = this.m_Target.gameObject.GetComponent<PhotonTransformView>();
|
||||
if (_ptv == null)
|
||||
{
|
||||
// no ptv yet, we create one and enable position and rotation, no scaling, as it's too rarely needed to take bandwidth for nothing
|
||||
_ptv = Undo.AddComponent<PhotonTransformView>(this.m_Target.gameObject);
|
||||
}
|
||||
// switch observe from transform to _ptv
|
||||
listProperty.GetArrayElementAtIndex(i).objectReferenceValue = _ptv;
|
||||
Debug.Log("PhotonView has detected you dropped a Transform. Instead it's better to observe a PhotonTransformView for better control and performances");
|
||||
}
|
||||
else if (_newType == typeof(Rigidbody))
|
||||
{
|
||||
|
||||
Rigidbody _rb = listProperty.GetArrayElementAtIndex(i).objectReferenceValue as Rigidbody;
|
||||
|
||||
// try to get an existing PhotonRigidbodyView ( we don't want any duplicates...)
|
||||
PhotonRigidbodyView _prbv = _rb.gameObject.GetComponent<PhotonRigidbodyView>();
|
||||
if (_prbv == null)
|
||||
{
|
||||
// no _prbv yet, we create one
|
||||
_prbv = Undo.AddComponent<PhotonRigidbodyView>(_rb.gameObject);
|
||||
}
|
||||
// switch observe from transform to _prbv
|
||||
listProperty.GetArrayElementAtIndex(i).objectReferenceValue = _prbv;
|
||||
Debug.Log("PhotonView has detected you dropped a RigidBody. Instead it's better to observe a PhotonRigidbodyView for better control and performances");
|
||||
}
|
||||
else if (_newType == typeof(Rigidbody2D))
|
||||
{
|
||||
|
||||
// try to get an existing PhotonRigidbody2DView ( we don't want any duplicates...)
|
||||
PhotonRigidbody2DView _prb2dv = this.m_Target.gameObject.GetComponent<PhotonRigidbody2DView>();
|
||||
if (_prb2dv == null)
|
||||
{
|
||||
// no _prb2dv yet, we create one
|
||||
_prb2dv = Undo.AddComponent<PhotonRigidbody2DView>(this.m_Target.gameObject);
|
||||
}
|
||||
// switch observe from transform to _prb2dv
|
||||
listProperty.GetArrayElementAtIndex(i).objectReferenceValue = _prb2dv;
|
||||
Debug.Log("PhotonView has detected you dropped a Rigidbody2D. Instead it's better to observe a PhotonRigidbody2DView for better control and performances");
|
||||
}
|
||||
else if (_newType == typeof(Animator))
|
||||
{
|
||||
|
||||
// try to get an existing PhotonAnimatorView ( we don't want any duplicates...)
|
||||
PhotonAnimatorView _pav = this.m_Target.gameObject.GetComponent<PhotonAnimatorView>();
|
||||
if (_pav == null)
|
||||
{
|
||||
// no _pav yet, we create one
|
||||
_pav = Undo.AddComponent<PhotonAnimatorView>(this.m_Target.gameObject);
|
||||
}
|
||||
// switch observe from transform to _prb2dv
|
||||
listProperty.GetArrayElementAtIndex(i).objectReferenceValue = _pav;
|
||||
Debug.Log("PhotonView has detected you dropped a Animator, so we switched to PhotonAnimatorView so that you can serialized the Animator variables");
|
||||
}
|
||||
else if (!typeof(IPunObservable).IsAssignableFrom(_newType))
|
||||
{
|
||||
bool _ignore = false;
|
||||
#if PLAYMAKER
|
||||
_ignore = _newType == typeof(PlayMakerFSM);// Photon Integration for PlayMaker will swap at runtime to a proxy using iPunObservable.
|
||||
#endif
|
||||
|
||||
if (_newType == null || _newType == typeof(Rigidbody) || _newType == typeof(Rigidbody2D))
|
||||
{
|
||||
_ignore = true;
|
||||
}
|
||||
|
||||
if (!_ignore)
|
||||
{
|
||||
listProperty.GetArrayElementAtIndex(i).objectReferenceValue = null;
|
||||
Debug.LogError("PhotonView Detected you dropped a Component missing IPunObservable Interface,\n You dropped a <" + _newType + "> instead. It's been removed from observed field.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.Log( listProperty.GetArrayElementAtIndex( i ).objectReferenceValue.GetType() );
|
||||
//Rect statsPosition = new Rect( propertyPosition.xMax + 7, propertyPosition.yMin, statsIcon.width, statsIcon.height );
|
||||
//ReorderableListResources.DrawTexture( statsPosition, statsIcon );
|
||||
|
||||
Rect removeButtonRect = new Rect(elementRect.xMax - PhotonGUI.DefaultRemoveButtonStyle.fixedWidth,
|
||||
elementRect.yMin + 2,
|
||||
PhotonGUI.DefaultRemoveButtonStyle.fixedWidth,
|
||||
PhotonGUI.DefaultRemoveButtonStyle.fixedHeight);
|
||||
|
||||
GUI.enabled = !disabled && listProperty.arraySize > 1;
|
||||
if (GUI.Button(removeButtonRect, new GUIContent(ReorderableListResources.texRemoveButton), PhotonGUI.DefaultRemoveButtonStyle))
|
||||
{
|
||||
listProperty.DeleteArrayElementAtIndex(i);
|
||||
}
|
||||
GUI.enabled = !disabled;
|
||||
|
||||
if (i < listProperty.arraySize - 1)
|
||||
{
|
||||
texturePosition = new Rect(elementRect.xMin + 2, elementRect.yMax, elementRect.width - 4, 1);
|
||||
PhotonGUI.DrawSplitter(texturePosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PhotonGUI.AddButton())
|
||||
{
|
||||
listProperty.InsertArrayElementAtIndex(Mathf.Max(0, listProperty.arraySize - 1));
|
||||
}
|
||||
|
||||
this.serializedObject.ApplyModifiedProperties();
|
||||
|
||||
bool isObservedComponentsEmpty = this.m_Target.ObservedComponents.FindAll(item => item != null).Count == 0;
|
||||
|
||||
if (wasObservedComponentsEmpty == true && isObservedComponentsEmpty == false && this.m_Target.Synchronization == ViewSynchronization.Off)
|
||||
{
|
||||
Undo.RecordObject(this.m_Target, "Change PhotonView");
|
||||
this.m_Target.Synchronization = ViewSynchronization.UnreliableOnChange;
|
||||
this.serializedObject.Update();
|
||||
}
|
||||
|
||||
if (wasObservedComponentsEmpty == false && isObservedComponentsEmpty == true)
|
||||
{
|
||||
Undo.RecordObject(this.m_Target, "Change PhotonView");
|
||||
this.m_Target.Synchronization = ViewSynchronization.Off;
|
||||
this.serializedObject.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e73a30c46df19194f873ea7a9ce12753
|
||||
labels:
|
||||
- ExitGames
|
||||
- PUN
|
||||
- Photon
|
||||
- Networking
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
BIN
Assets/Photon/PhotonUnityNetworking/Code/Editor/PunGradient.png
Normal file
BIN
Assets/Photon/PhotonUnityNetworking/Code/Editor/PunGradient.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 308 B |
@ -0,0 +1,45 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1faa1cf0448470c4ebbb23b97759ab50
|
||||
TextureImporter:
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 256
|
||||
textureSettings:
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
@ -0,0 +1,178 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PunSceneSettings.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Optional lowest-viewID setting per-scene. So PhotonViews don't get the same ID.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
[Serializable]
|
||||
public class SceneSetting
|
||||
{
|
||||
public SceneAsset sceneAsset;
|
||||
public string sceneName;
|
||||
public int minViewId;
|
||||
}
|
||||
|
||||
[HelpURL("https://doc.photonengine.com/en-us/pun/current/getting-started/feature-overview#scene_photonviews_in_multiple_scenes")]
|
||||
public class PunSceneSettings : ScriptableObject
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Suppressing compiler warning "this variable is never used". Only used in the CustomEditor, only in Editor
|
||||
#pragma warning disable 0414
|
||||
[SerializeField]
|
||||
bool SceneSettingsListFoldoutOpen = true;
|
||||
#pragma warning restore 0414
|
||||
#endif
|
||||
|
||||
[SerializeField]
|
||||
public List<SceneSetting> MinViewIdPerScene = new List<SceneSetting>();
|
||||
|
||||
|
||||
private const string SceneSettingsFileName = "PunSceneSettingsFile.asset";
|
||||
|
||||
// we use the path to PunSceneSettings.cs as path to create a scene settings file
|
||||
private static string punSceneSettingsCsPath;
|
||||
|
||||
public static string PunSceneSettingsCsPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(punSceneSettingsCsPath))
|
||||
{
|
||||
return punSceneSettingsCsPath;
|
||||
}
|
||||
|
||||
// Unity 4.3.4 does not yet have AssetDatabase.FindAssets(). Would be easier.
|
||||
var result = Directory.GetFiles(Application.dataPath, "PunSceneSettings.cs", SearchOption.AllDirectories);
|
||||
if (result.Length >= 1)
|
||||
{
|
||||
punSceneSettingsCsPath = Path.GetDirectoryName(result[0]);
|
||||
punSceneSettingsCsPath = punSceneSettingsCsPath.Replace('\\', '/');
|
||||
punSceneSettingsCsPath = punSceneSettingsCsPath.Replace(Application.dataPath, "Assets");
|
||||
|
||||
// AssetDatabase paths have to use '/' and are relative to the project's folder. Always.
|
||||
punSceneSettingsCsPath = punSceneSettingsCsPath + "/" + SceneSettingsFileName;
|
||||
}
|
||||
|
||||
return punSceneSettingsCsPath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static PunSceneSettings instanceField;
|
||||
|
||||
public static PunSceneSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instanceField != null)
|
||||
{
|
||||
return instanceField;
|
||||
}
|
||||
|
||||
instanceField = (PunSceneSettings)AssetDatabase.LoadAssetAtPath(PunSceneSettingsCsPath, typeof(PunSceneSettings));
|
||||
if (instanceField == null)
|
||||
{
|
||||
instanceField = CreateInstance<PunSceneSettings>();
|
||||
#pragma warning disable 0168
|
||||
try
|
||||
{
|
||||
AssetDatabase.CreateAsset(instanceField, PunSceneSettingsCsPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
#if PHOTON_UNITY_NETWORKING
|
||||
Debug.LogError("-- WARNING: PROJECT CLEANUP NECESSARY -- If you delete pun from your project, make sure you also clean up the Scripting define symbols from any reference to PUN like 'PHOTON_UNITY_NETWORKING ");
|
||||
#endif
|
||||
}
|
||||
#pragma warning restore 0168
|
||||
}
|
||||
|
||||
return instanceField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int MinViewIdForScene(string sceneName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sceneName))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
PunSceneSettings pss = Instance;
|
||||
if (pss == null)
|
||||
{
|
||||
Debug.LogError("pss cant be null");
|
||||
return 1;
|
||||
}
|
||||
|
||||
foreach (SceneSetting setting in pss.MinViewIdPerScene)
|
||||
{
|
||||
if (setting.sceneName.Equals(sceneName))
|
||||
{
|
||||
return setting.minViewId;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static void SanitizeSceneSettings()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
foreach (SceneSetting sceneSetting in Instance.MinViewIdPerScene)
|
||||
{
|
||||
if (sceneSetting.sceneAsset == null && !string.IsNullOrEmpty(sceneSetting.sceneName))
|
||||
{
|
||||
|
||||
string[] guids = AssetDatabase.FindAssets(sceneSetting.sceneName + " t:SceneAsset");
|
||||
|
||||
foreach (string guid in guids)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (Path.GetFileNameWithoutExtension(path) == sceneSetting.sceneName)
|
||||
{
|
||||
sceneSetting.sceneAsset =
|
||||
AssetDatabase.LoadAssetAtPath<SceneAsset>(
|
||||
AssetDatabase.GUIDToAssetPath(guid));
|
||||
|
||||
// Debug.Log("SceneSettings : ''"+sceneSetting.sceneName+"'' scene is missing: Issue corrected",Instance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.Log("SceneSettings : ''"+sceneSetting.sceneName+"'' scene is missing",Instance);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sceneSetting.sceneAsset != null && sceneSetting.sceneName!= sceneSetting.sceneAsset.name )
|
||||
{
|
||||
// Debug.Log("SceneSettings : '"+sceneSetting.sceneName+"' mismatch with sceneAsset: '"+sceneSetting.sceneAsset.name+"' : Issue corrected",Instance);
|
||||
sceneSetting.sceneName = sceneSetting.sceneAsset.name;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc3284eace5a64d4bb516df7d7effdb9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,21 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fc3284eace5a64d4bb516df7d7effdb9, type: 3}
|
||||
m_Name: PunSceneSettingsFile
|
||||
m_EditorClassIdentifier:
|
||||
SceneSettingsListFoldoutOpen: 1
|
||||
MinViewIdPerScene:
|
||||
- sceneAsset: {fileID: 102900000, guid: 559222f4671e440cba71aecba1de3505, type: 3}
|
||||
sceneName: SceneView_A
|
||||
minViewId: 2
|
||||
- sceneAsset: {fileID: 102900000, guid: a81615022a16c489aac8daadf8f51fae, type: 3}
|
||||
sceneName: SceneView_B
|
||||
minViewId: 10
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0aacb83307022d449e90a09d28222ae
|
@ -0,0 +1,260 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PunSceneSettingsInspector.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2019 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Custom inspector for the PunSceneSettings component.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
[CustomEditor(typeof(PunSceneSettings))]
|
||||
internal class PunSceneSettingsInspector : Editor
|
||||
{
|
||||
private PunSceneSettings m_Target;
|
||||
private bool isOpen;
|
||||
private List<string> _duplicateScenesDefinition;
|
||||
private List<int> _duplicateViewIdDefinition;
|
||||
|
||||
private SerializedProperty listProperty;
|
||||
private SerializedProperty _sceneSettings_i;
|
||||
private SerializedProperty sceneNameProperty;
|
||||
private SerializedProperty sceneAssetProperty;
|
||||
private SerializedProperty minViewIdProperty;
|
||||
|
||||
private bool _firstTime;
|
||||
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
this.m_Target = (PunSceneSettings) this.target;
|
||||
|
||||
// error checking
|
||||
_duplicateScenesDefinition = m_Target.MinViewIdPerScene.GroupBy(x => x.sceneName)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(y => y.Key)
|
||||
.ToList();
|
||||
|
||||
_duplicateViewIdDefinition = m_Target.MinViewIdPerScene.GroupBy(x => x.minViewId)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(y => y.Key)
|
||||
.ToList();
|
||||
|
||||
DrawSceneSettingsList();
|
||||
|
||||
foreach (string dup in _duplicateScenesDefinition)
|
||||
{
|
||||
EditorGUILayout.LabelField("Found duplicates for scene",dup);
|
||||
}
|
||||
|
||||
|
||||
foreach (SceneSetting sceneSettings in m_Target.MinViewIdPerScene)
|
||||
{
|
||||
if (_duplicateViewIdDefinition.Contains(sceneSettings.minViewId))
|
||||
{
|
||||
GUILayout.Label("Found view Id duplicates '"+sceneSettings.minViewId+"' for scene: " +sceneSettings.sceneName);
|
||||
}
|
||||
|
||||
if (sceneSettings.minViewId > PhotonNetwork.MAX_VIEW_IDS)
|
||||
{
|
||||
GUILayout.Label(sceneSettings.sceneName+" view Id can not exceed the max view Id "+PhotonNetwork.MAX_VIEW_IDS);
|
||||
}
|
||||
|
||||
if (sceneSettings.minViewId < 1)
|
||||
{
|
||||
GUILayout.Label(sceneSettings.sceneName+" view Id can not be less than 1");
|
||||
}
|
||||
|
||||
if (sceneSettings.sceneAsset == null && !string.IsNullOrEmpty(sceneSettings.sceneName))
|
||||
{
|
||||
GUILayout.Label("'"+sceneSettings.sceneName+"' scene is missing in the project");
|
||||
}
|
||||
}
|
||||
|
||||
_firstTime = false;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_firstTime = true;
|
||||
}
|
||||
|
||||
private void DrawSceneSettingsList()
|
||||
{
|
||||
GUILayout.Space(5);
|
||||
|
||||
// check for changes ( from undo for example)
|
||||
this.serializedObject.Update();
|
||||
|
||||
listProperty = this.serializedObject.FindProperty("MinViewIdPerScene");
|
||||
|
||||
if (listProperty == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float containerElementHeight = 44;
|
||||
float containerHeight = listProperty.arraySize * containerElementHeight;
|
||||
|
||||
isOpen = PhotonGUI.ContainerHeaderFoldout("Scene Settings (" + listProperty.arraySize + ")", this.serializedObject.FindProperty("SceneSettingsListFoldoutOpen").boolValue);
|
||||
this.serializedObject.FindProperty("SceneSettingsListFoldoutOpen").boolValue = isOpen;
|
||||
|
||||
if (isOpen == false)
|
||||
{
|
||||
containerHeight = 0;
|
||||
}
|
||||
|
||||
Rect containerRect = PhotonGUI.ContainerBody(containerHeight);
|
||||
if (isOpen == true)
|
||||
{
|
||||
for (int i = 0; i < listProperty.arraySize; ++i)
|
||||
{
|
||||
Rect elementRect = new Rect(containerRect.xMin, containerRect.yMin + containerElementHeight * i,
|
||||
containerRect.width, containerElementHeight);
|
||||
{
|
||||
Rect texturePosition = new Rect(elementRect.xMin + 6,
|
||||
elementRect.yMin + elementRect.height / 2f - 1, 9, 5);
|
||||
ReorderableListResources.DrawTexture(texturePosition, ReorderableListResources.texGrabHandle);
|
||||
|
||||
Rect propertyPosition = new Rect(elementRect.xMin + 20, elementRect.yMin + 3,
|
||||
elementRect.width - 45, 16);
|
||||
|
||||
_sceneSettings_i = listProperty.GetArrayElementAtIndex(i);
|
||||
|
||||
sceneNameProperty = _sceneSettings_i.FindPropertyRelative("sceneName");
|
||||
sceneAssetProperty = _sceneSettings_i.FindPropertyRelative("sceneAsset");
|
||||
minViewIdProperty = _sceneSettings_i.FindPropertyRelative("minViewId");
|
||||
|
||||
string _sceneName = sceneNameProperty.stringValue;
|
||||
SceneAsset _sceneAsset = m_Target.MinViewIdPerScene[i].sceneAsset;
|
||||
|
||||
// check if we need to find the scene asset based on the scene name. This is for backward compatibility or when the scene asset was deleted
|
||||
if (_firstTime)
|
||||
{
|
||||
if (_sceneAsset == null && !string.IsNullOrEmpty(_sceneName))
|
||||
{
|
||||
string[] guids = AssetDatabase.FindAssets(_sceneName + " t:SceneAsset");
|
||||
|
||||
foreach (string guid in guids)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (Path.GetFileNameWithoutExtension(path) == _sceneName)
|
||||
{
|
||||
sceneAssetProperty.objectReferenceValue =
|
||||
AssetDatabase.LoadAssetAtPath<SceneAsset>(
|
||||
AssetDatabase.GUIDToAssetPath(guid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _missingSceneAsset = _sceneAsset == null && !string.IsNullOrEmpty(_sceneName);
|
||||
// if we don't have a scene asset for the serialized scene named, we show an error.
|
||||
if (_missingSceneAsset ||
|
||||
(sceneNameProperty!=null && _duplicateScenesDefinition!=null && _duplicateScenesDefinition.Contains(sceneNameProperty.stringValue))
|
||||
)
|
||||
{
|
||||
GUI.color = Color.red;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
string _label = _missingSceneAsset
|
||||
? "Scene Asset: Missing '" + _sceneName + "'"
|
||||
: "Scene Asset";
|
||||
|
||||
EditorGUI.PropertyField(propertyPosition,sceneAssetProperty, new GUIContent(_label));
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
_sceneAsset = sceneAssetProperty.objectReferenceValue as SceneAsset;
|
||||
if (_sceneAsset == null && !string.IsNullOrEmpty(sceneNameProperty.stringValue))
|
||||
{
|
||||
sceneNameProperty.stringValue = null;
|
||||
}
|
||||
else if (sceneNameProperty.stringValue != _sceneAsset.name)
|
||||
{
|
||||
sceneNameProperty.stringValue = _sceneAsset.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// EditorGUI.PropertyField(propertyPosition, sceneNameProperty,
|
||||
// new GUIContent("Scene Name"));
|
||||
|
||||
GUI.color = Color.white;
|
||||
|
||||
if ( minViewIdProperty.intValue<1 || minViewIdProperty.intValue> PhotonNetwork.MAX_VIEW_IDS)
|
||||
{
|
||||
GUI.color = Color.red;
|
||||
}
|
||||
Rect secondPropertyPosition = new Rect(elementRect.xMin + 20, elementRect.yMin + containerElementHeight/2,
|
||||
elementRect.width - 45, 16);
|
||||
|
||||
EditorGUI.PropertyField(secondPropertyPosition, _sceneSettings_i.FindPropertyRelative("minViewId"),
|
||||
new GUIContent("Minimum View ID"));
|
||||
|
||||
GUI.color = Color.white;
|
||||
|
||||
//Debug.Log( listProperty.GetArrayElementAtIndex( i ).objectReferenceValue.GetType() );
|
||||
//Rect statsPosition = new Rect( propertyPosition.xMax + 7, propertyPosition.yMin, statsIcon.width, statsIcon.height );
|
||||
//ReorderableListResources.DrawTexture( statsPosition, statsIcon );
|
||||
|
||||
|
||||
Rect removeButtonRect = new Rect(
|
||||
elementRect.xMax - PhotonGUI.DefaultRemoveButtonStyle.fixedWidth,
|
||||
elementRect.yMin + 2,
|
||||
PhotonGUI.DefaultRemoveButtonStyle.fixedWidth,
|
||||
PhotonGUI.DefaultRemoveButtonStyle.fixedHeight);
|
||||
|
||||
|
||||
if (GUI.Button(removeButtonRect, new GUIContent(ReorderableListResources.texRemoveButton),
|
||||
PhotonGUI.DefaultRemoveButtonStyle))
|
||||
{
|
||||
listProperty.DeleteArrayElementAtIndex(i);
|
||||
|
||||
Undo.RecordObject(this.m_Target, "Removed SceneSettings Entry");
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (i < listProperty.arraySize - 1)
|
||||
{
|
||||
texturePosition = new Rect(elementRect.xMin + 2, elementRect.yMax, elementRect.width - 4,
|
||||
1);
|
||||
PhotonGUI.DrawSplitter(texturePosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PhotonGUI.AddButton())
|
||||
{
|
||||
this.listProperty.InsertArrayElementAtIndex(Mathf.Max(0, listProperty.arraySize - 1));
|
||||
_sceneSettings_i = this.listProperty.GetArrayElementAtIndex(listProperty.arraySize - 1);
|
||||
sceneNameProperty = _sceneSettings_i.FindPropertyRelative("sceneName");
|
||||
sceneAssetProperty = _sceneSettings_i.FindPropertyRelative("sceneAsset");
|
||||
minViewIdProperty = _sceneSettings_i.FindPropertyRelative("minViewId");
|
||||
|
||||
sceneAssetProperty.objectReferenceValue = null;
|
||||
sceneNameProperty.stringValue = "";
|
||||
minViewIdProperty.intValue = 1;
|
||||
|
||||
Undo.RecordObject(this.m_Target, "Added SceneSettings Entry");
|
||||
}
|
||||
|
||||
this.serializedObject.ApplyModifiedProperties();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ad59deacfd0848dcb64a51b0a0eb960
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62126d9bb7b8eb64ea07a039d902d0ac
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,26 @@
|
||||
Copyright (c) 2013, Rotorz Limited
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2fbd2e43c3dfae4d9830e9921238cf5
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,237 @@
|
||||
// Copyright (c) 2012-2013 Rotorz Limited. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System;
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Resources to assist with reorderable list control.
|
||||
/// </summary>
|
||||
internal static class ReorderableListResources
|
||||
{
|
||||
|
||||
static ReorderableListResources()
|
||||
{
|
||||
GenerateSpecialTextures();
|
||||
LoadResourceAssets();
|
||||
}
|
||||
|
||||
#region Texture Resources
|
||||
|
||||
private enum ResourceName
|
||||
{
|
||||
add_button = 0,
|
||||
add_button_active,
|
||||
container_background,
|
||||
grab_handle,
|
||||
remove_button,
|
||||
remove_button_active,
|
||||
title_background,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resource assets for light skin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Resource assets are PNG images which have been encoded using a base-64
|
||||
/// string so that actual asset files are not necessary.</para>
|
||||
/// </remarks>
|
||||
private static string[] s_LightSkin = {
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAB4AAAAQCAYAAAABOs/SAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAW0lEQVRIS+3NywnAQAhF0anI4mzVCmzBBl7QEBgGE5JFhBAXd+OHM5gZZgYRKcktNxu+HRFF2e6qhtOjtQM7K/tZ+xY89wSbazg9eqOfw6oag4rcChjY8coAjA2l1RxFDY8IFAAAAABJRU5ErkJggg==",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAB4AAAAQCAYAAAABOs/SAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAGlJREFUeNpiFBER+f/jxw8GNjY2BnqAX79+MXBwcDAwMQwQGHoWnzp1CoxHjo8pBSykBi8+MTMzs2HmY2QfwXxKii9HExdZgNwgHuFB/efPH7pZCLOL8f///wyioqL/6enbL1++MAIEGABvGSLA+9GPZwAAAABJRU5ErkJggg==",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAMElEQVQYV2P4//8/Q1FR0X8YBvHBAp8+ffp/+fJlMA3igwUfPnwIFgDRYEFM7f8ZAG1EOYL9INrfAAAAAElFTkSuQmCC",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAkAAAAFCAYAAACXU8ZrAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAIElEQVQYV2P49OnTf0KYobCw8D8hzPD/P2FMLesK/wMAs5yJpK+6aN4AAAAASUVORK5CYII=",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAACCAIAAADq9gq6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABVJREFUeNpiVFZWZsAGmBhwAIAAAwAURgBt4C03ZwAAAABJRU5ErkJggg==",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAACCAIAAADq9gq6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABVJREFUeNpivHPnDgM2wMSAAwAEGAB8VgKYlvqkBwAAAABJRU5ErkJggg==",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEFJREFUeNpi/P//P0NxcfF/BgRgZP78+fN/VVVVhpCQEAZjY2OGs2fPNrCApBwdHRkePHgAVwoWnDVrFgMyAAgwAAt4E1dCq1obAAAAAElFTkSuQmCC"
|
||||
};
|
||||
/// <summary>
|
||||
/// Resource assets for dark skin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Resource assets are PNG images which have been encoded using a base-64
|
||||
/// string so that actual asset files are not necessary.</para>
|
||||
/// </remarks>
|
||||
private static string[] s_DarkSkin = {
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAB4AAAAQCAYAAAABOs/SAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIBJREFUeNpiVFZW/u/i4sLw4sULBnoACQkJhj179jAwMQwQGHoWl5aWgvHI8TGlgIXU4MUn1t3dPcx8HB8fD2cvXLgQQ0xHR4c2FmMzmBTLhl5QYwt2cn1MtsXkWjg4gvrt27fgWoMeAGQXCDD+//+fQUVF5T89fXvnzh1GgAADAFmSI1Ed3FqgAAAAAElFTkSuQmCC",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAB4AAAAQCAYAAAABOs/SAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHlJREFUeNpiFBER+f/jxw8GNjY2BnqAX79+MXBwcDAwMQwQGHoWv3nzBoxHjo8pBSykBi8+MWAOGWY+5uLigrO/ffuGIYbMppnF5Fg2tFM1yKfk+pbkoKZGEA+OVP3nzx+6WQizi/H///8MoqKi/+np2y9fvjACBBgAoTYjgvihfz0AAAAASUVORK5CYII=",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD1JREFUeNpi/P//P4OKisp/Bii4c+cOIwtIwMXFheHFixcMEhISYAVMINm3b9+CBUA0CDCiazc0NGQECDAAdH0YelA27kgAAAAASUVORK5CYII=",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAkAAAAFCAYAAACXU8ZrAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACRJREFUeNpizM3N/c9AADAqKysTVMTi5eXFSFAREFPHOoAAAwBCfwcAO8g48QAAAABJRU5ErkJggg==",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAECAYAAACzzX7wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi/P//PwM+wHL06FG8KpgYCABGZWVlvCYABBgA7/sHvGw+cz8AAAAASUVORK5CYII=",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAECAYAAACzzX7wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi/P//PwM+wPKfgAomBgKAhYuLC68CgAADAAxjByOjCHIRAAAAAElFTkSuQmCC",
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAECAYAAABGM/VAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADtJREFUeNpi/P//P4OKisp/Bii4c+cOIwtIQE9Pj+HLly9gQRCfBcQACbx69QqmmAEseO/ePQZkABBgAD04FXsmmijSAAAAAElFTkSuQmCC"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets light or dark texture "add_button.png".
|
||||
/// </summary>
|
||||
public static Texture2D texAddButton
|
||||
{
|
||||
get { return s_Cached[ (int)ResourceName.add_button ]; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets light or dark texture "add_button_active.png".
|
||||
/// </summary>
|
||||
public static Texture2D texAddButtonActive
|
||||
{
|
||||
get { return s_Cached[ (int)ResourceName.add_button_active ]; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets light or dark texture "container_background.png".
|
||||
/// </summary>
|
||||
public static Texture2D texContainerBackground
|
||||
{
|
||||
get { return s_Cached[ (int)ResourceName.container_background ]; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets light or dark texture "grab_handle.png".
|
||||
/// </summary>
|
||||
public static Texture2D texGrabHandle
|
||||
{
|
||||
get { return s_Cached[ (int)ResourceName.grab_handle ]; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets light or dark texture "remove_button.png".
|
||||
/// </summary>
|
||||
public static Texture2D texRemoveButton
|
||||
{
|
||||
get { return s_Cached[ (int)ResourceName.remove_button ]; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets light or dark texture "remove_button_active.png".
|
||||
/// </summary>
|
||||
public static Texture2D texRemoveButtonActive
|
||||
{
|
||||
get { return s_Cached[ (int)ResourceName.remove_button_active ]; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets light or dark texture "title_background.png".
|
||||
/// </summary>
|
||||
public static Texture2D texTitleBackground
|
||||
{
|
||||
get { return s_Cached[ (int)ResourceName.title_background ]; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Generated Resources
|
||||
|
||||
public static Texture2D texItemSplitter { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Generate special textures.
|
||||
/// </summary>
|
||||
private static void GenerateSpecialTextures()
|
||||
{
|
||||
var splitterColor = EditorGUIUtility.isProSkin
|
||||
? new Color( 1f, 1f, 1f, 0.14f )
|
||||
: new Color( 0.59f, 0.59f, 0.59f, 0.55f )
|
||||
;
|
||||
texItemSplitter = CreatePixelTexture( "(Generated) Item Splitter", splitterColor );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create 1x1 pixel texture of specified color.
|
||||
/// </summary>
|
||||
/// <param name="name">Name for texture object.</param>
|
||||
/// <param name="color">Pixel color.</param>
|
||||
/// <returns>
|
||||
/// The new <c>Texture2D</c> instance.
|
||||
/// </returns>
|
||||
public static Texture2D CreatePixelTexture( string name, Color color )
|
||||
{
|
||||
var tex = new Texture2D( 1, 1, TextureFormat.ARGB32, false, true );
|
||||
tex.name = name;
|
||||
tex.hideFlags = HideFlags.HideAndDontSave;
|
||||
tex.filterMode = FilterMode.Point;
|
||||
tex.SetPixel( 0, 0, color );
|
||||
tex.Apply();
|
||||
return tex;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Load PNG from Base-64 Encoded String
|
||||
|
||||
private static Texture2D[] s_Cached;
|
||||
|
||||
/// <summary>
|
||||
/// Read textures from base-64 encoded strings. Automatically selects assets based
|
||||
/// upon whether the light or dark (pro) skin is active.
|
||||
/// </summary>
|
||||
private static void LoadResourceAssets()
|
||||
{
|
||||
var skin = EditorGUIUtility.isProSkin ? s_DarkSkin : s_LightSkin;
|
||||
s_Cached = new Texture2D[ skin.Length ];
|
||||
|
||||
for( int i = 0; i < s_Cached.Length; ++i )
|
||||
{
|
||||
// Get image data (PNG) from base64 encoded strings.
|
||||
byte[] imageData = Convert.FromBase64String( skin[ i ] );
|
||||
|
||||
// Gather image size from image data.
|
||||
int texWidth, texHeight;
|
||||
GetImageSize( imageData, out texWidth, out texHeight );
|
||||
|
||||
// Generate texture asset.
|
||||
var tex = new Texture2D( texWidth, texHeight, TextureFormat.ARGB32, false, true );
|
||||
tex.hideFlags = HideFlags.HideAndDontSave;
|
||||
tex.name = "(Generated) ReorderableList:" + i;
|
||||
tex.filterMode = FilterMode.Point;
|
||||
tex.LoadImage( imageData );
|
||||
|
||||
s_Cached[ i ] = tex;
|
||||
}
|
||||
|
||||
s_LightSkin = null;
|
||||
s_DarkSkin = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read width and height if PNG file in pixels.
|
||||
/// </summary>
|
||||
/// <param name="imageData">PNG image data.</param>
|
||||
/// <param name="width">Width of image in pixels.</param>
|
||||
/// <param name="height">Height of image in pixels.</param>
|
||||
private static void GetImageSize( byte[] imageData, out int width, out int height )
|
||||
{
|
||||
width = ReadInt( imageData, 3 + 15 );
|
||||
height = ReadInt( imageData, 3 + 15 + 2 + 2 );
|
||||
}
|
||||
|
||||
private static int ReadInt( byte[] imageData, int offset )
|
||||
{
|
||||
return ( imageData[ offset ] << 8 ) | imageData[ offset + 1 ];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI Helper
|
||||
private static GUIStyle s_TempStyle = new GUIStyle();
|
||||
|
||||
/// <summary>
|
||||
/// Draw texture using <see cref="GUIStyle"/> to workaround bug in Unity where
|
||||
/// <see cref="GUI.DrawTexture"/> flickers when embedded inside a property drawer.
|
||||
/// </summary>
|
||||
/// <param name="position">Position of which to draw texture in space of GUI.</param>
|
||||
/// <param name="texture">Texture.</param>
|
||||
public static void DrawTexture( Rect position, Texture2D texture )
|
||||
{
|
||||
if( Event.current.type != EventType.Repaint )
|
||||
return;
|
||||
|
||||
s_TempStyle.normal.background = texture;
|
||||
|
||||
s_TempStyle.Draw( position, GUIContent.none, false, false, false, false );
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60c609ded101b0a468fb5cf27b31cf27
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,322 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="ServerSettingsInspector.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// This is a custom editor for the ServerSettings scriptable object.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
using Photon.Pun;
|
||||
|
||||
using ExitGames.Client.Photon;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Photon.Realtime;
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
[CustomEditor(typeof(ServerSettings))]
|
||||
public class ServerSettingsInspector : Editor
|
||||
{
|
||||
private string versionPhoton;
|
||||
|
||||
private string[] regionsPrefsList;
|
||||
|
||||
private string prefLabel;
|
||||
private const string notAvailableLabel = "n/a";
|
||||
|
||||
private string rpcCrc;
|
||||
private bool showRpcs;
|
||||
|
||||
private GUIStyle vertboxStyle;
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
this.versionPhoton = System.Reflection.Assembly.GetAssembly(typeof(PhotonPeer)).GetName().Version.ToString();
|
||||
}
|
||||
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (vertboxStyle == null)
|
||||
vertboxStyle = new GUIStyle("HelpBox") { padding = new RectOffset(6, 6, 6, 6) };
|
||||
|
||||
SerializedObject sObj = new SerializedObject(this.target);
|
||||
ServerSettings settings = this.target as ServerSettings;
|
||||
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
#region Version Vertical Box
|
||||
|
||||
EditorGUILayout.BeginVertical(/*vertboxStyle*/);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel(new GUIContent("Version:", "Version of PUN and Photon3Unity3d.dll."));
|
||||
GUILayout.FlexibleSpace();
|
||||
var helpicorect = EditorGUILayout.GetControlRect(GUILayout.MaxWidth(16));
|
||||
EditorGUIUtility.AddCursorRect(helpicorect, MouseCursor.Link);
|
||||
if (GUI.Button(helpicorect, PhotonGUI.HelpIcon, GUIStyle.none))
|
||||
{
|
||||
Application.OpenURL(PhotonEditor.UrlPunSettings);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.LabelField("Pun: " + PhotonNetwork.PunVersion + " Photon lib: " + this.versionPhoton);
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
#endregion Version Vertical Box
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
SerializedProperty showSettingsProp = this.serializedObject.FindProperty("ShowSettings");
|
||||
bool showSettings = showSettingsProp.Foldout(new GUIContent("Server/Cloud Settings", "Core Photon Server/Cloud settings."));
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
|
||||
if (showSettings != settings.ShowSettings)
|
||||
{
|
||||
showSettingsProp.boolValue = showSettings;
|
||||
}
|
||||
|
||||
if (showSettingsProp.boolValue)
|
||||
{
|
||||
SerializedProperty settingsSp = this.serializedObject.FindProperty("AppSettings");
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
//Realtime APP ID
|
||||
this.BuildAppIdField(settingsSp.FindPropertyRelative("AppIdRealtime"), "App Id PUN");
|
||||
|
||||
if (PhotonEditorUtils.HasChat)
|
||||
{
|
||||
this.BuildAppIdField(settingsSp.FindPropertyRelative("AppIdChat"));
|
||||
}
|
||||
if (PhotonEditorUtils.HasVoice)
|
||||
{
|
||||
this.BuildAppIdField(settingsSp.FindPropertyRelative("AppIdVoice"));
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("AppVersion"));
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("UseNameServer"), new GUIContent("Use Name Server", "Photon Cloud requires this checked.\nUncheck for Photon Server SDK (OnPremise)."));
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("FixedRegion"), new GUIContent("Fixed Region", "Photon Cloud setting, needs a Name Server.\nDefine one region to always connect to.\nLeave empty to use the best region from a server-side region list."));
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("Server"), new GUIContent("Server", "Typically empty for Photon Cloud.\nFor Photon OnPremise, enter your host name or IP. Also uncheck \"Use Name Server\" for older Photon OnPremise servers."));
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("Port"), new GUIContent("Port", "Leave 0 to use default Photon Cloud ports for the Name Server.\nOnPremise defaults to 5055 for UDP and 4530 for TCP."));
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("ProxyServer"), new GUIContent("Proxy Server", "HTTP Proxy Server for WebSocket connection. See LoadBalancingClient.ProxyServerAddress for options."));
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("Protocol"), new GUIContent("Protocol", "Use UDP where possible.\nWSS works on WebGL and Xbox exports.\nDefine WEBSOCKET for use on other platforms."));
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("EnableProtocolFallback"), new GUIContent("Protocol Fallback", "Automatically try another network protocol, if initial connect fails.\nWill use default Name Server ports."));
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("EnableLobbyStatistics"), new GUIContent("Lobby Statistics", "When using multiple room lists (lobbies), the server can send info about their usage."));
|
||||
EditorGUILayout.PropertyField(settingsSp.FindPropertyRelative("NetworkLogging"), new GUIContent("Network Logging", "Log level for the Photon libraries."));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(this.serializedObject.FindProperty("PunLogging"), new GUIContent("PUN Logging", "Log level for the PUN layer."));
|
||||
EditorGUILayout.PropertyField(this.serializedObject.FindProperty("EnableSupportLogger"), new GUIContent("Support Logger", "Logs additional info for debugging.\nUse this when you submit bugs to the Photon Team."));
|
||||
EditorGUILayout.PropertyField(this.serializedObject.FindProperty("RunInBackground"), new GUIContent("Run In Background", "Enables apps to keep the connection without focus. Android and iOS ignore this."));
|
||||
EditorGUILayout.PropertyField(this.serializedObject.FindProperty("StartInOfflineMode"), new GUIContent("Start In Offline Mode", "Simulates an online connection.\nPUN can be used as usual."));
|
||||
|
||||
EditorGUILayout.PropertyField(this.serializedObject.FindProperty("DevRegion"), new GUIContent("Dev Region", "Photon Cloud setting, needs a Name Server.\nDefine region the Editor and Development builds will always connect to - ensuring all users can find common rooms.\nLeave empty to use the Fixed Region or best region from a server-side region list. This value will be ignored for non-Development builds."));
|
||||
|
||||
#region Best Region Box
|
||||
|
||||
EditorGUILayout.BeginVertical(vertboxStyle);
|
||||
|
||||
if (!string.IsNullOrEmpty(PhotonNetwork.BestRegionSummaryInPreferences))
|
||||
{
|
||||
this.regionsPrefsList = PhotonNetwork.BestRegionSummaryInPreferences.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (this.regionsPrefsList.Length < 2)
|
||||
{
|
||||
this.prefLabel = notAvailableLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.prefLabel = string.Format("'{0}' ping:{1}ms ", this.regionsPrefsList[0], this.regionsPrefsList[1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.prefLabel = notAvailableLabel;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField(new GUIContent("Best Region Preference: " + prefLabel, "Best region is used if Fixed Region is empty."));
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
var resetrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(64));
|
||||
var editrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(64));
|
||||
if (GUI.Button(resetrect, "Reset", EditorStyles.miniButton))
|
||||
{
|
||||
ServerSettings.ResetBestRegionCodeInPreferences();
|
||||
}
|
||||
|
||||
if (GUI.Button(editrect, "Edit WhiteList", EditorStyles.miniButton))
|
||||
{
|
||||
Application.OpenURL("https://dashboard.photonengine.com/en-US/App/RegionsWhitelistEdit/" + PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime);
|
||||
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
#endregion Best Region Box
|
||||
|
||||
|
||||
//this.showRpcs = EditorGUILayout.Foldout(this.showRpcs, new GUIContent("RPCs", "RPC shortcut list."));
|
||||
EditorGUI.indentLevel--;
|
||||
this.showRpcs = this.showRpcs.Foldout(new GUIContent("RPCs", "RPC shortcut list."));
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
if (this.showRpcs)
|
||||
{
|
||||
// first time check to get the rpc has proper
|
||||
if (string.IsNullOrEmpty(this.rpcCrc))
|
||||
{
|
||||
this.rpcCrc = this.RpcListHashCode().ToString("X");
|
||||
}
|
||||
|
||||
#region Begin Vertical Box CRC
|
||||
|
||||
EditorGUILayout.BeginVertical(vertboxStyle);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel("List CRC");
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
var copyrect = EditorGUILayout.GetControlRect(GUILayout.MaxWidth(16));
|
||||
EditorGUILayout.GetControlRect(GUILayout.MaxWidth(12));
|
||||
var hashrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(16)); // new Rect(copyrect) { xMin = copyrect.xMin + 32 };
|
||||
|
||||
EditorGUIUtility.AddCursorRect(copyrect, MouseCursor.Link);
|
||||
EditorGUI.LabelField(copyrect, new GUIContent("", "Copy Hashcode to Clipboard"));
|
||||
if (GUI.Button(copyrect, PhotonGUI.CopyIcon, GUIStyle.none))
|
||||
{
|
||||
Debug.Log("RPC-List HashCode copied into your ClipBoard: " + this.rpcCrc + ". Make sure clients that send each other RPCs have the same RPC-List.");
|
||||
EditorGUIUtility.systemCopyBuffer = this.rpcCrc;
|
||||
}
|
||||
EditorGUI.SelectableLabel(hashrect, this.rpcCrc);
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
var refreshrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(64));
|
||||
var clearrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(64));
|
||||
|
||||
if (GUI.Button(refreshrect, "Refresh RPCs", EditorStyles.miniButton))
|
||||
{
|
||||
PhotonEditor.UpdateRpcList();
|
||||
this.Repaint();
|
||||
}
|
||||
|
||||
if (GUI.Button(clearrect, "Clear RPCs", EditorStyles.miniButton))
|
||||
{
|
||||
PhotonEditor.ClearRpcList();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
#endregion End Vertical Box CRC
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
SerializedProperty sRpcs = sObj.FindProperty("RpcList");
|
||||
EditorGUILayout.PropertyField(sRpcs, true);
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
sObj.ApplyModifiedProperties();
|
||||
this.serializedObject.ApplyModifiedProperties();
|
||||
|
||||
// cache the rpc hash
|
||||
this.rpcCrc = this.RpcListHashCode().ToString("X");
|
||||
}
|
||||
|
||||
#region Simple Settings
|
||||
|
||||
/// Conditional Simple Sync Settings DrawGUI - Uses reflection to avoid having to hard connect the libraries
|
||||
var SettingsScriptableObjectBaseType = GetType("Photon.Utilities.SettingsScriptableObjectBase");
|
||||
if (SettingsScriptableObjectBaseType != null)
|
||||
{
|
||||
EditorGUILayout.GetControlRect(false, 3);
|
||||
|
||||
EditorGUILayout.LabelField("Simple Extension Settings", (GUIStyle)"BoldLabel");
|
||||
|
||||
var drawAllMethod = SettingsScriptableObjectBaseType.GetMethod("DrawAllSettings");
|
||||
|
||||
if (drawAllMethod != null && this != null)
|
||||
{
|
||||
bool initializeAsOpen = false;
|
||||
drawAllMethod.Invoke(null, new object[2] { this, initializeAsOpen });
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
private static Type GetType(string typeName)
|
||||
{
|
||||
var type = Type.GetType(typeName);
|
||||
if (type != null) return type;
|
||||
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
type = a.GetType(typeName);
|
||||
if (type != null)
|
||||
return type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int RpcListHashCode()
|
||||
{
|
||||
// this is a hashcode generated to (more) easily compare this Editor's RPC List with some other
|
||||
int hashCode = PhotonNetwork.PhotonServerSettings.RpcList.Count + 1;
|
||||
foreach (string s in PhotonNetwork.PhotonServerSettings.RpcList)
|
||||
{
|
||||
int h1 = s.GetHashCode();
|
||||
hashCode = ((h1 << 5) + h1) ^ hashCode;
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
private void BuildAppIdField(SerializedProperty property, string label = null)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
if (label != null)
|
||||
{
|
||||
EditorGUILayout.PropertyField(property, new GUIContent(label), GUILayout.MinWidth(32));
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(property, GUILayout.MinWidth(32));
|
||||
}
|
||||
|
||||
property.stringValue = property.stringValue.Trim();
|
||||
string appId = property.stringValue;
|
||||
|
||||
string url = "https://dashboard.photonengine.com/en-US/PublicCloud";
|
||||
|
||||
if (!string.IsNullOrEmpty(appId))
|
||||
{
|
||||
url = string.Format("https://dashboard.photonengine.com/en-US/App/Manage/{0}", appId);
|
||||
}
|
||||
if (GUILayout.Button("Dashboard", EditorStyles.miniButton, GUILayout.MinWidth(78), GUILayout.MaxWidth(78)))
|
||||
{
|
||||
Application.OpenURL(url);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21239ba77ac4b534f958e8617ef13ede
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6024eaa234f94341af9e45cc99285c7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,40 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonAnimatorViewEditor.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// This is a custom editor for the AnimatorView component.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(MonoBehaviourPun))]
|
||||
public abstract class MonoBehaviourPunEditor : Editor
|
||||
{
|
||||
MonoBehaviourPun mbTarget;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
mbTarget = target as MonoBehaviourPun;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
mbTarget = target as MonoBehaviourPun;
|
||||
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (mbTarget.photonView == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Unable to find a PhotonView on this GameObject or on any parent GameObject.", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6da457ee57ad5794782f1f76644536e4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,295 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonAnimatorViewEditor.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// This is a custom editor for the AnimatorView component.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
[CustomEditor(typeof(PhotonAnimatorView))]
|
||||
public class PhotonAnimatorViewEditor : MonoBehaviourPunEditor
|
||||
{
|
||||
private Animator m_Animator;
|
||||
private PhotonAnimatorView m_Target;
|
||||
private AnimatorController m_Controller;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (this.m_Animator == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("GameObject doesn't have an Animator component to synchronize", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
this.DrawWeightInspector();
|
||||
|
||||
if (this.GetLayerCount() == 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Animator doesn't have any layers setup to synchronize", MessageType.Warning);
|
||||
}
|
||||
|
||||
this.DrawParameterInspector();
|
||||
|
||||
if (this.GetParameterCount() == 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Animator doesn't have any parameters setup to synchronize", MessageType.Warning);
|
||||
}
|
||||
|
||||
this.serializedObject.ApplyModifiedProperties();
|
||||
|
||||
//GUILayout.Label( "m_SynchronizeLayers " + serializedObject.FindProperty( "m_SynchronizeLayers" ).arraySize );
|
||||
//GUILayout.Label( "m_SynchronizeParameters " + serializedObject.FindProperty( "m_SynchronizeParameters" ).arraySize );
|
||||
}
|
||||
|
||||
|
||||
private int GetLayerCount()
|
||||
{
|
||||
return (this.m_Controller == null) ? 0 : this.m_Controller.layers.Length;
|
||||
}
|
||||
|
||||
private int GetParameterCount()
|
||||
{
|
||||
return (this.m_Controller == null) ? 0 : this.m_Controller.parameters.Length;
|
||||
}
|
||||
|
||||
private AnimatorControllerParameter GetAnimatorControllerParameter(int i)
|
||||
{
|
||||
return this.m_Controller.parameters[i];
|
||||
}
|
||||
|
||||
|
||||
private RuntimeAnimatorController GetEffectiveController(Animator animator)
|
||||
{
|
||||
RuntimeAnimatorController controller = animator.runtimeAnimatorController;
|
||||
|
||||
AnimatorOverrideController overrideController = controller as AnimatorOverrideController;
|
||||
while (overrideController != null)
|
||||
{
|
||||
controller = overrideController.runtimeAnimatorController;
|
||||
overrideController = controller as AnimatorOverrideController;
|
||||
}
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
this.m_Target = (PhotonAnimatorView)this.target;
|
||||
this.m_Animator = this.m_Target.GetComponent<Animator>();
|
||||
|
||||
if (m_Animator)
|
||||
{
|
||||
this.m_Controller = this.GetEffectiveController(this.m_Animator) as AnimatorController;
|
||||
|
||||
this.CheckIfStoredParametersExist();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawWeightInspector()
|
||||
{
|
||||
SerializedProperty foldoutProperty = this.serializedObject.FindProperty("ShowLayerWeightsInspector");
|
||||
foldoutProperty.boolValue = PhotonGUI.ContainerHeaderFoldout("Synchronize Layer Weights", foldoutProperty.boolValue);
|
||||
|
||||
if (foldoutProperty.boolValue == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float lineHeight = 20;
|
||||
Rect containerRect = PhotonGUI.ContainerBody(this.GetLayerCount() * lineHeight);
|
||||
|
||||
for (int i = 0; i < this.GetLayerCount(); ++i)
|
||||
{
|
||||
if (this.m_Target.DoesLayerSynchronizeTypeExist(i) == false)
|
||||
{
|
||||
this.m_Target.SetLayerSynchronized(i, PhotonAnimatorView.SynchronizeType.Disabled);
|
||||
}
|
||||
|
||||
PhotonAnimatorView.SynchronizeType syncType = this.m_Target.GetLayerSynchronizeType(i);
|
||||
|
||||
Rect elementRect = new Rect(containerRect.xMin, containerRect.yMin + i * lineHeight, containerRect.width, lineHeight);
|
||||
|
||||
Rect labelRect = new Rect(elementRect.xMin + 5, elementRect.yMin + 2, EditorGUIUtility.labelWidth - 5, elementRect.height);
|
||||
GUI.Label(labelRect, "Layer " + i);
|
||||
|
||||
Rect popupRect = new Rect(elementRect.xMin + EditorGUIUtility.labelWidth, elementRect.yMin + 2, elementRect.width - EditorGUIUtility.labelWidth - 5, EditorGUIUtility.singleLineHeight);
|
||||
syncType = (PhotonAnimatorView.SynchronizeType)EditorGUI.EnumPopup(popupRect, syncType);
|
||||
|
||||
if (i < this.GetLayerCount() - 1)
|
||||
{
|
||||
Rect splitterRect = new Rect(elementRect.xMin + 2, elementRect.yMax, elementRect.width - 4, 1);
|
||||
PhotonGUI.DrawSplitter(splitterRect);
|
||||
}
|
||||
|
||||
if (syncType != this.m_Target.GetLayerSynchronizeType(i))
|
||||
{
|
||||
Undo.RecordObject(this.target, "Modify Synchronize Layer Weights");
|
||||
this.m_Target.SetLayerSynchronized(i, syncType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool DoesParameterExist(string name)
|
||||
{
|
||||
for (int i = 0; i < this.GetParameterCount(); ++i)
|
||||
{
|
||||
if (this.GetAnimatorControllerParameter(i).name == name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CheckIfStoredParametersExist()
|
||||
{
|
||||
var syncedParams = this.m_Target.GetSynchronizedParameters();
|
||||
List<string> paramsToRemove = new List<string>();
|
||||
|
||||
for (int i = 0; i < syncedParams.Count; ++i)
|
||||
{
|
||||
string parameterName = syncedParams[i].Name;
|
||||
if (this.DoesParameterExist(parameterName) == false)
|
||||
{
|
||||
Debug.LogWarning("Parameter '" + this.m_Target.GetSynchronizedParameters()[i].Name + "' doesn't exist anymore. Removing it from the list of synchronized parameters");
|
||||
paramsToRemove.Add(parameterName);
|
||||
}
|
||||
}
|
||||
|
||||
if (paramsToRemove.Count > 0)
|
||||
{
|
||||
foreach (string param in paramsToRemove)
|
||||
{
|
||||
this.m_Target.GetSynchronizedParameters().RemoveAll(item => item.Name == param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawParameterInspector()
|
||||
{
|
||||
// flag to expose a note in Interface if one or more trigger(s) are synchronized
|
||||
bool isUsingTriggers = false;
|
||||
|
||||
SerializedProperty foldoutProperty = this.serializedObject.FindProperty("ShowParameterInspector");
|
||||
foldoutProperty.boolValue = PhotonGUI.ContainerHeaderFoldout("Synchronize Parameters", foldoutProperty.boolValue);
|
||||
|
||||
if (foldoutProperty.boolValue == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float lineHeight = 20;
|
||||
Rect containerRect = PhotonGUI.ContainerBody(this.GetParameterCount() * lineHeight);
|
||||
|
||||
for (int i = 0; i < this.GetParameterCount(); i++)
|
||||
{
|
||||
AnimatorControllerParameter parameter = null;
|
||||
parameter = this.GetAnimatorControllerParameter(i);
|
||||
|
||||
string defaultValue = "";
|
||||
|
||||
if (parameter.type == AnimatorControllerParameterType.Bool)
|
||||
{
|
||||
if (Application.isPlaying && this.m_Animator.gameObject.activeInHierarchy)
|
||||
{
|
||||
defaultValue += this.m_Animator.GetBool(parameter.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultValue += parameter.defaultBool.ToString();
|
||||
}
|
||||
}
|
||||
else if (parameter.type == AnimatorControllerParameterType.Float)
|
||||
{
|
||||
if (Application.isPlaying && this.m_Animator.gameObject.activeInHierarchy)
|
||||
{
|
||||
defaultValue += this.m_Animator.GetFloat(parameter.name).ToString("0.00");
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultValue += parameter.defaultFloat.ToString();
|
||||
}
|
||||
}
|
||||
else if (parameter.type == AnimatorControllerParameterType.Int)
|
||||
{
|
||||
if (Application.isPlaying && this.m_Animator.gameObject.activeInHierarchy)
|
||||
{
|
||||
defaultValue += this.m_Animator.GetInteger(parameter.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultValue += parameter.defaultInt.ToString();
|
||||
}
|
||||
}
|
||||
else if (parameter.type == AnimatorControllerParameterType.Trigger)
|
||||
{
|
||||
if (Application.isPlaying && this.m_Animator.gameObject.activeInHierarchy)
|
||||
{
|
||||
defaultValue += this.m_Animator.GetBool(parameter.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultValue += parameter.defaultBool.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.m_Target.DoesParameterSynchronizeTypeExist(parameter.name) == false)
|
||||
{
|
||||
this.m_Target.SetParameterSynchronized(parameter.name, (PhotonAnimatorView.ParameterType)parameter.type, PhotonAnimatorView.SynchronizeType.Disabled);
|
||||
}
|
||||
|
||||
PhotonAnimatorView.SynchronizeType value = this.m_Target.GetParameterSynchronizeType(parameter.name);
|
||||
|
||||
// check if using trigger and actually synchronizing it
|
||||
if (value != PhotonAnimatorView.SynchronizeType.Disabled && parameter.type == AnimatorControllerParameterType.Trigger)
|
||||
{
|
||||
isUsingTriggers = true;
|
||||
}
|
||||
|
||||
Rect elementRect = new Rect(containerRect.xMin, containerRect.yMin + i * lineHeight, containerRect.width, lineHeight);
|
||||
|
||||
Rect labelRect = new Rect(elementRect.xMin + 5, elementRect.yMin + 2, EditorGUIUtility.labelWidth - 5, elementRect.height);
|
||||
GUI.Label(labelRect, parameter.name + " (" + defaultValue + ")");
|
||||
|
||||
Rect popupRect = new Rect(elementRect.xMin + EditorGUIUtility.labelWidth, elementRect.yMin + 2, elementRect.width - EditorGUIUtility.labelWidth - 5, EditorGUIUtility.singleLineHeight);
|
||||
value = (PhotonAnimatorView.SynchronizeType)EditorGUI.EnumPopup(popupRect, value);
|
||||
|
||||
if (i < this.GetParameterCount() - 1)
|
||||
{
|
||||
Rect splitterRect = new Rect(elementRect.xMin + 2, elementRect.yMax, elementRect.width - 4, 1);
|
||||
PhotonGUI.DrawSplitter(splitterRect);
|
||||
}
|
||||
|
||||
if (value != this.m_Target.GetParameterSynchronizeType(parameter.name))
|
||||
{
|
||||
Undo.RecordObject(this.target, "Modify Synchronize Parameter " + parameter.name);
|
||||
this.m_Target.SetParameterSynchronized(parameter.name, (PhotonAnimatorView.ParameterType)parameter.type, value);
|
||||
}
|
||||
}
|
||||
|
||||
// display note when synchronized triggers are detected.
|
||||
if (isUsingTriggers)
|
||||
{
|
||||
EditorGUILayout.HelpBox("When using triggers, make sure this component is last in the stack. " +
|
||||
"If you still experience issues, implement triggers as a regular RPC " +
|
||||
"or in custom IPunObservable component instead.", MessageType.Warning);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3f61bade114730459f7ad45f5f292c1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,50 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonRigidbody2DViewEditor.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// This is a custom editor for the PhotonRigidbody2DView component.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
[CustomEditor(typeof (PhotonRigidbody2DView))]
|
||||
public class PhotonRigidbody2DViewEditor : MonoBehaviourPunEditor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Editing is disabled in play mode.", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
PhotonRigidbody2DView view = (PhotonRigidbody2DView)target;
|
||||
|
||||
view.m_TeleportEnabled = PhotonGUI.ContainerHeaderToggle("Enable teleport for large distances", view.m_TeleportEnabled);
|
||||
|
||||
if (view.m_TeleportEnabled)
|
||||
{
|
||||
Rect rect = PhotonGUI.ContainerBody(20.0f);
|
||||
view.m_TeleportIfDistanceGreaterThan = EditorGUI.FloatField(rect, "Teleport if distance greater than", view.m_TeleportIfDistanceGreaterThan);
|
||||
}
|
||||
|
||||
view.m_SynchronizeVelocity = PhotonGUI.ContainerHeaderToggle("Synchronize Velocity", view.m_SynchronizeVelocity);
|
||||
view.m_SynchronizeAngularVelocity = PhotonGUI.ContainerHeaderToggle("Synchronize Angular Velocity", view.m_SynchronizeAngularVelocity);
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
EditorUtility.SetDirty(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a82e8e86b9eecb40ac3f6ebc949f6ef
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,50 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonRigidbodyViewEditor.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// This is a custom editor for the RigidbodyView component.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
[CustomEditor(typeof (PhotonRigidbodyView))]
|
||||
public class PhotonRigidbodyViewEditor : MonoBehaviourPunEditor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Editing is disabled in play mode.", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
PhotonRigidbodyView view = (PhotonRigidbodyView)target;
|
||||
|
||||
view.m_TeleportEnabled = PhotonGUI.ContainerHeaderToggle("Enable teleport for large distances", view.m_TeleportEnabled);
|
||||
|
||||
if (view.m_TeleportEnabled)
|
||||
{
|
||||
Rect rect = PhotonGUI.ContainerBody(20.0f);
|
||||
view.m_TeleportIfDistanceGreaterThan = EditorGUI.FloatField(rect, "Teleport if distance greater than", view.m_TeleportIfDistanceGreaterThan);
|
||||
}
|
||||
|
||||
view.m_SynchronizeVelocity = PhotonGUI.ContainerHeaderToggle("Synchronize Velocity", view.m_SynchronizeVelocity);
|
||||
view.m_SynchronizeAngularVelocity = PhotonGUI.ContainerHeaderToggle("Synchronize Angular Velocity", view.m_SynchronizeAngularVelocity);
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
EditorUtility.SetDirty(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4bcfebc9a2f1074488adedd1fe84e6c9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,412 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonTransformViewClassicEditor.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// This is a custom editor for the TransformView component.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
[CustomEditor(typeof(PhotonTransformViewClassic))]
|
||||
public class PhotonTransformViewClassicEditor : MonoBehaviourPunEditor
|
||||
{
|
||||
//private PhotonTransformViewClassic m_Target;
|
||||
|
||||
private SerializedProperty m_SynchronizePositionProperty;
|
||||
private SerializedProperty m_SynchronizeRotationProperty;
|
||||
private SerializedProperty m_SynchronizeScaleProperty;
|
||||
|
||||
private bool m_InterpolateHelpOpen;
|
||||
private bool m_ExtrapolateHelpOpen;
|
||||
private bool m_InterpolateRotationHelpOpen;
|
||||
private bool m_InterpolateScaleHelpOpen;
|
||||
|
||||
private const int EDITOR_LINE_HEIGHT = 20;
|
||||
|
||||
private const string INTERPOLATE_TOOLTIP =
|
||||
"Choose between synchronizing the value directly (by disabling interpolation) or smoothly move it towards the newest update.";
|
||||
|
||||
private const string INTERPOLATE_HELP =
|
||||
"You can use interpolation to smoothly move your GameObject towards a new position that is received via the network. "
|
||||
+ "This helps to reduce the stuttering movement that results because the network updates only arrive 10 times per second.\n"
|
||||
+ "As a side effect, the GameObject is always lagging behind the actual position a little bit. This can be addressed with extrapolation.";
|
||||
|
||||
private const string EXTRAPOLATE_TOOLTIP = "Extrapolation is used to predict where the GameObject actually is";
|
||||
|
||||
private const string EXTRAPOLATE_HELP =
|
||||
"Whenever you deal with network values, all values you receive will be a little bit out of date since that data needs "
|
||||
+ "to reach you first. You can use extrapolation to try to predict where the player actually is, based on the movement data you have received.\n"
|
||||
+
|
||||
"This has to be tweaked carefully for each specific game in order to insure the optimal prediction. Sometimes it is very easy to extrapolate states, because "
|
||||
+
|
||||
"the GameObject behaves very predictable (for example for vehicles). Other times it can be very hard because the user input is translated directly to the game "
|
||||
+ "and you cannot really predict what the user is going to do (for example in fighting games)";
|
||||
|
||||
private const string INTERPOLATE_HELP_URL = "https://doc.photonengine.com/en-us/pun/current/demos-and-tutorials/package-demos/rpg-movement#interpolate_options";
|
||||
private const string EXTRAPOLATE_HELP_URL = "https://doc.photonengine.com/en-us/pun/current/demos-and-tutorials/package-demos/rpg-movement#extrapolate_options";
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
SetupSerializedProperties();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
base.OnInspectorGUI();
|
||||
|
||||
//this.m_Target = (PhotonTransformViewClassic) target;
|
||||
|
||||
DrawIsPlayingWarning();
|
||||
GUI.enabled = !Application.isPlaying;
|
||||
|
||||
DrawSynchronizePositionHeader();
|
||||
DrawSynchronizePositionData();
|
||||
|
||||
GUI.enabled = !Application.isPlaying;
|
||||
DrawSynchronizeRotationHeader();
|
||||
DrawSynchronizeRotationData();
|
||||
|
||||
GUI.enabled = !Application.isPlaying;
|
||||
DrawSynchronizeScaleHeader();
|
||||
DrawSynchronizeScaleData();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
private void DrawIsPlayingWarning()
|
||||
{
|
||||
if (Application.isPlaying == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GUILayout.BeginVertical(GUI.skin.box);
|
||||
{
|
||||
GUILayout.Label("Editing is disabled in play mode so the two objects don't go out of sync");
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void SetupSerializedProperties()
|
||||
{
|
||||
this.m_SynchronizePositionProperty = serializedObject.FindProperty("m_PositionModel.SynchronizeEnabled");
|
||||
this.m_SynchronizeRotationProperty = serializedObject.FindProperty("m_RotationModel.SynchronizeEnabled");
|
||||
this.m_SynchronizeScaleProperty = serializedObject.FindProperty("m_ScaleModel.SynchronizeEnabled");
|
||||
}
|
||||
|
||||
private void DrawSynchronizePositionHeader()
|
||||
{
|
||||
DrawHeader("Synchronize Position", this.m_SynchronizePositionProperty);
|
||||
}
|
||||
|
||||
private void DrawSynchronizePositionData()
|
||||
{
|
||||
if (this.m_SynchronizePositionProperty == null || this.m_SynchronizePositionProperty.boolValue == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SerializedProperty interpolatePositionProperty = serializedObject.FindProperty("m_PositionModel.InterpolateOption");
|
||||
PhotonTransformViewPositionModel.InterpolateOptions interpolateOption = (PhotonTransformViewPositionModel.InterpolateOptions)interpolatePositionProperty.enumValueIndex;
|
||||
|
||||
SerializedProperty extrapolatePositionProperty = serializedObject.FindProperty("m_PositionModel.ExtrapolateOption");
|
||||
PhotonTransformViewPositionModel.ExtrapolateOptions extrapolateOption = (PhotonTransformViewPositionModel.ExtrapolateOptions)extrapolatePositionProperty.enumValueIndex;
|
||||
|
||||
float containerHeight = 155;
|
||||
|
||||
switch (interpolateOption)
|
||||
{
|
||||
case PhotonTransformViewPositionModel.InterpolateOptions.FixedSpeed:
|
||||
case PhotonTransformViewPositionModel.InterpolateOptions.Lerp:
|
||||
containerHeight += EDITOR_LINE_HEIGHT;
|
||||
break;
|
||||
/*case PhotonTransformViewPositionModel.InterpolateOptions.MoveTowardsComplex:
|
||||
containerHeight += EDITOR_LINE_HEIGHT*3;
|
||||
break;*/
|
||||
}
|
||||
|
||||
if (extrapolateOption != PhotonTransformViewPositionModel.ExtrapolateOptions.Disabled)
|
||||
{
|
||||
containerHeight += EDITOR_LINE_HEIGHT;
|
||||
}
|
||||
|
||||
switch (extrapolateOption)
|
||||
{
|
||||
case PhotonTransformViewPositionModel.ExtrapolateOptions.FixedSpeed:
|
||||
containerHeight += EDITOR_LINE_HEIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.m_InterpolateHelpOpen == true)
|
||||
{
|
||||
containerHeight += GetInterpolateHelpBoxHeight();
|
||||
}
|
||||
|
||||
if (this.m_ExtrapolateHelpOpen == true)
|
||||
{
|
||||
containerHeight += GetExtrapolateHelpBoxHeight();
|
||||
}
|
||||
|
||||
// removed Gizmo Options. -3 lines, -1 splitter
|
||||
containerHeight -= EDITOR_LINE_HEIGHT * 3;
|
||||
|
||||
Rect rect = PhotonGUI.ContainerBody(containerHeight);
|
||||
|
||||
Rect propertyRect = new Rect(rect.xMin + 5, rect.yMin + 2, rect.width - 10, EditorGUIUtility.singleLineHeight);
|
||||
|
||||
DrawTeleport(ref propertyRect);
|
||||
DrawSplitter(ref propertyRect);
|
||||
|
||||
DrawSynchronizePositionDataInterpolation(ref propertyRect, interpolatePositionProperty, interpolateOption);
|
||||
DrawSplitter(ref propertyRect);
|
||||
|
||||
DrawSynchronizePositionDataExtrapolation(ref propertyRect, extrapolatePositionProperty, extrapolateOption);
|
||||
}
|
||||
|
||||
private float GetInterpolateHelpBoxHeight()
|
||||
{
|
||||
return PhotonGUI.RichLabel.CalcHeight(new GUIContent(INTERPOLATE_HELP), Screen.width - 54) + 35;
|
||||
}
|
||||
|
||||
private float GetExtrapolateHelpBoxHeight()
|
||||
{
|
||||
return PhotonGUI.RichLabel.CalcHeight(new GUIContent(EXTRAPOLATE_HELP), Screen.width - 54) + 35;
|
||||
}
|
||||
|
||||
private void DrawSplitter(ref Rect propertyRect)
|
||||
{
|
||||
Rect splitterRect = new Rect(propertyRect.xMin - 3, propertyRect.yMin, propertyRect.width + 6, 1);
|
||||
PhotonGUI.DrawSplitter(splitterRect);
|
||||
|
||||
propertyRect.y += 5;
|
||||
}
|
||||
|
||||
private void DrawHelpBox(ref Rect propertyRect, bool isOpen, float height, string helpText, string url)
|
||||
{
|
||||
if (isOpen == true)
|
||||
{
|
||||
Rect helpRect = new Rect(propertyRect.xMin, propertyRect.yMin, propertyRect.width, height - 5);
|
||||
GUI.BeginGroup(helpRect, GUI.skin.box);
|
||||
GUI.Label(new Rect(5, 5, propertyRect.width - 10, height - 30), helpText, PhotonGUI.RichLabel);
|
||||
if (GUI.Button(new Rect(5, height - 30, propertyRect.width - 10, 20), "Read more in our documentation"))
|
||||
{
|
||||
Application.OpenURL(url);
|
||||
}
|
||||
|
||||
GUI.EndGroup();
|
||||
|
||||
propertyRect.y += height;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPropertyWithHelpIcon(ref Rect propertyRect, ref bool isHelpOpen, SerializedProperty property, string tooltip)
|
||||
{
|
||||
Rect propertyFieldRect = new Rect(propertyRect.xMin, propertyRect.yMin, propertyRect.width - 20, propertyRect.height);
|
||||
string propertyName = ObjectNames.NicifyVariableName(property.name);
|
||||
EditorGUI.PropertyField(propertyFieldRect, property, new GUIContent(propertyName, tooltip));
|
||||
|
||||
Rect helpIconRect = new Rect(propertyFieldRect.xMax + 5, propertyFieldRect.yMin, 20, propertyFieldRect.height);
|
||||
isHelpOpen = GUI.Toggle(helpIconRect, isHelpOpen, PhotonGUI.HelpIcon, GUIStyle.none);
|
||||
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
}
|
||||
|
||||
private void DrawSynchronizePositionDataExtrapolation(ref Rect propertyRect, SerializedProperty extrapolatePositionProperty,
|
||||
PhotonTransformViewPositionModel.ExtrapolateOptions extrapolateOption)
|
||||
{
|
||||
DrawPropertyWithHelpIcon(ref propertyRect, ref this.m_ExtrapolateHelpOpen, extrapolatePositionProperty, EXTRAPOLATE_TOOLTIP);
|
||||
DrawHelpBox(ref propertyRect, this.m_ExtrapolateHelpOpen, GetExtrapolateHelpBoxHeight(), EXTRAPOLATE_HELP, EXTRAPOLATE_HELP_URL);
|
||||
|
||||
if (extrapolateOption != PhotonTransformViewPositionModel.ExtrapolateOptions.Disabled)
|
||||
{
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_PositionModel.ExtrapolateIncludingRoundTripTime"));
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
}
|
||||
|
||||
switch (extrapolateOption)
|
||||
{
|
||||
case PhotonTransformViewPositionModel.ExtrapolateOptions.FixedSpeed:
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_PositionModel.ExtrapolateSpeed"));
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawTeleport(ref Rect propertyRect)
|
||||
{
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_PositionModel.TeleportEnabled"),
|
||||
new GUIContent("Enable teleport for great distances"));
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_PositionModel.TeleportIfDistanceGreaterThan"),
|
||||
new GUIContent("Teleport if distance greater than"));
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
}
|
||||
|
||||
private void DrawSynchronizePositionDataInterpolation(ref Rect propertyRect, SerializedProperty interpolatePositionProperty,
|
||||
PhotonTransformViewPositionModel.InterpolateOptions interpolateOption)
|
||||
{
|
||||
DrawPropertyWithHelpIcon(ref propertyRect, ref this.m_InterpolateHelpOpen, interpolatePositionProperty, INTERPOLATE_TOOLTIP);
|
||||
DrawHelpBox(ref propertyRect, this.m_InterpolateHelpOpen, GetInterpolateHelpBoxHeight(), INTERPOLATE_HELP, INTERPOLATE_HELP_URL);
|
||||
|
||||
switch (interpolateOption)
|
||||
{
|
||||
case PhotonTransformViewPositionModel.InterpolateOptions.FixedSpeed:
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_PositionModel.InterpolateMoveTowardsSpeed"),
|
||||
new GUIContent("MoveTowards Speed"));
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
break;
|
||||
|
||||
case PhotonTransformViewPositionModel.InterpolateOptions.Lerp:
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_PositionModel.InterpolateLerpSpeed"), new GUIContent("Lerp Speed"));
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
break;
|
||||
|
||||
/*case PhotonTransformViewPositionModel.InterpolateOptions.MoveTowardsComplex:
|
||||
Rect curveRect = new Rect(propertyRect.xMin, propertyRect.yMin, propertyRect.width - 100, propertyRect.height);
|
||||
EditorGUI.PropertyField(curveRect, serializedObject.FindProperty("m_PositionModel.InterpolateSpeedCurve"), new GUIContent("MoveTowards Speed Curve"));
|
||||
|
||||
Rect labelRect = new Rect(propertyRect.xMax - 95, propertyRect.yMin, 10, propertyRect.height);
|
||||
GUI.Label(labelRect, "x");
|
||||
|
||||
Rect multiplierRect = new Rect(propertyRect.xMax - 80, propertyRect.yMin, 80, propertyRect.height);
|
||||
EditorGUI.PropertyField(multiplierRect, serializedObject.FindProperty("m_PositionModel.InterpolateMoveTowardsSpeed"), GUIContent.none);
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_PositionModel.InterpolateMoveTowardsAcceleration"),
|
||||
new GUIContent("Acceleration"));
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_PositionModel.InterpolateMoveTowardsDeceleration"),
|
||||
new GUIContent("Deceleration"));
|
||||
propertyRect.y += EDITOR_LINE_HEIGHT;
|
||||
break;*/
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSynchronizeRotationHeader()
|
||||
{
|
||||
DrawHeader("Synchronize Rotation", this.m_SynchronizeRotationProperty);
|
||||
}
|
||||
|
||||
private void DrawSynchronizeRotationData()
|
||||
{
|
||||
if (this.m_SynchronizeRotationProperty == null || this.m_SynchronizeRotationProperty.boolValue == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SerializedProperty interpolateRotationProperty = serializedObject.FindProperty("m_RotationModel.InterpolateOption");
|
||||
PhotonTransformViewRotationModel.InterpolateOptions interpolateOption =
|
||||
(PhotonTransformViewRotationModel.InterpolateOptions)interpolateRotationProperty.enumValueIndex;
|
||||
|
||||
float containerHeight = 20;
|
||||
|
||||
switch (interpolateOption)
|
||||
{
|
||||
case PhotonTransformViewRotationModel.InterpolateOptions.RotateTowards:
|
||||
case PhotonTransformViewRotationModel.InterpolateOptions.Lerp:
|
||||
containerHeight += EDITOR_LINE_HEIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.m_InterpolateRotationHelpOpen == true)
|
||||
{
|
||||
containerHeight += GetInterpolateHelpBoxHeight();
|
||||
}
|
||||
|
||||
Rect rect = PhotonGUI.ContainerBody(containerHeight);
|
||||
Rect propertyRect = new Rect(rect.xMin + 5, rect.yMin + 2, rect.width - 10, EditorGUIUtility.singleLineHeight);
|
||||
|
||||
DrawPropertyWithHelpIcon(ref propertyRect, ref this.m_InterpolateRotationHelpOpen, interpolateRotationProperty, INTERPOLATE_TOOLTIP);
|
||||
DrawHelpBox(ref propertyRect, this.m_InterpolateRotationHelpOpen, GetInterpolateHelpBoxHeight(), INTERPOLATE_HELP, INTERPOLATE_HELP_URL);
|
||||
|
||||
switch (interpolateOption)
|
||||
{
|
||||
case PhotonTransformViewRotationModel.InterpolateOptions.RotateTowards:
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_RotationModel.InterpolateRotateTowardsSpeed"),
|
||||
new GUIContent("RotateTowards Speed"));
|
||||
break;
|
||||
case PhotonTransformViewRotationModel.InterpolateOptions.Lerp:
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_RotationModel.InterpolateLerpSpeed"), new GUIContent("Lerp Speed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSynchronizeScaleHeader()
|
||||
{
|
||||
DrawHeader("Synchronize Scale", this.m_SynchronizeScaleProperty);
|
||||
}
|
||||
|
||||
private void DrawSynchronizeScaleData()
|
||||
{
|
||||
if (this.m_SynchronizeScaleProperty == null || this.m_SynchronizeScaleProperty.boolValue == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SerializedProperty interpolateScaleProperty = serializedObject.FindProperty("m_ScaleModel.InterpolateOption");
|
||||
PhotonTransformViewScaleModel.InterpolateOptions interpolateOption = (PhotonTransformViewScaleModel.InterpolateOptions)interpolateScaleProperty.enumValueIndex;
|
||||
|
||||
float containerHeight = EDITOR_LINE_HEIGHT;
|
||||
|
||||
switch (interpolateOption)
|
||||
{
|
||||
case PhotonTransformViewScaleModel.InterpolateOptions.MoveTowards:
|
||||
case PhotonTransformViewScaleModel.InterpolateOptions.Lerp:
|
||||
containerHeight += EDITOR_LINE_HEIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.m_InterpolateScaleHelpOpen == true)
|
||||
{
|
||||
containerHeight += GetInterpolateHelpBoxHeight();
|
||||
}
|
||||
|
||||
Rect rect = PhotonGUI.ContainerBody(containerHeight);
|
||||
Rect propertyRect = new Rect(rect.xMin + 5, rect.yMin + 2, rect.width - 10, EditorGUIUtility.singleLineHeight);
|
||||
|
||||
DrawPropertyWithHelpIcon(ref propertyRect, ref this.m_InterpolateScaleHelpOpen, interpolateScaleProperty, INTERPOLATE_TOOLTIP);
|
||||
DrawHelpBox(ref propertyRect, this.m_InterpolateScaleHelpOpen, GetInterpolateHelpBoxHeight(), INTERPOLATE_HELP, INTERPOLATE_HELP_URL);
|
||||
|
||||
switch (interpolateOption)
|
||||
{
|
||||
case PhotonTransformViewScaleModel.InterpolateOptions.MoveTowards:
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_ScaleModel.InterpolateMoveTowardsSpeed"),
|
||||
new GUIContent("MoveTowards Speed"));
|
||||
break;
|
||||
case PhotonTransformViewScaleModel.InterpolateOptions.Lerp:
|
||||
EditorGUI.PropertyField(propertyRect, serializedObject.FindProperty("m_ScaleModel.InterpolateLerpSpeed"), new GUIContent("Lerp Speed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawHeader(string label, SerializedProperty property)
|
||||
{
|
||||
if (property == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool newValue = PhotonGUI.ContainerHeaderToggle(label, property.boolValue);
|
||||
|
||||
if (newValue != property.boolValue)
|
||||
{
|
||||
property.boolValue = newValue;
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22292ca8ffb574945bedfaf49266672e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,72 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonTransformViewEditor.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// This is a custom editor for the TransformView component.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Photon.Pun
|
||||
{
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
[CustomEditor(typeof(PhotonTransformView))]
|
||||
public class PhotonTransformViewEditor : Editor
|
||||
{
|
||||
private bool helpToggle = false;
|
||||
|
||||
SerializedProperty pos, rot, scl, lcl;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
pos = serializedObject.FindProperty("m_SynchronizePosition");
|
||||
rot = serializedObject.FindProperty("m_SynchronizeRotation");
|
||||
scl = serializedObject.FindProperty("m_SynchronizeScale");
|
||||
lcl = serializedObject.FindProperty("m_UseLocal");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Editing is disabled in play mode.", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
PhotonTransformView view = (PhotonTransformView)target;
|
||||
|
||||
|
||||
EditorGUILayout.LabelField("Synchronize Options");
|
||||
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
{
|
||||
EditorGUILayout.BeginVertical("HelpBox");
|
||||
{
|
||||
EditorGUILayout.PropertyField(pos, new GUIContent("Position", pos.tooltip));
|
||||
EditorGUILayout.PropertyField(rot, new GUIContent("Rotation", rot.tooltip));
|
||||
EditorGUILayout.PropertyField(scl, new GUIContent("Scale", scl.tooltip));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.PropertyField(lcl, new GUIContent("Use Local", lcl.tooltip));
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
this.helpToggle = EditorGUILayout.Foldout(this.helpToggle, "Info");
|
||||
if (this.helpToggle)
|
||||
{
|
||||
EditorGUILayout.HelpBox("The Photon Transform View of PUN 2 is simple by design.\nReplace it with the Photon Transform View Classic if you want the old options.\nThe best solution is a custom IPunObservable implementation.", MessageType.Info, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8c9ec475ad103b43b901d942ff66e02
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Assets/Photon/PhotonUnityNetworking/Code/Editor/help.png
Normal file
BIN
Assets/Photon/PhotonUnityNetworking/Code/Editor/help.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,45 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f1212502533cb34188dd6ef094188cb
|
||||
TextureImporter:
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
Reference in New Issue
Block a user