In about every game you need to instantiate one or more player objects for every player. There are various options to do so which are listed below.
在每一场比赛你需要实例化一个或多个玩家对象为每一个玩家。 有各种选项,下面列出。
PUN can automatically take care of spawning an object by passing a starting position, rotation and a prefab name to the PhotonNetwork.Instantiate method. Requirement: The prefab should be available directly under a Resources/ folder so that the prefab can be loaded at run time. Watch out with webplayers: Everything in the resources folder will be streamed at the very first scene per default. Under the webplayer settings you can specify the first level that uses assets from the Resources folder by using the “First streamed level”. If you set this to your first game scene, your preloader and mainmenu will not be slowed down if they don’t use the Resources folder assets.
If don’t want to rely on the Resources folders to instantiate objects over the network you’ll have to manually Instantiate objects as shown in the example at the end of this section.
如果不想依赖资源文件夹来实例化对象在网络上你必须手动实例化对象的例子所示在本小节的末尾
The main reason for wanting to instantiate manually is gaining control over what is downloaded when for streaming webplayers. The details about streaming and the Resources folder in Unity can be found here.
If you spawn manually, you will have to assign a PhotonViewID yourself, these viewID’s are the key to routing network messages to the correct gameobject/scripts. The player who wants to own and spawn a new object should allocate a new viewID using PhotonNetwork.AllocateViewID();. This PhotonViewID should then be send to all other players using a PhotonView that has already been set up (for example an existing scene PhotonView). You will have to keep in mind that this RPC needs to be buffered so that any clients that connect later will also receive the spawn instructions. Then the RPC message that is used to spawn the object will need a reference to your desired prefab and instantiate this using Unity’s GameObject.Instantiate. Finally you will need to set setup the PhotonViews attached to this prefab by assigning all PhotonViews a PhotonViewID.
If you want to use asset bundles to load your network objects from, all you have to do is add your own assetbundle loading code and replace the “playerPrefab” from the example with the prefab from your asset bundle.
Offline mode is a feature to be able to re-use your multiplayer code in singleplayer game modes as well. 离线模式功能能够重用多人代码在单人游戏模式。
Mike Hergaarden: At M2H we had to rebuild our games several times as game portals usually require you to remove multiplayer functionality completely. Furthermore, being able to use the same code for single and multiplayer saves a lot of work on itself.
The most common features that you’ll want to be able to use in singleplayer are sending RPCs and using PhotonNetwork.Instantiate. The main goal of offline mode is to disable nullreferences and other errors when using PhotonNetwork functionality while not connected. You would still need to keep track of the fact that you’re running a singleplayer game, to set up the game etc. However, while running the game, all code should be reusable.
You need to manually enable offline mode, as PhotonNetwork needs to be able to distinguish erroneous from intended behaviour. Enabling this feature is very easy:
You can now reuse certain multiplayer methods without generating any connections and errors. Furthermore there is no noticeable overhead. Below follows a list of PhotonNetwork functions and variables and their results during offline mode:
PhotonNetwork.player The player ID is always -1 PhotonNetwork.playerName Works as expected. PhotonNetwork.playerList Contains only the local player
PhotonNetwork.otherPlayers Always empty PhotonNetwork.time returns Time.time; PhotonNetwork.isMasterClient Always true PhotonNetwork.AllocateViewID() Works as expected.
PhotonNetwork.Instantiate Works as expected PhotonNetwork.Destroy Works as expected.
PhotonNetwork.RemoveRPCs/RemoveRPCsInGroup/SetReceivingEnabled/SetSendingEnabled/SetLevelPrefix While these make no sense in Singleplayer, they will not hurt either.
PhotonView.RPC Works as expected.
PhotonView。 RPC是预期。
Note that using other methods than the ones above can yield unexpected results and some will simply do nothing. E.g. PhotonNetwork.room will, obviously, return null. If you intend on starting a game in singleplayer, but move it to multiplayer at a later stage, you might want to consider hosting a 1 player game instead; this will preserve buffered RPCs and Instantiation calls, whereas offline mode Instantiations will not automatically carry over after Connecting.
Either set PhotonNetwork.offlineMode = false; or Simply call Connect() to stop offline mode.
For performance reasons, the PhotonNetwork API supports up to 1000 PhotonViews per player and a maximum of 2,147,483 players (note that this is WAY higher than your hardware can support!). You can easily allow for more PhotonViews per player, at the cost of maximum players. This works as follows: PhotonViews send out a viewID for every network message. This viewID is an integer and it is composed of the player ID and the player’s view ID. The maximum size of an int is 2,147,483,647, divided by our MAX_VIEW_IDS(1000) that allows for over 2 million players, each having 1000 view IDs. As you can see, you can easily increase the player count by reducing the MAX_VIEW_IDS. The other way around, you can give all players more VIEW_IDS at the cost of less maximum players. It is important to note that most games will never need more than a few view ID’s per player (one or two for the character..and that’s usually it). If you need much more then you might be doing something wrong! It is extremely inefficient to assign a PhotonView and ID for every bullet that your weapon fires, instead keep track of your fire bullets via the player or weapon’s PhotonView.
于性能原因,PhotonNetwork API支持多达1000 PhotonViews玩家和最多2147483名玩家(注意,这是高于你的硬件可以支持!)。 你可以很容易地让每个玩家PhotonViews,代价是最大的玩家。 其工作原理如下:PhotonViews viewID对于每一个网络发送消息。 这viewID是一个整数,它由玩家ID和玩家的视图ID。int的最大大小是2147483647,除以MAX_VIEW_IDS(1000),允许超过200万的玩家,每个有1000视图ID。 如您所见,您可以很容易地增加MAX_VIEW_IDS玩家数减少。 反过来,你可以给所有玩家更多VIEW_IDS少的代价最大的玩家。 重要的是要注意,大多数游戏永远不会需要几个视图ID的每个玩家(一个或两个角色。 通常是这样)。 如果你需要更多的,那么你可能是做得不对! 它是非常
There is room for improving your bandwidth performance by reducing the int to a short (value range: −32,768 to 32,768). By setting MAX_VIEW_IDS to 32 you can then still support 1023 players Search for “//LIMITS NETWORKVIEWS&PLAYERS” for all occurrences of the int viewID. Furthermore, currently the API is not using uint/ushort but only the positive range of the numbers. This is done for simplicity and the usage of viewIDs is not a crucial performance issue for most situations.
The PhotonNetwork plugin does not support network groups fully. See above: "Using Groups in PUN".
PhotonNetwork插件不支持网络组织。 看到上图:“使用组双关”。
Unity’s “scope” feature is not implemented.
We are interested in your feedback, as this solution is an ongoing project for us. Let us know if something was too hidden, missing or not working. To let us know, post in our Forum: forum.exitgames.com
Yes this is perfectly fine. You will need multiple PhotonViews if you need to observe 2 or more targets; You can only observe one per PhotonView. For your RPC’s you’ll only ever need one PhotonView and this can be the same PhotonView that is already observing something. RPC’s never clash with an observed target.
To use PUN from UnityScript, move both folders "PhotonNetwork" and "UtilityScripts" to the Assets\ folder. Now PUN compiles before UnityScript and that makes it available from regular UnityScript code.
Converting your Unity networking project to Photon can be done in one day. Just to be sure, make a backup of your project, as our automated converter will change your scripts. After this is done, run the converter from the Photon editor window (Window -> Photon Unity Networking -> Converter -> Start). The automatic conversion takes between 30 seconds to 10 minutes, depending on the size of your project and your computers performance. This automatic conversion takes care of the following:
There are some minor differences, therefore you will need to manually fix a few script conversion bugs. After conversion, you will most likely see some compile errors. You’ll have to fix these first. Most common compile errors:
PhotonNetwork.RemoveRPCs(player); PhotonNetwork.DestroyPlayerObjects(player); These do not exist, and can be safely removed. Photon automatically cleans up players when they leave (even though you can disable this and take care of cleanup yourself if you want to) ..CloseConnection takes ‘2' arguments… Remove the second, boolean, argument from this call. PhotonNetwork.GetPing(player); GetPing does not take any arguments, you can only request the ping to the photon server, not ping to other players. myPlayerClass.transform.photonView.XXX error You will need to convert code like this to: myPlayerClass.transform.GetComponent
You should be able to fix all compile errors in 5-30 minutes. Most errors will originate from main menu/GUI code, related to IPs/Ports/Lobby GUI.
This is where Photon differs most from Unity's solution:
There is only one Photon server and you connect using the room names. Therefore all references to IPs/ports can be removed from your code (usually GUI code).
PhotonNetwork.JoinRoom(string room) only takes a room argument, you’ll need to remove your old IP/port/NAT arguments. If you have been using the “Ultimate Unity networking project” by M2H, you should remove the MultiplayerFunctions class.
PhotonNetwork。 房间JoinRoom(string)只需要一个房间参数,您需要删除你的旧IP /端口/ NAT参数。 如果你一直使用M2H“终极Unity网络项目”,你应该删除MultiplayerFunctions类。
Lastly, all old MasterServer calls can be removed. You never need to register servers, and fetching the room list is as easy as calling PhotonNetwork.GetRoomList(). This list is always up to date (no need to fetch/poll etc). Rewriting the room listing can be most work, if your GUI needs to be redone, it might be simpler to write the GUI from scratch.
最后,可以删除所有旧MasterServer调用。 你永远不需要注册服务器和抓取房间列表一样容易调用PhotonNetwork.GetRoomList()。 这个列表总是最新(不需要获取/调查等)。 清单可以重写房间大部分工作,如果您的GUI需要重做,这可能是简单的从头开始编写GUI。