最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Unity學(xué)習(xí)筆記09聯(lián)網(wǎng)

2021-11-30 08:14 作者:挽秋_z  | 我要投稿

聯(lián)網(wǎng)

網(wǎng)絡(luò)基礎(chǔ)

多為策略游戲:MMORTS ? ? ?角色扮演游戲:MMORPG

聯(lián)網(wǎng)功能

1.現(xiàn)在的游戲引擎都提供了基本的聯(lián)網(wǎng)功能,比如LAN方式的聯(lián)網(wǎng)對(duì)戰(zhàn)。

2.大規(guī)模多人在線游戲的網(wǎng)絡(luò)處理很復(fù)雜。

局域網(wǎng)

一般沒有專用的服務(wù)器,通常是一臺(tái)機(jī)器充當(dāng)兩個(gè)角色,其他機(jī)器連接到該機(jī)器上,構(gòu)成局域網(wǎng),穩(wěn)定性

比較高。

廣域網(wǎng)

一般有一臺(tái)專用的,性能極高的作為服務(wù)器,其他所有的機(jī)器通過互聯(lián)網(wǎng)遠(yuǎn)程連接到該機(jī)器上。

游戲聯(lián)網(wǎng)的網(wǎng)絡(luò)架構(gòu)(廣域網(wǎng)下):一般是這兩種




分組交換技術(shù)

互聯(lián)網(wǎng)是一種分組交換并且容錯(cuò)的網(wǎng)絡(luò)系統(tǒng)

