簡體   English   中英

從C插件向Unity3D發送字節數據的任何正確方法?

[英]Any proper way of sending byte data to Unity3D from a C plugin?

這里只是一個好奇的問題。

當您在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]);

基本上我只是將字節流編碼為字符串。 在Unity中,我然后獲取字符串的字節並從那里反序列化:

System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
Byte[] bytes = encoding.GetBytes(message);

這確實有效。 但是真的沒有辦法做到這一點嗎? 也許有人知道如何以某種替代方式完成它?

Base-64(或其他類似的基礎)是正確的方法; 不能在這里使用編碼(例如UTF8) - 編碼旨在轉換:

arbitrary string <===encoding===> structured bytes

即字節具有定義的結構; protobuf的情況並非如此; 你想要的是:

arbitrary bytes <===transform===> structured string

在大多數情況下,base-64是最方便的實現。 嚴格地說,你有時可能會高於64,但你可能不得不手動滾動它 - 不漂亮。 Base-64易於理解並得到很好的支持,使其成為一個不錯的選擇。 我不知道你是怎么用C語言做的,但在Unity中應該只是:

string s = Convert.ToBase64String(bytes);

通常,您也可以避免使用額外的緩沖區,假設您在內存中序列化為MemoryStream

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

    s = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
}

基於Marc Gravell答案的例子:

在ios方面:

-(void)sendData:(NSData*)data
{
    NSString* base64String = [data base64Encoding];
    const char* utf8String = [base64String cStringUsingEncoding:NSUTF8StringEncoding];
    UnitySendMessage("iOSNativeCommunicationManager", "dataReceived", utf8String);
}

在統一方面:

public delegate void didReceivedData( byte[] data );
public static event didReceivedData didReceivedDataEvent;

public void dataReceived( string bytesString )
{
    byte[] data = System.Convert.FromBase64String(bytesString);

    if( didReceivedDataEvent != null )
        didReceivedDataEvent(data);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM