++Unity网络基础数据库
++++Unity基本网络知识编程
++++NetworkManager类建立服务器和客户端设计模式
++++RPC(远程过程调用)技术服务器
++++Unity网络管理器网络
++Unity网络:架构
++++NetworkServer 建立服务器(注册事件)框架
++++NetworkClient 链接服务器,注册事件,注册预设体dom
++++NetworkBehavior : IsLocalPlayer,区分不一样网络对象的全部者分布式
++++Rpc技术:ide
--Command :从客户端发起,在服务器执行。
--RpcClient : 从服务器发起,在客户端执行。
++++同步变量:
--[SyncVar] : float int v3[struct] string
++1、网络是什么?
++++网络:
++2、网络的做用?
++++1、信息交互
++++2、资源共享
++++3、分布式处理
++3、网络通信协议
++++1、TCP/IP 4层模型
--应用层
--传输层
--互联网层
--网络接口层
++++2、TCP/IP 5层模型
--应用层
--传输层
--互联网层
--数据链路层
--物理层
++++3、OSI 7层模型
--应用层
--表示层
--会话层
--传输层
--网络层
--数据链路层
--物理层
++4、IP地址
++++网际协议地址
++++IPV4--32位
++++IPV6--128位
++5、NAT地址转换
++++PC1: 192.168.200.2
++++内网
++++SecPath F1000-E
++++外网
--PC2: 218.197.70.2
--PC3: 218.197.70.3
--PC4: ...
++6、端口Port
++++每一个端口对应一个服务。
++7、软件系统体系结构
++++C/S
++++Client/Server
++++客户端/服务器
++8、网络游戏
++9、Unity网络框架解析
++++多人游戏和网络
++++Unity新版网络API
++++HLAPI架构图
++10、多人游戏和网络
++++思考一下,制做相似Data或者LOL这样的多人竞技游戏,须要实现那些功能?
++11、Unity新版网络API
++++Unity网络The High Level API(HLAPI)是为在Unity中建立多人在线游戏所创建的一套系统,HLAPI封装了网络游戏中大部分功能,提高开发效率,简化简单网络游戏的难度。
++++主要实现功能以下:
--网络状态管理[建立服务器、主机、客户端]
--状态同步
--过程过程调用
--互联网服务[中继服务器、游戏大厅、匹配比赛]
++12、HLAPI架构图
++++Low Level API
--Transport / Configuration
++++Messaging & Serialization
--Connection / Reader / Writer
++++Connection Management
--NetworkClient / NetworkServer
++++Object state & Actions
--NetworkIdentity / NetworkBehaviour
++++Object Life Cycle
--NetworkScene / ClientScene
++++Game Control
--NetworkManager
++++Player Control
--NetworkLobbyManager
++++Engine Integration
--NetworkTransform
--NetworkAnimator
--NetworkProimityChecker
++1.1、NetworkServer
++++NetworkServer类负责建立服务器监听接口,管理客户端的链接,它也负责处理游戏相关的一些特性: 玩家管理、监听、卵生对象和消息处理。
++1.2、Server方法(静态方法)
++++静态方法: 功能
++++Listen :根据指定端口开启服务器。
++++RegisterHandler :注册回调函数。
++++Spawn : 在全部已准备的客户端上实例化物体。
++++SpawnWithClientAuthority :跟Spawn()方法同样,而且设置客户端权限。
++++Destroy : 在全部客户端上删除物体。
++++AddPlayerForConnection :将卵生的物体与客户端创建关系。
++1.3、Server属性
++++静态变量 : 功能
++++active : 检查服务器是否开启。
++++connections : 当前全部链接的客户端列表。
++++handlers : 以字典形式返回服务器注册的全部回调方法。
++++listenPort : 服务器监听端口。
++++localClientActive : 在服务器上的客户端,即为主机是返回true。
++++maxDelay : 链接之间发送数据的最大延迟。
++1.4、建立服务器
Button StartServerButton;
void OnEnable(){
Application.runInBackground = true;
StartServerButton = GetComponent<Button>();
StartServerButton.onClick.RemoveAllListeners();
StartServerButton.onClick.AddListener(StartServer);
}
void StartServer(){
//服务器是否开启
if(!NetworkServer.active){
NetworkServer.Listen(7777); //根据指定端口,开启服务器
Debug.Log(“服务器开启”);
}
}
++2.1、NetworkClient
++++该类对象负责链接服务器,并与服务器通讯(即收到服务器消息和发送消息给服务器)。
++2.2、Client方法
++++Connect : 根据指定IP和Port链接服务器。
++++RegisterHandler : 注册回调函数。
++2.3、建立客户端
++++NetworkClient用于链接服务器
Button clientButton;
NetworkClient client;
void OnEnable(){
clientButton = GetComponent<Button>();
clientButton.onClick.AddListener(Connect);
}
void Connect(){
client = new NetworkClient(); //建立一个客户端对象
client.RegisterHandler(MsgType.Connect, OnClientConnect); //注册回调函数
client.Connect(“127.0.0.1”,7777); //链接服务器
}
//成功链接服务器以后
void OnClientConnect(NetworkMessage netMsg){
clientButton.GetComponentInChildren<Text>().text = “链接成功!”;
}
++2.4、Client属性
++++Client属性
++3.1、卵生对象
++++网络中,全部网络对象都应该由服务器产生。
++++客户端玩家对象生成步骤:
--1、客户端发请求
--2、服务器接收请求后实例化客户端对象
++3.2、卵生对象步骤
++++1、新建预设体,添加NetWorkIdentity组件,标示为网络物体。
++++2、客户端调用ClientScene.Ready()方法告知服务器本身已经准备好。
++++3、客户端调用ClientScene.RegisterPrefab()注册网络预设体。
++++4、客户端调用ClientScene.AddPlayer()方法告诉服务器卵生对象。
++++5、服务器RegisterHandler->MsgType.AddPlayer的回调AddPlayer。
++++6、服务器在AddPlayer方法实例化物体,调用Spawn方法卵生。
++3.3、客户端代码
//成功链接服务器以后
void OnClientConnect(NetworkMessage msg){
clientButton.GetComponentInChildren<Text>().text = “链接成功!”;
ClientScene.Ready(msg.conn); //告诉服务器已就位
ClientScene.RegisterPrefab(playerPrefab); //提早注册网络预设体
ClientScene.AddPlayer(0); //告诉服务器实例化预设体,参数暂不重要
}
++3.4、服务器代码
void OnServerAddPlayer(NetworkMessage netMsg){
Debug.Log(“收到客户端发送添加玩家的请求”);
GameObject player = (GameObject)Instantiate(playerPrefab);
//将物体与客户端创建关系,即表示该物体由该客户端生成
NetworkServer.AddPlayerForConnection(netMsg.conn, player, 0);
//卵生[同步到其余客户端]
NetworkServer.Spawn(player);
}
++4.1、NetworkIdentity
++++NetworkIdentity组件是网络的核心,用NetworkServer.Spawn卵生的物体都必须具有该组件。该组件在卵生的时候会自动分配assetId和权限。
++++属性: 功能
++++isClient : 物体在客户端上时返回True。
++++isServer : 物体在服务器上时返回True。
++++hasAuthority : 有权限时返回True。
++++localPlayerAuthority : 只有当本地的客户端玩家时返回True。
++4.2、NetworkBehaiour
++++NetworkBehavior组件是一个特殊组件,它依赖NetworkIdentity组件,用来实现RPC技术和状态同步属性。咱们想实现网络物体的控制脚本,必须继承自NetworkBehaviour。
public class PlayerScript:NetworkBehavior{
[SyncVar]
public int HP;
[ClientCallback] //表示只在客户端调用
void Update(){
if(isLocalPlayer){
//表示本地客户端玩家
h = Input.GetAxis(“Horizontal”);
v = Input.GetAxis(“Vertical”);
transform.Translate(new Vector(h,0,v) *Time.deltaTime);
}
}
}
++4.3、特性
++++NetworkBehaviour组件内包含的经常使用特性[Attrivute]以下:
--[SyncVar] : 用于标识序列化变量,实现变量同步。
--[Client] : 表示只能在客户端调用。
--[ClientCallback] : 表示客户端执行的回调。
--[Command] : 表示客户端向服务器发送的命令,在服务器执行。
--[ClientRpc] : 表示服务器向客户端发送的命令,在客户端执行。
++1、远程调用
++++网络系统能够实现客户端和服务器的通讯,咱们将这种通讯称之为: 远程调用(Remote Procedure Calls),即RPC。
++++RPC框架能够方便实现方法调用,使用户不须要关心如何编码、链接和传输。
++++Unity中的RPC有两种类型:
--客户端调用服务器方法(Command)
--服务器调用客户端方法(ClientRpc)
++2、RPC类型图解
++++Command : 由客户端发送给服务器[在服务器执行方法]
++++ClientRPC : 由服务器发送给客户端[在客户端执行方法]
++3、RPC编程步骤
++++编程:
public class RPCTest:NetworkBehaviour{
private GameObject img;
void Start(){
img = Resources.Load(“Canvas”) as GameObject;
CmdTest();
}
void Update(){
if(!isLocalPlayer){
return;
}
if(Input.GetKeyDown(KeyCode.Space)){
CmdTest();
}
}
[Command] //表示为RPC方法--Command类型,方法名必须加前缀Cmd
void CmdTest(){ //Command方法只能在服务器调用
Instantiate(img);
Debug.Log(1);
}
}
++++前提: 建立好网络工程。
--第一步: 给客户端新建脚本RPCTest,继承自NetworkBehaviour。
--第二步: 建立Command方法或ClientRPC方法。
--第三步: 调用RPC方法。
++1、NetworkManager组件
++++网络管理器(NetworkManager)是Unity新版网络HLAPI中的一个核心组件,该组件封装了网络建立、运行和Debug等各类方法。
++++初级开发者,不须要写一行代码,便可实现简单的网络游戏。
++2、组件方法讲解
++++方法 : 功能
++++StartServer : 调用该方法,将开启一个新服务器。
++++OnStartServer : 回调方法,服务器开启后会自动调用该方法[On前缀方法为回调方法]
++++StartHost : 调用该方法,将开启一个主机。
++++OnStartHost : 回调方法,主机开启后会自动调用该方法。
++++OnServerConnect : 服务器回调方法,当有客户端链接时调用。
++++OnClientConnect : 客户端回调方法,当客户端链接到服务器时调用。
++练习:
++++新建脚本MyNetworkManager组件,继承自NetworkManager组件,使用OnGUI回调函数,绘制按钮,开启服务器,并在服务器开启以后自动输出:Server OK!
++++NetworkManager组件在UnityEngine.Networking命名空间下。
++++思考:
public class MyNetworkManager:NetworkManager{
bool isAtStartUp = false;
void OnGUI(){
if(isAtStartUp){
this.enabled=false;
}
if(GUILayout.Button(“建立服务器”)){ //客户端如何链接?
StartServer();
isAtStartUp = true;
}
}
public override void OnStartServer(){
base.OnStartServer();
print(“Server OK!”);
}
}
++组件属性讲解
++3、使用步骤
++++1、新建场景A,新建一个空物体,并给其添加NetworkManager组件和NetworkManagerHUD组件。
++++2、保存场景,并添加到Scenes In Build中。
++++3、将场景A拖到NetworkManager的Offline Scene框中。
++++4、新建场景B,保存并添加到Scenes In Build中。
++++5、将场景B拖到NetworkManager的Online Scene中。
++++6、新建一个小球,添加组件Network Identity组件,勾选Local Player Authority选项,拖成预设体,在Hierarchy视图中删除该物体。
++++7、将预设体小球拖到NetworkManager的Player Prefab框中,运行程序。
++总结
++++NetworkManager包含功能以下:
--游戏状态管理
--卵生管理
--场景管理
--Debug输出
--匹配比赛
--用户自定义
++UNet的一个简单应用
++++MyNet_AppConst.cs
++++Scene02NetWorkManager.cs
++++Scene02PlayerAController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyNet_AppConst{
public const int myServerPort=34567;
public const string myServerIp= “127.0.0.1”;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //引入UI命名空间
using unityEngine.Networking; //引入Unet网络命名空间
publicclassScene02NetWorkManager:MonoBehaviour{
[HideInInspector]
public static Scene02NetWorkManager MyNetInstance; //一个快捷访问简单实例
Button m_createServerBtn; //1、建立服务器button
Button m_connectServBth;
InputField m_myInputServIp;
InputField m_myInputServPort;
NetworkClient m_MyClient;
public GameObject mPlayerPrefab; //16、增长玩家
private void Awake(){
myNetInstance = this;
//0、后台运行
Application.runInBackground = true;
}
void Start(){
//2、找到建立服务器的button
m_createServerBtn = GameObject.Find(“Button_CreateServer”).GetComponent<Button>();
m_createServerBtn.onClick.AddListener(OnMyServerInitAction);
m_MyClient = new NetworkClient();
m_connectServBtn = GameObject.Find(“Button_ConnectServer”).GetComponent<Button>();
m_connectServBtn.onClick.AddListener(OnMyClientConnectToServAction);
m_myInputServIp = GameObject.Find(“InputField_ServIP”).GetComponent<InputField>();
m_myInputServPort = GameObject.Find(“InputField_ServPort”).GetComponet<InputField>();
}
void Update(){
}
//3、建立服务器
private void OnMyServerInitAction(){
//4、启动服务器
bool bListen = NetworkServer.Listen(MyNet_AppConst.myServerPort);
if(bListen){
m_createServerBtn.interactable = false; //取消交互
}else{
}
//5、MsgType事件注册方法
//MsgType.AddPlayer;
//MsgType.Animation;
//MsgType.AnimationParameters;
//MsgType.AnimationTrigger;
//MsgType.Command;
//MsgType.Connect;
//MsgType.CRC;
//MsgType.Disconnect;
//MsgType.Error;
//MsgType.Fragment;
//5、为事件注册方法
NetworkServer.RegisterHandler(MsgType.AddPlayer, OnMyServerAddPlayer);
NetworkServer.RegisterHandler(MsgType.Connect, OnMyServerConnectTo); //一旦有人链接到服务器,就会执行
NetworkServer.RegisterHandler(MsgType.Disconnect, OnMyServerDisConnect);
//22、对服务器玩家的建立过程单独处理
m_MyClient = ClientScene.ConnectLocalServer();
m_MyClient.RegisterHandler(MsgType.Conncet, OnMyClientConnectSuccess);
}
//6、收到客户端添加玩家的请求
private void OnMyServerAddPlayer(NetworkMessage netMsg){
//18、收到了客户端发送的添加玩家的消息
float randomPos = UnityEngine.Random.Range(-2,2);
GameObject playerA = GameObject.Instantiate(myPlayerPrefab, new Vector3(randomPos, 1,randomPos), Quaternion.identity);
//19、为该游戏对象指明权限
NetworkServer.AddPlayerForConnection(netMsg.conn, playerA, 0);
//20、卵生出去
NetworkServer.Spawn(playerA);
}
//7、有人链接服务器的回调方法
private void OnMyServerConnectTo(NetworkMessage netMsg){
}
//8、有人断开服务器的回调方法
private void OnMyServerDisConnect(NetworkMessage netMsg){
}
//点击链接服务器的事件
private void OnMyClientConnectToServAction(){
//12、链接服务器
string servIpStr;
int servPortInt;
if(m_myInputServIp.text.Length == 0){
servIpStr = MyNet_AppConst.myServerIp;
}else{
servIpStr = m_myInputServIp.text;
}
if(m_myInputServPort.text.Length == 0){
servPortInt = MyNet_AppConst.myServerPort;
}else{
servPortInt = int.Parse(m_myInputServPort.text);
}
m_MyClient.Connect(servIpStr, servPortInt); //链接服务器
//13、注册链接成功的回调
m_MyClient.RegisterHandler(MsgType.Connect, OnMyClientConnectSuccess);
}
//14、客户端链接服务器成功的方法
public void OnMyClientConnectSuccess(NetworkMessage netMsg){
//15、告诉服务器,当前客户端已经准备好
ClientScene.Ready(netMsg.conn);
//21、注册预制体
ClientScene.RegisterPrefab(mPlayerPrefab); //fix:特别重要
//17、实例化预设体
//网络游戏对象必须由服务器产生,卵生到客户端
ClientScene.AddPlayer(0); //发送 //fix:特别重要
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Scene02PlayerAContoller:NetworkBehaiour{
float hor,ver;
public GameObject bulletPrefab; //子弹预设体
public Transform firePos; //炮口
//计时器
public float myTimer=0f;
public float myTimeCd=1f;
//血条
public Scrollbar myScrollbar; //血条
//血量--全局变量(客户端修改,全部客户端同步修改)
//同步变量的修改,必定要经过服务器。
[SyncVar]
float hp = 100; //血量
void Start(){
//血条须要共同刷新
myScrollbar.size = hp/100f; //设置血条百分比
myScrollbar.transform.rotation=Camera.main.transform.rotation; //血条和主摄像机四元数方向一致
if(isLocalPlayer == false){
return;
}
hor=Input.GetAxis(“Horizontal”);
ver=Input.GetAxis(“Vertical”);
if(hor!=0){
transform.Rotate(Vector3.up*Time.deltaTime*180f*hor);
}
if(ver!=0){
transform.postion+=transform.forward*Time.deltaTime*3f*ver;
}
//开火
myTimer -= Time.deltaTime;
if(Input.GetMouseButtonDown(0)){
if(myTimer<=0){
Cmd_MyPlayer_Fire();
myTimer = myTimeCd;
}
}
//模拟受到伤害
if(Input.GetKeyDown(KeyCode.Space)){
Cmd_MyPlayer_TakeDamage(10f);
}
}
//开火
[Commad]
public void Cmd_MyPlayer_Fire(){
//服务器中执行
GameObject mybullet = GameObject.Instantiate(bulletPrefab, firePos.position, firePos.rotation);
Rigidbody rig = mybullet.GetComponent<Rigidbody>();
rig.velocity = mybullet.transform.forward*100f;
Destroy(mybullet, 5f);
NetworkServer.Spawn(mybullet);
}
//受到伤害
[Command]
public void Cmd_MyPlayer_TakeDamage(float damage){
hp -= damage;
if(hp <= 0){
NetworkServer.Destroy(gameObject);
}
}
}
++Unity的UNET组件
++++新建一个UnetProject。
++++新建一个GameObject重命名为Network Manager,给它添加Network Manager组件,这是Unet提供的一个核心管理组件,能够在脚本里访问Network Manager进行网络开发。
++++还须要添加一个Network Manager HUD组件,这个用来显示UI,UI上的按钮会跟Network Manager交互。
++Network Manager HUD组件
++++LAN Host(H) : 把本机做为Server + Client,即服务器加客户端。
++++LAN Client(C) : 与服务器链接,后面填ip地址(localhost就是本机)。
++++LAN Server Only(S) : 本机只做为服务器。
++++通常在测试时才会用这个组件。
++搭建一个Player
++++如今用Unity自带的模型拼装一个Player出来(随便就行),给他添加Network Identity组件,这是一个网络标识符,拥有标识符的物体能够在网络上生成,也就是同步到其余客户端。
++++Server Only :只会在服务器端时才有权限对他进行操做。
++++Local Player Authority : 会在客户端时有权限,是一个局部角色。
++++咱们给Player选中Local Player Authority,表示运行时链接上服务器咱们也能够对他进行操做。
++++为了让他能在局域网生成,这表示咱们要生成的角色是哪一个,这样在每次联机时Network Manager会自动根据Player Prefab建立一个角色。
++++Auto Create Player : 每次服务器,客户端链接都会建立一个Player,如今运行看见的效果不明显,优化角色控制后再运行看效果。
++++新建PlayerController脚本并编辑:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
//为了能让脚本在连上局域网的同时还能分别控制物体,须要继承NetworkBehaviour
public class PlayerController:NetworkBehaviour{
public float traSpeed = 3; //移动的速度
public float rotSpeed=120; //一秒旋转的角度
void Update(){
if(!isLocalPlayer){
//isLocalPlayer是NetworkBehaviour的内置属性
//若是不是本地客户端,就返回,不执行下面的操做
return;
}
float h = Input.GetAxis(“Horizontal”);
float v = Input.GetAxis(“Vertical”);
transform.Translate(Vector3.forward*v*traSpeed*Time.deltaTime); //朝某个方向移动
transform.Rotate(Vector3.up* h *rotSpeed*Time.deltaTime); //围绕某轴旋转
}
}
++添加Network Transform组件
++++还须要给Player添加一个Network Transform组件,这是一个同步Transform的组件,包括:position、rotation、scale。它的同步是单向的,就是将你控制的物体同步到其余客户端,当你在服务端改变物体时,客户端不会跟着改变。
++添加差别化脚本
++++两个角色看起来同样,添加控制脚本。
//这是重写NetworkBehaviour内的方法
//这个方法只会在建立本地角色时调用
public override void OnStartLocalPlayer(){
GetComponent<MeshRenderer>().material.color = Color.bule;
}
++++运行:
++++本身控制的是蓝色,另一个是默认的白色。
++给角色添加枪和子弹
++++给角色添加上枪和子弹,让他能够射击。
++++还要给子弹添加上Rigidbody组件,取消重力。
++++把枪的碰撞器去掉,它不须要作检测。
#立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
++立钻哥哥推荐的拓展学习连接(Link_Url):
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
++++Unity引擎基础:http://www.javashuo.com/article/p-beommoeb-ka.html
++++Unity面向组件开发:http://www.javashuo.com/article/p-eigmuvut-dt.html
++++Unity物理系统:http://www.javashuo.com/article/p-nqvvciwv-kd.html
++++Unity2D平台开发:http://www.javashuo.com/article/p-ycaagdtj-hs.html
++++UGUI基础:http://www.javashuo.com/article/p-rukxwckw-mc.html
++++UGUI进阶:http://www.javashuo.com/article/p-wcatruhq-gt.html
++++UGUI综合:http://www.javashuo.com/article/p-dkccmqii-gg.html
++++Unity动画系统基础:http://www.javashuo.com/article/p-mbrdouxy-dq.html
++++Unity动画系统进阶:http://www.javashuo.com/article/p-aqaqpbkh-bp.html
++++Navigation导航系统:http://www.javashuo.com/article/p-dswwllas-t.html
++++Unity特效渲染:http://www.javashuo.com/article/p-ckojjyfj-bp.html
++++Unity数据存储:http://www.javashuo.com/article/p-bvlzynso-m.html
++++Unity中Sqlite数据库:http://www.javashuo.com/article/p-ejutsbxl-ca.html
++++WWW类和协程:http://www.javashuo.com/article/p-dbwmhsav-cy.html
++++Unity网络:http://www.javashuo.com/article/p-sqrlntgh-dw.html
++++C#事件:http://www.javashuo.com/article/p-zmwruvql-gm.html
++++C#委托:http://www.javashuo.com/article/p-uozpymaf-gh.html
++++C#集合:http://www.javashuo.com/article/p-sfqfdqsf-ex.html
++++C#泛型:http://www.javashuo.com/article/p-xrttqngo-ee.html
++++C#接口:http://www.javashuo.com/article/p-vhlfplgv-dm.html
++++C#静态类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630979
++++C#中System.String类:http://www.javashuo.com/article/p-olslkfao-cq.html
++++C#数据类型:http://www.javashuo.com/article/p-hmabbtmc-ba.html
++++Unity3D默认的快捷键:http://www.javashuo.com/article/p-wuwcrclr-s.html
++++游戏相关缩写:http://www.javashuo.com/article/p-mwacxwca-gm.html
++++设计模式简单整理:http://www.javashuo.com/article/p-rngqugib-hg.html
++++U3D小项目参考:https://blog.csdn.net/vrunsoftyanlz/article/details/80141811
++++UML类图:http://www.javashuo.com/article/p-sxberuew-bm.html
++++Unity知识点0001:http://www.javashuo.com/article/p-ryvdxxjr-ep.html
++++U3D_Shader编程(第一篇:快速入门篇):http://www.javashuo.com/article/p-kyppgrac-gz.html
++++U3D_Shader编程(第二篇:基础夯实篇):http://www.javashuo.com/article/p-qkyowtli-hv.html
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
--_--VRunSoft : lovezuanzuan--_--