Master Server And Lobby 主服務器和大廳
PUN always uses a master server and one or more game servers. The master server manages currently running games on the various game servers and will provide a game server address when you join or create a room. PUN (the client) automatically switches to that game server.
PUN總是使用一個主服務器和一個或多個遊戲服務器。 主服務器管理當前運行遊戲的各種遊戲服務器和將提供一個遊戲服務器地址當你加入或創建一個房間。 PUN(客戶端),它會自動切換到遊戲服務器。
Individual matches are known as Rooms. They are independent of each other and identified by name. Rooms are grouped into one or multiple lobbies. Lobbies are an optional part in matchmaking. If you don't use custom lobbies explicitly, PUN will use a single lobby for all rooms.
By default, PUN will join the default lobby after connecting. This lobby sends a list of existing rooms to the client, so the player can pick a room (by name or some properties listed). Access the current list by using PhotonNetwork.GetRoomList(). The lists is updated in intervals to keep traffic low.
Clients don't have to join a lobby to join or create rooms. If you don't want to show a list of rooms in your client, set PhotonNetwork.autoJoinLobby = false before you connect and your clients will skip the lobby.
You can use more than one lobby to organize room-lists as needed for your game. PhotonNetwork.JoinLobby is the method to join a specific lobby. You can make them up on the client side - the server will keep track of them. As long as name and type are the same, the TypedLobby will be the same for all clients, too.
A client is always just in one lobby and while being in a lobby, creating a room will relate to this lobby, too. Multiple lobbies mean the clients get shorter rooms lists, which is good. There is no limit to the rooms lists.
A parameter in JoinRoom, JoinRandomRoom and CreateRoom enables you to select a lobby without joining it.
Players won't notice each other in the Lobby and can't send data (to prevent issues when it's getting crowded).
玩家不會注意到彼此在大堂,不能發送數據(防止問題的時候擁擠)。
The servers are all run on dedicated machines - there is no such thing as player-hosted ‘servers’. You don’t have to bother remembering about the server organization though, as the API all hides this for you.
The code above is required to make use of any PhotonNetwork features. It sets your client’s game version and uses the setup-wizard’s config (stored in: PhotonServerSettings). The wizard can also be used when you host Photon yourself. Alternatively, use Connect() and you can ignore the PhotonServerSettings file.
Versioning 版本控制
The loadbalancing logic for Photon uses your appID to separate your players from anyone else’s. The same is done by game version, which separates players with a new client from those with older clients. As we can’t guarantee that different Photon Unity Networking versions are compatible with each other, we add the PUN version to your game’s version before sending it (since PUN v1.7).
Creating and Joining Games 創建和加入遊戲
Next, you’ll want to join or create a room. The following code showcases some required functions: 接下來,您將想要加入或創建一個房間。 下面的代碼展示了一些需要的功能:
A list of currently running games is provided by the master server’s lobby. It can be joined like other rooms but only provides and updates the list of rooms. The PhotonNetwork plugin will automatically join the lobby after connecting. When you’re joining a room, the list will no longer update.
To display the list of rooms (in a lobby): 顯示的房間列表
Alternatively, the game can use random matchmaking: It will try to join any room and fail if none has room for another player. In that case: Create a room without name and wait until other players join it randomly.
Advanced Matchmaking & Room Properties
Fully random matchmaking is not always something players enjoy. Sometimes you just want to play a certain map or just two versus two.
In Photon Cloud and Loadbalancing, you can set arbitrary room properties and filter for those in JoinRandom.
Room Properties and the Lobby
Room properties are synced to all players in the room and can be useful to keep track of the current map, round, starttime, etc. They are handled as Hashtable with string keys. Preferably short keys.
You can forward selected properties to the lobby, too. This makes them available for listing them and for random matchmaking, too. Not all room properties are interesting in the lobby, so you define the set of properties for the lobby on room creation.
Note that "ai" is not a key in the room-properties yet. It won't show up in the lobby until it's set in the game via Room.SetCustomProperties(). When you change the values for "map" or "ai", they will be updated in the lobby with a short delay, too.
請注意,“人工智能”還沒有room-properties的關鍵。 它不會出現在大廳裏,直到它設置在遊戲中通過Room.SetCustomProperties()。 當你改變的值“地圖”或“人工智能”,他們將在大堂與短的延遲更新,。
Keep the list short to make sure performance doesn't suffer from loading the list.
Filtering Room Properties in Join Random
In JoinRandom, you could pass a Hashtable with expected room properties and max player value. These work as filters when the server selects a "fitting" room for you.
If you pass more filter properties, chances are lower that a room matches them. Better limit the options.
Make sure you never filter for properties that are not known to the lobby (see above).
MonoBehaviour Callbacks 回調
PUN uses several callbacks to let your game know about state changes like “connected” or “joined a game”. All you have to do is implement the fitting method in any MonoBehaviour and it gets called when the event happens.
To get a good overview of available callbacks, take a look at the class Photon.PunBehaviour. If you make your script a PunBehaviour (instead of a MonoBehaviour), you can override individual callbacks easily. If you begin to type "override", your coding IDE should provide you a list of callbacks, so they are easy to find while coding, too.
This covers the basics of setting up game rooms. Next up is actual communication in games.
Sending messages in rooms 發送消息在房間
Inside a room you are able to send network messages to other connected players. Furthermore you are able to send buffered messages that will also be sent to players that connect in the future (for spawning your player for instance).
Sending messages can be done using two methods. Either RPCs or by using the PhotonView property OnSerializePhotonView. There is more network interaction though. You can listen for callbacks for certain network events (e.g. OnPhotonInstantiate, OnPhotonPlayerConnected) and you can trigger some of these events (PhotonNetwork.Instantiate). Don’t worry if you’re confused by the last paragraph, next up we’ll explain for each of these subjects.
Using Groups in PUN 用組
Groups are not synchronized when they are changed on any PhotonView. It's up to the developer to keep photonviews in the same groups on all clients, if that's needed. Using different group numbers for the same photonview on several clients will cause some inconsistent behaviour.組不同步時在任何PhotonView改變。 由開發人員保持photonviews在同一組對所有客戶,如果這是必要的。 使用不同組數據相同的photonview幾個客戶會導致一些不一致的行爲。
Some network messages are checked for their receiver group at the receiver side only, namely: 一些網絡消息檢查接收器組在接收機端,即:
- RPCS that are targeted to a single player (or MasterClient) rpc是針對一個單一的玩家(或MasterClient)
- RPCS that are buffered (AllBuffered/OthersBuffered). rpc緩衝(AllBuffered / OthersBuffered)。
- This includes PhotonNetwork.Instantiate (as it is buffered). 這包括PhotonNetwork。 實例化(緩衝)。
Technical reason for this: the photon server only supports interestgroups for messages that are not cached and are not targetted at sepcific actor(s). This might change in the future.
PhotonView
PhotonView is a script component that is used to send messages (RPCs and OnSerializePhotonView). You need to attach the PhotonView to your games gameobjects. Note that the PhotonView is very similar to Unity’s NetworkView.
At all times, you need at least one PhotonView in your game in order to send messages and optionally instantiate/allocate other PhotonViews.
To add a PhotonView to a gameobject, simply select a gameobject and use: “Components/Miscellaneous/Photon View”.
Observe Transform 觀察變換
If you attach a Transform to a PhotonView’s Observe property, you can choose to sync Position, Rotation and Scale or a combination of those across the players. This can be a great help for prototyping or smaller games. Note: A change to any observed value will send out all observed values - not just the single value that’s changed. Also, updates are not smoothed or interpolated.
Observe MonoBehaviour
A PhotonView can be set to observe a MonoBehaviour. In this case, the script’s OnPhotonSerializeView method will be called. This method is called for writing an object’s state and for reading it, depending on whether the script is controlled by the local player.
一個MonoBehaviour PhotonView可以觀察。 在這種情況下,腳本OnPhotonSerializeView方法將被調用。 調用此方法爲寫作對象的狀態和閱讀它,取決於該腳本是由當地的玩家。
The simple code below shows how to add character state synchronization with just a few lines of code more:
If you send something “ReliableDeltaCompressed”, make sure to always write data to the stream in the same order. If you write no data to the PhotonStream, the update is not sent. This can be useful in pauses. Now on, to yet another way to communicate: RPCs.
如果你發送一些“ReliableDeltaCompressed”,確保總是在相同的順序向流寫入數據。 如果你寫PhotonStream沒有數據,更新不發送。 這可能是有用的在停頓了一下。 現在,另一種方法來溝通:rpc。