位置: 编程技术 - 正文
推荐整理分享Unity 多人联网客户端编写(unity多人联机服务器客户端),希望有所帮助,仅作参考,欢迎阅读内容。
文章相关热门搜索词:unity多人网络游戏,unity多人游戏,unity多人游戏,unity怎么多人开发,unity局域网多人游戏,unity多人网络游戏,unity多人协作,unity多人联机服务器客户端,内容如对您有帮助,希望把文章链接给更多的朋友!
Unity 多人联网客户端编写
网络编程的运用在unity现在的游戏里面是必须的。完整的游戏都需要提供网络功能。
Unity自带的Networkview效果不是很令人满意,局域网内的处理还是可以接受,但是广域网就很难适应。
为此给Unity加上我们常见的基本编程模型是很有必要的。在此,我们来采用流行Socket通信来进行。
多人网络编程里面有几个难点先解释一下:
1、网络里面如何进行持续的消息传递。
以下代码段正是解决这个问题。
Socket的有点变体现在此。
我们在游戏的脚本里面编写了一个全局的单例类。不继承MonoBehaviour的单例类。
这个类确保2件事情,
1、全局存在。
2、全局唯一。
在进行单例创建的时候进行初始化,也就是下面的init()
回答上面的问题,利用Socket进行网络消息的接收,发送。
.NET里面自带的Socket类很方便得为我们处理了很多底层得东西。
怎么进行一直得监听呀?是有通讯啊,但是只是执行了一次呀/
问题问得好,解决不断地监听秘诀在于:回调。
注意看ReceiveCallBack我们里面的最后一局。当接收消息成功之后,socket自动调用我们的回调。Buff作为参数继续参与下一轮的接收。(这是.NET Socket类里面为我们处理好的很方便的功能)。
public void init()
{
try
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Connect(_ip, _port);
Debug.Log("服务器连接成功");
_socket.BeginReceive(buff,0,,SocketFlags.None,ReceiveCallBack,buff);
}
catch
{
Debug.Log("服务器连接成功");
}
}
//连接成功之后要进行网络监听瑈
private void ReceiveCallBack(System.IAsyncResult ar)
{
Debug.Log("开始监听");
int readCount = 0;
try
{
readCount=_socket.EndReceive(ar);
byte[] temp=new byte[readCount];
System.Buffer.BlockCopy(buff,0,temp,0,readCount);
//Debug.Log(temp);
ReadMessage(temp);
}
catch (System.Exception ex)
{
_socket.Close();
}
_socket.BeginReceive(buff, 0, , SocketFlags.None, ReceiveCallBack, buff);
}
至此,我们能够持续的网络消息进行持续的接收和发送了!
2、网络接收与发送的数据是怎么一个处理。
我们来介绍一种常见的流行式。
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
底层数据数据流式里面我们采用“字节流”-Stream的式。
首先,一定要明确一点,涉及到网络同步的数据传输,式一定是客户端和服务器协商好的。我们才能对传输过来的数据进行合理的数据解析。
这里我们假定我们跟服务确定了这样一种传输协议(Protocol):
{Type,Area,Command,Message};
这里的意义就是,我们发送给服务器的stream内容的组织式就是以上面这个样子进行定义和排序的。
演示下流程
对应的数据从写入到发送到接收,解析对应的代码示例如下:
发送
注册:写入账号和密码,发送给服务器:
LoginDto dto = new LoginDto();
dto.userName = nameText.text;
dto.passWord = pwText.text;
string message = JsonConvert<LoginDto>.encode(dto);
NetWorkScript.getInstance().SendMessage(Protocol.LOGIN, 0, LoginProtocol.REG_CREQ, message);
=========================================
SendMessage的实现:
public void SendMessage(int type,int area,int command,string message)
{
ByteArray ba = new ByteArray();
ba.WriteInt(type);
ba.WriteInt(area);
ba.WriteInt(command);
ba.WriteInt(message.Length);
ba.WriteUTFBytes(message);
_socket.Send(ba.Buffer);
}
============================================
接收
由我们的单例网络脚本进行接收,注意最后一句,加入消息列表
public void ReadMessage(byte[] message)
{
MemoryStream ms = new MemoryStream(message, 0, message.Length);
ByteArray ba = new ByteArray(ms);
SocketModel model = new SocketModel();
//model.Type = ba.ReadInt();
//model.Area = ba.ReadInt();
//model.Command = ba.ReadInt();
//int length = ba.ReadInt();
//这是因为网络和本机数,需要进行一个最大的转换。
//另外第一个数表示整个消息的长度,不用不着,要去掉
int ff = System.Net.IPAddress.NetworkToHostOrder(ba.ReadInt());
model.type = System.Net.IPAddress.NetworkToHostOrder(ba.ReadInt());
model.area = System.Net.IPAddress.NetworkToHostOrder(ba.ReadInt());
model.command = System.Net.IPAddress.NetworkToHostOrder(ba.ReadInt());
int length = System.Net.IPAddress.NetworkToHostOrder(ba.ReadInt());
if (length > 0)
{
model.message = ba.ReadUTFBytes((uint)length);
}
messagelist.Add(model);
}
接下来是列表的分发,由一个队列分发脚本进行处理。每帧处理8个消息。并且根据消息的type分发到不同的handle(处理函数)里面去
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Assets.Script.Model;
/// <summary>
/// 将NetWorkScript里面获取到的Message分发给各个模块(Handle)去处理。
/// 作为一个分发的管理器。
/// 每个场景必备,回收消息分发的基本处理脚本
/// </summary>
public class MessageManagerForHandles : MonoBehaviour {
private LoginHandle _loginhandle;
private UserHandle _userhandle;
private MapHandle _maphandle;
// Use this for initialization
void Start () {
_loginhandle = GetComponent<LoginHandle>();
_userhandle = GetComponent<UserHandle>();
_maphandle = GetComponent<MapHandle>();
}
// Update is called once per frame
void Update () {
List<SocketModel> list = NetWorkScript.getInstance().getMessages();
//定义每一帧只取八条消息
for (int i = 0; i < 8; i)
{
if (list.Count > 0)
{
Debug.Log("list count:" list.Count);
SocketModel model = list[0];
OnMessage(model);
list.RemoveAt(0);
}
else {
break;
}
}
}
//消息分发给各个Handle
private void OnMessage(SocketModel model)
{
Debug.Log("model.message:"model.message);
Debug.Log("model.command:"model.command);
Debug.Log("model.type:" model.type);
switch(model.type)
{
case Protocol.LOGIN:
_loginhandle.OnMessage(model);
break;
case Protocol.USER:
_userhandle.OnMessage(model);
break;
case Protocol.MAP:
_maphandle.OnMessage(model);
break;
default:
WindowConstance.ErrorWindowList.Add(WindowConstance.SOCKET_TYPE_FAIL);
break;
}
}
}
Unity3D Mesh学习笔记2-创建MeshBuilder usingUnityEngine;usingSystem.Collections;usingSystem.Collections.Generic;//实现了MeshBuilder得类,会使得我们生成mesh的时候犯的错误更少一些publicclassMeshBuilder{privateListVect
Unity基于组件的对象模型 转载:
unity3d发布apk在android虚拟机中运行的详细步骤 这篇文章主要介绍了unity3d发布apk在android虚拟机中运行的详细步骤,需要的朋友可以参考下unity3d发布apk在android虚拟机中运行的详细步骤(unity3d导出androidapk
标签: unity多人联机服务器客户端
本文链接地址:https://www.jiuchutong.com/biancheng/382505.html 转载请保留说明!友情链接: 武汉网站建设