码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-10-20 22:32:21      阅读:763      评论:0      收藏:0      [点我收藏+]

标签:

众所周知,在游戏中,我们经常会简单带聊天系统。一般,我们常见的有公会聊天,也就是大家熟知的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,我们还是一头雾水。有了解的小伙伴,我们一起交流交流啊。哎,无论何时都要努力啊。毕竟活到老,学到老。在这个圈子,三天不学习,就落后了。加油!!!

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

标签:

原文地址:http://www.cnblogs.com/AhrenLi/p/4896216.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!