testing
This commit is contained in:
reedgamingstudio
2014-12-16 00:23:12 -06:00
parent c0c0755cc6
commit 5b8ebb7a35
1697 changed files with 1115979 additions and 0 deletions
@@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: dcbd9d9cedc5c08428abc8d2aea83a12
folderAsset: yes
DefaultImporter:
userData:
@@ -0,0 +1,209 @@
// ----------------------------------------------------------------------------
// <copyright file="AccountService.cs" company="Exit Games GmbH">
// Photon Cloud Account Service - Copyright (C) 2012 Exit Games GmbH
// </copyright>
// <summary>
// Provides methods to register a new user-account for the Photon Cloud and
// get the resulting appId.
// </summary>
// <author>developer@exitgames.com</author>
// ----------------------------------------------------------------------------
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Newtonsoft.Json;
public class AccountService
{
private const string ServiceUrl = "https://service.exitgames.com/AccountExt/AccountServiceExt.aspx";
private Action<AccountService> registrationCallback; // optional (when using async reg)
public string Message { get; private set; } // msg from server (in case of success, this is the appid)
protected internal Exception Exception { get; set; } // exceptions in account-server communication
public string AppId { get; private set; }
public int ReturnCode { get; private set; } // 0 = OK. anything else is a error with Message
public enum Origin : byte { ServerWeb = 1, CloudWeb = 2, Pun = 3, Playmaker = 4 };
/// <summary>
/// Creates a instance of the Account Service to register Photon Cloud accounts.
/// </summary>
public AccountService()
{
WebRequest.DefaultWebProxy = null;
ServicePointManager.ServerCertificateValidationCallback = Validator;
}
public static bool Validator(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors)
{
return true; // any certificate is ok in this case
}
/// <summary>
/// Attempts to create a Photon Cloud Account.
/// Check ReturnCode, Message and AppId to get the result of this attempt.
/// </summary>
/// <param name="email">Email of the account.</param>
/// <param name="origin">Marks which channel created the new account (if it's new).</param>
public void RegisterByEmail(string email, Origin origin)
{
this.registrationCallback = null;
this.AppId = string.Empty;
this.Message = string.Empty;
this.ReturnCode = -1;
string result;
try
{
WebRequest req = HttpWebRequest.Create(this.RegistrationUri(email, (byte)origin));
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
// now read result
StreamReader reader = new StreamReader(resp.GetResponseStream());
result = reader.ReadToEnd();
}
catch (Exception ex)
{
this.Message = "Failed to connect to Cloud Account Service. Please register via account website.";
this.Exception = ex;
return;
}
this.ParseResult(result);
}
/// <summary>
/// Attempts to create a Photon Cloud Account asynchronously.
/// Once your callback is called, check ReturnCode, Message and AppId to get the result of this attempt.
/// </summary>
/// <param name="email">Email of the account.</param>
/// <param name="origin">Marks which channel created the new account (if it's new).</param>
/// <param name="callback">Called when the result is available.</param>
public void RegisterByEmailAsync(string email, Origin origin, Action<AccountService> callback = null)
{
this.registrationCallback = callback;
this.AppId = string.Empty;
this.Message = string.Empty;
this.ReturnCode = -1;
try
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(this.RegistrationUri(email, (byte)origin));
req.Timeout = 5000;
req.BeginGetResponse(this.OnRegisterByEmailCompleted, req);
}
catch (Exception ex)
{
this.Message = "Failed to connect to Cloud Account Service. Please register via account website.";
this.Exception = ex;
if (this.registrationCallback != null)
{
this.registrationCallback(this);
}
}
}
/// <summary>
/// Internal callback with result of async HttpWebRequest (in RegisterByEmailAsync).
/// </summary>
/// <param name="ar"></param>
private void OnRegisterByEmailCompleted(IAsyncResult ar)
{
try
{
HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
HttpWebResponse response = request.EndGetResponse(ar) as HttpWebResponse;
if (response != null && response.StatusCode == HttpStatusCode.OK)
{
// no error. use the result
StreamReader reader = new StreamReader(response.GetResponseStream());
string result = reader.ReadToEnd();
this.ParseResult(result);
}
else
{
// a response but some error on server. show message
this.Message = "Failed to connect to Cloud Account Service. Please register via account website.";
}
}
catch (Exception ex)
{
// not even a response. show message
this.Message = "Failed to connect to Cloud Account Service. Please register via account website.";
this.Exception = ex;
}
if (this.registrationCallback != null)
{
this.registrationCallback(this);
}
}
/// <summary>
/// Creates the service-call Uri, escaping the email for security reasons.
/// </summary>
/// <param name="email">Email of the account.</param>
/// <param name="origin">1 = server-web, 2 = cloud-web, 3 = PUN, 4 = playmaker</param>
/// <returns>Uri to call.</returns>
private Uri RegistrationUri(string email, byte origin)
{
string emailEncoded = Uri.EscapeDataString(email);
string uriString = string.Format("{0}?email={1}&origin={2}", ServiceUrl, emailEncoded, origin);
return new Uri(uriString);
}
/// <summary>
/// Reads the Json response and applies it to local properties.
/// </summary>
/// <param name="result"></param>
private void ParseResult(string result)
{
if (string.IsNullOrEmpty(result))
{
this.Message = "Server's response was empty. Please register through account website during this service interruption.";
return;
}
Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(result);
if (values == null)
{
this.Message = "Service temporarily unavailable. Please register through account website.";
return;
}
int returnCodeInt = -1;
string returnCodeString = string.Empty;
string message;
values.TryGetValue("ReturnCode", out returnCodeString);
values.TryGetValue("Message", out message);
int.TryParse(returnCodeString, out returnCodeInt);
this.ReturnCode = returnCodeInt;
if (returnCodeInt == 0)
{
// returnCode == 0 means: all ok. message is new AppId
this.AppId = message;
}
else
{
// any error gives returnCode != 0
this.AppId = string.Empty;
this.Message = message;
}
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 166dfe22956ef0341b28e18d0499e363
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0268f98d7c649564a818b0768fc68d4b
MonoAssemblyImporter:
serializedVersion: 1
iconMap: {}
executionOrder: {}
userData:
@@ -0,0 +1,341 @@
// ----------------------------------------------------------------------------
// <copyright file="PhotonConverter.cs" company="Exit Games GmbH">
// PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
// </copyright>
// <summary>
// Script to convert a Unity Networking project to PhotonNetwork.
// </summary>
// <author>developer@exitgames.com</author>
// ----------------------------------------------------------------------------
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
public class PhotonConverter : Photon.MonoBehaviour
{
public static void RunConversion()
{
//Ask if user has made a backup.
bool result = EditorUtility.DisplayDialog("Conversion", "Did you create a backup of your project before converting?", "Yes", "Abort conversion");
if (!result)
{
return;
}
//REAAAALY?
result = EditorUtility.DisplayDialog("Conversion", "Disclaimer: The code conversion feature is quite crude, but should do it's job well (see the sourcecode). A backup is therefore strongly recommended!", "Yes, I've made a backup: GO", "Abort");
if (!result)
{
return;
}
Output(EditorApplication.timeSinceStartup + " Started conversion of Unity networking -> Photon");
//Ask to save current scene (optional)
EditorApplication.SaveCurrentSceneIfUserWantsTo();
EditorUtility.DisplayProgressBar("Converting..", "Starting.", 0);
//Convert NetworkViews to PhotonViews in Project prefabs
//Ask the user if we can move all prefabs to a resources folder
bool movePrefabs = EditorUtility.DisplayDialog("Conversion", "Can all prefabs that use a PhotonView be moved to a Resources/ folder? You need this if you use Network.Instantiate.", "Yes", "No");
string[] prefabs = Directory.GetFiles("Assets/", "*.prefab", SearchOption.AllDirectories);
foreach (string prefab in prefabs)
{
EditorUtility.DisplayProgressBar("Converting..", "Object:" + prefab, 0.6f);
Object[] objs = (Object[])AssetDatabase.LoadAllAssetsAtPath(prefab);
int converted = 0;
foreach (Object obj in objs)
{
if (obj != null && obj.GetType() == typeof(GameObject))
converted += ConvertNetworkView(((GameObject)obj).GetComponents<NetworkView>(), false);
}
if (movePrefabs && converted > 0)
{
//This prefab needs to be under the root of a Resources folder!
string path = prefab.Replace("\\", "/");
int lastSlash = path.LastIndexOf("/");
int resourcesIndex = path.LastIndexOf("/Resources/");
if (resourcesIndex != lastSlash - 10)
{
if (path.Contains("/Resources/"))
{
Debug.LogWarning("Warning, prefab [" + prefab + "] was already in a resources folder. But has been placed in the root of another one!");
}
//This prefab NEEDS to be placed under a resources folder
string resourcesFolder = path.Substring(0, lastSlash) + "/Resources/";
EnsureFolder(resourcesFolder);
string newPath = resourcesFolder + path.Substring(lastSlash + 1);
string error = AssetDatabase.MoveAsset(prefab, newPath);
if (error != "")
Debug.LogError(error);
Output("Fixed prefab [" + prefab + "] by moving it into a resources folder.");
}
}
}
//Convert NetworkViews to PhotonViews in scenes
string[] sceneFiles = Directory.GetFiles("Assets/", "*.unity", SearchOption.AllDirectories);
foreach (string sceneName in sceneFiles)
{
EditorApplication.OpenScene(sceneName);
EditorUtility.DisplayProgressBar("Converting..", "Scene:" + sceneName, 0.2f);
int converted2 = ConvertNetworkView((NetworkView[])GameObject.FindObjectsOfType(typeof(NetworkView)), true);
if (converted2 > 0)
{
//This will correct all prefabs: The prefabs have gotten new components, but the correct ID's were lost in this case
PhotonViewInspector.VerifyAllSceneViews();
Output("Replaced " + converted2 + " NetworkViews with PhotonViews in scene: " + sceneName);
EditorApplication.SaveScene(EditorApplication.currentScene);
}
}
//Convert C#/JS scripts (API stuff)
List<string> scripts = new List<string>();
scripts.AddRange(Directory.GetFiles("Assets/", "*.cs", SearchOption.AllDirectories));
scripts.AddRange(Directory.GetFiles("Assets/", "*.js", SearchOption.AllDirectories));
scripts.AddRange(Directory.GetFiles("Assets/", "*.boo", SearchOption.AllDirectories));
EditorUtility.DisplayProgressBar("Converting..", "Scripts..", 0.9f);
ConvertScripts(scripts);
Output(EditorApplication.timeSinceStartup + " Completed conversion!");
EditorUtility.ClearProgressBar();
}
static void ConvertScripts(List<string> scripts)
{
foreach (string script in scripts)
{
if (script.Contains("PhotonNetwork"))//Don't convert this file (and others)
continue;
if (script.Contains("Image Effects"))
continue;
string text = File.ReadAllText(script);
text = ConvertToPhotonAPI(script, text);
File.WriteAllText(script, text);
}
foreach (string script in scripts){
AssetDatabase.ImportAsset(script, ImportAssetOptions.ForceUpdate);
}
}
static string ConvertToPhotonAPI(string file, string input)
{
bool isJS = file.Contains(".js");
file =file.Replace("\\", "/"); // Get Class name for JS
string className = file.Substring(file.LastIndexOf("/")+1);
className = className.Substring(0, className.IndexOf("."));
//REGEXP STUFF
//Valid are: Space { } , /n /r
//string NOT_VAR = @"([^A-Za-z0-9_\[\]\.]+)";
string NOT_VAR_WITH_DOT = @"([^A-Za-z0-9_]+)";
//string VAR_NONARRAY = @"[^A-Za-z0-9_]";
//NetworkView
{
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkView" + NOT_VAR_WITH_DOT, "$1PhotonView$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "networkView" + NOT_VAR_WITH_DOT, "$1photonView$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "stateSynchronization" + NOT_VAR_WITH_DOT, "$1synchronization$2");
//.RPC
input = PregReplace(input, NOT_VAR_WITH_DOT + "RPCMode.Server" + NOT_VAR_WITH_DOT, "$1PhotonTargets.MasterClient$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "RPCMode" + NOT_VAR_WITH_DOT, "$1PhotonTargets$2");
}
//NetworkMessageInfo: 100%
{
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkMessageInfo" + NOT_VAR_WITH_DOT, "$1PhotonMessageInfo$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "networkView" + NOT_VAR_WITH_DOT, "$1photonView$2");
}
//NetworkViewID:
{
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkViewID" + NOT_VAR_WITH_DOT, "$1PhotonViewID$2");
}
//NetworkPlayer
{
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkPlayer" + NOT_VAR_WITH_DOT, "$1PhotonPlayer$2");
}
//Network
{
//Monobehaviour callbacks
{
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnPlayerConnected" + NOT_VAR_WITH_DOT, "$1OnPhotonPlayerConnected$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnPlayerDisconnected" + NOT_VAR_WITH_DOT, "$1OnPhotonPlayerDisconnected$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnNetworkInstantiate" + NOT_VAR_WITH_DOT, "$1OnPhotonInstantiate$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnSerializeNetworkView" + NOT_VAR_WITH_DOT, "$1OnPhotonSerializeView$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "BitStream" + NOT_VAR_WITH_DOT, "$1PhotonStream$2");
//Not completely the same meaning
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnServerInitialized" + NOT_VAR_WITH_DOT, "$1OnCreatedRoom$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnConnectedToServer" + NOT_VAR_WITH_DOT, "$1OnJoinedRoom$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnFailedToConnectToMasterServer" + NOT_VAR_WITH_DOT, "$1OnFailedToConnectToPhoton$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnFailedToConnect" + NOT_VAR_WITH_DOT, "$1OnFailedToConnect_OBSELETE$2");
}
//Variables
{
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.connections" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.playerList$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.isServer" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.isMasterClient$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.isClient" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.isNonMasterClientInRoom$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkPeerType" + NOT_VAR_WITH_DOT, "$1ConnectionState$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.peerType" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.connectionState$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "ConnectionState.Server" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.isMasterClient$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "ConnectionState.Client" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.isNonMasterClientInRoom$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "PhotonNetwork.playerList.Length" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.playerList.Count$2");
/*DROPPED:
minimumAllocatableViewIDs
natFacilitatorIP is dropped
natFacilitatorPort is dropped
connectionTesterIP
connectionTesterPort
proxyIP
proxyPort
useProxy
proxyPassword
*/
}
//Methods
{
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.InitializeServer" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.JoinRoom$2");//Either Join or Create room
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.Connect" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.JoinRoom$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.GetAveragePing" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.GetPing$2");
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.GetLastPing" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.GetPing$2");
/*DROPPED:
TestConnection
TestConnectionNAT
HavePublicAddress
*/
}
//Overall
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network" + NOT_VAR_WITH_DOT, "$1PhotonNetwork$2");
}
//General
{
if (input.Contains("Photon")) //Only use the PhotonMonoBehaviour if we use photonView and friends.
{
if (isJS)//JS
{
if (input.Contains("extends MonoBehaviour"))
input = PregReplace(input, "extends MonoBehaviour", "extends Photon.MonoBehaviour");
else
input = "class " + className + " extends Photon.MonoBehaviour {\n" + input + "\n}";
}
else //C#
input = PregReplace(input, ": MonoBehaviour", ": Photon.MonoBehaviour");
}
}
return input;
}
static string PregReplace(string input, string[] pattern, string[] replacements)
{
if (replacements.Length != pattern.Length)
Debug.LogError("Replacement and Pattern Arrays must be balanced");
for (var i = 0; i < pattern.Length; i++)
{
input = Regex.Replace(input, pattern[i], replacements[i]);
}
return input;
}
static string PregReplace(string input, string pattern, string replacement)
{
return Regex.Replace(input, pattern, replacement);
}
static void EnsureFolder(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
AssetDatabase.Refresh();
}
}
static int ConvertNetworkView(NetworkView[] netViews, bool isScene)
{
for (int i = netViews.Length - 1; i >= 0; i--)
{
NetworkView netView = netViews[i];
PhotonView view = netView.gameObject.AddComponent<PhotonView>();
if (isScene)
{
//Get scene ID
string str = netView.viewID.ToString().Replace("SceneID: ", "");
int firstSpace = str.IndexOf(" ");
str = str.Substring(0, firstSpace);
int oldViewID = int.Parse(str);
view.viewID = new PhotonViewID(oldViewID, null);
view.SetSceneID(oldViewID);
EditorUtility.SetDirty(view);
EditorUtility.SetDirty(view.gameObject);
}
view.observed = netView.observed;
if (netView.stateSynchronization == NetworkStateSynchronization.Unreliable)
{
view.synchronization = ViewSynchronization.Unreliable;
}
else if (netView.stateSynchronization == NetworkStateSynchronization.ReliableDeltaCompressed)
{
view.synchronization = ViewSynchronization.ReliableDeltaCompressed;
}
else
{
view.synchronization = ViewSynchronization.Off;
}
DestroyImmediate(netView, true);
}
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
return netViews.Length;
}
static void Output(string str)
{
Debug.Log(((int)EditorApplication.timeSinceStartup) + " " + str);
}
static void ConversionError(string file, string str)
{
Debug.LogError("Scrip conversion[" + file + "]: " + str);
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 15757b26cd9b53247be86da9e8da19dd
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,629 @@
// ----------------------------------------------------------------------------
// <copyright file="PhotonEditor.cs" company="Exit Games GmbH">
// PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
// </copyright>
// <summary>
// MenuItems and in-Editor scripts for PhotonNetwork.
// </summary>
// <author>developer@exitgames.com</author>
// ----------------------------------------------------------------------------
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class PhotonEditor : EditorWindow
{
protected static AccountService.Origin RegisterOrigin = AccountService.Origin.Pun;
protected Vector2 scrollPos = Vector2.zero;
protected static string DocumentationLocation = "Assets/Photon Unity Networking/PhotonNetwork-Documentation.pdf";
protected static string UrlFreeLicense = "http://www.exitgames.com/Download/Photon";
protected static string UrlDevNet = "http://doc.exitgames.com/photon-cloud";
protected static string UrlForum = "http://forum.exitgames.com";
protected static string UrlCompare = "http://doc.exitgames.com/photon-cloud";
protected static string UrlHowToSetup = "http://doc.exitgames.com/photon-server/PhotonIn5Min/#cat-First%20Steps";
protected static string UrlAppIDExplained = "http://doc.exitgames.com/photon-cloud/PhotonDashboard/#cat-getting_started";
protected static string UrlAccountPage = "https://www.exitgames.com/Account/SignIn?email="; // opened in browser
private enum GUIState
{
Uninitialized,
Main,
Setup
}
private enum PhotonSetupStates
{
RegisterForPhotonCloud,
EmailAlreadyRegistered,
SetupPhotonCloud,
SetupSelfHosted
}
private GUIState guiState = GUIState.Uninitialized;
private bool isSetupWizard = false;
private PhotonSetupStates photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
private static double lastWarning = 0;
private string photonAddress = "127.0.0.1";
private int photonPort = ServerSettings.DefaultMasterPort;
private string emailAddress = string.Empty;
private string cloudAppId = string.Empty;
private static int lastPhotonViewListLength = -1;
private static UnityEngine.Object lastFirstElement;
private static string lastScene = string.Empty;
private static bool dontCheckPunSetupField;
/// <summary>
/// Can be used to (temporarily) disable the checks for PUN Setup and scene PhotonViews.
/// This will prevent scene PhotonViews from being updated, so be careful.
/// When you re-set this value, checks are used again and scene PhotonViews get IDs as needed.
/// </summary>
protected static bool dontCheckPunSetup
{
get
{
return dontCheckPunSetupField;
}
set
{
if (dontCheckPunSetupField != value)
{
lastPhotonViewListLength = 0;
dontCheckPunSetupField = value;
}
}
}
protected static Type WindowType = typeof(PhotonEditor);
protected static string WindowTitle = "PUN Setup Wizard";
[MenuItem("Window/Photon Unity Networking")]
protected static void Init()
{
PhotonEditor.ReLoadCurrentSeetings();
PhotonEditor win = GetWindow(WindowType, false, WindowTitle) as PhotonEditor;
win.ReApplySettingsToWindow();
}
static PhotonEditor()
{
EditorApplication.projectWindowChanged += EditorUpdate;
EditorApplication.hierarchyWindowChanged += EditorUpdate;
EditorApplication.playmodeStateChanged += PlaymodeStateChanged;
}
// 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 EditorUpdate()
{
if (dontCheckPunSetup)
{
return;
}
// 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 (!PhotonEditor.Current.DisableAutoOpenWizard && PhotonEditor.Current.HostType == ServerSettings.HostingOption.NotSet)
{
ShowRegistrationWizard();
}
// Workaround for TCP crash. Plus this surpresses any other recompile errors.
if (EditorApplication.isCompiling)
{
if (PhotonNetwork.connected)
{
if (lastWarning > EditorApplication.timeSinceStartup - 3)
{
// Prevent error spam
Debug.LogWarning("Unity recompile forced a Photon Disconnect");
lastWarning = EditorApplication.timeSinceStartup;
}
PhotonNetwork.Disconnect();
}
}
else if (!EditorApplication.isPlaying)
{
// The following code could be optimized if Unity provides the right callbacks.
// The current performance is 'OK' as we do check if the list changes (add/remove/duplicate should always change the length)
// We are currently checking all selected PhotonViews on hierarchy- and on project-change
// Instead, we only want to check this when an NEW asset is placed in a scene (at editor time)
// We need some sort of "OnCreated" call for scene objects.
UnityEngine.Object[] objs = Selection.GetFiltered(typeof(PhotonView), SelectionMode.ExcludePrefab | SelectionMode.Editable | SelectionMode.Deep);
if (objs.Length > 0 && (objs.Length != lastPhotonViewListLength || (lastFirstElement != objs[0])))
{
bool changed = false;
foreach (UnityEngine.Object obj in objs)
{
PhotonView view = obj as PhotonView;
if (!PhotonViewInspector.VerifySceneView(view))
{
changed = true;
}
}
if (changed)
{
Debug.Log("PUN: Corrected one or more scene-PhotonViews.");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
lastPhotonViewListLength = objs.Length;
lastFirstElement = objs[0];
}
// Check the newly opened scene for wrong PhotonViews
// This can happen when changing a prefab while viewing scene A. Instances in scene B will not be corrected.
if (lastScene != EditorApplication.currentScene && EditorApplication.currentScene != string.Empty)
{
lastScene = EditorApplication.currentScene;
PhotonViewInspector.VerifyAllSceneViews();
}
}
}
// called in editor on change of play-mode (used to show a message popup that connection settings are incomplete)
private static void PlaymodeStateChanged()
{
if (dontCheckPunSetup || EditorApplication.isPlaying || !EditorApplication.isPlayingOrWillChangePlaymode)
{
return;
}
if (PhotonEditor.Current.HostType == ServerSettings.HostingOption.NotSet)
{
EditorUtility.DisplayDialog("Warning", "You have not yet run the Photon setup wizard! Your game won't be able to connect. See Windows -> Photon Unity Networking.", "Ok");
}
}
private void SwitchMenuState(GUIState newState)
{
this.guiState = newState;
if (this.isSetupWizard && newState != GUIState.Setup)
{
this.Close();
}
}
/// <summary>Creates an Editor window, showing the cloud-registration wizard for Photon (entry point to setup PUN).</summary>
protected static void ShowRegistrationWizard()
{
PhotonEditor.Current.DisableAutoOpenWizard = true;
PhotonEditor.Save();
PhotonEditor window = (PhotonEditor)GetWindow(WindowType, false, WindowTitle, true);
window.isSetupWizard = true;
window.InitPhotonSetupWindow();
}
/// <summary>Re-initializes the Photon Setup window and shows one of three states: register cloud, setup cloud, setup self-hosted.</summary>
protected void InitPhotonSetupWindow()
{
this.SwitchMenuState(GUIState.Setup);
this.ReApplySettingsToWindow();
switch (PhotonEditor.Current.HostType)
{
case ServerSettings.HostingOption.PhotonCloud:
this.photonSetupState = PhotonSetupStates.SetupPhotonCloud;
break;
case ServerSettings.HostingOption.SelfHosted:
this.photonSetupState = PhotonSetupStates.SetupSelfHosted;
break;
case ServerSettings.HostingOption.NotSet:
default:
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
break;
}
}
protected virtual void OnGUI()
{
this.scrollPos = GUILayout.BeginScrollView(this.scrollPos);
if (this.guiState == GUIState.Uninitialized)
{
this.ReApplySettingsToWindow();
this.guiState = (PhotonEditor.Current.HostType == ServerSettings.HostingOption.NotSet) ? GUIState.Setup : GUIState.Main;
}
if (this.guiState == GUIState.Main)
{
this.OnGuiMainWizard();
}
else
{
this.OnGuiRegisterCloudApp();
}
GUILayout.EndScrollView();
}
protected virtual void OnGuiRegisterCloudApp()
{
GUI.skin.label.wordWrap = true;
if (!this.isSetupWizard)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Close setup", GUILayout.ExpandWidth(false)))
{
this.SwitchMenuState(GUIState.Main);
}
GUILayout.EndHorizontal();
GUILayout.Space(15);
}
if (this.photonSetupState == PhotonSetupStates.RegisterForPhotonCloud)
{
GUI.skin.label.fontStyle = FontStyle.Bold;
GUILayout.Label("Connect to Photon Cloud");
GUI.skin.label.fontStyle = FontStyle.Normal;
GUILayout.Label("Your e-mail address is required to access your own free app.");
this.emailAddress = EditorGUILayout.TextField("Email:", this.emailAddress);
if (GUILayout.Button("Send"))
{
GUIUtility.keyboardControl = 0;
this.RegisterWithEmail(this.emailAddress);
}
EditorGUILayout.Separator();
GUILayout.Label("I am already signed up. Let me enter my AppId.");
if (GUILayout.Button("Setup"))
{
this.photonSetupState = PhotonSetupStates.SetupPhotonCloud;
}
GUILayout.Label("I want to register by a website.");
if (GUILayout.Button("Open account website"))
{
EditorUtility.OpenWithDefaultApp(UrlAccountPage + Uri.EscapeUriString(this.emailAddress));
}
EditorGUILayout.Separator();
}
else if (this.photonSetupState == PhotonSetupStates.EmailAlreadyRegistered)
{
GUI.skin.label.fontStyle = FontStyle.Bold;
GUILayout.Label("Oops!");
GUI.skin.label.fontStyle = FontStyle.Normal;
GUILayout.Label("The provided e-mail-address has already been registered.");
if (GUILayout.Button("Mh, see my account page"))
{
EditorUtility.OpenWithDefaultApp(UrlAccountPage + Uri.EscapeUriString(this.emailAddress));
}
EditorGUILayout.Separator();
GUILayout.Label("Ah, I know my Application ID. Get me to setup.");
GUILayout.BeginHorizontal();
if (GUILayout.Button("Cancel"))
{
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
}
if (GUILayout.Button("Setup"))
{
this.photonSetupState = PhotonSetupStates.SetupPhotonCloud;
}
GUILayout.EndHorizontal();
}
else if (this.photonSetupState == PhotonSetupStates.SetupPhotonCloud)
{
// cloud setup
GUI.skin.label.fontStyle = FontStyle.Bold;
GUILayout.Label("Connect to Photon Cloud");
GUI.skin.label.fontStyle = FontStyle.Normal;
EditorGUILayout.Separator();
this.OnGuiSetupCloudAppId();
this.OnGuiCompareAndHelpOptions();
}
else if (this.photonSetupState == PhotonSetupStates.SetupSelfHosted)
{
// self-hosting setup
GUI.skin.label.fontStyle = FontStyle.Bold;
GUILayout.Label("Setup own Photon Host");
GUI.skin.label.fontStyle = FontStyle.Normal;
EditorGUILayout.Separator();
this.OnGuiSetupSelfhosting();
this.OnGuiCompareAndHelpOptions();
}
}
protected virtual void OnGuiMainWizard()
{
// settings button
GUILayout.BeginHorizontal();
GUILayout.Label("Settings", EditorStyles.boldLabel, GUILayout.Width(100));
if (GUILayout.Button(new GUIContent("Setup", "Setup wizard for setting up your own server or the cloud.")))
{
this.InitPhotonSetupWindow();
}
GUILayout.EndHorizontal();
GUILayout.Space(12);
// converter
GUILayout.BeginHorizontal();
GUILayout.Label("Converter", EditorStyles.boldLabel, GUILayout.Width(100));
if (GUILayout.Button(new GUIContent("Start", "Converts pure Unity Networking to Photon Unity Networking.")))
{
PhotonConverter.RunConversion();
}
GUILayout.EndHorizontal();
GUILayout.Space(12);
// add PhotonView
GUILayout.BeginHorizontal();
GUILayout.Label("Component", EditorStyles.boldLabel, GUILayout.Width(100));
if (GUILayout.Button(new GUIContent("Add PhotonView", "Also in menu: Component, Miscellaneous")))
{
if (Selection.activeGameObject != null)
{
Selection.activeGameObject.AddComponent<PhotonView>();
}
}
GUILayout.EndHorizontal();
GUILayout.Space(22);
// license
GUILayout.BeginHorizontal();
GUILayout.Label("Licenses", EditorStyles.boldLabel, GUILayout.Width(100));
if (GUILayout.Button(new GUIContent("Download Free", "Get your free license for up to 100 concurrent players.")))
{
EditorUtility.OpenWithDefaultApp(UrlFreeLicense);
}
GUILayout.EndHorizontal();
GUILayout.Space(12);
// documentation
GUILayout.BeginHorizontal();
GUILayout.Label("Documentation", EditorStyles.boldLabel, GUILayout.Width(100));
GUILayout.BeginVertical();
if (GUILayout.Button(new GUIContent("Open PDF", "Opens the local documentation pdf.")))
{
EditorUtility.OpenWithDefaultApp(DocumentationLocation);
}
if (GUILayout.Button(new GUIContent("Open DevNet", "Online documentation for Photon.")))
{
EditorUtility.OpenWithDefaultApp(UrlDevNet);
}
if (GUILayout.Button(new GUIContent("Open Cloud Dashboard", "Review Cloud App information and statistics.")))
{
EditorUtility.OpenWithDefaultApp(UrlAccountPage + Uri.EscapeUriString(this.emailAddress));
}
if (GUILayout.Button(new GUIContent("Open Forum", "Online support for Photon.")))
{
EditorUtility.OpenWithDefaultApp(UrlForum);
}
GUILayout.EndVertical();
GUILayout.EndHorizontal();
}
protected virtual void OnGuiCompareAndHelpOptions()
{
EditorGUILayout.Separator();
GUILayout.Label("I am not quite sure how 'my own host' compares to 'cloud'.");
if (GUILayout.Button("See comparison page"))
{
Application.OpenURL(UrlCompare);
}
EditorGUILayout.Separator();
GUILayout.Label("Questions? Need help or want to give us feedback? You are most welcome!");
if (GUILayout.Button("See the Photon Forum"))
{
Application.OpenURL(UrlForum);
}
}
protected virtual void OnGuiSetupCloudAppId()
{
GUILayout.Label("Your APP ID:");
this.cloudAppId = EditorGUILayout.TextField(this.cloudAppId);
GUILayout.BeginHorizontal();
if (GUILayout.Button("Cancel"))
{
GUIUtility.keyboardControl = 0;
this.ReApplySettingsToWindow();
}
if (GUILayout.Button("Save"))
{
GUIUtility.keyboardControl = 0;
PhotonEditor.Current.UseCloud(this.cloudAppId);
PhotonEditor.Save();
EditorUtility.DisplayDialog("Success", "Saved your settings.", "ok");
}
GUILayout.EndHorizontal();
EditorGUILayout.Separator();
GUILayout.Label("Running my app in the cloud was fun but...\nLet me setup my own Photon server.");
if (GUILayout.Button("Switch to own host"))
{
this.photonAddress = ServerSettings.DefaultServerAddress;
this.photonPort = ServerSettings.DefaultMasterPort;
this.photonSetupState = PhotonSetupStates.SetupSelfHosted;
}
}
protected virtual void OnGuiSetupSelfhosting()
{
GUILayout.Label("Your Photon Host");
this.photonAddress = EditorGUILayout.TextField("IP:", this.photonAddress);
this.photonPort = EditorGUILayout.IntField("Port:", this.photonPort);
// photonProtocol = (ExitGames.Client.Photon.ConnectionProtocol)EditorGUILayout.EnumPopup("Protocol:", photonProtocol);
GUILayout.BeginHorizontal();
if (GUILayout.Button("Cancel"))
{
GUIUtility.keyboardControl = 0;
this.ReApplySettingsToWindow();
}
if (GUILayout.Button("Save"))
{
GUIUtility.keyboardControl = 0;
PhotonEditor.Current.UseMyServer(this.photonAddress, this.photonPort, null);
PhotonEditor.Save();
EditorUtility.DisplayDialog("Success", "Saved your settings.", "ok");
}
GUILayout.EndHorizontal();
EditorGUILayout.Separator();
GUILayout.Label("Running my own server is too much hassle..\nI want to give Photon's free app a try.");
if (GUILayout.Button("Get the free cloud app"))
{
this.cloudAppId = string.Empty;
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
}
}
protected virtual void RegisterWithEmail(string email)
{
EditorUtility.DisplayProgressBar("Connecting", "Connecting to the account service..", 0.5f);
var client = new AccountService();
client.RegisterByEmail(email, RegisterOrigin); // this is the synchronous variant using the static RegisterOrigin. "result" is in the client
EditorUtility.ClearProgressBar();
if (client.ReturnCode == 0)
{
PhotonEditor.Current.UseCloud(client.AppId);
PhotonEditor.Save();
this.ReApplySettingsToWindow();
this.photonSetupState = PhotonSetupStates.SetupPhotonCloud;
}
else
{
if (client.Message.Contains("Email already registered"))
{
this.photonSetupState = PhotonSetupStates.EmailAlreadyRegistered;
}
else
{
EditorUtility.DisplayDialog("Error", client.Message, "OK");
// Debug.Log(client.Exception);
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
}
}
}
#region SettingsFileHandling
private static ServerSettings currentSettings;
public static ServerSettings Current
{
get
{
if (currentSettings == null)
{
ReLoadCurrentSeetings();
// if still not loaded, create one
if (currentSettings == null)
{
currentSettings = (ServerSettings)ScriptableObject.CreateInstance(typeof(ServerSettings));
string settingsPath = Path.GetDirectoryName(PhotonNetwork.serverSettingsAssetPath);
if (!Directory.Exists(settingsPath))
{
Directory.CreateDirectory(settingsPath);
AssetDatabase.ImportAsset(settingsPath);
}
AssetDatabase.CreateAsset(currentSettings, PhotonNetwork.serverSettingsAssetPath);
}
}
return currentSettings;
}
protected set
{
currentSettings = value;
}
}
public static void Save()
{
EditorUtility.SetDirty(PhotonEditor.Current);
}
public static void ReLoadCurrentSeetings()
{
PhotonEditor.Current = (ServerSettings)AssetDatabase.LoadAssetAtPath(PhotonNetwork.serverSettingsAssetPath, typeof(ServerSettings));
}
protected void ReApplySettingsToWindow()
{
this.cloudAppId = string.IsNullOrEmpty(PhotonEditor.Current.AppID) ? string.Empty : PhotonEditor.Current.AppID;
this.photonAddress = string.IsNullOrEmpty(PhotonEditor.Current.ServerAddress) ? string.Empty : PhotonEditor.Current.ServerAddress;
this.photonPort = PhotonEditor.Current.ServerPort;
}
#endregion
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: dabbbed2a74eac44dac281f20d706ba8
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,380 @@
// ----------------------------------------------------------------------------
// <copyright file="PhotonViewInspector.cs" company="Exit Games GmbH">
// PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
// </copyright>
// <summary>
// Custom inspector for the PhotonView component.
// </summary>
// <author>developer@exitgames.com</author>
// ----------------------------------------------------------------------------
using System;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(PhotonView))]
public class PhotonViewInspector : Editor
{
private bool doubleView = false;
private static PhotonView lastView;
private static GameObject GetPrefabParent(GameObject mp)
{
#if UNITY_2_6_1 || UNITY_2_6 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4
// Unity 3.4 and older use EditorUtility
return (EditorUtility.GetPrefabParent(mp) as GameObject);
#else
// Unity 3.5 uses PrefabUtility
return PrefabUtility.GetPrefabParent(mp) as GameObject;
#endif
}
public override void OnInspectorGUI()
{
EditorGUIUtility.LookLikeInspector();
EditorGUI.indentLevel = 1;
PhotonView mp = (PhotonView)this.target;
bool isProjectPrefab = EditorUtility.IsPersistent(mp.gameObject);
if (!EditorApplication.isPlaying)
{
if (mp != lastView)
{
// First opening of this viewID
if (!isProjectPrefab)
{
if (!IsSceneViewIDFree(mp.viewID.ID, mp))
{
Debug.LogWarning("PhotonView: Wrong view ID(" + mp.viewID.ID + ") on " + mp.name + ", checking entire scene for fixes...");
VerifyAllSceneViews();
}
}
lastView = mp;
}
}
SerializedObject sObj = new SerializedObject(mp);
SerializedProperty sceneProp = sObj.FindProperty("sceneViewID");
// SerializedProperty sceneProp2 = sObj.FindProperty("isSceneView");
// FIX for an issue where a prefab(with photon view) is dragged to the scene and its changes APPLIED
// This means that the scene assigns a ID, but this ID may not be saved to the prefab.
// Unity's prefab AssetImporter doesn't seem to work (3.4), hence this nasty workaround.
// Desired values:
// scene = true true proj = false false. Thus, error case=
if (sceneProp.isInstantiatedPrefab && !sceneProp.prefabOverride)
{
// Fix the assignment
// EDIT: THIS ISSUE HAS BEEN FIXED IN PHOTONVIEW.CS BY CHECKING FOR THE PhotonViewSetup_FindMatchingRoot in Setup();
// #if !UNITY_3_5
// sceneProp.prefabOverride = true;
// #endif
sObj.ApplyModifiedProperties();
// FIX THE EDITOR PREFAB: set it to 0
GameObject prefabParent = GetPrefabParent(mp.gameObject);
if (prefabParent != null)
{
// find all PhotonViews on prefab, including those on inactive components to assign a PhotonViewId
PhotonView[] views = prefabParent.transform.root.GetComponentsInChildren<PhotonView>(true) as PhotonView[];
foreach (PhotonView viewX in views)
{
MakeProjectView(viewX);
}
// ForceUpdate re-import for the prefab
ForceAssetUpdate(mp.gameObject);
}
// Assign the desired scene IDs back (they were reset to 0 by applying)
PhotonView[] views2 = mp.transform.root.GetComponentsInChildren<PhotonView>();
foreach (PhotonView view in views2)
{
int wantedID = view.viewID.ID;
view.SetSceneID(wantedID);
EditorUtility.SetDirty(view);
}
}
// Setup
if (!isProjectPrefab)
{
if (mp.viewID.ID == 0)
{
SetViewID(mp, GetFreeSceneID(mp));
}
}
else
{
if (mp.viewID.ID != 0 || mp.isSceneView)
{
// Correct the settings
Debug.LogWarning("Correcting view ID on project prefab (should be unassigned, but it was " + mp.viewID.ID + ")");
MakeProjectView(mp);
}
}
// OWNER
if (isProjectPrefab)
{
EditorGUILayout.LabelField("Owner:", "Set at runtime");
}
else if (mp.isSceneView)
{
EditorGUILayout.LabelField("Owner:", "Scene");
}
else if (mp.owner == null)
{
EditorGUILayout.LabelField("Owner:", "null, disconnected?");
}
else
{
EditorGUILayout.LabelField("Owner:", "[" + mp.owner.ID + "] " + mp.owner.name);
}
// View ID
if (isProjectPrefab)
{
EditorGUILayout.LabelField("View ID", "Set at runtime");
}
else if (EditorApplication.isPlaying)
{
if (mp.owner != null)
{
EditorGUILayout.LabelField("View ID", "[" + mp.owner.ID + "] " + mp.viewID);
}
else
{
EditorGUILayout.LabelField("View ID", mp.viewID + string.Empty);
}
}
else
{
int newID = EditorGUILayout.IntField("View ID", mp.viewID.ID);
if (GUI.changed)
{
SetViewID(mp, newID);
}
if (this.doubleView)
{
GUI.color = Color.red;
EditorGUILayout.LabelField("ERROR:", "Invalid view ID");
GUI.color = Color.white;
}
if (GUI.changed)
{
this.ChangedSetting();
this.doubleView = false;
PhotonView[] photonViews = Resources.FindObjectsOfTypeAll(typeof(PhotonView)) as PhotonView[];
foreach (PhotonView view in photonViews)
{
if (view.isSceneView && view.viewID == mp.viewID && view != mp)
{
this.doubleView = true;
EditorUtility.DisplayDialog("Error", "There is already a viewID with ID=" + view.viewID, "OK");
}
}
}
}
// OBSERVING
EditorGUILayout.BeginHorizontal();
// Using a lower version then 3.4? Remove the TRUE in the next line to fix an compile error
string title = string.Empty;
int firstOpen = 0;
if (mp.observed != null)
{
firstOpen = mp.observed.ToString().IndexOf('(');
}
if (firstOpen > 0)
{
title = mp.observed.ToString().Substring(firstOpen - 1);
}
mp.observed = (Component)EditorGUILayout.ObjectField("Observe: " + title, mp.observed, typeof(Component), true);
if (GUI.changed)
{
this.ChangedSetting();
if (mp.observed != null)
{
mp.synchronization = ViewSynchronization.ReliableDeltaCompressed;
}
else
{
mp.synchronization = ViewSynchronization.Off;
}
}
EditorGUILayout.EndHorizontal();
if (mp.synchronization == ViewSynchronization.Off)
{
GUI.color = Color.grey;
}
mp.synchronization = (ViewSynchronization)EditorGUILayout.EnumPopup("Observe option:", mp.synchronization);
if (GUI.changed)
{
this.ChangedSetting();
if (mp.synchronization != ViewSynchronization.Off && mp.observed == null)
{
EditorUtility.DisplayDialog("Warning", "Setting the synchronization option only makes sense if you observe something.", "OK, I will fix it.");
}
}
if (mp.observed != null)
{
Type type = mp.observed.GetType();
if (type == typeof(Transform))
{
mp.onSerializeTransformOption = (OnSerializeTransform)EditorGUILayout.EnumPopup("Serialization:", mp.onSerializeTransformOption);
}
else if (type == typeof(Rigidbody))
{
mp.onSerializeRigidBodyOption = (OnSerializeRigidBody)EditorGUILayout.EnumPopup("Serialization:", mp.onSerializeRigidBodyOption);
}
}
GUI.color = Color.white;
EditorGUIUtility.LookLikeControls();
}
private void ChangedSetting()
{
PhotonView mp = (PhotonView)this.target;
if (!EditorApplication.isPlaying)
{
EditorUtility.SetDirty(mp);
}
}
public static void MakeProjectView(PhotonView view)
{
view.viewID = new PhotonViewID(0, null);
view.SetSceneID(0);
EditorUtility.SetDirty(view);
}
private static void SetViewID(PhotonView mp, int ID)
{
ID = Mathf.Clamp(ID, 1, PhotonNetwork.MAX_VIEW_IDS - 1);
if (!IsSceneViewIDFree(ID, mp))
{
ID = GetFreeSceneID(mp);
}
if (mp.viewID.ID != ID)
{
mp.viewID = new PhotonViewID(ID, null);
}
if (!EditorApplication.isPlaying)
{
mp.SetSceneID(mp.viewID.ID);
ForceAssetUpdate(mp.gameObject);
}
EditorUtility.SetDirty(mp);
}
public static void ForceAssetUpdate(GameObject mp)
{
GameObject pPrefab = GetPrefabParent(mp);
if (pPrefab != null)
{
pPrefab = pPrefab.transform.root.gameObject;
string assetPath = AssetDatabase.GetAssetPath(pPrefab);
if (assetPath == string.Empty)
{
Debug.LogError("No assetpath for " + pPrefab);
}
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
}
}
private static int GetFreeSceneID(PhotonView targetView)
{
// No need for bit shifting as scene is "player 0".
/* Hashtable takenIDs = new Hashtable();
PhotonView[] views = (PhotonView[])GameObject.FindObjectsOfType(typeof(PhotonView));
foreach (PhotonView view in views)
{
takenIDs[view.viewID] = view;
}*/
for (int i = 1; i < PhotonNetwork.MAX_VIEW_IDS; i++)
{
if (IsSceneViewIDFree(i, targetView))
{
return i;
}
}
EditorUtility.DisplayDialog("Error", "You ran out of view ID's (" + PhotonNetwork.MAX_VIEW_IDS + "). Something is seriously wrong!", "OK");
return 1;
}
private static bool IsSceneViewIDFree(int ID, PhotonView targetView)
{
if (ID <= 0)
{
return false;
}
PhotonView[] photonViews = Resources.FindObjectsOfTypeAll(typeof(PhotonView)) as PhotonView[];
foreach (PhotonView view in photonViews)
{
if (!view.isSceneView)
{
continue;
}
if (view != targetView && view.viewID != null && view.viewID.ID == ID)
{
return false;
}
}
return true;
}
public static int VerifyAllSceneViews()
{
int correctedViews = 0;
PhotonView[] photonViews = Resources.FindObjectsOfTypeAll(typeof(PhotonView)) as PhotonView[];
foreach (PhotonView view in photonViews)
{
if (!VerifySceneView(view))
{
correctedViews++;
}
}
if (correctedViews > 0)
{
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
return correctedViews;
}
public static bool VerifySceneView(PhotonView view)
{
if (!EditorUtility.IsPersistent(view.gameObject) && !IsSceneViewIDFree(view.viewID.ID, view))
{
SetViewID(view, GetFreeSceneID(view));
return false;
}
return true;
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e73a30c46df19194f873ea7a9ce12753
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,49 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
public class PhotonViewPrefabApply : AssetPostprocessor
{
static void OnPostprocessAllAssets(
string[] importedAssets,
string[] deletedAssets,
string[] movedAssets,
string[] movedFromAssetPaths)
{
bool weChangedPhotonViews = false;
// Strips any scene settings from PhotonViews in prefabs.
// (i.e.: assigned viewIDs are removed)
foreach (string str in importedAssets)
{
if (str.EndsWith(".prefab"))
{
Object[] objs = (Object[])AssetDatabase.LoadAllAssetsAtPath(str);
foreach (Object obj in objs)
{
if (obj != null && obj.GetType() == typeof(GameObject))
{
PhotonView[] views = ((GameObject)obj).GetComponents<PhotonView>();
foreach (PhotonView view in views)
PhotonViewInspector.MakeProjectView(view);
if (views.Length > 0)
weChangedPhotonViews = true;
}
}
}
}
// Problem here: VerifyAllSceneViews will only fix the prefabs instances in the current open scene, not for other scenes!
// See PhotonEditor.EditorUpdate: Here we will check all newly opened scenes for this possible issue.
// No known issues as of 5 March 2011 this seems to work fine with changing viewIDs on prefabs etc. (Even for scenes that are not open) - Mike/Leepo
if (weChangedPhotonViews)
{
PhotonViewInspector.VerifyAllSceneViews();
}
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8fc479a7e9762e6419b446c9fa57fcfb
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData: