/// The main class to use the PhotonNetwork plugin.
/// This class is static.
/// </summary>
/// \ingroup publicApi
publicstaticclassPhotonNetwork
{
/// <summary>Version number of PUN. Also used in GameVersion to separate client version from each other.</summary>
publicconststringversionPUN="1.80";
/// <summary>Version string for your this build. Can be used to separate incompatible clients. Sent during connect.</summary>
/// <remarks>This is only sent when you connect so that is also the place you set it usually (e.g. in ConnectUsingSettings).</remarks>
publicstaticstringgameVersion{get;set;}
/// <summary>
/// This Monobehaviour allows Photon to run an Update loop.
/// </summary>
internalstaticreadonlyPhotonHandlerphotonMono;
/// <summary>
/// Photon peer class that implements LoadBalancing in PUN.
/// Primary use is internal (by PUN itself).
/// </summary>
internalstaticNetworkingPeernetworkingPeer;
/// <summary>
/// The maximum number of assigned PhotonViews <i>per player</i> (or scene). See the [General Documentation](@ref general) topic "Limitations" on how to raise this limitation.
/// </summary>
publicstaticreadonlyintMAX_VIEW_IDS=1000;// VIEW & PLAYER LIMIT CAN BE EASILY CHANGED, SEE DOCS
/// <summary>Name of the PhotonServerSettings file (used to load and by PhotonEditor to save new files).</summary>
/// The minimum difference that a Vector2 or Vector3(e.g. a transforms rotation) needs to change before we send it via a PhotonView's OnSerialize/ObservingComponent.
/// </summary>
/// <remarks>
/// Note that this is the sqrMagnitude. E.g. to send only after a 0.01 change on the Y-axix, we use 0.01f*0.01f=0.0001f. As a remedy against float inaccuracy we use 0.000099f instead of 0.0001f.
/// <summary>If true, PUN will use a Stopwatch to measure time since start/connect. This is more precise than the Environment.TickCount used by default.</summary>
privatestaticboolUsePreciseTimer=false;
staticStopwatchstartupStopwatch;
/// <summary>
/// Defines how many seconds PUN keeps the connection, after Unity's OnApplicationPause(true) call. Default: 60 seconds.
/// </summary>
/// <remarks>
/// It's best practice to disconnect inactive apps/connections after a while but to also allow users to take calls, etc..
/// We think a reasonable backgroung timeout is 60 seconds.
///
/// To handle the timeout, implement: OnDisconnectedFromPhoton(), as usual.
/// Your application will "notice" the background disconnect when it becomes active again (running the Update() loop).
///
/// If you need to separate this case from others, you need to track if the app was in the background
/// (there is no special callback by PUN).
///
/// A value below 0.1 seconds will disable this timeout (careful: connections can be kept indefinitely).
///
///
/// Info:
/// PUN is running a "fallback thread" to send ACKs to the server, even when Unity is not calling Update() regularly.
/// This helps keeping the connection while loading scenes and assets and when the app is in the background.
///
/// Note:
/// Some platforms (e.g. iOS) don't allow to keep a connection while the app is in background.
/// In those cases, this value does not change anything, the app immediately loses connection in background.
///
/// Unity's OnApplicationPause() callback is broken in some exports (Android) of some Unity versions.
/// Make sure OnApplicationPause() gets the callbacks you'd expect on the platform you target!
/// Check PhotonHandler.OnApplicationPause(bool pause), to see the implementation.
/// </remarks>
publicstaticfloatBackgroundTimeout=60.0f;
/// <summary>
/// Are we the master client?
/// </summary>
publicstaticboolisMasterClient
{
get
{
if(offlineMode)
{
returntrue;
}
else
{
returnnetworkingPeer.mMasterClientId==player.ID;
}
}
}
/// <summary>Is true while being in a room (connectionStateDetailed == ClientState.Joined).</summary>
/// <remarks>
/// Many actions can only be executed in a room, like Instantiate or Leave, etc.
/// You can join a room in offline mode, too.
/// </remarks>
publicstaticboolinRoom
{
get
{
// in offline mode, you can be in a room too and connectionStateDetailed then returns Joined like on online mode!
/// True if we are in a room (client) and NOT the room's masterclient
/// </summary>
publicstaticboolisNonMasterClientInRoom
{
get
{
return!isMasterClient&&room!=null;
}
}
/// <summary>
/// The count of players currently looking for a room (available on MasterServer in 5sec intervals).
/// </summary>
publicstaticintcountOfPlayersOnMaster
{
get
{
returnnetworkingPeer.PlayersOnMasterCount;
}
}
/// <summary>
/// Count of users currently playing your app in some room (sent every 5sec by Master Server). Use playerList.Count to get the count of players in the room you're in!
/// </summary>
publicstaticintcountOfPlayersInRooms
{
get
{
returnnetworkingPeer.PlayersInRoomsCount;
}
}
/// <summary>
/// The count of players currently using this application (available on MasterServer in 5sec intervals).
/// The count of rooms currently in use (available on MasterServer in 5sec intervals).
/// </summary>
/// <remarks>
/// While inside the lobby you can also check the count of listed rooms as: PhotonNetwork.GetRoomList().Length.
/// Since PUN v1.25 this is only based on the statistic event Photon sends (counting all rooms).
/// </remarks>
publicstaticintcountOfRooms
{
get
{
returnnetworkingPeer.RoomsCount;
}
}
/// <summary>
/// Enables or disables the collection of statistics about this client's traffic.
/// </summary>
/// <remarks>
/// If you encounter issues with clients, the traffic stats are a good starting point to find solutions.
/// Only with enabled stats, you can use GetVitalStats
/// </remarks>
publicstaticboolNetworkStatisticsEnabled
{
get
{
returnnetworkingPeer.TrafficStatsEnabled;
}
set
{
networkingPeer.TrafficStatsEnabled=value;
}
}
/// <summary>
/// Count of commands that got repeated (due to local repeat-timing before an ACK was received).
/// </summary>
/// <remarks>
/// If this value increases a lot, there is a good chance that a timeout disconnect will happen due to bad conditions.
/// </remarks>
publicstaticintResentReliableCommands
{
get{returnnetworkingPeer.ResentReliableCommands;}
}
/// <summary>Crc checks can be useful to detect and avoid issues with broken datagrams. Can be enabled while not connected.</summary>
publicstaticboolCrcCheckEnabled
{
get{returnnetworkingPeer.CrcEnabled;}
set
{
if(!connected&&!connecting)
{
networkingPeer.CrcEnabled=value;
}
else
{
Debug.Log("Can't change CrcCheckEnabled while being connected. CrcCheckEnabled stays "+networkingPeer.CrcEnabled);
}
}
}
/// <summary>If CrcCheckEnabled, this counts the incoming packages that don't have a valid CRC checksum and got rejected.</summary>
publicstaticintPacketLossByCrcCheck
{
get{returnnetworkingPeer.PacketLossByCrc;}
}
/// <summary>Defines the number of times a reliable message can be resent before not getting an ACK for it will trigger a disconnect. Default: 5.</summary>
/// <remarks>Less resends mean quicker disconnects, while more can lead to much more lag without helping. Min: 3. Max: 10.</remarks>
publicstaticintMaxResendsBeforeDisconnect
{
get{returnnetworkingPeer.SentCountAllowance;}
set
{
if(value<3)value=3;
if(value>10)value=10;
networkingPeer.SentCountAllowance=value;
}
}
/// <summary>In case of network loss, reliable messages can be repeated quickly up to 3 times.</summary>
/// <remarks>
/// When reliable messages get lost more than once, subsequent repeats are delayed a bit
/// to allow the network to recover.<br/>
/// With this option, the repeats 2 and 3 can be sped up. This can help avoid timeouts but
/// also it increases the speed in which gaps are closed.<br/>
/// When you set this, increase PhotonNetwork.MaxResendsBeforeDisconnect to 6 or 7.
/// </remarks>
publicstaticintQuickResends
{
get{returnnetworkingPeer.QuickResendAttempts;}
set
{
if(value<0)value=0;
if(value>3)value=3;
networkingPeer.QuickResendAttempts=(byte)value;
}
}
/// <summary>
/// Defines the delegate usable in OnEventCall.
/// </summary>
/// <remarks>Any eventCode < 200 will be forwarded to your delegate(s).</remarks>
/// <param name="eventCode">The code assigend to the incoming event.</param>
/// <param name="content">The content the sender put into the event.</param>
/// <param name="senderId">The ID of the player who sent the event. It might be 0, if the "room" sent the event.</param>
//Debug.Log(string.Format("PhotonNetwork.ctor() Not playing {0} {1}", UnityEditor.EditorApplication.isPlaying, UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode));
return;
}
// This can happen when you recompile a script IN play made
// This helps to surpress some errors, but will not fix breaking
/// - Invalid region (calls: OnConnectionFail() with DisconnectCause.InvalidRegion)
/// - Subscription CCU limit reached (calls: OnConnectionFail() with DisconnectCause.MaxCcuReached. also calls: OnPhotonMaxCccuReached())
///
/// More about the connection limitations:
/// http://doc.exitgames.com/en/pun
/// </remarks>
/// <param name="gameVersion">This client's version number. Users are separated from each other by gameversion (which allows you to make breaking changes).</param>
/// - Invalid region (calls: OnConnectionFail() with DisconnectCause.InvalidRegion)
/// - Subscription CCU limit reached (calls: OnConnectionFail() with DisconnectCause.MaxCcuReached. also calls: OnPhotonMaxCccuReached())
///
/// More about the connection limitations:
/// http://doc.exitgames.com/en/pun
/// </remarks>
/// <param name="gameVersion">This client's version number. Users are separated from each other by gameversion (which allows you to make breaking changes).</param>
/// <returns>If this client is going to connect to cloud server based on ping. Even if true, this does not guarantee a connection but the attempt is being made.</returns>
Debug.LogWarning("ConnectToBestCloudServer() failed. Can only connect while in state 'Disconnected'. Current state: "+networkingPeer.PeerState);
returnfalse;
}
if(PhotonServerSettings==null)
{
Debug.LogError("Can't connect: Loading settings failed. ServerSettings asset must be in any 'Resources' folder as: "+PhotonNetwork.serverSettingsAssetFile);
/// Creates a room with given name but fails if this room(name) is existing already. Creates random name for roomName null.
/// </summary>
/// <remarks>
/// If you don't want to create a unique room-name, pass null or "" as name and the server will assign a roomName (a GUID as string).
///
/// The created room is automatically placed in the currently used lobby (if any) or the default-lobby if you didn't explicitly join one.
///
/// Call this only on the master server.
/// Internally, the master will respond with a server-address (and roomName, if needed). Both are used internally
/// to switch to the assigned game server and roomName.
///
/// PhotonNetwork.autoCleanUpPlayerObjects will become this room's AutoCleanUp property and that's used by all clients that join this room.
/// </remarks>
/// <param name="roomName">Unique name of the room to create.</param>
/// <returns>If the operation got queued and will be sent.</returns>
publicstaticboolCreateRoom(stringroomName)
{
returnCreateRoom(roomName,null,null,null);
}
/// <summary>
/// Creates a room but fails if this room is existing already. Can only be called on Master Server.
/// </summary>
/// <remarks>
/// When successful, this calls the callbacks OnCreatedRoom and OnJoinedRoom (the latter, cause you join as first player).
/// If the room can't be created (because it exists already), OnPhotonCreateRoomFailed gets called.
///
/// If you don't want to create a unique room-name, pass null or "" as name and the server will assign a roomName (a GUID as string).
///
/// Rooms can be created in any number of lobbies. Those don't have to exist before you create a room in them (they get
/// auto-created on demand). Lobbies can be useful to split room lists on the server-side already. That can help keep the room
/// lists short and manageable.
/// If you set a typedLobby parameter, the room will be created in that lobby (no matter if you are active in any).
/// If you don't set a typedLobby, the room is automatically placed in the currently active lobby (if any) or the
/// default-lobby.
///
/// Call this only on the master server.
/// Internally, the master will respond with a server-address (and roomName, if needed). Both are used internally
/// to switch to the assigned game server and roomName.
///
/// PhotonNetwork.autoCleanUpPlayerObjects will become this room's autoCleanUp property and that's used by all clients that join this room.
/// </remarks>
/// <param name="roomName">Unique name of the room to create. Pass null or "" to make the server generate a name.</param>
/// <param name="roomOptions">Common options for the room like MaxPlayers, initial custom room properties and similar. See RoomOptions type..</param>
/// <param name="typedLobby">If null, the room is automatically created in the currently used lobby (which is "default" when you didn't join one explicitly).</param>
/// <returns>If the operation got queued and will be sent.</returns>
/// Creates a room but fails if this room is existing already. Can only be called on Master Server.
/// </summary>
/// <remarks>
/// When successful, this calls the callbacks OnCreatedRoom and OnJoinedRoom (the latter, cause you join as first player).
/// If the room can't be created (because it exists already), OnPhotonCreateRoomFailed gets called.
///
/// If you don't want to create a unique room-name, pass null or "" as name and the server will assign a roomName (a GUID as string).
///
/// Rooms can be created in any number of lobbies. Those don't have to exist before you create a room in them (they get
/// auto-created on demand). Lobbies can be useful to split room lists on the server-side already. That can help keep the room
/// lists short and manageable.
/// If you set a typedLobby parameter, the room will be created in that lobby (no matter if you are active in any).
/// If you don't set a typedLobby, the room is automatically placed in the currently active lobby (if any) or the
/// default-lobby.
///
/// Call this only on the master server.
/// Internally, the master will respond with a server-address (and roomName, if needed). Both are used internally
/// to switch to the assigned game server and roomName.
///
/// PhotonNetwork.autoCleanUpPlayerObjects will become this room's autoCleanUp property and that's used by all clients that join this room.
///
/// You can define an array of expectedUsers, to block player slots in the room for these users.
/// The corresponding feature in Photon is called "Slot Reservation" and can be found in the doc pages.
/// </remarks>
/// <param name="roomName">Unique name of the room to create. Pass null or "" to make the server generate a name.</param>
/// <param name="roomOptions">Common options for the room like MaxPlayers, initial custom room properties and similar. See RoomOptions type..</param>
/// <param name="typedLobby">If null, the room is automatically created in the currently used lobby (which is "default" when you didn't join one explicitly).</param>
/// <param name="expectedUsers">Optional list of users (by UserId) who are expected to join this game and who you want to block a slot for.</param>
/// <returns>If the operation got queued and will be sent.</returns>
Debug.LogError("CreateRoom failed. Client is not on Master Server or not yet ready to call operations. Wait for callback: OnJoinedLobby or OnConnectedToMaster.");
returnfalse;
}
typedLobby=typedLobby??((networkingPeer.insideLobby)?networkingPeer.lobby:null);// use given lobby, or active lobby (if any active) or none
EnterRoomParamsopParams=newEnterRoomParams();
opParams.RoomName=roomName;
opParams.RoomOptions=roomOptions;
opParams.Lobby=typedLobby;
opParams.ExpectedUsers=expectedUsers;
returnnetworkingPeer.OpCreateGame(opParams);
}
/// <summary>Join room by roomname and on success calls OnJoinedRoom(). This is not affected by lobbies.</summary>
/// <remarks>
/// On success, the method OnJoinedRoom() is called on any script. You can implement it to react to joining a room.
///
/// JoinRoom fails if the room is either full or no longer available (it might become empty while you attempt to join).
/// Implement OnPhotonJoinRoomFailed() to get a callback in error case.
///
/// To join a room from the lobby's listing, use RoomInfo.Name as roomName here.
/// Despite using multiple lobbies, a roomName is always "global" for your application and so you don't
/// have to specify which lobby it's in. The Master Server will find the room.
/// In the Photon Cloud, an application is defined by AppId, Game- and PUN-version.
Debug.LogError("JoinRoom failed. Client is not on Master Server or not yet ready to call operations. Wait for callback: OnJoinedLobby or OnConnectedToMaster.");
returnfalse;
}
if(string.IsNullOrEmpty(roomName))
{
Debug.LogError("JoinRoom failed. A roomname is required. If you don't know one, how will you join?");
returnfalse;
}
EnterRoomParamsopParams=newEnterRoomParams();
opParams.RoomName=roomName;
opParams.ExpectedUsers=expectedUsers;
returnnetworkingPeer.OpJoinRoom(opParams);
}
/// <summary>Lets you either join a named room or create it on the fly - you don't have to know if someone created the room already.</summary>
/// <remarks>
/// This makes it easier for groups of players to get into the same room. Once the group
/// exchanged a roomName, any player can call JoinOrCreateRoom and it doesn't matter who
/// actually joins or creates the room.
///
/// The parameters roomOptions and typedLobby are only used when the room actually gets created by this client.
/// You know if this client created a room, if you get a callback OnCreatedRoom (before OnJoinedRoom gets called as well).
/// </remarks>
/// <param name="roomName">Name of the room to join. Must be non null.</param>
/// <param name="roomOptions">Options for the room, in case it does not exist yet. Else these values are ignored.</param>
/// <param name="typedLobby">Lobby you want a new room to be listed in. Ignored if the room was existing and got joined.</param>
/// <returns>If the operation got queued and will be sent.</returns>
Debug.LogError("JoinOrCreateRoom failed. Client is not on Master Server or not yet ready to call operations. Wait for callback: OnJoinedLobby or OnConnectedToMaster.");
returnfalse;
}
if(string.IsNullOrEmpty(roomName))
{
Debug.LogError("JoinOrCreateRoom failed. A roomname is required. If you don't know one, how will you join?");
returnfalse;
}
typedLobby=typedLobby??((networkingPeer.insideLobby)?networkingPeer.lobby:null);// use given lobby, or active lobby (if any active) or none
/// Attempts to join an open room with fitting, custom properties but fails if none is currently available.
/// </summary>
/// <remarks>
/// Rooms can be created in arbitrary lobbies which get created on demand.
/// You can join rooms from any lobby without actually joining the lobby.
/// Use the JoinRandomRoom overload with TypedLobby parameter.
///
/// This method will only match rooms attached to one lobby! If you use many lobbies, you
/// might have to repeat JoinRandomRoom, to find some fitting room.
/// This method looks up a room in the currently active lobby or (if no lobby is joined)
/// in the default lobby.
///
/// If this fails, you can still create a room (and make this available for the next who uses JoinRandomRoom).
/// Alternatively, try again in a moment.
/// </remarks>
/// <param name="expectedCustomRoomProperties">Filters for rooms that match these custom properties (string keys and values). To ignore, pass null.</param>
/// <param name="expectedMaxPlayers">Filters for a particular maxplayer setting. Use 0 to accept any maxPlayer value.</param>
/// <returns>If the operation got queued and will be sent.</returns>
/// Attempts to join an open room with fitting, custom properties but fails if none is currently available.
/// </summary>
/// <remarks>
/// Rooms can be created in arbitrary lobbies which get created on demand.
/// You can join rooms from any lobby without actually joining the lobby with this overload.
///
/// This method will only match rooms attached to one lobby! If you use many lobbies, you
/// might have to repeat JoinRandomRoom, to find some fitting room.
/// This method looks up a room in the specified lobby or the currently active lobby (if none specified)
/// or in the default lobby (if none active).
///
/// If this fails, you can still create a room (and make this available for the next who uses JoinRandomRoom).
/// Alternatively, try again in a moment.
///
/// In offlineMode, a room will be created but no properties will be set and all parameters of this
/// JoinRandomRoom call are ignored. The event/callback OnJoinedRoom gets called (see enum PhotonNetworkingMessage).
///
/// You can define an array of expectedUsers, to block player slots in the room for these users.
/// The corresponding feature in Photon is called "Slot Reservation" and can be found in the doc pages.
/// </remarks>
/// <param name="expectedCustomRoomProperties">Filters for rooms that match these custom properties (string keys and values). To ignore, pass null.</param>
/// <param name="expectedMaxPlayers">Filters for a particular maxplayer setting. Use 0 to accept any maxPlayer value.</param>
/// <param name="matchingType">Selects one of the available matchmaking algorithms. See MatchmakingMode enum for options.</param>
/// <param name="typedLobby">The lobby in which you want to lookup a room. Pass null, to use the default lobby. This does not join that lobby and neither sets the lobby property.</param>
/// <param name="sqlLobbyFilter">A filter-string for SQL-typed lobbies.</param>
/// <param name="expectedUsers">Optional list of users (by UserId) who are expected to join this game and who you want to block a slot for.</param>
/// <returns>If the operation got queued and will be sent.</returns>
Debug.LogError("JoinRandomRoom failed. Client is not on Master Server or not yet ready to call operations. Wait for callback: OnJoinedLobby or OnConnectedToMaster.");
returnfalse;
}
typedLobby=typedLobby??((networkingPeer.insideLobby)?networkingPeer.lobby:null);// use given lobby, or active lobby (if any active) or none
Debug.LogError("ReJoinRoom failed. Client is not on Master Server or not yet ready to call operations. Wait for callback: OnJoinedLobby or OnConnectedToMaster.");
returnfalse;
}
if(string.IsNullOrEmpty(roomName))
{
Debug.LogError("ReJoinRoom failed. A roomname is required. If you don't know one, how will you join?");
Debug.LogWarning("PhotonNetwork.room is null. You don't have to call LeaveRoom() when you're not in one. State: "+PhotonNetwork.connectionStateDetailed);
}
returnnetworkingPeer.OpLeave();
}
returntrue;
}
/// <summary>
/// Gets currently known rooms as RoomInfo array. This is available and updated while in a lobby (check insideLobby).
/// </summary>
/// <remarks>
/// This list is a cached copy of the internal rooms list so it can be accessed each frame if needed.
/// Per RoomInfo you can check if the room is full by comparing playerCount and MaxPlayers before you allow a join.
///
/// The name of a room must be used to join it (via JoinRoom).
///
/// Closed rooms are also listed by lobbies but they can't be joined. While in a room, any player can set
/// Room.visible and Room.open to hide rooms from matchmaking and close them.
/// </remarks>
/// <returns>RoomInfo[] of current rooms in lobby.</returns>
publicstaticRoomInfo[]GetRoomList()
{
if(offlineMode||networkingPeer==null)
{
returnnewRoomInfo[0];
}
returnnetworkingPeer.mGameListCopy;
}
/// <summary>
/// Sets this (local) player's properties and synchronizes them to the other players (don't modify them directly).
/// </summary>
/// <remarks>
/// While in a room, your properties are synced with the other players.
/// CreateRoom, JoinRoom and JoinRandomRoom will all apply your player's custom properties when you enter the room.
/// The whole Hashtable will get sent. Minimize the traffic by setting only updated key/values.
///
/// If the Hashtable is null, the custom properties will be cleared.
/// Custom properties are never cleared automatically, so they carry over to the next room, if you don't change them.
///
/// Don't set properties by modifying PhotonNetwork.player.customProperties!
/// </remarks>
/// <param name="customProperties">Only string-typed keys will be used from this hashtable. If null, custom properties are all deleted.</param>
/// With the senderId, you can look up the PhotonPlayer who sent the event.
/// It is best practice to assign a eventCode for each different type of content and action. You have to cast the content.
///
/// The eventContent is optional. To be able to send something, it must be a "serializable type", something that
/// the client can turn into a byte[] basically. Most basic types and arrays of them are supported, including
/// Unity's Vector2, Vector3, Quaternion. Transforms or classes some project defines are NOT supported!
/// You can make your own class a "serializable type" by following the example in CustomTypes.cs.
///
///
/// The RaiseEventOptions have some (less intuitive) combination rules:
/// If you set targetActors (an array of PhotonPlayer.ID values), the receivers parameter gets ignored.
/// When using event caching, the targetActors, receivers and interestGroup can't be used. Buffered events go to all.
/// When using cachingOption removeFromRoomCache, the eventCode and content are actually not sent but used as filter.
/// </remarks>
/// <param name="eventCode">A byte identifying the type of event. You might want to use a code per action or to signal which content can be expected. Allowed: 0..199.</param>
/// <param name="eventContent">Some serializable object like string, byte, integer, float (etc) and arrays of those. Hashtables with byte keys are good to send variable content.</param>
/// <param name="sendReliable">Makes sure this event reaches all players. It gets acknowledged, which requires bandwidth and it can't be skipped (might add lag in case of loss).</param>
/// <param name="options">Allows more complex usage of events. If null, RaiseEventOptions.Default will be used (which is fine).</param>
/// <returns>False if event could not be sent</returns>
Debug.LogWarning(string.Format("UnAllocateViewID() should be called after the PhotonView was destroyed (GameObject.Destroy()). ViewID: {0} still found in: {1}",viewID,networkingPeer.photonViewList[viewID]));
}
}
/// <summary>
/// Instantiate a prefab over the network. This prefab needs to be located in the root of a "Resources" folder.
/// </summary>
/// <remarks>
/// Instead of using prefabs in the Resources folder, you can manually Instantiate and assign PhotonViews. See doc.
/// </remarks>
/// <param name="prefabName">Name of the prefab to instantiate.</param>
/// <param name="position">Position Vector3 to apply on instantiation.</param>
/// <param name="rotation">Rotation Quaternion to apply on instantiation.</param>
/// <param name="group">The group for this PhotonView.</param>
/// <returns>The new instance of a GameObject with initialized PhotonView.</returns>
Debug.LogError("Failed to Instantiate prefab: "+prefabName+". Client should be in a room. Current connectionStateDetailed: "+PhotonNetwork.connectionStateDetailed);
/// Instantiate a scene-owned prefab over the network. The PhotonViews will be controllable by the MasterClient. This prefab needs to be located in the root of a "Resources" folder.
/// </summary>
/// <remarks>
/// Only the master client can Instantiate scene objects.
/// Instead of using prefabs in the Resources folder, you can manually Instantiate and assign PhotonViews. See doc.
/// </remarks>
/// <param name="prefabName">Name of the prefab to instantiate.</param>
/// <param name="position">Position Vector3 to apply on instantiation.</param>
/// <param name="rotation">Rotation Quaternion to apply on instantiation.</param>
/// <param name="group">The group for this PhotonView.</param>
/// <param name="data">Optional instantiation data. This will be saved to it's PhotonView.instantiationData.</param>
/// <returns>The new instance of a GameObject with initialized PhotonView.</returns>
Debug.LogError("Failed to InstantiateSceneObject prefab: "+prefabName+". Client should be in a room. Current connectionStateDetailed: "+PhotonNetwork.connectionStateDetailed);
returnnull;
}
if(!isMasterClient)
{
Debug.LogError("Failed to InstantiateSceneObject prefab: "+prefabName+". Client is not the MasterClient in this room.");
/// Network-Destroy all GameObjects, PhotonViews and their RPCs of targetPlayer. Can only be called on local player (for "self") or Master Client (for anyone).
/// </summary>
/// <remarks>
/// Destroying a networked GameObject includes:
/// - Removal of the Instantiate call from the server's room buffer.
/// - Removing RPCs buffered for PhotonViews that got created indirectly with the PhotonNetwork.Instantiate call.
/// - Sending a message to other clients to remove the GameObject also (affected by network lag).
///
/// Destroying networked objects works only if they got created with PhotonNetwork.Instantiate().
/// Objects loaded with a scene are ignored, no matter if they have PhotonView components.
/// </remarks>
/// <returns>Nothing. Check error debug log for any issues.</returns>
Debug.LogError("DestroyPlayerObjects() failed, cause parameter 'targetPlayer' was null.");
}
DestroyPlayerObjects(targetPlayer.ID);
}
/// <summary>
/// Network-Destroy all GameObjects, PhotonViews and their RPCs of this player (by ID). Can only be called on local player (for "self") or Master Client (for anyone).
/// </summary>
/// <remarks>
/// Destroying a networked GameObject includes:
/// - Removal of the Instantiate call from the server's room buffer.
/// - Removing RPCs buffered for PhotonViews that got created indirectly with the PhotonNetwork.Instantiate call.
/// - Sending a message to other clients to remove the GameObject also (affected by network lag).
///
/// Destroying networked objects works only if they got created with PhotonNetwork.Instantiate().
/// Objects loaded with a scene are ignored, no matter if they have PhotonView components.
/// </remarks>
/// <returns>Nothing. Check error debug log for any issues.</returns>
Debug.LogError("DestroyPlayerObjects() failed, cause players can only destroy their own GameObjects. A Master Client can destroy anyone's. This is master: "+PhotonNetwork.isMasterClient);
}
}
/// <summary>
/// Network-Destroy all GameObjects, PhotonViews and their RPCs in the room. Removes anything buffered from the server. Can only be called by Master Client (for anyone).
/// </summary>
/// <remarks>
/// Can only be called by Master Client (for anyone).
/// Unlike the Destroy methods, this will remove anything from the server's room buffer. If your game
/// buffers anything beyond Instantiate and RPC calls, that will be cleaned as well from server.
///
/// Destroying all includes:
/// - Remove anything from the server's room buffer (Instantiate, RPCs, anything buffered).
/// - Sending a message to other clients to destroy everything locally, too (affected by network lag).
///
/// Destroying networked objects works only if they got created with PhotonNetwork.Instantiate().
/// Objects loaded with a scene are ignored, no matter if they have PhotonView components.
/// </remarks>
/// <returns>Nothing. Check error debug log for any issues.</returns>
publicstaticvoidDestroyAll()
{
if(isMasterClient)
{
networkingPeer.DestroyAll(false);
}
else
{
Debug.LogError("Couldn't call DestroyAll() as only the master client is allowed to call this.");
}
}
/// <summary>
/// Remove all buffered RPCs from server that were sent by targetPlayer. Can only be called on local player (for "self") or Master Client (for anyone).
/// </summary>
/// <remarks>
/// This method requires either:
/// - This is the targetPlayer's client.
/// - This client is the Master Client (can remove any PhotonPlayer's RPCs).
///
/// If the targetPlayer calls RPCs at the same time that this is called,
/// network lag will determine if those get buffered or cleared like the rest.
/// </remarks>
/// <param name="targetPlayer">This player's buffered RPCs get removed from server buffer.</param>
/// Remove all buffered RPCs from server that were sent in the targetGroup, if this is the Master Client or if this controls the individual PhotonView.
/// </summary>
/// <remarks>
/// This method requires either:
/// - This client is the Master Client (can remove any RPCs per group).
/// - Any other client: each PhotonView is checked if it is under this client's control. Only those RPCs are removed.
/// </remarks>
/// <param name="targetGroup">Interest group that gets all RPCs removed.</param>
publicstaticvoidRemoveRPCsInGroup(inttargetGroup)
{
if(!VerifyCanUseNetwork())
{
return;
}
networkingPeer.RemoveRPCsInGroup(targetGroup);
}
/// <summary>
/// Internal to send an RPC on given PhotonView. Do not call this directly but use: PhotonView.RPC!