2018-06-07 13:41:08 +00:00
#if ENABLE_UNET
using System ;
using System.Collections.Generic ;
using UnityEngine.Networking.NetworkSystem ;
namespace UnityEngine.Networking
{
public class ClientScene
{
static List < PlayerController > s_LocalPlayers = new List < PlayerController > ( ) ;
static NetworkConnection s_ReadyConnection ;
static Dictionary < NetworkSceneId , NetworkIdentity > s_SpawnableObjects ;
static bool s_IsReady ;
static bool s_IsSpawnFinished ;
static NetworkScene s_NetworkScene = new NetworkScene ( ) ;
static internal void SetNotReady ( )
{
s_IsReady = false ;
}
struct PendingOwner
{
public NetworkInstanceId netId ;
public short playerControllerId ;
}
static List < PendingOwner > s_PendingOwnerIds = new List < PendingOwner > ( ) ;
public static List < PlayerController > localPlayers { get { return s_LocalPlayers ; } }
public static bool ready { get { return s_IsReady ; } }
public static NetworkConnection readyConnection { get { return s_ReadyConnection ; } }
//NOTE: spawn handlers, prefabs and local objects now live in NetworkScene
public static Dictionary < NetworkInstanceId , NetworkIdentity > objects { get { return s_NetworkScene . localObjects ; } }
public static Dictionary < NetworkHash128 , GameObject > prefabs { get { return NetworkScene . guidToPrefab ; } }
public static Dictionary < NetworkSceneId , NetworkIdentity > spawnableObjects { get { return s_SpawnableObjects ; } }
internal static void Shutdown ( )
{
s_NetworkScene . Shutdown ( ) ;
s_LocalPlayers = new List < PlayerController > ( ) ;
s_PendingOwnerIds = new List < PendingOwner > ( ) ;
s_SpawnableObjects = null ;
s_ReadyConnection = null ;
s_IsReady = false ;
s_IsSpawnFinished = false ;
2018-06-14 10:20:23 +00:00
2018-06-07 13:41:08 +00:00
NetworkTransport . Shutdown ( ) ;
NetworkTransport . Init ( ) ;
}
// this is called from message handler for Owner message
internal static void InternalAddPlayer ( NetworkIdentity view , short playerControllerId )
{
if ( LogFilter . logDebug ) { Debug . LogWarning ( "ClientScene::InternalAddPlayer: playerControllerId : " + playerControllerId ) ; }
if ( playerControllerId > = s_LocalPlayers . Count )
{
if ( LogFilter . logWarn ) { Debug . LogWarning ( "ClientScene::InternalAddPlayer: playerControllerId higher than expected: " + playerControllerId ) ; }
while ( playerControllerId > = s_LocalPlayers . Count )
{
s_LocalPlayers . Add ( new PlayerController ( ) ) ;
}
}
// NOTE: It can be "normal" when changing scenes for the player to be destroyed and recreated.
// But, the player structures are not cleaned up, we'll just replace the old player
var newPlayer = new PlayerController { gameObject = view . gameObject , playerControllerId = playerControllerId , unetView = view } ;
s_LocalPlayers [ playerControllerId ] = newPlayer ;
2018-06-08 12:23:59 +00:00
if ( s_ReadyConnection = = null )
{
if ( LogFilter . logWarn ) { Debug . LogWarning ( "No ready connection found for setting player controller during InternalAddPlayer" ) ; }
}
else
{
s_ReadyConnection . SetPlayerController ( newPlayer ) ;
}
2018-06-07 13:41:08 +00:00
}
// use this if already ready
public static bool AddPlayer ( short playerControllerId )
{
return AddPlayer ( null , playerControllerId ) ;
}
// use this to implicitly become ready
public static bool AddPlayer ( NetworkConnection readyConn , short playerControllerId )
{
return AddPlayer ( readyConn , playerControllerId , null ) ;
}
// use this to implicitly become ready
public static bool AddPlayer ( NetworkConnection readyConn , short playerControllerId , MessageBase extraMessage )
{
if ( playerControllerId < 0 )
{
if ( LogFilter . logError ) { Debug . LogError ( "ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is negative" ) ; }
return false ;
}
if ( playerControllerId > PlayerController . MaxPlayersPerClient )
{
if ( LogFilter . logError ) { Debug . LogError ( "ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is too high, max is " + PlayerController . MaxPlayersPerClient ) ; }
return false ;
}
if ( playerControllerId > PlayerController . MaxPlayersPerClient / 2 )
{
if ( LogFilter . logWarn ) { Debug . LogWarning ( "ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " is unusually high" ) ; }
}
// fill out local players array
while ( playerControllerId > = s_LocalPlayers . Count )
{
s_LocalPlayers . Add ( new PlayerController ( ) ) ;
}
// ensure valid ready connection
2018-06-28 13:50:13 +00:00
if ( readyConn ! = null )
2018-06-07 13:41:08 +00:00
{
s_IsReady = true ;
s_ReadyConnection = readyConn ;
}
2018-06-28 13:50:13 +00:00
if ( ! s_IsReady )
{
if ( LogFilter . logError ) { Debug . LogError ( "Must call AddPlayer() with a connection the first time to become ready." ) ; }
return false ;
}
2018-06-07 13:41:08 +00:00
PlayerController existingPlayerController ;
if ( s_ReadyConnection . GetPlayerController ( playerControllerId , out existingPlayerController ) )
{
if ( existingPlayerController . IsValid & & existingPlayerController . gameObject ! = null )
{
if ( LogFilter . logError ) { Debug . LogError ( "ClientScene::AddPlayer: playerControllerId of " + playerControllerId + " already in use." ) ; }
return false ;
}
}
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::AddPlayer() for ID " + playerControllerId + " called with connection [" + s_ReadyConnection + "]" ) ; }
var msg = new AddPlayerMessage ( ) ;
msg . playerControllerId = playerControllerId ;
if ( extraMessage ! = null )
{
var writer = new NetworkWriter ( ) ;
extraMessage . Serialize ( writer ) ;
msg . msgData = writer . ToArray ( ) ;
}
s_ReadyConnection . Send ( MsgType . AddPlayer , msg ) ;
return true ;
}
public static bool RemovePlayer ( short playerControllerId )
{
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::RemovePlayer() for ID " + playerControllerId + " called with connection [" + s_ReadyConnection + "]" ) ; }
PlayerController playerController ;
if ( s_ReadyConnection . GetPlayerController ( playerControllerId , out playerController ) )
{
var msg = new RemovePlayerMessage ( ) ;
msg . playerControllerId = playerControllerId ;
s_ReadyConnection . Send ( MsgType . RemovePlayer , msg ) ;
s_ReadyConnection . RemovePlayerController ( playerControllerId ) ;
s_LocalPlayers [ playerControllerId ] = new PlayerController ( ) ;
Object . Destroy ( playerController . gameObject ) ;
return true ;
}
if ( LogFilter . logError ) { Debug . LogError ( "Failed to find player ID " + playerControllerId ) ; }
return false ;
}
public static bool Ready ( NetworkConnection conn )
{
if ( s_IsReady )
{
if ( LogFilter . logError ) { Debug . LogError ( "A connection has already been set as ready. There can only be one." ) ; }
return false ;
}
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::Ready() called with connection [" + conn + "]" ) ; }
if ( conn ! = null )
{
var msg = new ReadyMessage ( ) ;
conn . Send ( MsgType . Ready , msg ) ;
s_IsReady = true ;
s_ReadyConnection = conn ;
s_ReadyConnection . isReady = true ;
return true ;
}
if ( LogFilter . logError ) { Debug . LogError ( "Ready() called with invalid connection object: conn=null" ) ; }
return false ;
}
static public NetworkClient ConnectLocalServer ( )
{
var newClient = new LocalClient ( ) ;
2018-06-22 18:34:35 +00:00
NetworkServer . ActivateLocalClientScene ( ) ;
2018-06-07 13:41:08 +00:00
newClient . InternalConnectLocalServer ( true ) ;
return newClient ;
}
static internal void HandleClientDisconnect ( NetworkConnection conn )
{
if ( s_ReadyConnection = = conn & & s_IsReady )
{
s_IsReady = false ;
s_ReadyConnection = null ;
}
}
internal static void PrepareToSpawnSceneObjects ( )
{
//NOTE: what is there are already objects in this dict?! should we merge with them?
s_SpawnableObjects = new Dictionary < NetworkSceneId , NetworkIdentity > ( ) ;
var uvs = Resources . FindObjectsOfTypeAll < NetworkIdentity > ( ) ;
for ( int i = 0 ; i < uvs . Length ; i + + )
{
var uv = uvs [ i ] ;
2018-06-13 09:50:24 +00:00
// not spawned yet etc.?
if ( ! uv . gameObject . activeSelf & &
uv . gameObject . hideFlags ! = HideFlags . NotEditable & & uv . gameObject . hideFlags ! = HideFlags . HideAndDontSave & &
! uv . sceneId . IsEmpty ( ) )
2018-06-07 13:41:08 +00:00
{
2018-06-13 09:50:24 +00:00
s_SpawnableObjects [ uv . sceneId ] = uv ;
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::PrepareSpawnObjects sceneId:" + uv . sceneId ) ; }
2018-06-07 13:41:08 +00:00
}
}
}
internal static NetworkIdentity SpawnSceneObject ( NetworkSceneId sceneId )
{
if ( s_SpawnableObjects . ContainsKey ( sceneId ) )
{
NetworkIdentity foundId = s_SpawnableObjects [ sceneId ] ;
s_SpawnableObjects . Remove ( sceneId ) ;
return foundId ;
}
return null ;
}
static internal void RegisterSystemHandlers ( NetworkClient client , bool localClient )
{
if ( localClient )
{
client . RegisterHandlerSafe ( MsgType . ObjectDestroy , OnLocalClientObjectDestroy ) ;
client . RegisterHandlerSafe ( MsgType . ObjectHide , OnLocalClientObjectHide ) ;
client . RegisterHandlerSafe ( MsgType . ObjectSpawn , OnLocalClientObjectSpawn ) ;
client . RegisterHandlerSafe ( MsgType . ObjectSpawnScene , OnLocalClientObjectSpawnScene ) ;
client . RegisterHandlerSafe ( MsgType . LocalClientAuthority , OnClientAuthority ) ;
}
else
{
// LocalClient shares the sim/scene with the server, no need for these events
client . RegisterHandlerSafe ( MsgType . ObjectSpawn , OnObjectSpawn ) ;
client . RegisterHandlerSafe ( MsgType . ObjectSpawnScene , OnObjectSpawnScene ) ;
client . RegisterHandlerSafe ( MsgType . SpawnFinished , OnObjectSpawnFinished ) ;
client . RegisterHandlerSafe ( MsgType . ObjectDestroy , OnObjectDestroy ) ;
client . RegisterHandlerSafe ( MsgType . ObjectHide , OnObjectDestroy ) ;
client . RegisterHandlerSafe ( MsgType . UpdateVars , OnUpdateVarsMessage ) ;
client . RegisterHandlerSafe ( MsgType . Owner , OnOwnerMessage ) ;
client . RegisterHandlerSafe ( MsgType . SyncList , OnSyncListMessage ) ;
client . RegisterHandlerSafe ( MsgType . Animation , NetworkAnimator . OnAnimationClientMessage ) ;
client . RegisterHandlerSafe ( MsgType . AnimationParameters , NetworkAnimator . OnAnimationParametersClientMessage ) ;
client . RegisterHandlerSafe ( MsgType . LocalClientAuthority , OnClientAuthority ) ;
}
client . RegisterHandlerSafe ( MsgType . Rpc , OnRPCMessage ) ;
client . RegisterHandlerSafe ( MsgType . SyncEvent , OnSyncEventMessage ) ;
client . RegisterHandlerSafe ( MsgType . AnimationTrigger , NetworkAnimator . OnAnimationTriggerClientMessage ) ;
}
// ------------------------ NetworkScene pass-throughs ---------------------
static internal string GetStringForAssetId ( NetworkHash128 assetId )
{
GameObject prefab ;
if ( NetworkScene . GetPrefab ( assetId , out prefab ) )
{
return prefab . name ;
}
SpawnDelegate handler ;
if ( NetworkScene . GetSpawnHandler ( assetId , out handler ) )
{
return handler . GetMethodName ( ) ;
}
return "unknown" ;
}
// this assigns the newAssetId to the prefab. This is for registering dynamically created game objects for already know assetIds.
static public void RegisterPrefab ( GameObject prefab , NetworkHash128 newAssetId )
{
NetworkScene . RegisterPrefab ( prefab , newAssetId ) ;
}
static public void RegisterPrefab ( GameObject prefab )
{
NetworkScene . RegisterPrefab ( prefab ) ;
}
static public void RegisterPrefab ( GameObject prefab , SpawnDelegate spawnHandler , UnSpawnDelegate unspawnHandler )
{
NetworkScene . RegisterPrefab ( prefab , spawnHandler , unspawnHandler ) ;
}
static public void UnregisterPrefab ( GameObject prefab )
{
NetworkScene . UnregisterPrefab ( prefab ) ;
}
static public void RegisterSpawnHandler ( NetworkHash128 assetId , SpawnDelegate spawnHandler , UnSpawnDelegate unspawnHandler )
{
NetworkScene . RegisterSpawnHandler ( assetId , spawnHandler , unspawnHandler ) ;
}
static public void UnregisterSpawnHandler ( NetworkHash128 assetId )
{
NetworkScene . UnregisterSpawnHandler ( assetId ) ;
}
static public void ClearSpawners ( )
{
NetworkScene . ClearSpawners ( ) ;
}
static public void DestroyAllClientObjects ( )
{
s_NetworkScene . DestroyAllClientObjects ( ) ;
}
static public void SetLocalObject ( NetworkInstanceId netId , GameObject obj )
{
// if still receiving initial state, dont set isClient
s_NetworkScene . SetLocalObject ( netId , obj , s_IsSpawnFinished , false ) ;
}
static public GameObject FindLocalObject ( NetworkInstanceId netId )
{
return s_NetworkScene . FindLocalObject ( netId ) ;
}
static void ApplySpawnPayload ( NetworkIdentity uv , Vector3 position , byte [ ] payload , NetworkInstanceId netId , GameObject newGameObject )
{
if ( ! uv . gameObject . activeSelf )
{
uv . gameObject . SetActive ( true ) ;
}
uv . transform . position = position ;
if ( payload ! = null & & payload . Length > 0 )
{
var payloadReader = new NetworkReader ( payload ) ;
uv . OnUpdateVars ( payloadReader , true ) ;
}
if ( newGameObject = = null )
{
return ;
}
newGameObject . SetActive ( true ) ;
uv . SetNetworkInstanceId ( netId ) ;
SetLocalObject ( netId , newGameObject ) ;
// objects spawned as part of initial state are started on a second pass
if ( s_IsSpawnFinished )
{
uv . OnStartClient ( ) ;
CheckForOwner ( uv ) ;
}
}
static void OnObjectSpawn ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
ObjectSpawnMessage msg = new ObjectSpawnMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
2018-06-07 13:41:08 +00:00
2018-06-10 08:00:46 +00:00
if ( ! msg . assetId . IsValid ( ) )
2018-06-07 13:41:08 +00:00
{
2018-06-10 08:00:46 +00:00
if ( LogFilter . logError ) { Debug . LogError ( "OnObjSpawn netId: " + msg . netId + " has invalid asset Id" ) ; }
2018-06-07 13:41:08 +00:00
return ;
}
2018-06-10 08:00:46 +00:00
if ( LogFilter . logDebug ) { Debug . Log ( "Client spawn handler instantiating [netId:" + msg . netId + " asset ID:" + msg . assetId + " pos:" + msg . position + "]" ) ; }
2018-06-07 13:41:08 +00:00
#if UNITY_EDITOR
UnityEditor . NetworkDetailStats . IncrementStat (
UnityEditor . NetworkDetailStats . NetworkDirection . Incoming ,
2018-06-10 08:00:46 +00:00
MsgType . ObjectSpawn , GetStringForAssetId ( msg . assetId ) , 1 ) ;
2018-06-07 13:41:08 +00:00
#endif
NetworkIdentity localNetworkIdentity ;
2018-06-10 08:00:46 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( msg . netId , out localNetworkIdentity ) )
2018-06-07 13:41:08 +00:00
{
// this object already exists (was in the scene), just apply the update to existing object
2018-06-29 00:05:20 +00:00
localNetworkIdentity . Reset ( ) ;
2018-06-10 08:00:46 +00:00
ApplySpawnPayload ( localNetworkIdentity , msg . position , msg . payload , msg . netId , null ) ;
2018-06-07 13:41:08 +00:00
return ;
}
GameObject prefab ;
SpawnDelegate handler ;
2018-06-10 08:00:46 +00:00
if ( NetworkScene . GetPrefab ( msg . assetId , out prefab ) )
2018-06-07 13:41:08 +00:00
{
2018-06-10 08:00:46 +00:00
var obj = ( GameObject ) Object . Instantiate ( prefab , msg . position , msg . rotation ) ;
2018-06-07 13:41:08 +00:00
if ( LogFilter . logDebug )
{
2018-06-10 08:00:46 +00:00
Debug . Log ( "Client spawn handler instantiating [netId:" + msg . netId + " asset ID:" + msg . assetId + " pos:" + msg . position + " rotation: " + msg . rotation + "]" ) ;
2018-06-07 13:41:08 +00:00
}
localNetworkIdentity = obj . GetComponent < NetworkIdentity > ( ) ;
if ( localNetworkIdentity = = null )
{
2018-06-10 08:00:46 +00:00
if ( LogFilter . logError ) { Debug . LogError ( "Client object spawned for " + msg . assetId + " does not have a NetworkIdentity" ) ; }
2018-06-07 13:41:08 +00:00
return ;
}
localNetworkIdentity . Reset ( ) ;
2018-06-10 08:00:46 +00:00
ApplySpawnPayload ( localNetworkIdentity , msg . position , msg . payload , msg . netId , obj ) ;
2018-06-07 13:41:08 +00:00
}
// lookup registered factory for type:
2018-06-10 08:00:46 +00:00
else if ( NetworkScene . GetSpawnHandler ( msg . assetId , out handler ) )
2018-06-07 13:41:08 +00:00
{
2018-06-10 08:00:46 +00:00
GameObject obj = handler ( msg . position , msg . assetId ) ;
2018-06-07 13:41:08 +00:00
if ( obj = = null )
{
2018-06-10 08:00:46 +00:00
if ( LogFilter . logWarn ) { Debug . LogWarning ( "Client spawn handler for " + msg . assetId + " returned null" ) ; }
2018-06-07 13:41:08 +00:00
return ;
}
localNetworkIdentity = obj . GetComponent < NetworkIdentity > ( ) ;
if ( localNetworkIdentity = = null )
{
2018-06-10 08:00:46 +00:00
if ( LogFilter . logError ) { Debug . LogError ( "Client object spawned for " + msg . assetId + " does not have a network identity" ) ; }
2018-06-07 13:41:08 +00:00
return ;
}
localNetworkIdentity . Reset ( ) ;
2018-06-10 08:00:46 +00:00
localNetworkIdentity . SetDynamicAssetId ( msg . assetId ) ;
ApplySpawnPayload ( localNetworkIdentity , msg . position , msg . payload , msg . netId , obj ) ;
2018-06-07 13:41:08 +00:00
}
else
{
2018-06-10 08:00:46 +00:00
if ( LogFilter . logError ) { Debug . LogError ( "Failed to spawn server object, did you forget to add it to the NetworkManager? assetId=" + msg . assetId + " netId=" + msg . netId ) ; }
2018-06-07 13:41:08 +00:00
}
}
static void OnObjectSpawnScene ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
ObjectSpawnSceneMessage msg = new ObjectSpawnSceneMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
2018-06-07 13:41:08 +00:00
2018-06-10 08:00:46 +00:00
if ( LogFilter . logDebug ) { Debug . Log ( "Client spawn scene handler instantiating [netId:" + msg . netId + " sceneId:" + msg . sceneId + " pos:" + msg . position ) ; }
2018-06-07 13:41:08 +00:00
#if UNITY_EDITOR
UnityEditor . NetworkDetailStats . IncrementStat (
UnityEditor . NetworkDetailStats . NetworkDirection . Incoming ,
MsgType . ObjectSpawnScene , "sceneId" , 1 ) ;
#endif
NetworkIdentity localNetworkIdentity ;
2018-06-10 08:00:46 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( msg . netId , out localNetworkIdentity ) )
2018-06-07 13:41:08 +00:00
{
// this object already exists (was in the scene)
2018-06-29 00:05:20 +00:00
localNetworkIdentity . Reset ( ) ;
2018-06-10 08:00:46 +00:00
ApplySpawnPayload ( localNetworkIdentity , msg . position , msg . payload , msg . netId , localNetworkIdentity . gameObject ) ;
2018-06-07 13:41:08 +00:00
return ;
}
2018-06-10 08:00:46 +00:00
NetworkIdentity spawnedId = SpawnSceneObject ( msg . sceneId ) ;
2018-06-07 13:41:08 +00:00
if ( spawnedId = = null )
{
2018-06-08 08:59:32 +00:00
if ( LogFilter . logError )
{
2018-06-10 08:00:46 +00:00
Debug . LogError ( "Spawn scene object not found for " + msg . sceneId + " SpawnableObjects.Count=" + s_SpawnableObjects . Count ) ;
2018-06-08 08:59:32 +00:00
// dump the whole spawnable objects dict for easier debugging
foreach ( var kvp in s_SpawnableObjects )
Debug . Log ( "Spawnable: SceneId=" + kvp . Key + " name=" + kvp . Value . name ) ;
}
2018-06-07 13:41:08 +00:00
return ;
}
2018-06-10 08:00:46 +00:00
if ( LogFilter . logDebug ) { Debug . Log ( "Client spawn for [netId:" + msg . netId + "] [sceneId:" + msg . sceneId + "] obj:" + spawnedId . gameObject . name ) ; }
2018-06-29 00:05:20 +00:00
spawnedId . Reset ( ) ;
2018-06-10 08:00:46 +00:00
ApplySpawnPayload ( spawnedId , msg . position , msg . payload , msg . netId , spawnedId . gameObject ) ;
2018-06-07 13:41:08 +00:00
}
static void OnObjectSpawnFinished ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
ObjectSpawnFinishedMessage msg = new ObjectSpawnFinishedMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
if ( LogFilter . logDebug ) { Debug . Log ( "SpawnFinished:" + msg . state ) ; }
2018-06-07 13:41:08 +00:00
2018-06-10 08:00:46 +00:00
if ( msg . state = = 0 )
2018-06-07 13:41:08 +00:00
{
PrepareToSpawnSceneObjects ( ) ;
s_IsSpawnFinished = false ;
return ;
}
foreach ( var uv in objects . Values )
{
if ( ! uv . isClient )
{
uv . OnStartClient ( ) ;
CheckForOwner ( uv ) ;
}
}
s_IsSpawnFinished = true ;
}
static void OnObjectDestroy ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
ObjectDestroyMessage msg = new ObjectDestroyMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::OnObjDestroy netId:" + msg . netId ) ; }
2018-06-07 13:41:08 +00:00
NetworkIdentity localObject ;
2018-06-10 08:00:46 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( msg . netId , out localObject ) )
2018-06-07 13:41:08 +00:00
{
#if UNITY_EDITOR
UnityEditor . NetworkDetailStats . IncrementStat (
UnityEditor . NetworkDetailStats . NetworkDirection . Incoming ,
MsgType . ObjectDestroy , GetStringForAssetId ( localObject . assetId ) , 1 ) ;
#endif
localObject . OnNetworkDestroy ( ) ;
if ( ! NetworkScene . InvokeUnSpawnHandler ( localObject . assetId , localObject . gameObject ) )
{
// default handling
if ( localObject . sceneId . IsEmpty ( ) )
{
Object . Destroy ( localObject . gameObject ) ;
}
else
{
// scene object.. disable it in scene instead of destroying
localObject . gameObject . SetActive ( false ) ;
s_SpawnableObjects [ localObject . sceneId ] = localObject ;
}
}
2018-06-10 08:00:46 +00:00
s_NetworkScene . RemoveLocalObject ( msg . netId ) ;
2018-06-07 13:41:08 +00:00
localObject . MarkForReset ( ) ;
}
else
{
2018-06-10 08:00:46 +00:00
if ( LogFilter . logDebug ) { Debug . LogWarning ( "Did not find target for destroy message for " + msg . netId ) ; }
2018-06-07 13:41:08 +00:00
}
}
static void OnLocalClientObjectDestroy ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
ObjectDestroyMessage msg = new ObjectDestroyMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::OnLocalObjectObjDestroy netId:" + msg . netId ) ; }
2018-06-07 13:41:08 +00:00
2018-06-10 08:00:46 +00:00
s_NetworkScene . RemoveLocalObject ( msg . netId ) ;
2018-06-07 13:41:08 +00:00
}
static void OnLocalClientObjectHide ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
ObjectDestroyMessage msg = new ObjectDestroyMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::OnLocalObjectObjHide netId:" + msg . netId ) ; }
2018-06-07 13:41:08 +00:00
NetworkIdentity localObject ;
2018-06-10 08:00:46 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( msg . netId , out localObject ) )
2018-06-07 13:41:08 +00:00
{
localObject . OnSetLocalVisibility ( false ) ;
}
}
static void OnLocalClientObjectSpawn ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
ObjectSpawnMessage msg = new ObjectSpawnMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
2018-06-07 13:41:08 +00:00
NetworkIdentity localObject ;
2018-06-10 08:00:46 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( msg . netId , out localObject ) )
2018-06-07 13:41:08 +00:00
{
localObject . OnSetLocalVisibility ( true ) ;
}
}
static void OnLocalClientObjectSpawnScene ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
ObjectSpawnSceneMessage msg = new ObjectSpawnSceneMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
2018-06-07 13:41:08 +00:00
NetworkIdentity localObject ;
2018-06-10 08:00:46 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( msg . netId , out localObject ) )
2018-06-07 13:41:08 +00:00
{
localObject . OnSetLocalVisibility ( true ) ;
}
}
static void OnUpdateVarsMessage ( NetworkMessage netMsg )
{
NetworkInstanceId netId = netMsg . reader . ReadNetworkId ( ) ;
if ( LogFilter . logDev ) { Debug . Log ( "ClientScene::OnUpdateVarsMessage " + netId + " channel:" + netMsg . channelId ) ; }
NetworkIdentity localObject ;
if ( s_NetworkScene . GetNetworkIdentity ( netId , out localObject ) )
{
localObject . OnUpdateVars ( netMsg . reader , false ) ;
}
else
{
2018-06-08 10:06:04 +00:00
if ( LogFilter . logWarn ) { Debug . LogWarning ( "Did not find target for sync message for " + netId + " . Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message." ) ; }
2018-06-07 13:41:08 +00:00
}
}
static void OnRPCMessage ( NetworkMessage netMsg )
{
var cmdHash = ( int ) netMsg . reader . ReadPackedUInt32 ( ) ;
var netId = netMsg . reader . ReadNetworkId ( ) ;
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::OnRPCMessage hash:" + cmdHash + " netId:" + netId ) ; }
NetworkIdentity uv ;
if ( s_NetworkScene . GetNetworkIdentity ( netId , out uv ) )
{
uv . HandleRPC ( cmdHash , netMsg . reader ) ;
}
else
{
if ( LogFilter . logWarn )
{
string errorCmdName = NetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) ;
Debug . LogWarningFormat ( "Could not find target object with netId:{0} for RPC call {1}" , netId , errorCmdName ) ;
}
}
}
static void OnSyncEventMessage ( NetworkMessage netMsg )
{
var cmdHash = ( int ) netMsg . reader . ReadPackedUInt32 ( ) ;
var netId = netMsg . reader . ReadNetworkId ( ) ;
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::OnSyncEventMessage " + netId ) ; }
NetworkIdentity uv ;
if ( s_NetworkScene . GetNetworkIdentity ( netId , out uv ) )
{
uv . HandleSyncEvent ( cmdHash , netMsg . reader ) ;
}
else
{
if ( LogFilter . logWarn ) { Debug . LogWarning ( "Did not find target for SyncEvent message for " + netId ) ; }
}
#if UNITY_EDITOR
UnityEditor . NetworkDetailStats . IncrementStat (
UnityEditor . NetworkDetailStats . NetworkDirection . Outgoing ,
MsgType . SyncEvent , NetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) , 1 ) ;
#endif
}
static void OnSyncListMessage ( NetworkMessage netMsg )
{
var netId = netMsg . reader . ReadNetworkId ( ) ;
var cmdHash = ( int ) netMsg . reader . ReadPackedUInt32 ( ) ;
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::OnSyncListMessage " + netId ) ; }
NetworkIdentity uv ;
if ( s_NetworkScene . GetNetworkIdentity ( netId , out uv ) )
{
uv . HandleSyncList ( cmdHash , netMsg . reader ) ;
}
else
{
if ( LogFilter . logWarn ) { Debug . LogWarning ( "Did not find target for SyncList message for " + netId ) ; }
}
#if UNITY_EDITOR
UnityEditor . NetworkDetailStats . IncrementStat (
UnityEditor . NetworkDetailStats . NetworkDirection . Outgoing ,
MsgType . SyncList , NetworkBehaviour . GetCmdHashHandlerName ( cmdHash ) , 1 ) ;
#endif
}
static void OnClientAuthority ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
ClientAuthorityMessage msg = new ClientAuthorityMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
2018-06-07 13:41:08 +00:00
2018-06-10 08:00:46 +00:00
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::OnClientAuthority for connectionId=" + netMsg . conn . connectionId + " netId: " + msg . netId ) ; }
2018-06-07 13:41:08 +00:00
NetworkIdentity uv ;
2018-06-10 08:00:46 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( msg . netId , out uv ) )
2018-06-07 13:41:08 +00:00
{
2018-06-10 08:00:46 +00:00
uv . HandleClientAuthority ( msg . authority ) ;
2018-06-07 13:41:08 +00:00
}
}
// OnClientAddedPlayer?
static void OnOwnerMessage ( NetworkMessage netMsg )
{
2018-06-10 08:00:46 +00:00
OwnerMessage msg = new OwnerMessage ( ) ;
netMsg . ReadMessage ( msg ) ;
2018-06-07 13:41:08 +00:00
2018-06-10 08:00:46 +00:00
if ( LogFilter . logDebug ) { Debug . Log ( "ClientScene::OnOwnerMessage - connectionId=" + netMsg . conn . connectionId + " netId: " + msg . netId ) ; }
2018-06-07 13:41:08 +00:00
// is there already an owner that is a different object??
PlayerController oldOwner ;
2018-06-10 08:00:46 +00:00
if ( netMsg . conn . GetPlayerController ( msg . playerControllerId , out oldOwner ) )
2018-06-07 13:41:08 +00:00
{
oldOwner . unetView . SetNotLocalPlayer ( ) ;
}
NetworkIdentity localNetworkIdentity ;
2018-06-10 08:00:46 +00:00
if ( s_NetworkScene . GetNetworkIdentity ( msg . netId , out localNetworkIdentity ) )
2018-06-07 13:41:08 +00:00
{
// this object already exists
localNetworkIdentity . SetConnectionToServer ( netMsg . conn ) ;
2018-06-10 08:00:46 +00:00
localNetworkIdentity . SetLocalPlayer ( msg . playerControllerId ) ;
InternalAddPlayer ( localNetworkIdentity , msg . playerControllerId ) ;
2018-06-07 13:41:08 +00:00
}
else
{
2018-06-10 08:00:46 +00:00
var pendingOwner = new PendingOwner { netId = msg . netId , playerControllerId = msg . playerControllerId } ;
2018-06-07 13:41:08 +00:00
s_PendingOwnerIds . Add ( pendingOwner ) ;
}
}
static void CheckForOwner ( NetworkIdentity uv )
{
for ( int i = 0 ; i < s_PendingOwnerIds . Count ; i + + )
{
var pendingOwner = s_PendingOwnerIds [ i ] ;
if ( pendingOwner . netId = = uv . netId )
{
// found owner, turn into a local player
// Set isLocalPlayer to true on this NetworkIdentity and trigger OnStartLocalPlayer in all scripts on the same GO
uv . SetConnectionToServer ( s_ReadyConnection ) ;
uv . SetLocalPlayer ( pendingOwner . playerControllerId ) ;
if ( LogFilter . logDev ) { Debug . Log ( "ClientScene::OnOwnerMessage - player=" + uv . gameObject . name ) ; }
if ( s_ReadyConnection . connectionId < 0 )
{
if ( LogFilter . logError ) { Debug . LogError ( "Owner message received on a local client." ) ; }
return ;
}
InternalAddPlayer ( uv , pendingOwner . playerControllerId ) ;
s_PendingOwnerIds . RemoveAt ( i ) ;
break ;
}
}
}
}
}
#endif //ENABLE_UNET