在做Unity游戏开发时,与后台的通信是必不可少的。我们可以用c#自带的WebRequest来与后台通信,但是这种通信方式效率是比较低的,特别是当游戏需要多人在线时,用c#来进行网络通信会完全无法满足要求。这个时候就需要用C或者C++来与后台进行通信了。所以在这儿,我主要讲一下Unity客户端如何通过C与后台服务器进行通信。
Unity中调用C的方法是通过调用用C生成的DLL库来实现的,所以我们先看看如何生成DLL文件。首先打开Visual Stdio新建Win32项目。
我先新建了一个简单的demo,实现一个加法的功能。添加DllDemo.h的头文件和DllDemo.c的源文件。这个两个文件的代码如下。
DllDemo.h文件
/*_declspec( dllexport )作是是将函数定义为导出函数,就是说函数要被外部程序调用。*/
#define EXPORTS_DEMO _declspec( dllexport )
/*定义个加法操作的方法*/
extern EXPORTS_DEMO int AddFun(int a, int b);
DllDemo.c文件,实现方法是注意要加上在.h文件中定义的EXPORTS_DEMO
#include "stdafx.h"
#include "DllDemo.h"
EXPORTS_DEMO int AddFun(int a, int b)
{
return (a + b);
}
然后点击生成,注意要生成x86和x64两个平台,生成后我们就可以在项目文件中找到生成的dll文件了
新建一个Unity项目,创建Plugins文件下,Plugins文件夹下面分别创建x86和x64两个子文件夹,将对应dll文件分别拖入响应的文件夹中
下面我们就可以调用这dll里面的方法了,调用的代码如下。
[DllImport("DllDemo")]
static extern int AddFun(int x, int y);
注意这里的方法名要与dll中声明的方法名一致,这样我们就可以在Unity中调用这个方法了。
通过一个简单的Demo我们了解了如何在Unity中调用C,现在可以开始说说如何在Unity中通过c与后台进行通信。我们需要使用到socket的知识。
c的socket知识网上有很详细的资料,一般的过程如下。
mclose = FALSE;
call = callback;
WSADATA wsaData;
WSAStartup(WINSOCK_VERSION, &wsaData);
g_soClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == g_soClient)
{
WSACleanup();
}
SOCKADDR_IN addrServer;
addrServer.sin_addr.S_un.S_addr = inet_addr(STR_SERVER_IP);
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(INT_SERVER_PORT);
int iResult;
int iTimeOut = 3000;
setsockopt(g_soClient, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimeOut, sizeof(iTimeOut));
iResult = connect(g_soClient, (SOCKADDR *)&addrServer, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == iResult)
{
puts("Failed to connect server!(Error: %d)\r\n");
WSACleanup();
ReCreateSocket();
}
我们可以在socket中开一个子线程,不断的接收和发送消息。那么Unity中如何接socket收返回来的消息呢? 这个时候我们可以用回调来接受,下面我们就来看看通过回调来使C和Unity之间传递数据。
我们首先在DllDemo.h中定义定义好回调函数,已经设置回调的方法。我定义的回调的返回参数为char*类型,这里可以随意定义成自己需要返回的数据类型。
typedef void *Callback (char* buffer);
extern EXPORTS_DEMO void SetCallback(Callback callback);
然后在DllDemo.c是实现SetCallback函数
EXPORTS_DEMO void SetCallback(Callback callback)
{
mCallback=callback;
}
现在我们能就可以使用这个mCallback回调方法来返回我们需要传递的数据了,通过socket接收到数据后,调用mCallback(data),就可以将数据返回了。接下来我们来看看Unity中的c#代码如何接收这个回调方法。
public delegate void Callback(string buf);
public Callback callback;
[DllImport("DllDemo", EntryPoint = "SetCallback", CallingConvention = CallingConvention.Cdecl)]
public extern static void SetCallback(RoomCallback callback);
/*在需要回调的地方,实现回调函数的委托*/
Callback = GameCallbackFunction;
SetCallback(Callback);
public void GameCallbackFunction(string buffer)
{
Debug.Log(buffer);
}
通过委托的方式,我们就可以接收C实时传送过来的数据了。