Appearance
原生层与unity通讯
通常从原生层想unity发送消息会使用UnityPlayer.UnitySendMessage("TargetName","MethodName","这是参数");
这要求我们的unity场景中存在一个名为TargetName的物体,且其上挂着一个包含MethodName方法的脚本,才能接收到相关数据,操作起来有些麻烦,今天介绍下另外一种方式。
android
在java中添加一个接口文件BLListener.java并在unity中继承此文件
java
package com.tuyazuo.unityhelper;
public interface BLListener {
public void onMsg(String json); //数据处理方法,注意处理在非UI线程更新UI的问题
}
在unity中添加脚本BLListener.cs,用于接收android回调过来的消息
c#
using System.Collections;
using System.Collections.Generic;
#if UNITY_IPHONE
using System;
using System.Runtime.InteropServices;
#endif
using UnityEngine;
#if UNITY_ANDROID
/*=======================================
* 数据接收对象,需继承 AndroidJavaProxy
* 需实现 onMsg 方法,此方法供安卓调用传输数据
*=======================================
*/
public class BLListener : AndroidJavaProxy
{
public BLListener() : base("com.tuyazuo.unityhelper.BLListener") { }
public void onMsg(string json)
{
// BLHelper.instance.onMsg(json);
}
}
#endif
#if UNITY_IPHONE
public class BLListener
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void BLHandler(string msg);
[AOT.MonoPInvokeCallback(typeof(BLHandler))]
public static void onMsg(string json)
{
// BLHelper.instance.onMsg(json);
}
public IntPtr handler {
get{
BLHandler handler = new BLHandler(BLListener.onMsg);
IntPtr ptr = Marshal.GetFunctionPointerForDelegate(handler);
return ptr;
}
}
}
#endif
在自己的桥接类中调用安卓方法进行初始化,参考如下
c#
#if UNITY_ANDROID
private static AndroidJavaClass _helper;
public static AndroidJavaClass helper
{
get
{
if (_helper != null) return _helper;
_helper = new AndroidJavaClass("com.tuyazuo.unityhelper.BLHelper");
return _helper;
}
}
#endif
//初始化方法
public void Init(string param, BLListener listener)
{
#if UNITY_ANDROID
helper.CallStatic("init", param, listener);
#elif UNITY_IPHONE
init(param, listener.handler);
#endif
}
#if UNITY_IPHONE
[DllImport("__Internal")]
static extern void init(string param, System.IntPtr handler);
#endif
BLHelper.java文件参考如下
java
package com.tuyazuo.unityhelper;
import android.annotation.SuppressLint;
import android.app.Activity;
public class BLHelper {
private BLListener listener; //接收数据对象
//unity初始化专用
public static void init(String param, BLListener listener) {
this.listener = listener;
}
}
当我们在安卓层需要发送数据时就可以直接调用listener.onMsg("xxx")
,你可以在接口中自己定义更多方法。
ios
c#部分的代码已经在上面贴出。 在ios项目中新建文件BLHelper.mm
objective-c
#import <Foundation/Foundation.h>
//unity
typedef void (*BLHandler) (const char *object);
@interface BLHelper : NSObject <BLListener>
@property BLHandler handler;
@end
static BLHelper *_helper;
@implementation BLHelper
+ (BLHelper *)sharedInstance{
if(_helper == nil)
_helper = [[BLHelper alloc] init];
return _helper;
}
- (void)onMsg:(NSDictionary *)msg{
NSString *json = [[BLDelegate sharedInstance] obj2Json:msg];
self.handler(getChar(json));
}
NSString *getString(char *str){
return [NSString stringWithUTF8String:str];
}
const char *getChar(NSString *str){
return [str cStringUsingEncoding:NSUTF8StringEncoding];
}
@end
extern "C" {
void init(char *param, BLHandler handler){
[[BLHelper sharedInstance] setHandler:handler];
[[BLDelegate sharedInstance] init:getString(param) listener:[BLHelper sharedInstance]];
}
}
在你的逻辑脚本(例如BLDelegate.h)中定义协议并在init方法中保存listener对象
objective-c
#import <Foundation/Foundation.h>
@protocol BLListener <NSObject>
@required
- (void)onMsg:(NSDictionary *)msg;
@end
@interface BLDelegate : NSObject
@property (nonatomic, strong) id<BLListener> listener;
+ (BLDelegate *)sharedInstance;
- (void)init:(NSString *)param listener:(id<BLListener>) listener;
@end
调用[self.listener onMsg:dic];
就可以跟unity通讯了。