上一篇文章我们学习了Unity向Android发送消息,如果Android又能给Unity回馈消息那么这就玩美了。恰好Unity for Andoid 和 IOS一样都是可以相互与Unity发送与接收消息,这篇文章MOMO就和大家好好聊聊Android向Unity发送消息的方法。在读本片博文之前,建议大家读一下我上一篇文章Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八),有关数据打包方面在上一篇中已经说的很清楚,这里就不再赘述。
我们在项目中创建两个Activity一个是主Activity一个是新打开的Activity和内容方面与上一篇文章类似。
UnityTestActivity.java 主Activity ,提供一个接口方法StartActivity(),它是由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 |
package com.xys; import android.content.Context; import android.content.Intent; import android.os.Bundle; import com.unity3d.player.UnityPlayerActivity; public class UnityTestActivity extends UnityPlayerActivity { /** Called when the activity is first created. */ Context mContext = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = this; } public void StartActivity0(String name) { Intent intent = new Intent(mContext,TestActivity0.class); intent.putExtra("name", name); this.startActivity(intent); } } |
接着是TestActivity.java 打开这个界面后,程序将在这里向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 32 33 34 35 36 37 38 39 |
package com.xys; import com.unity3d.player.UnityPlayer; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class TestActivity0 extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView text = (TextView)this.findViewById(R.id.textView1); text.setText(this.getIntent().getStringExtra("name")); final EditText edit = (EditText)this.findViewById(R.id.edit); Button close = (Button)this.findViewById(R.id.button0); close.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //注释1 UnityPlayer.UnitySendMessage("Main Camera","messgae",edit.getText().toString()); TestActivity0.this.finish(); } }); } } |
需要在程序头引入包import com.unity3d.player.UnityPlayer; 因为向Unity发送消息的静态方法写在这里。
注释1:意思是点击发送按钮后,程序将向Unity发送消息。UnityPlayer.UnitySendMessage() 参数1表示发送游戏对象的名称,参数2表示对象绑定的脚本接收该消息的方法,参数3表示本条消息发送的字符串信息,这个方法与IOS发送消息的方式非常相像。
接着,我们打开Unity工程将Android插件打包好复制在Unity工程当中,详细打包过程请看上一章,将脚本Test.cs绑定在Main Camera对象中,此时由于UnityPlayer.UnitySendMessage()方法发送消息给MainCamera对象,所以需要在Main Camera对象绑定的脚本中去接收这个消息,也就是说要在Test.cs脚本中接收。
(图片比较大,点击后浏览大图)
下面我们看看Test.cs脚本
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
using UnityEngine; using System.Collections; public class Test : MonoBehaviour { //请输入一个字符串 private string stringToEdit = "Please enter a string"; void Update () { //点击手机返回键关闭应用程序 if (Input.GetKeyDown(KeyCode.Escape) ¦¦ Input.GetKeyDown(KeyCode.Home) ) { Application.Quit(); } } void OnGUI() { //绘制一个输入框接收用户输入 stringToEdit = GUILayout.TextField (stringToEdit, GUILayout.Width(300),GUILayout.Height(100)); //一个提交按钮 if(GUILayout.Button("commit",GUILayout.Height(50))) { //注解1 using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { using( AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity")) { //调用Android插件中UnityTestActivity中StartActivity0方法,stringToEdit表示它的参数 jo.Call("StartActivity0",stringToEdit); } } } } //注解2 void messgae(string str) { stringToEdit = str; } } |
注解1:让代码放置在using中是为了告诉垃圾回收站及时的回收垃圾,建议这样来写代码。AndroidJavaClass表示一个java类,AndroidJavaObject表示一个java对象,在上一章已经明确说明。另外还有一些其它的方法,比如调用静态方法等,都在API中写的很清楚,大家可以查阅学习。
注解2:刚刚调用的方法UnityPlayer.UnitySendMessage()参数2为”message”,所以程序将调用 Main Camera对象的Test.cs脚本的message方法,参数为Android传递过来的。最后在这里修改了stringToEdit变量刷新了屏幕的UI。
打开程序后将启动Unity画面,如上图在这里我们写了输入框接收用户的键盘输入,最后用户点击commit按钮程序将打开Android的Activity,并且将字符串“Please enter a string”做为参数传递给了新Activity。
如上图所示,在新打开的Activity中已经看到Please enter a string字符串已经显示在界面当中,在布局文件中同样写了Android的高级控件 输入框与按钮,在输入框中输入字符串“xuanyusong”(任意输入),点击保存按钮将把”xuanyusong”刚刚输入的字符串传递给Unity。
如上图所示,此时在Unity中字符串“xuanyusong”已经显示在输入框中,那么这样就比较完美了实现发送与接收消息。希望大家继续支持雨松MOMO程序研究院。
源码下载地址:http://vdisk.weibo.com/s/abEoV
- 本文固定链接: https://www.xuanyusong.com/archives/676
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
雨松momo大神,请教两个问题,一个是unity发布Android后是全屏的,怎么设置成不全屏呢,第二个是android界面跳到unity场景中间有黑屏等待,能解决吗
大神你好,我用安卓调u3d,进入了u3d界面,然后我按返回键不能回到安卓界面,怎么办啊?
不退出 Android 界面 怎么给Unity 发送消息并 回调Android 方法
你好momo我现在的项目一半是android,一半是u3d,二者要互相调用是做不到的吗?如果main_activity主入口是u3d自己的activity,那jc.GetStatic(“currentActivity”); 中得到的当前静态activity应该是u3d本身的activity,那怎样才能通过这个由u3d封装好的activity调出android包里的activity呢?
又看了些博客文档,感觉稍微摸到了unity的想法事实上as里的UnityPlayerActivity与unity打包出来的activity是同一个activity所以在as里多做出来的方法可以通过 jc.GetStatic(“currentActivity”) .call调用到,我并没有新做一个activity出来,而是在unity做的那个activity里添加了一些方法这样一想就妥了
这个问题解决了吗?我也碰到了,求告知
我也出现了这个错误”Caused by: java.lang.UnsatisfiedLinkError: Native method not found: com.unity3d.player.UnityPlayer.UnitySendMessage”,我的开发工具是android studio,但当我用eclipse时就不会出现这个错误,很奇怪,研究很久了不知道怎么解决,难道是gradle编译的问题?
Unity5 打包出现”java.lang.IllegalArgumentException: already added” 错误请移步知乎:
https://www.zhihu.com/question/36016675/answer/65972738
请问一下,按照你的来制作安装的APK一直无法连接Android那一部分,但是下你的来加载APK安装又可以,实在想不通,不一样在哪。
雨松大哥您好。
在安卓程序里调用Unity程序后,当unity程序调用application.quit()退出时,主程序也跟着被退出了,
请问怎样才能在退出时返回到安卓程序界面,而不是连主程序也退出? 谢谢!
我也是这个问题,不知道您现在解决了没有
我也想知道怎么退出U3D界面,回到安卓界面。
现在行吗?我的报错是 java.lang.UnsatisfiedLinkError: No implement found for void com.unity3d.player.UnityPlayer.UnitySendMessage,以前还没问题。
雨松大哥 为什么我的unity5打安卓包的时候会出现java.lang.IllegalArgumentException: already added: Lcom/lifengapp/diandian/R$attr;这样的错误提示啊 我网上查了很多 别人也有遇到这样的问题 但是却解决不了 这个是unity5的bug吗
你现在解决了吗?
大兄弟,我人都快焦新死了
如果你没有用到res目录的文件,或者如果你只是因为启动图标用到了引用 ,你可以不要复制res(实际上官方文档上说res是不支持的)。将android:icon=”@drawable/ic_launcher” 改为android:icon=”@drawable/app_icon”
我猜这是与u3d里的配置文件共用的。我刚刚也是为这个问题找了半天。 我的需求是调用显示广告。所以完全不用res。现在已经能跑,但广告还没出来。继续调试中。我用的5.2.最新版本。
以下是官方配置示例。手册中有。
发现多出的直接不断了。。。好吧。请看手册里 Building Plugins for Android 部分
请问当某个activity继承于unity的activity时,在这个界面用了安卓原生的EditText,用软键盘输入时,只能输入不能退格删除或者清空,就是按下这些退格键和清空键时不会删除字符,请问怎么解决?
momo好~求助… 我直接把你项目下载下来打包时出现错误…UNEXPECTED TOP-LEVEL EXCEPTION:java.lang.IllegalArgumentException: already added: Lcom/xys/R$attr;………….我用的是unity5..这个和unity版本有关系吗?
没有问题哦,他的代码
本人遇到同样的问题,解决办法如下:
1 player settings里的bundle identifiers 必须设置的和.jar工程的不一样,建议改unity里的
2 AndroidManifest中的activity标签,android:name写全,使用.jar的。
Android 像U3d 发消息,错误Caused by: java.lang.UnsatisfiedLinkError: Native method not found: com.unity3d.player.UnityPlayer.UnitySendMessage:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)这个怎么解决啊。我是将unity 导出的Android project 然后进行的2次开发。
雨凇你好,我看了 好几遍了 ,官网蛮牛也查过类似。能成功 打包,导出的 eclipse 项目不能运行 好像是包名冲突了,这个不能调试吗[2015-05-29 16:39:43 – Dex Loader] Unable to execute dex: Multiple dex files define Lcom/xys/R$attr;[2015-05-29 16:39:43 – UnityTestActivity] Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lcom/xys/R$attr;
已解决,包名不一定要一致 activity 写绝对路径 可以
怎么写绝对路径啊?
你的unity 是 unity5+ 吗?我出了一个java.lang.IllegalArgumentException: already added: Lcom/lifengapp/diandian/R$attr;这样的错误提示,怎么解决呀
本人遇到同样的问题,解决办法如下:
1 player settings里的bundle identifiers 必须设置的和.jar工程的不一样,建议改unity里的
2 AndroidManifest中的activity标签,android:name写全,使用.jar的。
你的unity 是 unity5 吗?我出了一个java.lang.IllegalArgumentException: already added: Lcom/lifengapp/diandian/R$attr;这样的错误提示,怎么解决呀
Error R.layout.main