从C插件向Unity3D发送字节数据的任何正确方法?

Cod*_*gle 8 c c# objective-c protobuf-net unity-game-engine

这里只是一个好奇的问题.

当您在iOS平台上为Unity编写插件时,插件具有有限的本机到托管回调功能(从插件再到Unity).基本上这个文档: iOS插件Unity文档

说明你能够回拨的函数签名是这样的:

只能从本机代码调用与以下签名对应的脚本方法:function MethodName(message:string)

C中定义的签名如下所示:

void UnitySendMessage(const char*obj,const char*method,const char*msg);

所以这几乎意味着我只能将字符串发送回Unity.

现在在我的插件中,我使用protobuf-net来序列化对象并将它们发送回Unity以进行反序列化.我已经让这个工作,但通过一个解决方案,我觉得非常丑陋,并不是非常优雅:

Person* person = [[[[[Person builder] setId:123]
                    setName:@"Bob"]
                   setEmail:@"bob@example.com"] build];
NSData* data = [person data];

NSString *rawTest = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

UnitySendMessage("GameObject", "ReceiveProductRequestResponse", [rawTest cStringUsingEncoding:NSUTF8StringEncoding]);
Run Code Online (Sandbox Code Playgroud)

基本上我只是将字节流编码为字符串.在Unity中,我然后获取字符串的字节并从那里反序列化:

System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
Byte[] bytes = encoding.GetBytes(message);
Run Code Online (Sandbox Code Playgroud)

这确实有效.但是真的没有办法做到这一点吗?也许有人知道如何以某种替代方式完成它?

Mar*_*ell 4

Base-64(或其他类似的基地)是执行此操作的正确方法;您不能在此处使用编码(例如 UTF8) - 编码旨在转换:

arbitrary string <===encoding===> structured bytes
Run Code Online (Sandbox Code Playgroud)

即字节具有已定义的结构;protobuf 则不然;你想要的是:

arbitrary bytes <===transform===> structured string
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,base-64 是最方便的实现。严格来说,有时您可以比 64 高一点,但您可能必须手动滚动它 - 这不太好。Base-64 易于理解且得到良好支持,使其成为一个不错的选择。我不知道你在 C 中是如何做到这一点的,但在 Unity 中应该是:

string s = Convert.ToBase64String(bytes);
Run Code Online (Sandbox Code Playgroud)

通常,您还可以在此处避免额外的缓冲区,假设您将内存中序列化为MemoryStream

string s;
using(var ms = new MemoryStream()) {
    // not shown: serialization steps

    s = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
}
Run Code Online (Sandbox Code Playgroud)