unity3d android 回调,Unity3D Native 插件开发(4)— 异步与回调

这篇文章的目的,主要是介绍 Unity 与 Android、iOS 直接的函数异步调用机制

使用异步回调

在 Unity 游戏中,帧率直接影响游戏体验,更高的帧率给到用户更流畅的游戏体验

特别是在手机设备上,机器性能远比不上PC机器。所以应该在 Unity 尽量避免同步的耗时方法调用,避免游戏卡顿

而一些 Native 代码调用有很多很“重”的函数调用,所以应该异步调用就十分必要

在之前的文章中已经介绍了如何在 Unity 中调用 Native 代码,本章节

消息机制

Unity 中提供了一种消息机制来解决与 Native 层代码调用的问题,Android 和 iOS 平台的函数定义如下:

iOS 函数定义在 UnityInterface.h 头文件中

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

Android 函数定义在 com.unity3d.player.UnityPlayer 类中

public static native void UnitySendMessage(String obj, String method, String msg);

Unity 提供了jar包,方便用户在 Android Studio(或ADT)中使用,Mac OS 路径为 Unity 程序子目录:

/PlaybackEngines/AndroidPlayer/Variations/mono/Development/Classes/classes.jar

Windows 路径为安装程序子目录

EditorDataPlaybackEnginesandroidplayerdevelopmentbinclasses.jar

该方法向 Unity 的一个名为 “obj” 的 GameObject 对象发送一个消息,调用 “method” 方法,传递参数为 “msg”

例如,在游戏场景中有一个名为 “SomeGameObject” 的 GameObject ,并且绑定了脚本 SomeScript.cs,其中有个方法为 SomeFunction :

namespace NameSpace {

class SomeScript : MonoBehaviour {

void SomeFunction(string msg) {

Debug.Log("get native message : " + msg);

}

}

}

那么我们在 Native 代码中调用

iOS

UnitySendMessage("SomeGameObject", "SomeFunction", "this is test message");

Android

UnitySendMessage("SomeGameObject", "SomeFunction", "this is test message");

就可以实现在 Native 代码中调用 Unity 中的方法

不过该方法限制性也比较强:

函数定义必须是带一个string参数的函数

有一帧延迟

完整的示例

我们以弹出 Native 系统提示框,在 Unity 获取用户是点击了确认还是取消为例

Unity 代码

在游戏场景中,新建一个名为 “NativeAlert” 的 GameObject,新建 NativeAlert.cs 脚本并绑定到新建的 GameObject 上;脚本中,添加如下代码:

using UnityEngine;

using System.Collections;

using System.Runtime.InteropServices;

#if UNITY_EDITOR

using UnityEditor;

#endif

public class NativeAlert : MonoBehaviour {

[DllImport ("__Internal")]

private static extern void IOS_NativeAlert (string title, string message);

void OnNativeAlertResult(string flag) {

Debug.Log ("user choose : " + flag);

}

void Start () {

Debug.Log ("start ... ");

#if UNITY_EDITOR

if(EditorUtility.DisplayDialog("choose one", "choonse Yes or No", "Yes", "No")) {

OnNativeAlertResult("YES");

}

else {

OnNativeAlertResult("NO");

}

#elif UNITY_IOS

IOS_NativeAlert("choose one", "choonse Yes or No");

#elif UNITY_ANDROID

AndroidJavaObject jo = new AndroidJavaObject("com.tencent.imsdk.Alert", "choose one", "choonse Yes or No");

if(jo == null) {

OnNativeAlertResult("NO");

}

else {

try{

jo.Call("showAlert");

}

catch(AndroidJavaException e){

Debug.Log("get android java exeption : " + e.Message);

OnNativeAlertResult("NO");

}

}

#else

OnNativeAlertResult("NO");

#endif

}

}

iOS 代码

在 Unity 目录 Assets/Plugin/iOS 目录下,新建 NativeAlert.mm 文件,并编辑添加如下代码

extern "C" {

void IOS_NativeAlert (const char* title, const char* message) {

NSLog(@"call native alert : %s , %s", title, message);

UIAlertController* alertController = [UIAlertController alertControllerWithTitle:@(title) message:@(message) preferredStyle:UIAlertControllerStyleActionSheet];

UIAlertAction* yesAction = [UIAlertAction actionWithTitle:@"YES" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

UnitySendMessage("NativeAlert", "OnNativeAlertResult", "YES");

}];

[alertController addAction:yesAction];

UIAlertAction* noAction = [UIAlertAction actionWithTitle:@"NO" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

UnitySendMessage("NativeAlert", "OnNativeAlertResult", "NO");

}];

[alertController addAction:noAction];

[UnityGetGLViewController() presentViewController:alertController animated:YES completion:^() {

NSLog(@"show alert view done");

}];

}

}

Android 代码

新建 Android 组件(Module),命名包名为 com.tencent.imsdk,新建 Alert.java 文件,并添加如下代码:

package com.tencent.imsdk;

import android.app.AlertDialog;

import android.content.DialogInterface;

import com.unity3d.player.UnityPlayer;

public class Alert {

private String mTitile;

private String mContent;

public Alert(String title, String content) {

mTitile = title;

mContent = content;

}

public void showAlert() {

UnityPlayer.currentActivity.runOnUiThread(new Runnable() {

@Override

public void run() {

new AlertDialog.Builder(UnityPlayer.currentActivity)

.setTitle(mTitile)

.setMessage(mContent)

.setPositiveButton("Yes", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

UnityPlayer.UnitySendMessage("NativeAlert", "OnNativeAlertResult", "YES");

}

})

.setNegativeButton("No", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

UnityPlayer.UnitySendMessage("NativeAlert", "OnNativeAlertResult", "NO");

}

})

.show();

}

});

}

}

这里我们将代码放到了 UiThread 中运行,后续文件将针对这一使用方式进行说明

编译组件,将jar包拷贝到 Unity 的 Assets/Plugins/Android/libs目录下(如果没有就新建相应的目录)

运行结果

编译 iOS/Android 工程并运行,可以看到 Native 弹窗,并在各自平台输出日志

user choose : YES

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值