日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UNet详解(转)

發布時間:2024/8/23 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UNet详解(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Unity Networking(UNet)函數時序統計和分析

背景和概述

Unity Networking是官方自Unity5.1以來推出的新網絡通信解決方案。UNet是非官方但更民間更精簡的叫法。

本文需要讀者有基礎的UNet知識。

了解UNet時序,可以更好更嚴謹地編寫UNet相關的業務邏輯代碼。
本文針對UNet的HLAPI進行時序統計和分析。
本文可作為工具文檔,需要時可進行時序查閱。

在有時序統計的基礎上,本文再參考Unity Networking 5.3源代碼(Bitbucket網站可能需要翻墻)進行整合分析,可以幫助了解底層發生的具體邏輯。

當前將Unity(就算是Headless)運行在Linux服務器上,會出現一定的性能問題。聯系咨詢過Unity內部開發同學Ian和一位和藹大胖子,獲知Headless所剔除的功能模塊并不多,僅僅是最終不提交(也不能提交)到GPU、DSP而已。原話是“Modulization is hard”、“Should not run Unity on the server”。
所以當前,應避免粗暴地將Unity運行在“關鍵”服務器上。

  • 應從業務層著手剔除Headless模式下所啟用的業務功能(如模型、渲染、物理、音效等)
  • 將Unity運行于“非關鍵”服務器(比如用于外掛分析,等)是可能可行的
  • 將Unity無狀態地運行,多“關鍵”服務器(比如用于戰斗)共享該Unity服務器,是有成功案例的
  • 但粗暴地每一局游戲都在服務器運行一個Unity進程是欠妥的

可惜的是,UNet的默認思路正是最后一種。由于Ian并非UNet Team的開發同學,所以其并不十分了解將于Unity5.4(但被delay了)的Server Library所完成的功能。但一種推測是,Server Library正是為了避免將Unity運行于服務器,而是提供UNet、Unity的基礎功能(Math等),讓我們服務器同學利用UNet接口,重新實現邏輯。

測試方法

測試Unity版本為5.3.1。運行平臺是OSX。
測試NetworkManager通過NBNetworkManager繼承并override掉關鍵函數;測試Player的Prefab名字為NBPlayer。通過在這個Prefab加上測試腳本TestNetworkBehaviour進行日志輸出。
通過分析日志,可以統計UNet函數的時序。


函數時序概括

以下為關鍵函數的羅列,以供快速查詢之用。
如需可細看下一章節的詳細文檔及分析。

Dedicated Server情況

NetworkManagerNetworkBehaviour
Server初始化階段Server初始化階段
Awake()?
Start()?
OnStartServer()?
ServerChangeScene()?
OnServerSceneChanged()?
Client初始化階段Client初始化階段
OnServerConnect()?
OnServerReady()?
Player初始化階段Player初始化階段
OnServerAddPlayer()?
?Awake()
?OnEnable()
?OnStartServer()
?OnRebuildObservers()
?OnSerialize()(多次)
?Start()
Player運轉階段Player運轉階段
?FixedUpdate()(多次)
?Update()(多次)
?OnSerialize()(多次)
Player銷毀階段Player銷毀階段
?OnDisable()
?OnDestroy()
OnServerDisconnect?
Server銷毀階段Server銷毀階段
OnStopServer()?

Remote Client情況

NetworkManagerNetworkBehaviour
Client初始化階段Client初始化階段
Awake()?
Start()?
OnStartClient()?
OnClientConnect()?
OnClientSceneChanged()?
Player初始化階段Player初始化階段
?Awake()
?OnEnable()
?OnDeserialize()
?PreStartClient()
?OnStartClient()
?OnStartLocalPlayer()
?OnStartAuthority()
(后面運轉階段也可能調到)
?OnDeserialize()(多次)
?Start()
Player運轉階段Player運轉階段
?FixedUpdate()(多次)
?Update()(多次)
?OnDeserialize()(多次)
Player銷毀階段Player銷毀階段
?OnNetworkDestroy()
?OnDisable()
?OnDestroy()
Client銷毀階段Client銷毀階段
OnStopClient()?

Host情況

NetworkManagerNetworkBehaviour
Host初始化階段Host初始化階段
Awake()?
Start()?
OnStartHost()?
OnStartServer()?
ServerChangeScene()?
OnServerConnect()
(LocalClient混雜進來的Server函數)
?
OnStartClient()
(LocalClient混雜進來的Client函數)
?
OnClientConnect()
(LocalClient混雜進來的Client函數)
?
OnServerSceneChanged()?
OnClientSceneChanged()
(LocalClient混雜進來的Client函數)
?
OnServerReady()
(LocalClient混雜進來的Server函數)
?
OnServerAddPlayer()
(LocalClient混雜進來的Server函數)
?
OnServerConnect()?
OnServerReady()?
Player初始化階段Player初始化階段
OnServerAddPlayer()?
?Awake()
?OnEnable()
?OnStartServer()
?PreStartClient()
?OnStartClient()
?OnRebuildObservers()
?OnSerialize()(多次)
?OnSetLocalVisibility()
?Start()
Player運轉階段Player運轉階段
?FixedUpdate()(多次)
?Update()(多次)
?OnSerialize()(多次)
Player銷毀階段Player銷毀階段
?OnNetworkDestroy()
?OnDisable()
?OnDestroy()
OnServerDisconnect?
Host銷毀階段Host銷毀階段
OnStopHost()?
OnStopServer()?
ServerChangeScene()
(LocalClient混雜進來的Server函數)
?
OnStopClient()
(LocalClient混雜進來的Client函數)
?

函數時序的詳細文檔及分析

以下為嚴格按照時間次序進行羅列的UNet函數時序,附上官方文檔。重要地方也結合源碼進行解釋。

Dedicated Server情況

Dedicated Server的Server初始化階段

NetworkManager.Awake()
NetworkManager目前的Awake()(被不好地設計)為非virtual的私有方法。所以子類應注意不能再定義Awake(),否則將hide掉基類的Awake()。

NetworkManager.Start()

NetworkManager (NewBorn.NBNetworkManager).Start()

NetworkManager.OnStartServer()

public void OnStartServer();
Description
This hook is invoked when a server is started - including when a host is started.
StartServer has multiple signatures, but they all cause this hook to be called.

Server初始化函數。調用肯定比看似相似的OnStartClient()早。
注意在OnStartServer()之后,才進行網絡Connect的初始化、才進行場景的切換。

NetworkManager (NewBorn.NBNetworkManager).OnStartServer()

NetworkManager.ServerChangeScene()

public void ServerChangeScene(string newSceneName);
Parameters
newSceneName?The name of the scene to change to. The server will change scene immediately, and a message will be sent to connected clients to ask them to change scene also.
Description
This causes the server to switch scenes and sets the networkSceneName.
Clients that connect to this server will automatically switch to this scene. This is called autmatically if onlineScene or offlineScene are set, but it can be called from user code to switch scenes again while the game is in progress. This automatically sets clients to be not-ready. The clients must call NetworkClient.Ready() again to participate in the new scene.

StartServer()里、OnStartServer()之后,調用ServerChangeScene()進行場景切換。之后在任意時刻,也可以手動調用它進行中途的場景切換。
在ServerChangeScene()里,會發出MsgType.Scene通知當前已連接上的Client也進行場景的切換。

  • Battle_Demo_Official

  • NetworkManager (NewBorn.NBNetworkManager).ServerChangeScene()

  • NetworkManager.OnServerSceneChanged()

    public void OnServerSceneChanged(string sceneName);
    Parameters
    sceneName?The name of the new scene.
    Description
    Called on the server when a scene is completed loaded, when the scene load was initiated by the server with ServerChangeScene().

    Server完成場景切換后的一個回調。
    在本回調之前,Server會收集場景所有已有NetworkIdentity的GameObject,并發出Spawn的Message,從而通知已連接上的Client進行Spawn。

  • Battle_Demo_Official

  • NetworkManager (NewBorn.NBNetworkManager).OnServerSceneChanged()

  • 2016-01-01T10:57:28.8472060+08:00

  • 至此,Server的初始化階段結束。之后(通過上面的時間10:57:28和下面的時間11:04:10就可以看出時間差),當有Client連接進Server的時候,函數流程就進入該Client的初始化階段。

    Dedicated Server的Client初始化階段

    NetworkManager.OnServerConnect()

    public void OnServerConnect(Networking.NetworkConnection conn);
    Parameters
    conn?Connection from client.
    Description
    Called on the server when a new client connects.

    新玩家新Client和Server建立連接后的回調函數。
    Client剛連接上來,第一個問題肯定是“我現在在什么場景?”。所以在本回調之前,Server會發出MsgType.Scene,通知客戶端進行場景加載。

  • hostId: 0 connectionId: 1 isReady: False channel count: 2

  • NetworkManager (NewBorn.NBNetworkManager).OnServerConnect()

  • 2016-01-01T11:04:10.7621350+08:00

  • NetworkManager.OnServerReady()

    public void OnServerReady(Networking.NetworkConnection conn);
    Parameters
    conn?Connection from client.
    Description
    Called on the server when a client is ready.
    The default implementation of this function calls NetworkServer.SetClientReady() to continue the network setup process

    當Client“準備好”(加載好場景,一些自定義的初始化)后,需要發送MsgType.Ready給Server。
    Server收到這個Message了之后,就會調用本OnServerReady()函數。
    Client準備好了之后,接著問題是“我Client當前場景有什么網絡對象可見和需要同步?”
    所以在OnServerReady()里會調用NetworkServer.SetClientReady(),進行該Client的可見性檢測,然后在NetworkServer.SendSpawnMessage()里下發MsgType.ObjectSpawn進行Spawn。

  • hostId: 0 connectionId: 1 isReady: False channel count: 2

  • NetworkManager (NewBorn.NBNetworkManager).OnServerReady()

  • 至此,Client已經連接好、加載好場景、同步好已有的網絡對象。
    所以Server將進入Player初始化階段。

    Dedicated Server的Player初始化階段

    NetworkManager.OnServerAddPlayer()

    public void OnServerAddPlayer(Networking.NetworkConnection conn, short playerControllerId);
    Parameters
    conn?Connection from client.
    playerControllerId?Id of the new player.
    extraMessageReader?An extra message object passed for the new player.
    Description
    Called on the server when a client adds a new player with ClientScene.AddPlayer.
    The default implementation for this function creates a new player object from the playerPrefab.

    新連接上來的Client連接好了、場景準備好了、其他有NetworkIdentity的GameObject同步好了,接下來準備為該Client準備屬于它自己的Player了。
    通過調用ClientScene.AddPlayer()發出MsgType.AddPlayer可以通知服務器添加屬于該connection的Player,然后Server就響應該Message會調用OnServerAddPlayer()。
    用戶可以在OnServerAddPlayer()自定義新建Player的邏輯,包括直接Instantiate新Player、或者從自己的Spawn機制里取出Player、給Player修改初始化屬性等。
    然后,在OnServerAddPlayer()里就會調用NetworkServer.AddPlayerForConnection(),繼而一系列初始化Player邏輯(生成netId、決定Observer、收集SyncVar、發送MsgType.Spawn給Client),通知Client真正去創建Player。

  • hostId: 0 connectionId: 1 isReady: True channel count: 2, 0

  • NetworkManager (NewBorn.NBNetworkManager).OnServerAddPlayer()

  • 至此,Player的Prefab在Server已被Instantiate出來,繼而調用

    • NetworkServer.AddPlayerForConnection()、
    • NetworkServer.FinishPlayerForConnection()
    • NetworkServer.SpawnObject()

    等函數,正式開始NetworkIdentity/NetworkBehaviour的函數流程。
    NetworkBehaviour和NetworkIdentity是相互依存的。許多NetworkBehaviour的UNet相關函數事實上都是在其配對的NetworkIdentity中被NetworkIdentity所觸發調用的。

    NetworkBehaviour.Awake()
    留意到這次測試Player的GameObject的instanceID是-10746。

    只有localPlayerAuthority=True
    這個UNet配置變量是合法的。其他UNet變量都是非法的。

  • go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=0

  • playerControllerId=-1

  • connectionToClient=

  • connectionToServer=

  • isClient=False

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).Awake()

  • NetworkBehaviour.OnEnable()

  • go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=0

  • playerControllerId=-1

  • connectionToClient=

  • connectionToServer=

  • isClient=False

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnEnable()

  • NetworkBehaviour.OnStartServer()

    public void OnStartServer();
    Description
    This hook is invoked when a server is started - including when a host is started.
    StartServer has multiple signatures, but they all cause this hook to be called.

    在NetworkIdentity.OnStartServer()里,

    • 會cache住NetworkIdentity所同GameObject的所有NetworkBehaviour
    • 會生成netId給自己
    • 通過NetworkServer.instance.SetLocalObjectOnServer(),更新isServer的標志位
    • 調用這些NetworkBehaviour的OnStartServer()函數。

    所以這個時候,netId和isServer合法了。

  • go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 2 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnStartServer()

  • NetworkBehaviour.OnRebuildObservers()

    public bool OnRebuildObservers(HashSet<NetworkConnection> observers, bool initialize);
    Parameters
    observers?The new set of observers for this object.
    initialize?True if the set of observers is being built for the first time.
    Returns
    bool?Return true if this function did work.
    Description
    Callback used by the visibility system to (re)construct the set of observers that can see this object.
    Implementations of this callback should add network connections of players that can see this object to the observers set.

    這個新的NetworkIdentity在Server創建了,但哪些Client是其真正的“觀察者”(Observer)呢?只有這些觀察者Client,才需要在他們的運行時里創建這個新NetworkIdentity及其GameObject。

    NetworkIdentity會調用其所有NetworkBehaviour的OnRebuildObservers()。
    默認情況下,是當前已連接的所有Client都能觀察到這個新NetworkIdentity。
    但如果有NetworkBehaviour的OnRebuildObservers()返回了true,則以HashSet<NetworkConnection> observers里存在的連接作為Observer。

  • observers=System.Collections.Generic.HashSet`1[UnityEngine.Networking.NetworkConnection], initialize=True,

  • go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 2 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnRebuildObservers()

  • NetworkBehaviour.OnSerialize()

    public bool OnSerialize(Networking.NetworkWriter writer, bool initialState);
    Parameters
    writer?Writer to use to write to the stream.
    initialState?If this is being called to send initial state.
    Returns
    bool?True if data was written.
    Description
    Virtual function to override to send custom serialization data.

    決定了Observer后、給這些Observer發送MsgType.Spawn之前,需要在Server把這個新NetworkIdentity的GameObject的所有同步屬性進行序列化。

    OnSerialize()和OnDeserialize()
    是用于自定義NetworkBehaviour中變量的序列化和反序列化的虛函數。前者必然是只在Server被調用、后者必然是只在Client被調用。
    事實上,[SyncVar]修飾的變量和SyncList變量都是通過編譯時UNet將這些變量的序列化反序列化邏輯自動生成在OnSerialize()和OnDeserialize()中的。
    所以要注意,如果你在NetworkBehaviour中顯式override掉了這兩個函數,則該NetworkBehaviour的[SyncVar]修飾的變量和SyncList變量都需要你自行編寫代碼實現序列化反序列化。

  • serializeCount=1, writer=UnityEngine.Networking.NetworkWriter, initialState=True,

  • go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 2 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnSerialize()

  • NetworkBehaviour.Start()

    一幀真正開始。

  • go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 2 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).Start()

  • 至此,在Dedicated Server的Player初始化階段已結束。接下來是Player運轉階段。

    Dedicated Server的Player運轉階段

    NetworkBehaviour.FixedUpdate()(多次)

  • fixedUpdateCount=22, go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 2 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).FixedUpdate()

  • NetworkBehaviour.Update()(多次)

  • updateCount=22, go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 2 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).Update()

  • NetworkBehaviour.OnSerialize()(多次)

  • serializeCount=16, writer=UnityEngine.Networking.NetworkWriter, initialState=False,

  • go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 2 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnSerialize()

  • Dedicated Server的Player銷毀階段

    通過調用NetworkServer.Destroy(gameObject);,gameObject進入銷毀階段。

    NetworkBehaviour.OnDisable()

  • go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 2 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnDisable()

  • NetworkBehaviour.OnDestroy()
    留意到所有變量皆已非法。
    留意到在Server并不會調用OnNetworkDestroy()。

  • go.instanceID=-10746,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=0

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 2 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnDestroy()

  • 至此,Player的NetworkIdentity/NetworkBehaviour流程結束。

    NetworkManager.OnServerDisconnect()

    public void OnServerDisconnect(Networking.NetworkConnection conn);
    Parameters
    conn?Connection from client.
    Description?Called on the server when a client disconnects.

  • hostId: 0 connectionId: 2 isReady: False channel count: 2

  • NetworkManager (NewBorn.NBNetworkManager).OnServerDisconnect()

  • Dedicated Server的Server銷毀階段

    略。因為在Server kill掉Unity不能及時輸出日志。

    至此,Player的整個Dedicated Server流程結束。


    Remote Client情況

    在上面已有Dedicated Server情況的前提下,Remote Client情況將適度從簡,僅針對差異性進行描述。

    Remote Client的Client初始化階段

    NetworkManager.Awake()
    NetworkManager目前的Awake()(被不好地設計)為非virtual的私有方法。所以子類應注意不能再定義Awake(),否則將hide掉基類的Awake()。

    NetworkManager.Start()

    NetworkManager (NewBorn.NBNetworkManager).Start()

    NetworkManager.OnStartClient()

    public void OnStartClient(Networking.NetworkClient client);
    Parameters
    client?The NetworkClient object that was started.
    Description
    This is a hook that is invoked when the client is started.
    StartClient has multiple signatures, but they all cause this hook to be called.

    當調用NetworkManager.StartClient()的時候,在其內部進行:

    • Client注冊各種Client相關的MsgType監聽(MsgType.Connect/Disconnect/Scene/)
    • 連接,
    • 然后會調用OnStartClient()。
  • UnityEngine.Networking.NetworkClient

  • NetworkManager (NewBorn.NBNetworkManager).OnStartClient()

  • Client連接成功后,第一個問題肯定是“我現在在什么場景?”。通過之前Dedicated Server情況的分析可知,Server會在Client連接成功后、OnServerConnect()之前通過MsgType.Scene通知客戶端切換場景。
    所以此時之后,Client將進行場景加載并成功。

    BattleStarter.Awake()(場景中本就有的GameObject)

    BattleStarter (NewBorn.BattleStarter).Awake()

    GlobalObject.OnLevelWasLoaded()(加載場景前就DontDestroyOnLoad的GameObject)

    GlobalObject (MoreFun.GlobalObjectComponent).OnLevelWasLoaded()

    NetworkManager.OnClientConnect()

    public void OnClientConnect(Networking.NetworkConnection conn);
    Parameters
    conn?Connection to the server.
    Description
    Called on the client when connected to a server.
    The default implementation of this function sets the client as ready and adds a player.

    當場景加載成功后,才在NetworkManager.FinishLoadScene()里調用OnClientConnect()。
    在OnClientConnect()里,當沒有OnlineScene或當前就是OnlineScene時,就會立刻調用ClientScene.Ready()告訴Server本Client已準備好。
    所以此時的isReady是False。

  • hostId: 0 connectionId: 1 isReady: False channel count: 2

  • NetworkManager (NewBorn.NBNetworkManager).OnClientConnect()

  • NetworkManager.OnClientSceneChanged()

    public void OnClientSceneChanged(Networking.NetworkConnection conn);
    Parameters
    conn?The network connection that the scene change message arrived on.
    Description
    Called on clients when a scene has completed loaded, when the scene load was initiated by the server.
    Scene changes can cause player objects to be destroyed. The default implementation of OnClientSceneChanged in the NetworkManager is to add a player object for the connection if no player object exists.

    當場景加載成功后、調用OnClientConnect()后、在NetworkManager.FinishLoadScene()里繼續調用OnClientSceneChanged()。

    OnClientSceneChanged()必然會調用ClientScene.Ready()告訴Server本Client已準備好。所以根據之前的Dedicated Server情況分析可知,Server會在OnServerReady()里會調用NetworkServer.SetClientReady(),進行該Client的可見性檢測、并進行已在Server的NetworkIdentity的GameObject進行反序列化和Spawn。
    然后,如果NetworkManager配置成AutoCreatePlayer為true,則OnClientSceneChanged()還會在本Client找不到LocalPlayer時調用ClientScene.AddPlayer(0)通知Server生成本Client的玩家。

  • hostId: 0 connectionId: 1 isReady: False channel count: 2

  • NetworkManager (NewBorn.NBNetworkManager).OnClientSceneChanged()

  • 其他Player的GameObject的其他腳本的Awake()
    因此,其他Player就會比LocalPlayer先行在本Client被Spawn出來。

  • go.instanceID=-64522

  • NBPlayer(Clone) (NewBorn.PlayerController).Awake()

  • BattleStarter.OnStartClient()
    本身就在場景里的有NetworkIdentity的GameObject也比LocalPlayer先行被Spawn出來。

    BattleStarter (NewBorn.BattleStarter).OnStartClient()

    至此,Remote Client的Client本身就初始化好了。
    接下來,由于ClientScene.OnObjectSpawn()監聽了MsgType.ObjectSpawn,所以當Server生成本Client的LocalPlayer(或者Spawn其他任意GameObject時),本Client都會進入NetworkIdentity/NetworkBehaviour的函數流程。

    Remote Client的Player初始化階段

    NetworkBehaviour.Awake()
    只有localPlayerAuthority=True這個UNet配置變量是合法的。其他UNet變量都是非法的。

  • go.instanceID=-65642,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=0

  • playerControllerId=-1

  • connectionToClient=

  • connectionToServer=

  • isClient=False

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).Awake()

  • NetworkBehaviour.OnEnable()

  • go.instanceID=-65642,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=0

  • playerControllerId=-1

  • connectionToClient=

  • connectionToServer=

  • isClient=False

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnEnable()

  • NetworkBehaviour.OnDeserialize()

    public void OnDeserialize([Networking.NetworkReader reader, bool initialState);
    Parameters
    reader?Reader to read from the stream.
    initialState?True if being sent initial state.
    Description
    Virtual function to override to receive custom serialization data.

    Server把這個新NetworkIdentity的GameObject的所有同步屬性進行序列化會連同發送MsgType.Spawn一并下發。
    所以Client接受Server的數據后也通過OnDeserialize()在本地進行反序列化。留意到這是第一次反序列化initialState=True。

    OnSerialize()和OnDeserialize()
    是用于自定義NetworkBehaviour中變量的序列化和反序列化的虛函數。前者必然是只在Server被調用、后者必然是只在Client被調用。
    事實上,[SyncVar]修飾的變量和SyncList變量都是通過編譯時UNet將這些變量的序列化反序列化邏輯自動生成在OnSerialize()和OnDeserialize()中的。
    所以要注意,如果你在NetworkBehaviour中顯式override掉了這兩個函數,則該NetworkBehaviour的[SyncVar]修飾的變量和SyncList變量都需要你自行編寫代碼實現序列化反序列化。

  • deserializeCount=1, reader=NetBuf sz:87 pos:87, initialState=True,

  • go.instanceID=-65642,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=0

  • playerControllerId=-1

  • connectionToClient=

  • connectionToServer=

  • isClient=False

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnDeserialize()

  • NetworkBehaviour.PreStartClient()

    public void PreStartClient();
    Description
    An internal method called on client objects to resolve GameObject references.

    留意到經過上一步的OnDeserialize()之后,合法變量為

    • netId=7。
    • isClient=True。
    • isServer=False。
    • gameObject.name已經改變為跟server所給予的名字(NBPlayer7)。
    • 事實上,所有SyncVar此時皆已合法。
  • go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=-1

  • connectionToClient=

  • connectionToServer=

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).PreStartClient()

  • NetworkBehaviour.OnStartClient()

    public void OnStartClient();
    Description
    Called on every NetworkBehaviour when it is activated on a client.
    Objects on the host have this function called, as there is a local client on the host. The values of SyncVars on object are guaranteed to be initialized correctly with the latest state from the server when this function is called on the client.

    和PreStartClient()沒什么區別。當然,SyncVar已經合法。

  • go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=-1

  • connectionToClient=

  • connectionToServer=

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnStartClient()

  • NetworkBehaviour.OnStartLocalPlayer()

    public void OnStartLocalPlayer();
    Description
    Called when the local player object has been set up.
    This happens after OnStartClient(), as it is triggered by an ownership message from the server. This is an appropriate place to activate components or functionality that should only be active for the local player, such as cameras and input.

    在一個Client運行時中,只有一個Connection,有很多個Player。眾多Player中,只有和這個Connection綁定起來的Player,才“提拔為”LocalPlayer,代表的是本Client玩家的“MyPlayer”。所以,此時合法的變量就比較好理解了。
    合法變量:

    • playerControllerId=0
    • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2
    • isLocalPlayer=True

    Server發送MsgType.Owner給Client,然后Client就進行LocalPlayer的更新。
    注意,從源碼看來。LocalPlayer可以有多個。

    另,應注意,LocalPlayer的“Local”,和Host模式下的LocalClient的“Local”可不是同一個概念,應分清區別:

    • LocalClient的Local可理解為“同機器的”:是Host模式下,和Server同處于一部物理機器上的一種特殊的Client。LocalClient的并列相反概念是RemoteClient,RemoteClient是指和Server處于不同物理機器上的常見Client。
    • LocalPlayer的Local可理解為“我自己的”,不管是RemoteClient,還是LocalClient,它們都會有本客戶端的自己的LocalPlayer。LocalPlayer的并列相反概念是DumbPlayer(作者本人喜歡的叫法),DumbPlayer是指本客戶端代表其他玩家的Player。
  • go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=

  • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=True

  • isLocalPlayer=True

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnStartLocalPlayer()

  • NetworkBehaviour.OnStartAuthority()

    public void OnStartAuthority();
    Description
    This is invoked on behaviours that have authority, based on context and the LocalPlayerAuthority value on the NetworkIdentity.
    This is called after OnStartServer and OnStartClient.When NetworkIdentity.AssignClientAuthority() is called on the server, this will be called on the client that owns the object. When an object is spawned with NetworkServer.SpawnWithClientAuthority(), this will be called on the client that owns the object.

    當一個NetworkIdentity配置有LocalPlayerAuthority時,此NetworkIdentity認為是可以授權給Client的。只有一個Client真正有Authority的時候,才可以在該GameObject的NetworkBehaviour中發送Command給Server。
    什么時候Client才真正有Authority呢?LocalPlayer都是有Authority的。另自Unity5.2開始,也允許非Player在運行時通過在Server調用NetworkIdentity.AssignClientAuthority()或NetworkServer.SpawnWithClientAuthority()將Authority賦予特定的Connection,即指定該Connection的Client也擁有該非Player的Authority,即允許該Client也可以在該非Player的NetworkBehaviour中發Command給Server。此時OnStartAuthority()這個函數是可以在那個時候再被調用到的。

    Authority要么只有Server擁有,要么只有Client擁有。

    合法變量:

    • hasAuthority=True
  • go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=

  • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=True

  • isLocalPlayer=True

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnStartAuthority()

  • NetworkBehaviour.Start()
    一幀真正開始。

  • go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=

  • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=True

  • isLocalPlayer=True

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).Start()

  • 至此,NetworkBehaviour的初始化階段已結束。接下來是正常運轉階段。

    Remote Client的Player運轉階段

    NetworkBehaviour.FixedUpdate()(多次)

  • fixedUpdateCount=15, go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=

  • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=True

  • isLocalPlayer=True

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).FixedUpdate()

  • NetworkBehaviour.Update()(多次)

  • updateCount=4, go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=

  • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=True

  • isLocalPlayer=True

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).Update()

  • NetworkBehaviour.OnDeserialize()(多次)

  • deserializeCount=5, reader=NetBuf sz:28 pos:28, initialState=False, go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=

  • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=True

  • isLocalPlayer=True

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnDeserialize()

  • Remote Client的Player銷毀階段

    通過調用NetworkServer.Destroy(gameObject);,gameObject進入銷毀階段。

    NetworkBehaviour.OnNetworkDestroy()

    public void OnNetworkDestroy();
    Description
    This is invoked on clients when the server has caused this object to be destroyed.
    This can be used as a hook to invoke effects or do client specific cleanup.

    留意只有客戶端才會被調用OnNetworkDestroy()。

  • go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=

  • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=True

  • isLocalPlayer=True

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnNetworkDestroy()

  • NetworkBehaviour.OnDisable()

  • go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=

  • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=True

  • isLocalPlayer=True

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnDisable()

  • NetworkBehaviour.OnDestroy()

  • go.instanceID=-65642,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=

  • connectionToServer=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=True

  • isLocalPlayer=True

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnDestroy()

  • Remote Client的Client銷毀階段

    通過點擊NetworkManagerHUD的Stop按鈕,停止Remote Client。

    NetworkManager.OnStopHost()

    public void OnStopHost();
    Description
    This hook is called when a host is stopped.

    NetworkManagerHUD有bug。Remote Client情況點擊它也調用StopHost(),所以OnStopHost()也會被錯誤地調用。
    正式情況應忽略。

    NetworkManager (NewBorn.NBNetworkManager).OnStopHost()

    NetworkManager.OnStopClient()

    public void OnStopClient();
    Description
    This hook is called when a client is stopped.

    在NetworkManager.StopClient()調用時,先調用NetworkManager.OnStopClient(),然后再斷連接、清除GameObject、跳轉到OfflineScene。

    NetworkManager (NewBorn.NBNetworkManager).OnStopClient()

    至此,Remote Client整個流程結束。


    Host情況

    在已有上面Dedicated Server、Remote Client的情況,Host情況也將適當從略。

    Host初始化階段

    NetworkManager.Start()

    NetworkManager (NewBorn.NBNetworkManager).Start()

    NetworkManager.StartHost()

    public Networking.NetworkClient StartHost();
    Returns
    NetworkClient?The client object created - this is a "local client".
    Description
    This starts a network "host" - a server and client in the same application.
    The client returned from StartHost() is a special "local" client that communicates to the in-process server using a message queue instead of the real network. But in almost all other cases, it can be treated as a normal client.

    NetworkManager (NewBorn.NBNetworkManager).StartHost()

    NetworkManager.OnStartHost()

    NetworkManager (NewBorn.NBNetworkManager).OnStartHost()

    NetworkManager.OnStartServer()

    NetworkManager (NewBorn.NBNetworkManager).OnStartServer()

    NetworkManager.ServerChangeScene()

  • Battle_Demo_Official

  • NetworkManager (NewBorn.NBNetworkManager).ServerChangeScene()

  • NetworkManager.OnServerConnect()(2次)(LocalClient混雜進來的Server函數)

  • hostId: -1 connectionId: 0 isReady: False channel count: 0

  • NetworkManager (NewBorn.NBNetworkManager).OnServerConnect()

  • NetworkManager.OnStartClient()(LocalClient混雜進來的Client函數)

  • UnityEngine.Networking.LocalClient

  • NetworkManager (NewBorn.NBNetworkManager).OnStartClient()

  • NetworkManager.OnClientConnect()(LocalClient混雜進來的Client函數)

  • hostId: -1 connectionId: 0 isReady: False channel count: 0

  • NetworkManager (NewBorn.NBNetworkManager).OnClientConnect()

  • NetworkManager.OnServerSceneChanged()

  • Battle_Demo_Official

  • NetworkManager (NewBorn.NBNetworkManager).OnServerSceneChanged()

  • NetworkManager.OnClientSceneChanged()(LocalClient混雜進來的Client函數)

  • hostId: -1 connectionId: 0 isReady: False channel count: 0

  • NetworkManager (NewBorn.NBNetworkManager).OnClientSceneChanged()

  • NetworkManager.OnServerReady()(LocalClient混雜進來的Server函數)

  • hostId: -1 connectionId: 0 isReady: False channel count: 0

  • NetworkManager (NewBorn.NBNetworkManager).OnServerReady()

  • NetworkManager.OnServerAddPlayer()(LocalClient混雜進來的Server函數)

  • hostId: -1 connectionId: 0 isReady: True channel count: 0, 0

  • NetworkManager (NewBorn.NBNetworkManager).OnServerAddPlayer()

  • 至此,Host的Server初始化邏輯(混雜著LocalClient的初始化邏輯)結束。
    進入Player初始化階段。

    Host情況的Player初始化階段

    NetworkManager.OnServerConnect()

  • hostId: 0 connectionId: 1 isReady: False channel count: 2

  • NetworkManager (NewBorn.NBNetworkManager).OnServerConnect()

  • NetworkManager.OnServerReady()

  • hostId: 0 connectionId: 1 isReady: False channel count: 2

  • NetworkManager (NewBorn.NBNetworkManager).OnServerReady()

  • NetworkManager.OnServerAddPlayer()

  • hostId: 0 connectionId: 1 isReady: True channel count: 2, 0

  • NetworkManager (NewBorn.NBNetworkManager).OnServerAddPlayer()

  • 至此,開始Player的Prefab在Host已被Instantiate出來。正式開始NetworkIdentity/NetworkBehaviour的函數流程。

    NetworkBehaviour.Awake()

  • go.instanceID=-78256,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=0

  • playerControllerId=-1

  • connectionToClient=

  • connectionToServer=

  • isClient=False

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).Awake()

  • NetworkBehaviour.OnEnable()

  • go.instanceID=-78256,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=0

  • playerControllerId=-1

  • connectionToClient=

  • connectionToServer=

  • isClient=False

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnEnable()

  • NetworkBehaviour.OnStartServer()
    合法變量:

    • netId=2。由于是Host,所以不需調用OnDeserialize()。立刻確定了netId。
    • isServer=True
  • go.instanceID=-78256,go=NBPlayer(Clone) (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=False

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer(Clone) (MoreFun.TestNetworkBehaviour).OnStartServer()

  • NetworkBehaviour.PreStartClient()

  • go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).PreStartClient()

  • NetworkBehaviour.OnStartClient()

  • go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnStartClient()

  • NetworkBehaviour.OnRebuildObservers()

  • observers=System.Collections.Generic.HashSet`1[UnityEngine.Networking.NetworkConnection], initialize=True,

  • go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnRebuildObservers()

  • NetworkBehaviour.OnSerialize()(多次)

  • serializeCount=1, writer=UnityEngine.Networking.NetworkWriter, initialState=True, go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnSerialize()

  • NetworkBehaviour.OnSetLocalVisibility()

    public void OnSetLocalVisibility(bool vis);
    Parameters
    vis?New visibility state.
    Description
    Callback used by the visibility system for objects on a host.
    Objects on a host (with a local client) cannot be disabled or destroyed when they are not visibile to the local client. So this function is called to allow custom code to hide these objects. A typical implementation will disable renderer components on the object. This is only called on local clients on a host.

  • vis=True, go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnSetLocalVisibility()

  • NetworkBehaviour.Start()

  • go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).Start()

  • 至此,Host情況的NetworkIdentity/NetworkBehaviour的初始化階段已結束。接下來是正常運轉階段。

    Host情況的Player運轉階段

    NetworkBehaviour.FixedUpdate()(多次)

  • fixedUpdateCount=5,

  • go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).FixedUpdate()

  • NetworkBehaviour.Update()(多次)

  • updateCount=4,

  • go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).Update()

  • NetworkBehaviour.OnSerialize()(多次)

  • serializeCount=4, writer=UnityEngine.Networking.NetworkWriter, initialState=False, go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnSerialize()

  • Host情況的Player銷毀階段

    通過調用NetworkServer.Destroy(gameObject);,gameObject進入銷毀階段。

    NetworkBehaviour.OnNetworkDestroy()

  • go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=True

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnNetworkDestroy()

  • NetworkBehaviour.OnDisable()

  • go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=7

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnDisable()

  • NetworkBehaviour.OnDestroy()

  • go.instanceID=-78256,go=NBPlayer7 (UnityEngine.GameObject)

  • netId=0

  • playerControllerId=0

  • connectionToClient=hostId: 0 connectionId: 1 isReady: True channel count: 2

  • connectionToServer=

  • isClient=True

  • isServer=False

  • localPlayerAuthority=True

  • hasAuthority=False

  • isLocalPlayer=False

  • NBPlayer7 (MoreFun.TestNetworkBehaviour).OnDestroy()

  • NetworkManager.OnServerDisconnect()

  • hostId: 0 connectionId: 1 isReady: False channel count: 2

  • NetworkManager (NewBorn.NBNetworkManager).OnServerDisconnect()

  • 至此,Host情況的Player流程結束。

    Host銷毀流程

    NetworkManager.OnStopHost()

    NetworkManager (NewBorn.NBNetworkManager).OnStopHost()

    NetworkManager.OnStopServer()

    NetworkManager (NewBorn.NBNetworkManager).OnStopServer()

    NetworkManager.ServerChangeScene()

  • BattleOffline

  • NetworkManager (NewBorn.NBNetworkManager).ServerChangeScene()

  • NetworkManager.OnStopClient()

    NetworkManager (NewBorn.NBNetworkManager).OnStopClient()

    至此,Host情況全部流程結束。

    轉自http://www.jianshu.com/p/63bb685a36d6

    總結

    以上是生活随笔為你收集整理的UNet详解(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 五月天婷婷激情网 | 亚洲色图36p | 中文字幕亚洲欧美日韩 | 国产伦精品一区二区三区四区视频 | 91福利免费视频 | 不卡在线一区二区 | a级片久久| 国产精品自拍亚洲 | 99热超碰 | www.四虎影视 | 国产视频一区二区三区在线观看 | 国产91免费| 少妇xxx | 久久一级黄色片 | 婷婷影音| wwwxx国产 | a级片在线 | 性感少妇在线观看 | 色欲av无码一区二区三区 | 芭乐视频色 | 天天操天天干天天操 | 成人一区二区在线 | 青草视频在线观看视频 | 天天看av| www在线观看视频 | 日韩在线第二页 | 爱爱短视频 | 黄色片xxx | 男女网站视频 | 久久伊人精品视频 | 欧美一区精品 | 无码人妻丰满熟妇区毛片蜜桃精品 | 日本视频在线播放 | 成人小视频免费观看 | 国内精品久久久久久久久 | 黄毛片在线观看 | 精品国产三级 | 殴美一级片 | 一级片在线免费观看 | 直接看毛片 | 黑人欧美一区二区三区 | 中文字幕人妻丝袜二区 | 空姐吹箫视频大全 | 国产稀缺真实呦乱在线 | 国产无遮挡免费观看视频网站 | 国产污在线观看 | 大陆女明星乱淫合集 | 国产91一区在线精品 | 大尺码肥胖女系列av | 中文字幕97 | 丰满熟妇人妻av无码区 | 网友自拍咪咪爱 | www.999热| av在线播放网站 | www.成人av.com | 久久精品www人人爽人人 | 日本不卡免费 | 日韩久久久久久久久久久 | 91在线一区二区三区 | 啪视频网站 | 免费在线观看一区二区 | 国产思思 | 亚洲欧美日本韩国 | 亚洲一级在线观看 | 国产一级做a爰片久久毛片男男 | 日韩欧美国产一区二区在线观看 | 色哟哟av| 老太脱裤让老头玩ⅹxxxx | 动漫美女露胸网站 | 国产乱码77777777 | 黄网在线播放 | 涩涩视频免费在线观看 | 国产a一级片 | 91欧美激情一区二区三区成人 | 亚洲妇女体内精汇编 | 国产一区二区免费在线观看 | 日本人妻伦在线中文字幕 | 5566色| 91在现看 | 久久99这里只有精品 | 欧美第四页 | 欧美v亚洲 | 成人在线观看www | 一级片欧美 | 色爽影院| sese在线| 日韩一级一区 | 禁止18在线观看 | 亚洲熟女乱色一区二区三区 | 成人二三区 | 少妇高潮一区二区三区在线 | 福利视频在线看 | 依人在线视频 | 国产精品一区二区人妻喷水 | 视频精品久久 | 香蕉污视频在线观看 | 欧美大尺度做爰啪啪床戏明星 | 人禽高h交| 中文人妻熟女乱又乱精品 |