UnitySendMessage Library

I’ve been scouring the internet/these forums for an answer to this to no avail. I’m sorry if this has already been answered.

I’ve been working on creating an (internal) API at my company and I’ve written the API in native iOS and Android so far. I’m trying to port it to Unity and to reduce code duplication, I’m making a Unity plugin that calls/uses the native libraries. I’ve gotten it all done in Android and I’m almost done with the iOS version.

Here’s my problem, I have some calls in the iOS that call a server. When the call comes back I need to send a message back to Unity with the json’d data. From what I’ve read I need to call:

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

The problem is that this function doesn’t exist when I’m running the iOS code natively without Unity. I could just write in/uncomment the line that calls this function whenever I move the library into the Unity code, but that one step I’m bound to forget at some point. Can anyone tell me where the definition of this function is and how I can include it in my native libraries? I found a definition in “iPhone_target_Prefix.pch” but I cannot seem to include this file into the native code and still compile.

Thanks for taking the time to read!

Try wrapping it in #ifdef from something defined in one of the Unity files:

-(void)sendMessageToGameObject:(NSString*)gameObject withMethod:(NSString*)method andMessage:(NSString*)message {
    #ifdef UNITY_PRE_IOS6_SDK
    UnitySendMessage([gameObject UTF8String], [method UTF8String], [message UTF8String]);
    #endif
}

Note that you probably want to use a different define, I just grabbed that from an old file.

Thanks for the response cbaltzer!

That definitely put me in the right direction. For other’s future benefit here’s what I did:

First off, I didn’t know what #ifdef really was, I had used other # things before but never really knew what it was. Dreamora’s comment here explained it pretty well for me: http://forum.unity3d.com/threads/30015-Preprocessor-defines

td:lr, the areas enclosed by a #ifdef (or #if) and subsequent #endif have the #ifdef evaluated while compiling the code (true for all #-functions) and if the ifdef passes it includes the block of code in the final compile or removes it if the ifdef fails.

More specifically, ifdef checks if a #define statement exists or not.

So here’s what my function looked like in the end:

Objective-C Code:

+(void)SendUnityMessage:(NSString*)functionName arrayValuesToPass:(NSArray*)arrayValues {
    
    NSLog(@"trying to send unity a message");
#ifdef UNITY_VERSION
    
    NSError *error;
    NSData *arrayData = [NSJSONSerialization dataWithJSONObject:arrayValues options:NSJSONWritingPrettyPrinted error:&error];
    NSString* jsonArrayValues = [NSString stringWithCString:[arrayData bytes] encoding:NSUTF8StringEncoding];
      
    UnitySendMessage(strdup([@"NativeReciever" UTF8String]), strdup([functionName UTF8String]), strdup([jsonArrayValues UTF8String]));
   
#endif
}

To explain what’s going on here:
The function takes in the name of the function to call on the unity side and passes a NSArray of the values to pass to Unity. On my Unity side I have a gameObject named “NativeReciever” that has a MonoBehaviour subclassed script attached of the same name.

I looked through the Unity-generated libraries and chose the #define UNITY_VERSION to check for with my #ifdef. I chose this one since its in the same file as the function “UnitySendMessage” is defined in, it also came across as something that would always be there (I can’t guarantee though). Note that the #ifdef is only checking if it exists, if you want to check the value you’d have to do #if instead.

The next 3 lines take an id type object (basically any NS___ value, aka NSDictionary, NSArray, etc) and makes it into a JSON string, which I parse with MiniJSON on the Unity C# side.

Then, finally I send the message to Unity. Note the strdup([@“NativeReciever” UTF8String]) gets a char* of the NSString and then dupes it (otherwise the value tends to get garbage collected before Unity gets it).

Cheers!

Pardon the necropost, but I just wanted to say THANK YOU SO MUCH for posting your solution! Been trying to figure out how to make cross platform plugins for different build tools, and I tried using NSInvocation for UnitySendMessage.

#ifdef UNITY_VERSION fixed it perfectly, great solution :smile: