Unity+ Photon服务器实时对战游戏——Photon实例化网络化的对象 (六)

Instantiating Networked Objects 实例化网络化的对象

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.

在每一场比赛你需要实例化一个或多个玩家对象为每一个玩家。 有各种选项,下面列出。

PhotonNetwork.Instantiate PhotonNetwork的实例化

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.

双关可以自动照顾产卵对象通过一个起始位置,旋转和PhotonNetwork预制的名字。 实例化方法。 要求:预制应直属可用资源/文件夹,以便预制可以在运行时被加载。 小心webplayers:一切资源文件夹将默认在第一现场公示。 下webplayer设置您可以指定第一级,使用资产的资源文件夹使用“第一次流的水平”。 如果你设置你的第一场比赛现场,你的预紧器和mainmenu不会减慢如果他们不使用的资源文件夹的资产。
void SpawnMyPlayerEverywhere()
{
PhotonNetwork.Instantiate(“MyPrefabName”, new Vector3(0,0,0), Quaternion.identity, 0);
//The last argument is an optional group number, feel free to ignore it for now.
}

Gain more control: Manually instantiate 获得更多的控制:手动实例化

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.

手动要实例化的主要原因是控制流webplayers下载时。 流的详细信息和资源文件夹在Unity中可以在这里找到。

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.

如果你手动生成,必须分配一个PhotonViewID自己,这些viewID是网络消息路由到正确的关键gameobject /脚本。 玩家谁想拥有并生成一个新对象应该分配一个新的viewID使用PhotonNetwork.AllocateViewID();。 这个PhotonViewID应该发送给其他玩家使用PhotonView已经设置(例如PhotonView现有场景)。 你要记住这个RPC需要缓冲,以便任何客户端连接后还将得到产卵指令。 然后RPC消息用于生成所需的对象需要一个引用到你的这个使用Unity的GameObject.Instantiate预制并实例化。 最后您将需要设置设置PhotonViews附加到这个组合式分配PhotonViews PhotonViewID。
void SpawnMyPlayerEverywhere()
{
//Manually allocate PhotonViewID
PhotonViewID id1 = PhotonNetwork.AllocateViewID();
photonView.RPC( "SpawnOnNetwork", PhotonTargets.AllBuffered, transform.position,
transform.rotation, id1, PhotonNetwork.player);
}
public Transform playerPrefab; //set this in the inspector
[PunRPC]
void SpawnOnNetwork(Vector3 pos, Quaternion rot, PhotonViewID id1, PhotonPlayer np)
{
Transform newPlayer = Instantiate(playerPrefab, pos, rot) as Transform;
//Set the PhotonView
PhotonView[] nViews = go.GetComponentsInChildren<PhotonView>();
nViews[0].viewID = id1;
}

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.

如果你想使用资产包加载您的网络对象,所有你需要做的就是添加自己的assetbundle加载代码和取代“playerPrefab”组合式的例子从你的资产包。

Offline mode 离线模式

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.

迈克Hergaarden:M2H我们必须重建我们的游戏几次游戏门户通常要求你完全删除多人游戏功能。 此外,可以使用相同的代码单人和多人节省了大量的工作。

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.

最常见的特性,你会希望能够使用在单人使用PhotonNetwork.Instantiate发送rpc和。 离线模式的主要目标是禁用nullreferences和其他错误当使用PhotonNetwork功能而没有连接。 你仍然需要跟踪你运行一个单人游戏,设置游戏等等。然而,在运行游戏时,所有代码应该是可重用的。

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:

您需要手动启用离线模式,PhotonNetwork需要能够区分错误和预期的行为。 启用此功能非常简单:
PhotonNetwork.offlineMode = true;

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函数和变量的列表和他们的结果在离线模式:

PhotonNetwork.player The player ID is always -1 PhotonNetwork.playerName Works as expected. PhotonNetwork.playerList Contains only the local player

PhotonNetwork。 玩家总是1 PhotonNetwork玩家ID。 playerName是否按预期运行。 PhotonNetwork。 playerList只包含当地的玩家

PhotonNetwork.otherPlayers Always empty PhotonNetwork.time returns Time.time; PhotonNetwork.isMasterClient Always true PhotonNetwork.AllocateViewID() Works as expected.

PhotonNetwork。 otherPlayers总是空PhotonNetwork。 时间返回时间。 时间,PhotonNetwork。 isMasterClient总是如此PhotonNetwork.AllocateViewID()是否按预期运行。

PhotonNetwork.Instantiate Works as expected PhotonNetwork.Destroy Works as expected.

PhotonNetwork。 实例化PhotonNetwork是按预期运行的。 摧毁像预期的那样工作。

PhotonNetwork.RemoveRPCs/RemoveRPCsInGroup/SetReceivingEnabled/SetSendingEnabled/SetLevelPrefix While these make no sense in Singleplayer, they will not hurt either.

PhotonNetwork。 RemoveRPCs / RemoveRPCsInGroup SetReceivingEnabled / SetSendingEnabled SetLevelPrefix虽然这些毫无意义在单人,他们不会伤害。

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.

注意,使用其他方法比上面的可以产生意想不到的结果和一些只会什么都不做。 例如PhotonNetwork。 房间里,很明显,返回null。 如果你打算开始在单人游戏,但把它移动到多人在后面的一个阶段,你可能想考虑举办1玩家游戏相反;这将保护缓冲rpc和实例调用,而离线模式实例化连接后不会自动延续。

Either set PhotonNetwork.offlineMode = false; or Simply call Connect() to stop offline mode.

要么PhotonNetwork设置。 offlineMode = false;或者只是调用Connect()停止离线模式。

Limitations 限制

Views and players 视图和玩家

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.

有改善的空间带宽性能通过减少int短(值范围:32768 - 32768−)。 通过设置MAX_VIEW_IDS 32你仍然可以支持1023个玩家搜索“/ /限制NETWORKVIEWS&PLAYERS”出现的所有int viewID。 此外,目前API并不使用单位/ ushort但只有积极的数字。 这样做是为了简单性和使用viewIDs性能问题对于大多数情况不是至关重要的。

Groups and Scoping 组织和范围

The PhotonNetwork plugin does not support network groups fully. See above: "Using Groups in PUN".

PhotonNetwork插件不支持网络组织。 看到上图:“使用组双关”。

Unity’s “scope” feature is not implemented.

Unity的“范围”功能还没有实现。

Feedback 反馈

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

我们感兴趣的是你的反馈,这个解决方案对我们来说是一个正在进行的项目。 让我们知道如果太隐蔽,缺失或不工作。 让我们知道,在我们的论坛:forum.exitgames.com

F.A.Q.

Can I use multiple PhotonViews per GameObject? Why? 我可以使用多个PhotonViews / GameObject吗? 为什么?

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.

是的这是非常好。 你需要多个PhotonViews如果你需要观察2个或更多的目标;每PhotonView只能观察一个。 RPC的你只需要一个PhotonView这可以同一PhotonView已经观察的东西。 RPC从未与观察到的目标发生冲突。

Can I use UnityScript / Javascript?

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.

从UnityScript使用双关语,移动文件夹“PhotonNetwork”和“UtilityScripts”资产\文件夹。 现在双关语UnityScript之前编译,这使得它可以从常规UnityScript代码。

Converting your Unity networking project to Photon 将您的Unity网络项目转化为Photon

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:

将您的Unity网络项目转换成Photon可以在一天之内完成。 只是可以肯定的是,你的项目做一个备份,我们自动转换器将改变你的脚本。 在这个步骤完成之后,从Photon运行转换器编辑器窗口(窗口- >PhotonUnity网络- >转换器- >开始)。 之间的自动转换需要30秒到10分钟,根据项目的大小和你的电脑的性能。 这种自动转换负责以下:
  • All NetworkViews are replaced with PhotonViews and the exact same settings. This is applied for all scenes and all prefabs.
  • •所有NetworkViews PhotonViews取代和相同的设置。 这是申请所有场景和组合式。
  • All scripts (JS/BOO/C#) are scanned for Network API calls, and they are replaced with PhotonNetwork calls.
  • 所有脚本(c#)扫描网络API调用,并取代PhotonNetwork调用。

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<PhotonView>().XXX Inside of scripts, you can use photonView to get the attached PhotonView component. However, you cannot call this on an external transform directly. RegisterServer There’s no more need to register your games to a masterserver, Photon does this automatically.

PhotonNetwork.RemoveRPCs(玩家);PhotonNetwork.DestroyPlayerObjects(玩家);这些不存在,可以安全地删除。 Photon自动清理的玩家离开时(尽管你可以禁用这个照顾清理自己如果你想)… CloseConnection接受' 2 '参数…删除第二,布尔,这叫论证。 PhotonNetwork.GetPing(玩家);GetPing不带任何参数,你只能请求萍Photon服务器,不能ping其他玩家。 myPlayerClass.transform.photonView。 XXX这样的错误需要转换代码:myPlayerClass.transform.GetComponent < PhotonView >()。 XXX的脚本,您可以使用photonView photonView附加组件。 然而,你不能直接调用外部变换。 RegisterServer没有更多需要注册你的游戏masterserver,Photon这自动。

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.

你应该能够解决所有的编译错误5 - 30分钟。 大多数错误都来源于主菜单/ GUI代码,与ip /端口/游说GUI。

This is where Photon differs most from Unity's solution:

这就是Photon最不同于Unity的解决办法:

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).

只有一个Photon服务器和你连接使用名称空间。 因此所有引用ip /端口可以删除从您的代码(通常GUI代码)。

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。 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值