Unity3D-network网络相关(二)

    <一>NetworkManager 类创建服务器和客户端

<1>NetworkServer类负责创建服务器监听接口,管理客户端的连接 

它也负责处理游戏相关的一些特性 :玩家管理 ,监听,卵生对象和消息处理

 

Server方法 

静态方法                 功能

Listen                   根据指定端口开启服务器

RegisterHandler   注册回调函数  (接受客户端连接请求)

Spawn                  在所有已准备的客户端上实例化物体

 SpawnWithClientAuthority   跟Spawn() 方法一样 并且设置客户端权限

Destroy                 在所有客户端上删除物体

AddPlayerForConnection   将卵生的物体与客户端建立关系

 

Server属性

静态变量                     功能

active                     检查服务器是否开启

connections           当前所有连接的客户端列表

handles                  以字典形式返回服务器注册的所有回调方法

listenPort               服务器监听端口

localClientActive   在服务器上的客户端,即为主机是返回true

maxDelay               连接之间发送数据的最大延迟

 

创建服务器

需要引入using UnityEngine.NetWorking ; 系统

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

}

//接受客户端连接请求

 

}

 

 

 

<二>NetworkClient该类对象负责连接服务器,并与服务器通信(即收到服务器消息和发送消息给服务器)

Client方法

对象方法                         功能

Connect                  根据指定IP和Port连接服务器

RegisterHandler      注册回调函数

 

创建客户端

需要引入using UnityEngine.Networking;系统

 

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 msg){

print("连接服务器成功");

 

}

 

 ****完整代码****

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking ;
using UnityEngine.UI ;
public class NetworkMangerScr : MonoBehaviour {

    // 1.创建服务器按钮
    Button iButton;
    //8.连接服务器按钮
    Button CButton;
    //12.客户端对象
    NetworkClient m_client;
    //17.网络预设体
    public  GameObject m_prefab;
    void Awake(){
        m_client = new NetworkClient ();
        Application.runInBackground = true;
        iButton = GameObject.Find ("IButton").GetComponent <Button > ();
        CButton = GameObject.Find ("CButton").GetComponent <Button > ();
        //2.移除
        iButton.onClick.RemoveAllListeners ();
        //3.绑定
        iButton.onClick.AddListener (InitServerAction);
        //9.移除
        CButton.onClick.RemoveAllListeners ();
        //10.绑定
        CButton.onClick.AddListener (ConnectSever );
    
    }
    //11连接服务器的点击事件
    void ConnectSever(){
        //13.连接服务器
        m_client.Connect("127.0.0.1",3456);
        //14.注册连接成功的回调方法
        m_client.RegisterHandler (MsgType.Connect ,OnConnectSever );
    }
    //15.连接成功的回调方法
    void OnConnectSever(NetworkMessage msg){
        print ("连接服务器成功");

        //16.场景已经准备好   客户端场景准备进入Game窗口 conn 客户端连接准备

        ClientScene.Ready (msg.conn);
        //18.向服务器注册玩家预设体
        ClientScene.RegisterPrefab (m_prefab );
        //19.添加一个玩家 使用该方法之后 服务器端的MsgType.AddPlayer 注册方法就会调用
        ClientScene.AddPlayer (0);
    


    }
    //4.创建服务器的点击事件
    void InitServerAction(){
        //根据指定端口 开启服务器
        NetworkServer.Listen (3456);
        //6.接受客户端连接请求
        NetworkServer.RegisterHandler (MsgType.AddPlayer ,OnServerAddPlayer);
        //23.
        m_client =ClientScene.ConnectLocalServer ();
        m_client.RegisterHandler (MsgType.Connect ,OnConnectSever);
    }
    //7.玩家在服务器创建玩家对象的回调方法
    void OnServerAddPlayer(NetworkMessage msg){
        //20.在服务器端 实例化网络对象

        GameObject obj=Instantiate (m_prefab ,Vector3.zero ,Quaternion.identity );

        //21. 将创建的游戏对象与某个玩家建立联系,表示该obj由客户端生成

        NetworkServer.AddPlayerForConnection (msg.conn,obj,0);
        //22.将游戏对象卵生到所有客户端
        NetworkServer.Spawn (obj);
    }
    void Start () {
      
    }
    
    // Update is called once per frame
    void Update () {
        
    }

}

<二>Unity网络卵生

网络中 ,所有网络对象都应该由服务器产生

客户端玩家对象生成步骤:

1.客户端发请求

2.服务器接收请求后实例化客户端对象

 

卵生对象步骤

1.新建预设体,添加NetworkIdentity组件 标示为网络物体

2.客户端调用ClientScene.Ready() 方法告知服务器自己已准备好

3.客户端调用ClientScene.RegisterPrefab()提前 注册网络预设体