1.分組交換(信息被分解為多個(gè)小的包(幾個(gè)字節(jié)或千字節(jié)的大?。┓謩e發(fā)送出去。

2.容錯(cuò)(數(shù)據(jù)包在網(wǎng)絡(luò)出現(xiàn)錯(cuò)誤或者服務(wù)器發(fā)生故障的情況下仍然可以發(fā)送,如果一個(gè)服務(wù)器出現(xiàn)故障,數(shù)據(jù)包將

使用其他路徑到達(dá)目的地)

互聯(lián)網(wǎng)的協(xié)議

可以分為3層

1,最底層的是IP協(xié)議(用于報(bào)文交換網(wǎng)絡(luò)的一種面向數(shù)據(jù)的協(xié)議,定義了數(shù)據(jù)包在網(wǎng)際傳送的格式)

2,UDP協(xié)議或者TCP協(xié)議。

UDP或者TCP層將大的數(shù)據(jù)包傳給IP,IP將數(shù)據(jù)包分割為小的子數(shù)據(jù)包,為每個(gè)數(shù)據(jù)包加上一個(gè)信封再發(fā)送出去


3,最頂層的是一些應(yīng)用層協(xié)議。

推薦書籍:


聯(lián)網(wǎng)功能實(shí)現(xiàn):使用游戲引擎自帶的聯(lián)網(wǎng)模塊或者使用底層網(wǎng)絡(luò)接口自己實(shí)現(xiàn)功能


玩家連線(聯(lián)網(wǎng))

游戲聯(lián)網(wǎng)需要的幾個(gè)概念

1.網(wǎng)絡(luò)管理器(管理聯(lián)網(wǎng)物體)

2.聯(lián)網(wǎng)用戶界面

3.具備聯(lián)網(wǎng)功能的玩家預(yù)制件

4.具有聯(lián)網(wǎng)能力的腳本和游戲物體

客戶端,服務(wù)器

客戶端:連接到服務(wù)器的游戲?qū)嵗?/p>

服務(wù)器:專用服務(wù)器(廣域網(wǎng)),主機(jī)服務(wù)器(局域網(wǎng))

簡(jiǎn)單實(shí)踐

在unity的Package Manager中下載安裝Multiplayer ? HLAPI。

新建一個(gè)空物體,為其添加NetworkManager和NetworkManagerHUD組件。

制作用來聯(lián)網(wǎng)的預(yù)制件,為其添加NetworkIdentity(需要將Local Player Authority點(diǎn)上,組件是用來識(shí)別聯(lián)網(wǎng)的物

體)組件和NetworkTransfrom(可以自動(dòng)的將物體的變換在網(wǎng)絡(luò)之間進(jìn)行同步傳輸)。還添加Network Animator

組件(可以自動(dòng)的將物體的動(dòng)畫在網(wǎng)絡(luò)之間進(jìn)行同步傳輸)。但需要一個(gè)動(dòng)畫控制器,也可以直接將預(yù)制件拖拽過

去,勾選所需的屬性即可。

修改腳本的聯(lián)網(wǎng)功能,將預(yù)制件拖拽給NetworkManager的Player Prefab。

運(yùn)行游戲后,點(diǎn)擊LAN Host(H)生成一個(gè)本地主機(jī),要聯(lián)網(wǎng)的話至少需要兩個(gè)機(jī)器來聯(lián)網(wǎng),可以將當(dāng)前場(chǎng)景再生成

一個(gè)副本(file--build and run,需要為其選擇文件存儲(chǔ)位置),然后運(yùn)行兩個(gè)游戲,一個(gè)作為服務(wù)器,一個(gè)作為客

戶端,生成角色后可以在對(duì)方的場(chǎng)景里看到。

玩家角色比較特殊, 每個(gè)玩家控制自己本地的實(shí)例,然后由服務(wù)器端來完成同步


游戲物體同步

網(wǎng)絡(luò)權(quán)限Network ?Authority

1.客戶端和服務(wù)器都可以控制游戲物體行為

2.網(wǎng)絡(luò)權(quán)限指的是游戲物體如何以及在哪里被管理

3.默認(rèn)是服務(wù)器端(玩家角色特殊,是在客戶端)

動(dòng)態(tài)生成游戲物體

1.非聯(lián)網(wǎng)物體使用GameObject.Instantiate生成物體(動(dòng)態(tài)生成游戲物體:先制作好預(yù)制件,然后使用這個(gè)函數(shù))

2.而聯(lián)網(wǎng)物體需要由服務(wù)器端來生成(使用spawn方式生成,生成的物體交由Network Manager管理)

聯(lián)網(wǎng)和非聯(lián)網(wǎng)游戲物體

聯(lián)網(wǎng)游戲的場(chǎng)景中包含聯(lián)網(wǎng)和非聯(lián)網(wǎng)物體

1.聯(lián)網(wǎng)的物體需要在全網(wǎng)同步。

2.非聯(lián)網(wǎng)的物體只運(yùn)行于本地(靜態(tài)物體,比如石塊、樓梯。不需要同步的物體,比如隨風(fēng)擺動(dòng)的樹木、草叢或者

云朵)。

聯(lián)網(wǎng)物體

1.需要包含Network ldentity組件。

2.還需要開發(fā)人員指定物體的哪些屬性需要同步。

3.哪些屬性需要同步取決于游戲內(nèi)容(對(duì)于玩家或者非玩家角色的位置、朝向。帶有動(dòng)畫物體的動(dòng)畫狀態(tài)?!?shù)

值,比如游戲剩余時(shí)長(zhǎng)、玩家的能量值)

屬性同步

1.可以自動(dòng)同步的屬性

Network Transform組件來同步物體變換屬性。Network Animator組件來同步動(dòng)畫屬性。

2.無法自動(dòng)同步的屬性(在腳本里面指定)

簡(jiǎn)單實(shí)踐

Network transfrom中的Network send rate 調(diào)整為零,代表剛開始時(shí)自動(dòng)同步,之后則通過腳本來控制同步。如

果完全自動(dòng)同步的話對(duì)網(wǎng)絡(luò)的要求很高。

新建一個(gè)子彈預(yù)制件拖拽給網(wǎng)絡(luò)管理器的Registered ?Spawnable ?Prefabs(代表可網(wǎng)絡(luò)生成的物體)

修改玩家控制腳本,讓角色可以發(fā)射子彈,修改后記得將預(yù)制件賦給該腳本

using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityEngine.Networking;

namespace UnityStandardAssets.Characters.ThirdPerson
{
? ?[RequireComponent(typeof(ThirdPersonCharacter))]
? ?public class ThirdPersonUserControl : NetworkBehaviour
? ?{
? ? ? ?private ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object
? ? ? ?private Transform m_Cam; ? ? ? ? ? ? ? ? ?// A reference to the main camera in the scenes transform
? ? ? ?private Vector3 m_CamForward; ? ? ? ? ? ? // The current forward direction of the camera
? ? ? ?private Vector3 m_Move;
? ? ? ?private bool m_Jump; ? ? ? ? ? ? ? ? ? ? ?// the world-relative desired move direction, calculated from the camForward and user input.

? ? ? ?//發(fā)射子彈
? ? ? ?public GameObject bulletPrefab;

? ? ? ?private void Start()
? ? ? ?{
? ? ? ? ? ?// get the transform of the main camera
? ? ? ? ? ?if (Camera.main != null)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?m_Cam = Camera.main.transform;
? ? ? ? ? ?}
? ? ? ? ? ?else
? ? ? ? ? ?{
? ? ? ? ? ? ? ?Debug.LogWarning(
? ? ? ? ? ? ? ? ? ?"Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.", gameObject);
? ? ? ? ? ? ? ?// we use self-relative controls in this case, which probably isn't what the user wants, but hey, we warned them!
? ? ? ? ? ?}

? ? ? ? ? ?// get the third person character ( this should never be null due to require component )
? ? ? ? ? ?m_Character = GetComponent<ThirdPersonCharacter>();
? ? ? ?}


? ? ? ?private void Update()
? ? ? ?{
? ? ? ? ? ?if (!isLocalPlayer)//如果不是本地要控制的玩家角色的話,就不進(jìn)行后面的處理
? ? ? ? ? ?{
? ? ? ? ? ? ? ?return;
? ? ? ? ? ?}
? ? ? ? ? ?if (!m_Jump)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
? ? ? ? ? ?}
? ? ? ?}


? ? ? ?// Fixed update is called in sync with physics
? ? ? ?private void FixedUpdate()
? ? ? ?{
? ? ? ? ? ?if (!isLocalPlayer)//如果不是本地要控制的玩家角色的話,就不進(jìn)行后面的處理
? ? ? ? ? ?{
? ? ? ? ? ? ? ?return;
? ? ? ? ? ?}
? ? ? ? ? ?// read inputs
? ? ? ? ? ?float h = CrossPlatformInputManager.GetAxis("Horizontal");
? ? ? ? ? ?float v = CrossPlatformInputManager.GetAxis("Vertical");
? ? ? ? ? ?bool crouch = Input.GetKey(KeyCode.C);

? ? ? ? ? ?// calculate move direction to pass to character
? ? ? ? ? ?if (m_Cam != null)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?// calculate camera relative direction to move:
? ? ? ? ? ? ? ?m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).normalized;
? ? ? ? ? ? ? ?m_Move = v * m_CamForward + h * m_Cam.right;
? ? ? ? ? ?}
? ? ? ? ? ?else
? ? ? ? ? ?{
? ? ? ? ? ? ? ?// we use world-relative directions in the case of no main camera
? ? ? ? ? ? ? ?m_Move = v * Vector3.forward + h * Vector3.right;
? ? ? ? ? ?}
#if !MOBILE_INPUT
? ? ? ? ? ?// walk speed multiplier
? ? ? ? ? ?if (Input.GetKey(KeyCode.LeftShift)) m_Move *= 0.5f;
#endif

? ? ? ? ? ?// pass all parameters to the character control script
? ? ? ? ? ?m_Character.Move(m_Move, crouch, m_Jump);
? ? ? ? ? ?m_Jump = false;

? ? ? ? ? ?//
? ? ? ? ? ?if (Input.GetMouseButtonDown(0))
? ? ? ? ? ?{
? ? ? ? ? ? ? ?CmdFire();
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?public void Fire()
? ? ? ?{
? ? ? ? ? ?var bullet = Instantiate(bulletPrefab, transform.position + transform.up + transform.forward * 2,Quaternion.identity) as GameObject;
? ? ? ?}

? ? ? ?[Command]//加上這個(gè)前綴代表下面的函數(shù)是由客戶端發(fā)起調(diào)用,但是在服務(wù)器端執(zhí)行
? ? ? ?public void CmdFire()//必須加Cmd前綴,,,子彈聯(lián)網(wǎng)
? ? ? ?{
? ? ? ? ? ?var bullet = Instantiate(bulletPrefab, transform.position + transform.up + transform.forward * 2, transform.rotation) as GameObject;
? ? ? ? ? ?NetworkServer.Spawn(bullet);//生成并同步到各客戶端
? ? ? ?}
? ?}
}

玩家生命值腳本,賦給玩家預(yù)制件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class Health : NetworkBehaviour//有關(guān)網(wǎng)絡(luò)的操作需要繼承該類
{
? ?private static int hp_max = 100;//最大生命值
? ?public int hp = hp_max;//初始生命值
? ?public void GetDamage(int dmg)
? ?{
? ? ? ?if(!isServer)
? ? ? ?{
? ? ? ? ? ?return;
? ? ? ?}
? ? ? ?hp -= dmg;
? ? ? ?if(hp<0)
? ? ? ?{
? ? ? ? ? ?RpcRespawn();//生命值小于0時(shí)重置玩家
? ? ? ?}
? ?}
? ?[ClientRpc]//表示下面的函數(shù)是由服務(wù)器發(fā)起調(diào)用的,但是在客戶端來執(zhí)行
? ?public void RpcRespawn()//必須加上Rpc前綴
? ?{
? ? ? ?if(isLocalPlayer)
? ? ? ?{
? ? ? ? ? ?transform.position = Vector3.zero;//將位置重置為原點(diǎn)
? ? ? ? ? ?hp = hp_max;
? ? ? ?}
? ?}
? ?// Start is called before the first frame update
? ?void Start()
? ?{
? ? ? ?
? ?}

? ?// Update is called once per frame
? ?void Update()
? ?{
? ? ? ?
? ?}
}

子彈腳本,賦給子彈預(yù)制件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NetBullet : MonoBehaviour
{
? ?// Start is called before the first frame update
? ?void Start()
? ?{
? ? ? ?
? ?}

? ?// Update is called once per frame
? ?void Update()
? ?{
? ? ? ?
? ?}
? ?private void OnTriggerEnter(Collider other)//子彈預(yù)制件的Is trigger要點(diǎn)上
? ?{
? ? ? ?other.SendMessage("GetDamage",60,SendMessageOptions.DontRequireReceiver);//如果碰到的物體身上有GetDamage的話,執(zhí)行健康值減少60的函數(shù),因?yàn)橛锌赡艽虻狡渌奈矬w
? ?}
}


角色同步

(非玩家角色,每一個(gè)客戶端并不具備直接控制這些角色的能力,非玩家角色直接運(yùn)行于服務(wù)器端,只有服務(wù)器端

才能對(duì)其進(jìn)行控制以及網(wǎng)絡(luò)同步)

簡(jiǎn)單實(shí)踐

建立敵人預(yù)制件和腳本。

Instantiate

使用預(yù)制件在場(chǎng)景中生成物體,共有三個(gè)參數(shù),一是預(yù)制件,二是生成物體的位置,三是生成物體的朝向。

示例:

