Unity之NetworkView聊天室

本文介绍Unity中的NetworkView组件及其在网络游戏中实现多人联机的功能。文章详细解释了关键属性如isMine、observed等,以及如何使用RPC进行远程过程调用。通过一个聊天室实例,演示了客户端与服务器之间的信息同步过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 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聊天室



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

烫青菜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值