使用Unity自带的NetWorkView实现简单的聊天系统

众所周知,在游戏中,我们经常会简单带聊天系统。一般,我们常见的有公会聊天,也就是大家熟知的QQ群聊,还有就是私聊,相信大家都懂得。好了, 废话不多扯了,我们开工。

首先,我们来写服务器端的。

老规矩,我们先搭建基本的UI。我们这里仍然使用NGUI。服务器端,我们主要负责显示客户端接入情况和收集全部消息,然后同步给每个客户端。

首先,我们创建一个Sprite,重命名为BackGround,然后为其选择图集和精灵,将其颜色调整为黑色,大小为整个UIRoot。然后,我们创建一个Label,重命名为Title,这个需要什么选择一个支持中文在字体,我们可以从外部导入,不再赘叙。然后,我们输入“服务器端”,调整大小到页面顶部。然后,选中UIRoot,创建一个Sprite,命名为CreateServer,选择图集和精灵,修改颜色和尺寸。它是将用来管理我们创建服务器的。调整大小。说明下,我们所有的调整大小建议使用Anchors 来做,这样UI的尺寸比例不会再我们分辨率发生变化时改变,影响美观。然后,在CreateServer下创建一个Label用来显示“创建服务器”,一个Button,用来点击确认。

第二步,我需要创建一个Label,用来显示信息。首先,我们隐藏我们刚刚创建的CreateServer,然后创建一个Sprite,重命名为ShowInfo,调整大小和颜色。然后再其上,创建一个Label ,和一个Button。Label ,Attach一个BoxColider,然后添加TextList组件。好了,我们的服务器端的UI基本界面搭建完成了,下面开始编写脚本。

首先,我们创建一个脚本,用来管理我们的Ip地址,端口号和最大连接数。脚本如下:

using UnityEngine;
using System.Collections;

public class Global : MonoBehaviour {

    public static string ipAddress = "127.0.0.1";        //ip地址
    public static int port = 41254;            //端口号
    public static int connectCount = 10;        //最大连接数
}

Global

然后,我们保存,回到Unity中,在创建一个脚本,命名为ServerUIManager ,让后,将其挂在UIRoot上,脚本,我们用来处理服务器端的事物。包括,管理UI,点击事件等。脚本如下:

using UnityEngine;
using System.Collections;

public class ServerUIManager : MonoBehaviour {
    public GameObject createServer;        //创建服务器的管理对象
    public GameObject showInfo;        //显示客户端信息的管理对象

    private UITextList clientInfo;      //用来显示客服端信息的Label
    private bool isCreateServer = false;    //能否创建服务器
    private string message = "";        //信息

    void Start()
    {
        clientInfo = showInfo.transform.FindChild("ClientInfo").GetComponent<UITextList>();
        createServer.SetActive(true);        //显示
        showInfo.SetActive(false);        //隐藏
    }

    void Update()
    {
        if (Network.peerType == NetworkPeerType.Disconnected)
        {
            //创建服务器
            isCreateServer = true;
        }
        else if (Network.peerType == NetworkPeerType.Server)
        {
            //服务
            isCreateServer = false;
            OnServer();
        }
    }
    //当点击了创建服务器按钮时执行,
    public void OnCreateServerButtonClick()
    {
        if (isCreateServer)
        {
            //可以创建,创建服务器
            NetworkConnectionError error = Network.InitializeServer(Global.connectCount, Global.port, false);
            if (error == NetworkConnectionError.NoError)
                isCreateServer = false;        //创建成功
            else
                Debug.Log("创建失败" + error);
        }
    }
    //当服务器,初始化完成
    void OnServerInitialized()
    {
        Debug.Log("Server initialized and ready");
        createServer.SetActive(false);       //显示
        showInfo.SetActive(true);      //隐藏
        clientInfo.Clear();        //清空下textList
    }