4.客户端调用ClientScene.AddPlayer()方法告诉服务器执行卵生对象的程序,参数即给将要产生卵生对象贴一个IP

5.服务器RegisterHandler-->MsgType.AddPlayer的回调AddPlayer

6.服务器在AddPlayer方法实例化物体,调用Spawn方法卵生

<三>Unity状态同步

1.NetworkIdentity组件是网络的核心 用NetworkServer.Spawn卵生的物体都必须具备该组件

该组件在卵生的时候会自动分配assetld和权限

 

2.NetworkBehaviour组件是一个特殊组件,它依赖NetworkIdentity组件,用来实现RPC技术和状态同步属性.

我们想实现状态同步 则网络物体的控制脚本必须继承自NetworkBehaviour

 

NetworkBehaviour组件包含的常用特性[Attribute]

特性                         功能

[SyncVar]               用于标识序列化变量,实现变量同步

[Client]                   表示只能在客户端调用

[ClientCallback]     表示客户端执行的回调

[Command]            表示客户端向服务端发送的命令,在服务端执行

[ClientRpc]             表示服务端向客户端发送的命令,在客户端执行

***特别注意动画同步中 ,参数为Trigger的最为特殊 服务端不能直接执行该动画 因此需要先在客户端执行然后再在服务端执行

完整代码 (续上面代码)

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking ;
using UnityEngine.UI ;
public class PlayerScript : NetworkBehaviour {
    //血量   客户端执行服务端调用
    [SyncVar]
    float hp=100f;
    public GameObject bullet;
    Slider hpSlider;
    void Awake(){
        hpSlider = transform.Find ("Canvas/HpSlider").GetComponent <Slider >();
    }
    // Use this for initialization
    void Start () {
        //卵生到客户端
        ClientScene.RegisterPrefab (bullet );
    }
    
    // Update is called once per frame
    void Update () {
        //实时更新血条
        hpSlider.value =hp/100f;
        //判断是不是本地客户端
        if (!isLocalPlayer) {
            return;
        }
        //控制移动
        float hor=Input.GetAxis ("Horizontal");
        float ver = Input.GetAxis ("Vertical");
        if (ver!=0 ||hor!=0) {
            
            transform.position += new Vector3 (hor, ver, 0f) * 5f*Time.deltaTime ;
        }
        if (Input.GetKeyDown (KeyCode.Space )) {
            //发射子弹
            CmdFire ();
            
        }
    }
    //发射子弹
    //由[Command]修饰的方法 表示客户端调用 服务器执行 方法的名字必须以Cmd开头
    [Command]
    void CmdFire(){
        
        GameObject obj = Instantiate (bullet, transform.position+transform.right, Quaternion.identity);
        obj.GetComponent <Rigidbody > ().AddForce (transform.right  *1000f);
        NetworkServer.Spawn (obj);
    }
    void OnTriggerEnter(Collider other){
        CmdDemage ();
        Destroy (other.gameObject );
    }
    [Command ]
    void CmdDemage(){
        hp -= 20f;

    }

}

 

(动画状态同步重点)

完整代码

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking ;
public class PlayerController : NetworkBehaviour {
    Animator ani;
    // Use this for initialization
    void Start () {
        ani = GetComponent <Animator > ();
    }

    void Update () {
        if (!isLocalPlayer ) {
            return;
        }

        float ver = Input.GetAxis ("Vertical");
        float hor = Input.GetAxis ("Horizontal");
        transform.position += new Vector3 (hor,ver,0)*5f*Time.deltaTime ;
        if (Input.GetKeyDown (KeyCode.Alpha1 )) {
            //攻击
            ani.SetBool ("Attack",!ani.GetBool ("Attack"));
        }
        if (Input.GetKeyDown (KeyCode.Alpha2 )) {
            //跳跃
            CmdJump ();
        }

    }



    [Command ]
    void CmdJump(){
        //告诉服务器要执行代码 服务器去通知其他客户端执行Trigger控制的动画
        RpcJump ();
    }
    [ClientRpc ]
    void RpcJump(){
        ani.SetTrigger ("Jump");
    }

}

 

<四>RPC(远程过程调用)技术

 

需要引入Using UnityEngine.Networking; 系统

网络系统可以实现客户端和服务器的通信,则称之为:远程调用Remote Procedure Calls 即RPC

RPC框架可以方便实现方法调用 

Unity中有俩种类型: 客户端调用服务器方法(Command)  

                              服务器调用客户端方法(ClientRpc)

<完整代码看上面>

<五>Unity网络管理器

重点

网络管理器(NetworkManager)是Unity新版网络HLAPI中的一个核心组件 ,该组件封装了网络创建,运行和Debug等各种方法

初级开发者,不需要写一行代码,即可实现简单的网络游戏

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值