首页 >Unity3D频道 >【Unity3D研究院之游戏开发】 > Unity3D研究院之与Android相互传递消息(十九)
2012
05-03

Unity3D研究院之与Android相互传递消息(十九)

          上一篇文章我们学习了Unity向Android发送消息,如果Android又能给Unity回馈消息那么这就玩美了。恰好Unity for Andoid 和 IOS一样都是可以相互与Unity发送与接收消息,这篇文章MOMO就和大家好好聊聊Android向Unity发送消息的方法。在读本片博文之前,建议大家读一下我上一篇文章Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)有关数据打包方面在上一篇中已经说的很清楚,这里就不再赘述。

我们在项目中创建两个Activity一个是主Activity一个是新打开的Activity和内容方面与上一篇文章类似。

UnityTestActivity.java 主Activity ,提供一个接口方法StartActivity(),它是由Unity中调用

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发送消息。 

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脚本中接收。

 

Unity3D研究院之与Android相互传递消息(十九) - 雨松MOMO程序研究院 - 1

(图片比较大,点击后浏览大图)

 

下面我们看看Test.cs脚本

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。

 

Unity3D研究院之与Android相互传递消息(十九) - 雨松MOMO程序研究院 - 2

 

          打开程序后将启动Unity画面,如上图在这里我们写了输入框接收用户的键盘输入,最后用户点击commit按钮程序将打开Android的Activity,并且将字符串“Please enter a string”做为参数传递给了新Activity。

 

Unity3D研究院之与Android相互传递消息(十九) - 雨松MOMO程序研究院 - 3

 

         如上图所示,在新打开的Activity中已经看到Please enter a string字符串已经显示在界面当中,在布局文件中同样写了Android的高级控件 输入框与按钮,在输入框中输入字符串“xuanyusong”(任意输入),点击保存按钮将把”xuanyusong”刚刚输入的字符串传递给Unity。

 

Unity3D研究院之与Android相互传递消息(十九) - 雨松MOMO程序研究院 - 4

 

如上图所示,此时在Unity中字符串“xuanyusong”已经显示在输入框中,那么这样就比较完美了实现发送与接收消息。希望大家继续支持雨松MOMO程序研究院。

 

源码下载地址:http://vdisk.weibo.com/s/abEoV

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

Unity3D研究院之与Android相互传递消息(十九)》有 104 条评论

  1. 请问下如何unity3d读取Android手机上的GPS和陀螺仪的信息呢

  2. 闫烁说:

    BuildAssetBundleExplicitAssetNames这个方法用过么,大神。

  3. dfdsfd说:

    AndroidJavaObject.Dispose 这个方法什么时候调用呢

  4. 图片没发出,是这样的:Building DEX Failed! Failed to compile Java code to DEX.See the Console for details.

  5. 刚下了代码,但打包时遇到这个问题。博主看下是与JDK有关么,我的是jdk7。如果不是,怎么解决呢。。求解答,谢谢

  6. Burn说:

    雨松大哥,为什么我用你给的U3D源代码发布的apk文件都不能装在android机上,我照着你做的工程,发布出来的apk能装,但是一打开就崩溃了。(发布的时候,注意了包名的对应,版本是2.1的)。求指导!我的邮箱:334974857@qq.com

  7. Burn说:

    谢谢博主,刚好要用到这个。每次来都帮你刷下广告,嘎嘎!

  8. 拓跋亮说:

    cs脚本:void OnGUI(){//绘制一个输入框接收用户输入stringToEdit = GUILayout.TextField(stringToEdit, GUILayout.Width(300), GUILayout.Height(100));//提交按钮if(GUILayout.Button(“commit”, GUILayout.Height(50))){AndroidJavaClass ajc = new AndroidJavaClass(“com.main.unitytoandroid.MainActivity”);test = “2”;ajc.Call(“receiveMessage”, stringToEdit);}GUILayout.Label(test);}public void GetMessage(string str){stringToEdit = str;}activity代码:public class MainActivity extends UnityPlayerActivity {Context mContext = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mContext = this;}//接受来自unity的参数public void receiveMessage(String name){//再将值返回给unityUnityPlayer.UnitySendMessage(“Main Camera”, “GetMessage”, “从android返回的:” name);}}雨松大大你看我这样对不对啊,提交过去似乎android没有把值返回过来

  9. 拓跋亮说:

    cs脚本:void OnGUI(){ //绘制一个输入框接收用户输入 stringToEdit = GUILayout.TextField(stringToEdit, GUILayout.Width(300), GUILayout.Height(100)); //提交按钮 if(GUILayout.Button(“commit”, GUILayout.Height(50))){ AndroidJavaClass ajc = new AndroidJavaClass(“com.main.unitytoandroid.MainActivity”); test = “2”; ajc.Call(“receiveMessage”, stringToEdit); } GUILayout.Label(test); } public void GetMessage(string str){ stringToEdit = str;}activity代码:public class MainActivity extends UnityPlayerActivity { Context mContext = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = this; } //接受来自unity的参数 public void receiveMessage(String name){ //再将值返回给unity UnityPlayer.UnitySendMessage(“Main Camera”, “GetMessage”, “从android返回的:” + name); }}雨松大大你看我这样对不对啊,提交过去似乎android没有把值返回过来

  10. 还没细看,但是附件好像是第18章的?

  11. 松松大侠,看了你写的书,收获很多。不过有个问题一直困扰我,请教一下:Ray ray = new Ray(); ray = Camera.main.ScreenPointToRay(transform.position);射线是从屏幕左下射出的,我想做成虚拟按键,每次按下后,射线从当前第一视角屏幕正中射出,可以做到吗?(screen.width/2,screen.height/2)怎么转换成3D世界的坐标,然后传给上面括号里,当然传个触摸的坐标进去可以,不过我想模拟FPS那种固定瞄准镜在屏幕中间的效果。不知道表达清楚了没有?:(

    • 正常的逻辑应该是 把2D坐标转换成3D坐标 然后在用射线像这个3D坐标上射线。。API中写的很清楚的。public class example : MonoBehaviour { void OnDrawGizmosSelected() { Vector3 p = camera.ScreenToWorldPoint(new Vector3(100, 100, camera.nearClipPlane)); Gizmos.color = Color.yellow; Gizmos.DrawSphere(p, 0.1F); }}

    • 雨松MOMO说:

      正常的逻辑应该是 把2D坐标转换成3D坐标 然后在用射线像这个3D坐标上射线。。API中写的很清楚的。public class example : MonoBehaviour {void OnDrawGizmosSelected() {Vector3 p = camera.ScreenToWorldPoint(new Vector3(100, 100, camera.nearClipPlane));Gizmos.color = Color.yellow;Gizmos.DrawSphere(p, 0.1F);}}

  12. 唐敏说:

    unity 开发android 3D动态壁纸。。怎样一个思路呀。。。

  13. 海鹏说:

    您好,有个问题想请教一下,我想在android端为我的unity界面,添加一个webView ,只添加一个View,不是切换Activity,这个方法可行吗

  14. wudi说:

    雨松大的文章總是讓我受用不盡
    這邊想請教個問題:
    從Android打包成jar給Unity做Plugin(假設是webwiew或是撥放影片),有可能讓整個畫面的控制權主要還是給Unity而不是jar的功能嗎?

  15. 雨松MOMO说:

    我来第一个评论,加油哇咔咔~

留下一个回复

你的email不会被公开。 必填项已用 * 标注。