Adding Multiplayer shooting
添加多人射擊
This section adds networking to the bullets in this example.
本節(jié)將在本例中添加網(wǎng)絡(luò)商膊。
Both the Bullet prefab and the shooting code will need to be updated.
子彈預(yù)制板和射擊代碼都需要更新霎桅。
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.
首先宣赔,子彈預(yù)制件需要一個(gè)NetworkIdentity來(lái)識(shí)別它在網(wǎng)絡(luò)上的獨(dú)特之處,一個(gè)用于同步子彈位置和旋轉(zhuǎn)的NetworkTransform侣姆,而預(yù)制件本身需要在NetworkManager上注冊(cè)為一個(gè)可生成的預(yù)置。
Select the Bullet prefab in the Project Window.
在“項(xiàng)目”窗口中選擇“子彈預(yù)置”沉噩。
With the Bullet prefab selected,
有了子彈頭捺宗,
…
find and add the component: Network > NetworkIdentity.
查找并添加組件:Network > NetworkIdentity。
…
find and add the component: Network > NetworkTransform.
查找并添加組件:網(wǎng)絡(luò)>網(wǎng)絡(luò)轉(zhuǎn)換川蒙。
Set the Network Send Rate on the NetworkTransform component to 0.
將NetworkTransform組件的網(wǎng)絡(luò)發(fā)送速率設(shè)置為0蚜厉。
The bullet doesn’t change direction or velocity after it’s shot, so it doesn’t need to send movement updates.
子彈射擊后不會(huì)改變方向或速度,所以它不需要發(fā)送移動(dòng)更新畜眨。
Each client can reliably calculate the position of the bullet.
每個(gè)客戶端都能可靠地計(jì)算出子彈的位置昼牛。
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.
通過(guò)將發(fā)送速率設(shè)置為零,使得該位置在網(wǎng)絡(luò)上不同步康聂,并允許每個(gè)客戶端計(jì)算出子彈的位置贰健,從而減少了整個(gè)網(wǎng)絡(luò)流量,從而提高了游戲的性能恬汁。
Select the NetworkManager in the Hierarchy Window.
在層次結(jié)構(gòu)窗口中選擇NetworkManager伶椿。
With the NetworkManager selected,
使其選擇,
...
open the Spawn Info foldout.
打開生成的信息foldout。
In the list Registered Spawnable Prefabs, add a new row with the + button.
在列表注冊(cè)的可生成的Prefabs中氓侧,添加一個(gè)帶有+按鈕的新行脊另。
With the NetworkManager selected,
使其選擇,
…
add the Bullet prefab to the new row in the Registered Spawnable Prefabs list.
在已注冊(cè)的可生成的Prefabs列表中添加子彈預(yù)置到新行。
Next, the PlayerController script needs to be updated to make the shooting code network aware.
接下來(lái)约巷,需要更新PlayerController腳本偎痛,使射擊代碼網(wǎng)絡(luò)能夠感知。
Open the PlayerController script for editing.
打開PlayerController腳本進(jìn)行編輯独郎。
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.
早些時(shí)候踩麦,當(dāng)我們討論如何讓玩家移動(dòng)網(wǎng)絡(luò)意識(shí)到網(wǎng)絡(luò)玩家的移動(dòng)時(shí),我們討論了一個(gè)使用多人網(wǎng)絡(luò)的HLAPI的項(xiàng)目的架構(gòu)囚聚。
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.
基本原則是靖榕,服務(wù)器和所有客戶端同時(shí)在相同的游戲?qū)ο笊蠄?zhí)行相同的代碼。
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.
在服務(wù)器和多個(gè)客戶機(jī)共享的腳本中控制邏輯流的一種方法是檢查isLocalPlayer顽铸,以控制哪些對(duì)象可以執(zhí)行什么代碼茁计。
Another control is the [Command] attribute.
另一個(gè)控件是[命令]屬性。
The [Command] attribute indicates that the following function will be called by the Client, but will be run on the Server.
[命令]屬性指示客戶端調(diào)用以下函數(shù),但將在服務(wù)器上運(yùn)行星压。
Any arguments in the function will automatically be passed to the Server with the Command.
函數(shù)中的任何參數(shù)都將自動(dòng)通過(guò)命令傳遞給服務(wù)器践剂。
Commands can only be sent from the local player object.
命令只能從本地播放器對(duì)象發(fā)送。
When making a networked command, the function name must begin with “Cmd”.
在創(chuàng)建網(wǎng)絡(luò)命令時(shí)娜膘,函數(shù)名必須以“Cmd”開頭逊脯。
For more information on the [Command] attribute please see Remote Actions.
有關(guān)[命令]屬性的更多信息,請(qǐng)參見遠(yuǎn)程操作竣贪。
Add the [Command] attribute to the Fire function, making this a networked command.
將[命令]屬性添加到Fire函數(shù)中军洼,使之成為一個(gè)網(wǎng)絡(luò)命令。
Change the function name to “CmdFire” by adding the “Cmd” prefix.
通過(guò)添加“Cmd”前綴將函數(shù)名更改為“CmdFire”演怎。
[Command]
void CmdFire()
Update the function name being called in Update to CmdFire.
更新CmdFire更新的函數(shù)名匕争。
CmdFire();
The next concept, one that is somewhat unique to Multiplayer Networking, is the concept of Network Spawning.
下一個(gè)概念,是多玩家網(wǎng)絡(luò)特有的爷耀,是網(wǎng)絡(luò)生成的概念甘桑。
In the Multiplayer Networking HLAPI “Spawn” means more than just “Instantiate”.
在多人網(wǎng)絡(luò)中,HLAPI“衍生”不僅僅意味著“實(shí)例化”歹叮。
It means to create a GameObject on the Server and on all of the Clients connected to the Server.
它意味著在服務(wù)器上和所有連接到服務(wù)器的客戶機(jī)上創(chuàng)建一個(gè)GameObject跑杭。
The GameObject will then be managed by the spawning system;
游戲?qū)ο髮⒂僧a(chǎn)卵系統(tǒng)來(lái)管理;
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.
狀態(tài)更新發(fā)送到客戶服務(wù)器上的對(duì)象變化時(shí),GameObject將被摧毀時(shí)摧毀了在服務(wù)器上,客戶和催生了GameObject被添加到組服務(wù)器管理的網(wǎng)絡(luò)化GameObjects如果另一個(gè)客戶機(jī)加入游戲后,對(duì)象也將催生了客戶在正確的狀態(tài)。
For more information on Network Spawning please see Object Spawning.
有關(guān)網(wǎng)絡(luò)生成的更多信息咆耿,請(qǐng)參見對(duì)象生成德谅。
Add a NetworkServer.
添加一個(gè)NetworkServer。
Spawn function to spawn the bullet.
衍生函數(shù)來(lái)產(chǎn)生子彈票灰。
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.
測(cè)試項(xiàng)目的當(dāng)前狀態(tài)屑迂。
Build and Run this scene as a standalone application.
構(gòu)建并運(yùn)行這個(gè)場(chǎng)景作為一個(gè)獨(dú)立的應(yīng)用程序浸策。
Click the Host button from the in-game UI to start this game as a Host.
單擊游戲內(nèi)UI中的主機(jī)按鈕以作為主機(jī)啟動(dòng)此游戲。
Move the player GameObject.
玩家GameObject移動(dòng)惹盼。
Return to Unity.
回到Unity庸汗。
Enter Play Mode.
進(jìn)入播放模式。
Click the LAN Client button from the in-game UI to connect to the Host as a Client.
單擊游戲內(nèi)UI中的LAN客戶端按鈕以連接到主機(jī)作為客戶端手报。
Pressing the spacebar should now create a new bullet GameObject on all Clients for the correct player.
按下空格鍵現(xiàn)在應(yīng)該為正確的玩家創(chuàng)建一個(gè)新的子彈游戲?qū)ο蟆?/p>
Each player should be able to shoot at the other.
每個(gè)球員都應(yīng)該能夠投籃蚯舱。
Note, however, that the bullet GameObjects simply bounce off the other player and they have no apparent effect on the other player.
然而,請(qǐng)注意掩蛤,彈子游戲物體只是彈起另一個(gè)玩家枉昏,他們對(duì)另一個(gè)玩家沒有明顯的影響。
Close the standalone player.
關(guān)閉獨(dú)立的球員揍鸟。
Return to Unity.
回到Unity兄裂。
Exit Play Mode.
退出播放模式。