Adding Multiplayer shooting
添加多人射击
This section adds networking to the bullets in this example.
本节将在本例中添加网络。
Both the Bullet prefab and the shooting code will need to be updated.
子弹预制板和射击代码都需要更新。
First, the Bullet prefab needs a NetworkIdentity to identify it as unique on the network, a NetworkTransform to sync the position and rotation of the bullet, and the prefab itself will need to be registered with the NetworkManager as a Spawnable Prefab.
首先,子弹预制件需要一个NetworkIdentity来识别它在网络上的独特之处,一个用于同步子弹位置和旋转的NetworkTransform,而预制件本身需要在NetworkManager上注册为一个可生成的预置。
Select the Bullet prefab in the Project Window.
在“项目”窗口中选择“子弹预置”。
With the Bullet prefab selected,
有了子弹头,
…
find and add the component: Network > NetworkIdentity.
查找并添加组件:Network > NetworkIdentity。
…
find and add the component: Network > NetworkTransform.
查找并添加组件:网络>网络转换。
Set the Network Send Rate on the NetworkTransform component to 0.
将NetworkTransform组件的网络发送速率设置为0。
The bullet doesn’t change direction or velocity after it’s shot, so it doesn’t need to send movement updates.
子弹射击后不会改变方向或速度,所以它不需要发送移动更新。
Each client can reliably calculate the position of the bullet.
每个客户端都能可靠地计算出子弹的位置。
By setting the send rate to zero so the position is not synchronized over the network, and allowing each Client to calculate to position of the bullet, the overall network traffic is reduced to improve game performance.
通过将发送速率设置为零,使得该位置在网络上不同步,并允许每个客户端计算出子弹的位置,从而减少了整个网络流量,从而提高了游戏的性能。
Select the NetworkManager in the Hierarchy Window.
在层次结构窗口中选择NetworkManager。
With the NetworkManager selected,
使其选择,
...
open the Spawn Info foldout.
打开生成的信息foldout。
In the list Registered Spawnable Prefabs, add a new row with the + button.
在列表注册的可生成的Prefabs中,添加一个带有+按钮的新行。
With the NetworkManager selected,
使其选择,
…
add the Bullet prefab to the new row in the Registered Spawnable Prefabs list.
在已注册的可生成的Prefabs列表中添加子弹预置到新行。
Next, the PlayerController script needs to be updated to make the shooting code network aware.
接下来,需要更新PlayerController脚本,使射击代码网络能够感知。
Open the PlayerController script for editing.
打开PlayerController脚本进行编辑。
Earlier, when we were covering how to make player movement network aware in Networking Player Movment, we discussed the architecture of a project using the Multiplayer Networking HLAPI.
早些时候,当我们讨论如何让玩家移动网络意识到网络玩家的移动时,我们讨论了一个使用多人网络的HLAPI的项目的架构。
The basic principle is that the Server and all of the Clients are executing the same code from the same scripts on the same GameObjects at the same time.
基本原则是,服务器和所有客户端同时在相同的游戏对象上执行相同的代码。
One way to control the flow of logic in a script being shared by the Server and multiple Clients was the check against isLocalPlayer to control which objects can execute what code.
在服务器和多个客户机共享的脚本中控制逻辑流的一种方法是检查isLocalPlayer,以控制哪些对象可以执行什么代码。
Another control is the [Command] attribute.
另一个控件是[命令]属性。
The [Command] attribute indicates that the following function will be called by the Client, but will be run on the Server.
[命令]属性指示客户端调用以下函数,但将在服务器上运行。
Any arguments in the function will automatically be passed to the Server with the Command.
函数中的任何参数都将自动通过命令传递给服务器。
Commands can only be sent from the local player object.
命令只能从本地播放器对象发送。
When making a networked command, the function name must begin with “Cmd”.
在创建网络命令时,函数名必须以“Cmd”开头。
For more information on the [Command] attribute please see Remote Actions.
有关[命令]属性的更多信息,请参见远程操作。
Add the [Command] attribute to the Fire function, making this a networked command.
将[命令]属性添加到Fire函数中,使之成为一个网络命令。
Change the function name to “CmdFire” by adding the “Cmd” prefix.
通过添加“Cmd”前缀将函数名更改为“CmdFire”。
[Command]
void CmdFire()
Update the function name being called in Update to CmdFire.
更新CmdFire更新的函数名。
CmdFire();
The next concept, one that is somewhat unique to Multiplayer Networking, is the concept of Network Spawning.
下一个概念,是多玩家网络特有的,是网络生成的概念。
In the Multiplayer Networking HLAPI “Spawn” means more than just “Instantiate”.
在多人网络中,HLAPI“衍生”不仅仅意味着“实例化”。
It means to create a GameObject on the Server and on all of the Clients connected to the Server.
它意味着在服务器上和所有连接到服务器的客户机上创建一个GameObject。
The GameObject will then be managed by the spawning system;
游戏对象将由产卵系统来管理;
state updates are sent to Clients when the object changes on the Server, the GameObject will be destroyed on Clients when it is destroyed on the Server, and the spawned GameObject be added to the set of networked GameObjects that the Server is managing so that if another Client joins the game later, the objects will also be spawned on that Client in the correct state.
状态更新发送到客户服务器上的对象变化时,GameObject将被摧毁时摧毁了在服务器上,客户和催生了GameObject被添加到组服务器管理的网络化GameObjects如果另一个客户机加入游戏后,对象也将催生了客户在正确的状态。
For more information on Network Spawning please see Object Spawning.
有关网络生成的更多信息,请参见对象生成。
Add a NetworkServer.
添加一个NetworkServer。
Spawn function to spawn the bullet.
衍生函数来产生子弹。
NetworkServer.Spawn(bullet);
The final script should now look like this:
PlayerController
C#
usingUnityEngine;
usingUnityEngine.Networking;
publicclassPlayerController:NetworkBehaviour
{
publicGameObject bulletPrefab;
publicTransform bulletSpawn;
voidUpdate()
{
if(!isLocalPlayer)
{
return;
}
var x=Input.GetAxis("Horizontal")*Time.deltaTime* 150.0f;
var z=Input.GetAxis("Vertical")*Time.deltaTime* 3.0f;
transform.Rotate(0, x, 0);
transform.Translate(0, 0, z);
if(Input.GetKeyDown(KeyCode.Space))
{
CmdFire();
}
}
// This [Command] code is called on the Client …
// … but it is run on the Server!
[Command]
voidCmdFire()
{
// Create the Bullet from the Bullet Prefabvar bullet=(GameObject)Instantiate( bulletPrefab, bulletSpawn.position, bulletSpawn.rotation);
// Add velocity to the bulletbullet.GetComponent().velocity=bullet.transform.forward* 6;
// Spawn the bullet on the ClientsNetworkServer.Spawn(bullet);
// Destroy the bullet after 2 secondsDestroy(bullet, 2.0f);
}
publicoverridevoidOnStartLocalPlayer ()
{
GetComponent().material.color=Color.blue;
}
}
Save the PlayerController script.
保存该脚本。
Return to Unity.
回到Unity。
Test the current state of the project.
测试项目的当前状态。
Build and Run this scene as a standalone application.
构建并运行这个场景作为一个独立的应用程序。
Click the Host button from the in-game UI to start this game as a Host.
单击游戏内UI中的主机按钮以作为主机启动此游戏。
Move the player GameObject.
玩家GameObject移动。
Return to Unity.
回到Unity。
Enter Play Mode.
进入播放模式。
Click the LAN Client button from the in-game UI to connect to the Host as a Client.
单击游戏内UI中的LAN客户端按钮以连接到主机作为客户端。
Pressing the spacebar should now create a new bullet GameObject on all Clients for the correct player.
按下空格键现在应该为正确的玩家创建一个新的子弹游戏对象。
Each player should be able to shoot at the other.
每个球员都应该能够投篮。
Note, however, that the bullet GameObjects simply bounce off the other player and they have no apparent effect on the other player.
然而,请注意,弹子游戏物体只是弹起另一个玩家,他们对另一个玩家没有明显的影响。
Close the standalone player.
关闭独立的球员。
Return to Unity.
回到Unity。
Exit Play Mode.
退出播放模式。