var enemy = Instantiate(enemyProfab, new Vector3(unit_pos.x, 0, unit_pos.y), rnd_rot);

生成敵人的腳本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class EnemySpawner : NetworkBehaviour
{
? ?public GameObject enemyProfab;//敵人預(yù)制件
? ?public int enemyNum = 5;//生成的敵人數(shù)量

? ?public override void OnStartServer()//服務(wù)器端開始運(yùn)行的時(shí)候生成敵人
? ?{
? ? ? ?for(int i=0;i<enemyNum;++i)
? ? ? ?{
? ? ? ? ? ?var unit_pos = Random.insideUnitCircle;//隨機(jī)生成位置,使用這個(gè)函數(shù)是生成在一個(gè)單位圓內(nèi),unit_pos代表一個(gè)二維向量類型
? ? ? ? ? ?unit_pos = unit_pos * 6;//表示單位為6
? ? ? ? ? ?var rnd_rot = Quaternion.Euler(new Vector3(0, Random.Range(-180, 180), 0));//生成一個(gè)隨機(jī)的朝向
? ? ? ? ? ?var enemy = Instantiate(enemyProfab, new Vector3(unit_pos.x, 0, unit_pos.y), rnd_rot);
? ? ? ? ? ?NetworkServer.Spawn(enemy);//由服務(wù)器端生成敵人
? ? ? ?}
? ?}
}

生成后要將敵人預(yù)制件拖拽上去。

NetworkIdentity中的Server ?Only 如果勾選則表示阻止客戶端有權(quán)利生成公用的敵人。

修改Health腳本,讓子彈可以打到敵人,并且需要將敵人預(yù)制件的IsEnemy點(diǎn)上,表示是敵人,不是玩家

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class Health : NetworkBehaviour//有關(guān)網(wǎng)絡(luò)的操作需要繼承該類
{
? ?private static int hp_max = 100;//最大生命值
? ?public int hp = hp_max;//初始生命值

? ?public bool isEnemy = false;//標(biāo)識(shí)角色是不是敵人
? ?public void GetDamage(int dmg)
? ?{
? ? ? ?if(!isServer)
? ? ? ?{
? ? ? ? ? ?return;
? ? ? ?}
? ? ? ?hp -= dmg;
? ? ? ?if(hp<0)
? ? ? ?{
? ? ? ? ? ?if (isEnemy) Destroy(gameObject);//如果敵人血量小于0讓其消失
? ? ? ? ? ?RpcRespawn();//生命值小于0時(shí)重置玩家
? ? ? ?}
? ?}
? ?[ClientRpc]//表示下面的函數(shù)是由服務(wù)器發(fā)起調(diào)用的,但是在客戶端來執(zhí)行
? ?public void RpcRespawn()//必須加上Rpc前綴
? ?{
? ? ? ?if(isLocalPlayer)
? ? ? ?{
? ? ? ? ? ?transform.position = Vector3.zero;//將位置重置為原點(diǎn)
? ? ? ? ? ?hp = hp_max;
? ? ? ?}
? ?}
? ?// Start is called before the first frame update
? ?void Start()
? ?{
? ? ? ?
? ?}

? ?// Update is called once per frame
? ?void Update()
? ?{
? ? ? ?
? ?}
}













Unity學(xué)習(xí)筆記09聯(lián)網(wǎng)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
和平区| 措勤县| 青神县| 浙江省| 通化县| 芷江| 高州市| 阳新县| 辽源市| 石泉县| 民权县| 浮梁县| 丰原市| 黄石市| 开远市| 九江县| 延长县| 南陵县| 吉隆县| 台湾省| 梁山县| 米泉市| 肥城市| 丹巴县| 安平县| 河南省| 拜城县| 吴江市| 连州市| 吴忠市| 尖扎县| 达拉特旗| 洞口县| 米林县| 石渠县| 江华| 突泉县| 淳安县| 双江| 杭锦旗| 商洛市|