unity android编译器,Unity 插件开发 - Android与iOS

本文是对Unity开发插件的总结。介绍了Unity端调用Android和iOS端方法的方式,如使用特定类通过JNI对应Java类等。还阐述了插件回调至Unity端的两种方法,详细说明了在Unity与Android、iOS交互时如何实现接口、传递数据,以及相关的进阶操作和拓展知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于工作需要在接入第三方 SDK ,而一些第三方 SDK 没有提供 Unity 版本,就需要自己去包装一层需要调用的接口,之后就可以在 Unity 端统一接入,直接导出可用的对应平台的工程或程序包。

前几天开始封装 iOS 平台的 SDK,至此,已经接入过手机上主流的 Android 和 iOS 两个平台的SDK,这篇文章就是对之前开发插件的一个总结。

概述

Unity 端调用 Android 端的方法,可以使用 AndroidJavaClass, AndroidJavaObject 和 AndroidJavaProxy 这三个类,通过 JNI 对应了 Java 中的类,对象和接口。

Unity 端调用 iOS 端的方法,则相对容易一些,也就是 C# 和 Objective-C 两个语言相互交互,可以注意到这两个都是 C 系语言,所以实际上 Objective-C 写的本地插件会被编译成 DLL 来给 C# 调用,处理好原始类型和引用类型的相互转换就可以了。

而反过来,插件回调至 Unity 端则有两种方法:

Unity 在 Android 和 iOS 平台上都支持调用 UnitySendMessage 方法来向 Unity 传递信息,Unity 端根据传递来的信息执行对应的逻辑。不过使用这一方法会有一些限制,我们先看一下这个方法的签名:void UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");,需要在 Unity 端有一个 GameObject 来接收信息,这个方法不能返回值,只能传递一个字符串,也就导致类型信息在这个过程中是丢失的。

下面详细介绍对应这两个平台的另一种回调方法:

Unity 与 Android

Android 端 有一个 bar 方法,接受一个 ICallback 的实例作为参数:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16package com.test.sdk;

public class Foo {

public void bar(ICallback callback) {

if(success) {

callback.onSuccess();

} else {

callback.onFailure("Something wrong");

}

}

}

public interface ICallback {

public void onSuccess();

public void onFailure(String message);

}

为了能够给 bar 方法传递一个 ICallback 实例,我们需要在 Unity 端 对应定义一个接口:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32public class ICallback : AndroidJavaProxy

{

//这里的 Action 只是为了方便传递匿名方法

Action onSuccessAction;

Action onFailureAction;

public ICallback(Action onSuccessAction,

Action onFailureAction) :

base("com.test.sdk.ICallback")

//此处传递了对应 Android 端接口的类路径

{

this.onSuccessAction = onSuccessAction;

this.onFailureAction = onFailureAction;

}

//这里的方法名要对应 Android 端接口的方法名

public void onSuccess()

{

if (onSuccess != null)

{

onSuccess.Invoke(UserInfo.FromJavaObject(userInfo));

}

}

public void onFailureAction(string message)

{

if (onFailureAction != null)

{

onFailureAction.Invoke(message);

}

}

}

接下来我们就可以在 Unity 端直接调用 bar 方法了:

1

2

3

4

5

6public void bar(ICallback callback) {

using (AndroidJavaObject fooObj = new AndroidJavaClass("com.test.sdk.Foo").CallStatic("getInstance");)

{

fooObj.Call("bar", callback);

}

}

可以看到以上场景中,我们使用 AndroidJavaProxy 对应实现了接口,使用 AndroidJavaClass 获取到 Java 类对象,通过 CallStatic 方法获取到用 AndroidJavaObject 对应表示的实例对象。

基本上这样就完成 Unity 和 Java 两端交互的功能了,Unity 端包装好之后,使用者是不需要接触到 AndroidJavaObject 这些类的。

进阶,传递引用类型

上面用到的 ICallback 接口的方法定义中,只有 String 这种类型的数据,对于字符串、数字、布尔类型,Unity 和 Java 之间是可以直接相互传递的。

那要传递其他类型怎么办呢?这里以 Java 中 ArrayList 类型为例,除了刚才提到的可以直接传递的类型,其它类型都必须指定为 AndroidJavaObject。

如需要在 Unity 中遍历,则需要这样做:

1

2

3

4

5AndroidJavaObject arrayObj = new AndroidJavaClass("com.test.sdk.FooBar").CallStatic("getArray");

for (int i = 0; i < arrayObj.Call("size"); i = i + 1)

{

Console.WriteLine("值: {0}", arrayObj.Call("get", i));

}

也就是必须使用 AndroidJavaObject 的方法将数据从其中取出来,不能直接使用 Java 端的字段和方法定义。

Unity 与 iOS

iOS端有一个 bar 方法,定义如下:

1

2

3typedef void (*BarHandler) (const char* message);

void bar(BarHandler barHandler);

对应的我们需要在 Unity 端这样定义:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18//1. 声明 iOS 端的导出方法

[DllImport("__Internal")]

//IntPtr 即表示一个函数指针

static extern void bar(IntPtr barHandler);

//2. 声明回调方法的接口

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]

public delegate void BarHandler(string message);

//3. 实现回调方法

[MonoPInvokeCallback(typeof(BarHandler))]

public static void onBar(string message)

{

Debug.Log("[ReturnValue] " + message);

}

然后在 Unity 端这样调用:

1

2

3BarHandler handler = new BarHandler(onBar);

IntPtr functionPointer = Marshal.GetFunctionPointerForDelegate(handler);

bar (functionPointer);

拓展阅读DllImport(“__Internal”) iOS 平台上的插件是静态链接的,所以这里使用 [DllImport("__Internal")],其他平台的插件是动态链接的,使用 [DllImport("PluginName")]。

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 用来标记方法为非托管 (Unmanaged) 方法,CallingConvention.Cdecl 是C 和 C++ 语言默认的调用约定。

MonoPInvokeCallback(typeof(BarHandler)) 在静态方法上使用,被 Mono 的预编译器用来将 native 回调方法转换为对应的托管方法,接收的参数为之前定义的非托管 delegate 的类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值