Unity之NetworkView聊天室

  • NetworkView是Unity封装的一套快速实现多人联机游戏的功能。以此为基础,我们可以开发各种类型的多人游戏,可以开发过关游戏的双人联机,也可以开发类似于CS的射击游戏,以房间为单位。
  • 属性
    1. isMine : Network View 是否是由本机创建的。
    2. observed:指定被观察及同步的组件或者脚本。
    3. stateSynchronization:Network View的类型。OFF为没有数据将被同步,ReliableDeltaCompressed
     为当前数据发生变化时才发送,Unreliable为强制发送数据。
    4. viewID:NetworkViewID类型的ID。
  • 函数
    1. RPC(Remote Procedure Call,远程过程调用)。在Network系统中可以理解为向其他机器发送消息,如果
      有同名函数将被调用。
    2. networkView.RPC(string funName,RPCMode mode,params object[] args);参数funName为函数
     名,参数mode指定发送的范围,可选范围包括全部连接的机器包括本机,例如,All是发送给所有机器,
     Server是发送给服务器。args是传递的参数,可传可不传, 支持类型包括int, float, string,   
     NetworkPlayer,NetworkViewID,Vector3,Quaternion,不支持List集合
    3.只要有Network View,那么任何游戏对象上的脚本的函数体前用[RPC]标注,就可以通过RPC来通知调
     用,但是函数名必须是唯一的,否则其中只有一个会被调用。
  • 聊天室:要想达到信息共享,在有客户端加入时要清除所有用户(包括客服端与服务器)之前的数据,并在客户端与服务器端都要重新加载(使用Unity自带函数)。(比如需要记录每个进入聊天室人的姓名,当某个人退出时,删除他的名字,某个人进来时,记录他的名字,并将之前的已经进入的人的名字发送给这个人。这一系列操作只需通过服务器来实现,当客户端连接时,namesInfoDictionary添加信息并发送给所有客户端,客户端断开时,移除信息并发送给所有客户端。)

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Button = UnityEngine.UI.Button;

public class MyChat : MonoBehaviour
{
    private Text peopleCount;
    private Text peopleNames;
    private Text chatText;
    private InputField inputField;
    private Button senon;
    private InputField myNameField;
    private Button createServerButton;
    private Text createServeText;
    private Button connectServerButton;
    private Text connectServerText;
    private Text warn;
    private string ip = "192.168.0.118";
    private int port = 9001;
    private bool hasConnectServer;
    private bool hasCreateServer;
    private string myName;
    private Dictionary namesInfoDictionary = new Dictionary();
    private NetworkView networkView;
    private string namesStr;
    void Start()
    {
         peopleCount = transform.Find("bg/count").GetComponent< Text>();
        peopleNames = transform.Find("bg/name").GetComponent< Text>();
        chatText = transform.Find("bg/Image/Scroll View/Viewport/Content/Text").GetComponent< Text>();
        inputField = transform.Find("bg/InputField").GetComponent< InputField>();
        senon = transform.Find("bg/sendBtn").GetComponent< Button>();
        myNameField = transform.Find("myname").GetComponent< InputField>();
        createServerButton = transform.Find("createBtn").GetComponent< Button>();
        createServeText = createServerButton.transform.Find("Text").GetComponent< Text>();
        connectServerButton = transform.Find("connectBtn").GetComponent< Button>();
        connectServerText = connectServerButton.transform.Find("Text").GetComponent< Text>();
        warn = transform.Find("warn").GetComponent< Text>();
        peopleCount.text = "0";
        peopleNames.text = "";
        chatText.text = "";
        createServeText.text = "CreateServer";
        connectServerText.text = "ConnectServer";
        warn.text = "请先创建自己的昵称,根据自己需要创建/连接服务器。";
        networkView = transform.GetComponent< NetworkView>();
        senon.onClick.AddListener(delegate
        {
            networkView.RPC("SendMsg", RPCMode.All, myName + ":" + inputField.text);
        });
        createServerButton.onClick.AddListener(delegate
        {
            if (!hasCreateServer)
            {
                if (myNameField.text != null)
                {
                    NetworkConnectionError error = Network.InitializeServer(20, port, false);
                    if (error == NetworkConnectionError.NoError)
                    {

                        myName = myNameField.text;
                        hasCreateServer = true;
                        myNameField.text = "";
                        createServeText.text = "DestroyServer";
                        warn.text = "";
                        namesInfoDictionary.Add(Network.player.ToString(), myName);
                        StoreName(namesInfoDictionary);
                        networkView.RPC("GetNames", RPCMode.All, namesStr);
                        networkView.RPC("SendMsg", RPCMode.All, myName + "创建了聊天室");
                    }
                }
                else
                {
                    warn.text = "请创建自己的名字";
                }
            }
            else
            {
                Network.Disconnect();
                hasCreateServer = false;
                createServeText.text = "CreateServer";
            }
        });
        connectServerButton.onClick.AddListener(delegate
        {
            if (!hasConnectServer)
            {
                if (myNameField.text != null)
                {
                    NetworkConnectionError error = Network.Connect(ip, port);
                    if (error == NetworkConnectionError.NoError)
                    {
                        myName = myNameField.text;
                        hasConnectServer = true;
                        myNameField.text = "";
                        connectServerText.text = "DisConnect";
                        warn.text = "";
                    }
                }
                else
                {
                    warn.text = "请创建自己的名字";
                }
            }
            else
            {
                Network.Disconnect();
                hasConnectServer = false;
                connectServerText.text = "ConnectServer";
            }
        });
    }
---------------记录name列表,因为RPC不可以传入List集合,所以要把信息转为字符串------------
    private void StoreName(Dictionary namesDictionary)
    {
        namesStr = "";
        foreach (var VARIABLE in namesDictionary)
        {
            namesStr += VARIABLE.Value + ";";
        }
    }
-------------------------------------聊天,发送信息---------------------------------------
    [RPC]
    private void SendMsg(string info)
    {
        if (info != "")
        {
            chatText.text += info + "\n";
            inputField.text = "";
        }
    }
----------------------客户端调用,通知服务器,更改namesInfoDictionary---------------------
    void OnConnectedToServer()
    {
        networkView.RPC("PlayerJoin", RPCMode.Server, myName);
        networkView.RPC("SendMsg", RPCMode.All, myName + "进入了聊天室");
    }
--------------------服务器调用,更改namesInfoDictionary,并共享name列表------------------
    [RPC]
    private void PlayerJoin(string name, NetworkMessageInfo info)
    {
        namesInfoDictionary.Add(info.sender.ToString(), name);
        StoreName(namesInfoDictionary);
        networkView.RPC("GetNames", RPCMode.All, namesStr);
    }
-------------------------------客户端断开连接,服务器调用----------------------------------
    void OnPlayerDisconnected(NetworkPlayer player)
    {

        networkView.RPC("SendMsg", RPCMode.All, namesInfoDictionary[player.ToString()] + "离开了聊天室");
        PlayerRemove(player.ToString());
    }
--------------不必使用RPC,因为更新namesInfoDictionary只需在服务器端进行。----------------
    private void PlayerRemove(string nameID)
    {
        if (namesInfoDictionary.ContainsKey(nameID))
        {
            namesInfoDictionary.Remove(nameID);
        }
        StoreName(namesInfoDictionary);
        networkView.RPC("GetNames", RPCMode.All, namesStr);
    }
---------------------------客户端与服务器更新名字列表,参数不能为List-------------------------
    [RPC]
    private void GetNames(string names)
    {
        namesStr = names;
        peopleNames.text = "";
        string[] str = namesStr.Split(';');
        foreach (var VARIABLE in str)
        {
            if (VARIABLE != "")
                peopleNames.text += VARIABLE + "\n";
        }
        peopleCount.text = (str.Length - 1).ToString();
    }
}