    public void OnCloseServerButtonClick()
    {
        createServer.SetActive(true);       //显示
        showInfo.SetActive(false);      //隐藏
        Network.Disconnect();        //断开连接
        isCreateServer = true;        //重置
    }
    //服务脚本,用来获取客户端接入信息,可以收取全部客户端发的信息
    void OnServer()
    {
        int length = Network.connections.Length;    //获得链接的客户端数
        //遍历增加信息
        for (int i = 0; i < length; i++)
        {
            clientInfo.Add("客户端:" + i );
            clientInfo.Add("Ip:" + Network.connections[i].ipAddress );
            clientInfo.Add("端口:" + Network.connections[i].port + "\r\n");
            clientInfo.Add(message);
        }
    }
    [RPC]
    void ReciveMessage(string msg, NetworkMessageInfo info)
    {
        //刚从网络接收的数据的相关信息,会被保存到NetworkMessageInfo这个结构中
        message = "发送端" + info.sender + "消息: " + msg + "\n" + info.timestamp + "\n";
        //+"时间"+info.timestamp +"网络视图"+info.networkView
    }
}
  

ServerUIManager

好了,我们保存脚本,回到Unity中,选中UIRoot为其添加NetWorkView组件,然后为其拖脚本引用, 可以测试下,看有没有问题 。没有问题的话,我们就可以打包了,选择File-->Build Setting ,选择PC,...,点击PlayerSettings ,在Resolution and Presentation 选项栏中勾选上 Run In Background ,表示可以后台运行,然后打包。打包完成,我们的服务器端就完成了,然后我们编写客户端。为了以后修改方便,我们重新创建一个场景。用来编写客户端。

类似,我们先搭建基本的UI界面,在这个界面中,我们需要输入Ip地址,然后点击连接,跳转到聊天页面。在聊天页面,我们有一个面板用来显示我们的聊天信息,它需要加上UITextList组件。还需要一个Button按钮,用来发送信息。具体的跟服务器端类型,我就不赘叙了。我这边展示下我的Hierarchy面板,给大家一个参考。

好了,我们开始编写客户端脚本,我们创建一个脚本,命名为ClientUIManager ,将其挂在UIRoot上,打开脚本,编辑。在这个脚本中,我们需要获取用户输入的IP,然后连接到服务器,然后有个公共方法,用来接收用户输入的信息并且发送。然后,也是最重要的,我们有一个RPC方法,用来同步我们的信息。代码如下:

using UnityEngine;
using System.Collections;

public class ClientUIManager : MonoBehaviour {

    public GameObject connectToServer;      //连接到服务器管理对象
    public GameObject showMessage;      //消息管理对象

    private UILabel ipLabel;        //用户输入的Ip
    private UITextList messageList;        //用来展示信息
    private UILabel messageLabel;        //用来获取用户输入的信息
    private string message = "";        //信息
    private bool canConnect = false;    //能否连接
    private bool canSendMessage = false;    //能否发送
    private NetworkView nv;     //NetworkView组件引用

    void Start()
    {
        //获得各个引用
        ipLabel = connectToServer.transform.FindChild("IpInput/Label").GetComponent<UILabel>();
        messageList = showMessage.transform.FindChild("Message").GetComponent<UITextList>();
        messageLabel = showMessage.transform.FindChild("MessageInput/Label").GetComponent<UILabel>();
        nv = GetComponent<NetworkView>();

        connectToServer.SetActive(true);
        showMessage.SetActive(false);
    }
    void Update()
    {
        //没有连接时,连接
        if (Network.peerType == NetworkPeerType.Disconnected)
        {
            canConnect = true;
        }
    }
    //用户点击了连接按钮
    public void OnConnectToServerButtonClick()
    {
        //检测输入是否为空,并且利用连接
        if (ipLabel.text != "" && canConnect)
        {
            Global.ipAddress = ipLabel.text;
            //连接到对应的服务器端
            NetworkConnectionError error = Network.Connect(Global.ipAddress, Global.port);
            if (error == NetworkConnectionError.NoError)
                canConnect = false;
            else
                Debug.Log("连接出错" + error);
        }
    }
    //连接到了服务器
    void OnConnectedToServer()
    {
        Debug.Log("Connected to server");
        canConnect = false;
        canSendMessage = true;
        connectToServer.SetActive(false);
        showMessage.SetActive(true);
        messageList.Clear();        //清空消息列表
    }
    //用户点击了发送,或者按下Enter键时调用
    public void OnSendMessageButtonClick()
    {
        if (canSendMessage)
        {
            message = messageLabel.text;        //获得用户输入的文本
            //使用RPC来同步信息
            nv.RPC("ReciveMessage", RPCMode.AllBuffered,message);
        }
    }

    [RPC]
    void ReciveMessage(string msg, NetworkMessageInfo info)
    {
        //刚从网络接收的数据的相关信息,会被保存到NetworkMessageInfo这个结构中
        //+"时间"+info.timestam00p +"网络视图"+info.networkView
        message = "发送端" + info.sender + "消息: " + msg + "\n" + info.timestamp +"\n";
        messageList.Add(message);
    }
}

ClientUIManager

好了,我们同样的需要为UIRoot添加NetWorkView组件,并为其拖脚本引用。OK后,我们可以先运行我们之前的打包的Server.exe程序,然后创建服务器,再在UnityEditor中运行我们的Client场景,点击连接,看是否OK。OK后,我们打包这个场景,打包跟刚才一样。

现在,我们来测试下,我们的聊天系统。

首先,我们需要打开服务端程序,点击创建服务器,然后打开几个客户端程序,输入本地Ip后,连接到本地,试着在每个客户端中发送一条消息。如下:

客户端1:

客户端2:

OK,我们的简单的聊天系统就实现了。

总结,首先,在这个聊天系统中,我们使用了NetWorkView组件,和RPC远程过程调用,这是Unity封装好的网络组件,很简单,但是效率很低,所以在Unity5.2版本以后,就弃用了这个。当然,关于聊天等更网络相关的,我们最后自己使用Socket去封装一遍。一来,自己封装的更能满足当前项目需求,其次有很大的灵活性,我们可以随意更改和删除我们不需要的功能,这样更加节省资源,更加高效。但是,之前有个大神给我讲了一下Socket,我们还是一头雾水。有了解的小伙伴,我们一起交流交流啊。哎,无论何时都要努力啊。毕竟活到老,学到老。在这个圈子,三天不学习,就落后了。加油!!!

时间: 2024-10-20 13:37:35

使用Unity自带的NetWorkView实现简单的聊天系统的相关文章

Unity自带网络功能——NetworkView组件、Serialize、RPC

Unity拥有大量的第三方插件,专门提供了对网络功能的支持.可是,大部分开发人员第一次接触到的还是Unity自带的网络功能,也就是大家常常说到的Unity Networking API.这些API是借助于组件NetworkView发挥作用的,而它能够简化开发人员大量的网络功能编码任务.

【转】unity自带寻路Navmesh入门教程(一)

http://liweizhaolili.blog.163.com/blog/static/16230744201271161310135/ 说明:从今天开始,我阿赵打算写一些简单的教程,方便自己日后回顾,或者方便刚入门的朋友学习.水平有限请勿见怪.不过请尊重码字截图录屏的劳动,如需转载请先告诉我.谢谢! unity自从3.5版本之后,增加了NavMesh寻路的功能.在此之前,unity用户只能通过第三方插件(如Astar寻路插件)等做寻路功能.阿赵我也使用过A*寻路插件,A*的原理并不复杂,有

【转】unity自带寻路Navmesh入门教程(三)

http://liweizhaolili.blog.163.com/blog/static/16230744201271225812998/ 继续介绍NavMesh寻路的功能,接下来阿赵打算讲一下以下两个例子,先看看完成的效果: 第一个例子对于喜欢DOTA的朋友应该很熟悉了,就是不同小队分不同路线进攻的寻路,红绿蓝三个队伍分别根据三条路线进攻. 第二个例子是动态的控制道路的开关.当吊桥打开时,道路不通,当吊桥放下时,道路可以通行. 先来说说第一个例子吧,第一个例子其实很简单,只需要在之前两节的基

unity自带寻路Navmesh入门教程(一)

说明:从今天开始,我阿赵打算写一些简单的教程,方便自己日后回顾,或者方便刚入门的朋友学习.水平有限请勿见怪.不过请尊重码字截图录屏的劳动,如需转载请先告诉我.谢谢! unity自从3.5版本之后,增加了NavMesh寻路的功能.在此之前,unity用户只能通过第三方插件(如Astar寻路插件)等做寻路功能.阿赵我也使用过A*寻路插件,A*的原理并不复杂,有兴趣的朋友可以自己百度一下.不过由于不是自带的功能,所以在设定网格和烘焙的过程难免会出现很多不便.NavMesh作为unity自带的功能,用法

unity自带寻路Navmesh入门教程(三)

继续介绍NavMesh寻路的功能,接下来阿赵打算讲一下以下两个例子,先看看完成的效果: 第一个例子对于喜欢DOTA的朋友应该很熟悉了,就是不同小队分不同路线进攻的寻路,红绿蓝三个队伍分别根据三条路线进攻. 第二个例子是动态的控制道路的开关.当吊桥打开时,道路不通,当吊桥放下时,道路可以通行. 先来说说第一个例子吧,第一个例子其实很简单,只需要在之前两节的基础上修改一下层的设置就可以了. 先来分析一下我们的地形,为了做这个例子,我准备了两个plane分别作为我方基地和地方基地,然后用plane简单

【Unity】4.2 提升开发效率的捷径--导入Unity自带的资源包

分类:Unity.C#.VS2015 创建日期:2016-04-06 一.简介 Unity自带的资源包也称为标准资源包.换言之,Unity自带的所有标准资源包导入到Unity项目中以后,都会放在Project视图的Standed Assets文件夹下.如果是多平台,除了Standed Assets文件夹以外,还会有一个Edit文件夹. 如果你打开别人写的Unity项目,只要看到项目中包含有Standed Assets文件夹和Edit文件夹,你就应该马上想到,这些文件夹下的资源都是从Unity自带

Unity网络多玩家游戏开发教程第1章Unity自带网络功能

Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件,专门提供了对网络功能的支持.但是,大部分开发者第一次接触到的还是Unity自带的网络功能,也就是大家经常说到的Unity Networking API.这些API是借助于组件NetworkView发挥作用的,而它可以简化开发者大量的网络功能编码任务.本文选自<Unity网络多玩家游戏开发教程(大学霸内部资料)> NetworkView组件 在Unity中,NetworkView组件用于处理游戏在网络上

Unity模拟龙之谷人物行走简单控制

我个人挺喜欢龙之谷(DN)的人物控制的(不是广告哈....),就是人物太萌了一点,动作.打击感都挺好的. 今天用Unity简单模仿了一下DN的人物控制,当然,游戏里面动作很多,我这里只做了简单的walk和run的测试哈,但是感觉也蛮舒服的,哈哈. 期待的效果:鼠标旋转控制视角位置,滚轮控制镜头缩放.点击一次W键为行走,快速点击两次为奔跑. 1.准给工作: 场景中, 一个Camera.一块地皮.一只Cube 2.镜头的缩放和旋转实现: 看下Camera的组件: 再看下Cube的组件: mousel

SQL Server中带事务的存储过程简单举例

先来看一个概念: 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完整地执行,要么完全地不执行.那么在存储过程里添加事务,则可以保证该事务里的所有sql代码要么完全执行要么完全不执行. 举个简单的带事务的存储过程: Begin Set NOCOUNT ON; --不返回影响行数 Set XACT_ABORT ON; --使用存储过程执行事务需要开启XACT_ABORT参数(默认为OFF) delete from table1 where n