1.聊天室界面:
           Unity之NetworkView聊天室
2.创建服务器server
Unity之NetworkView聊天室
3.创建客户端client1,并连接服务器。(client1界面)
Unity之NetworkView聊天室
3.创建客户端client1,并连接服务器。(server界面)
Unity之NetworkView聊天室
4.client1与server互动。(server界面)
Unity之NetworkView聊天室
4.client1与server互动。(client1界面)
Unity之NetworkView聊天室
5.创建客户端client2,并连接服务器。(client2界面)
Unity之NetworkView聊天室
5.创建客户端client2,并连接服务器。(server界面)
Unity之NetworkView聊天室
5.创建客户端client2,并连接服务器。(client1界面)
Unity之NetworkView聊天室
6.client2与server互动。(client2界面)
Unity之NetworkView聊天室
6.client2与server互动。(client1界面)
Unity之NetworkView聊天室
6.client2与server互动。(server界面)
Unity之NetworkView聊天室
7.client1与client2都断开连接。(server界面)
Unity之NetworkView聊天室



  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
UnityNetworkView组件是用于实现多人游戏的网络同步功能的一部分。它允许不同玩家之间的游戏对象在网络上进行同步,并确保它们在所有连接的客户端上具有相同的状态。 下载NetworkView组件非常简单。首先,打开Unity编辑器,并确保您的项目中已经导入了Unity网络库。然后,在编辑器中打开“组件”窗口,找到“Network”类别,您将找到NetworkView组件。 要将NetworkView组件添加到游戏对象上,只需使用拖放操作将其从组件窗口拖动到框架窗口或场景视图中的游戏对象上即可。一旦添加了NetworkView组件,您可以在Inspector窗口中设置其属性和参数。 其中一个重要属性是“Observed”(观察的对象),它指定了该NetworkView组件应该同步的游戏对象。您可以选择从项目中的游戏对象列表中选择一个对象,或者通过拖放操作直接从场景中选择对象。可以为一个游戏对象添加多个NetworkView组件,以便同步多个方面的状态。 NetworkingView组件还有其他属性和方法,用于更精细地控制网络同步的方式。例如,“Synchronization”属性指定了在网络上如何同步游戏对象的变换信息。您可以选择使用基于位置、旋转和缩放的同步方式,或者自定义同步方式来适应特定的游戏需求。 总之,使用UnityNetworkView组件,您可以方便地在多个玩家之间实现游戏对象的网络同步。通过添加和配置NetworkView组件,您可以确保所有连接的客户端上的游戏对象都具有相同的状态,创建出更好的多人游戏体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烫青菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值