首页 > 代码库 > Unity与Android的对调

Unity与Android的对调

本文结构

  • 使用注意
  • 新工程
  • UnityAndroid参数
  • AndroidUnity参数
  • SDK嵌入
  • SDK封装入类

?

使用注意

  1. 安装APK,通常旧的不需要删除,安装后会被覆盖;
  2. 任何代码文件都可以使用UnityPlayer.UnitySendMessage() Unity发消息。只要import com.unity3d.player.UnityPlayer;然后写UnityPlayer.UnitySendMessage()即可;
  3. Android调用Android的相关方法,参数UnityPlayer.UnitySendMessage("Android_IAPManager","SimpleReturn","555:"+mIAP);参数1:GameObject名称,参数2:函数名,参数3:字符串参数。只能传一个字符串参数,不能传多个,如果需要传多个参数,只能分几个函数调用,或者字符串用‘|‘之类的字符合并传递再拆分接收了。物体上不存在名称为参数2的函数,不会报错,但是参数3不能为null,否则会强制退出;
  4. Unity调用安卓jo.Call("fun name",pram); 参数是什么格式都行,但是函数签名必须符合,即参数顺序格式必须符合;
  5. 在调用非MainActivity类对象里的函数时,由于有UI的处理和回调,所以必须在Unity调用Android的函数内,参数存储在变量里,然后mHandler.sendMessage(),最后在handler里调用。
  6. 如果NGUIUI Android 前后显示层级不正确的话,可能是使用了OpenGL ES 2.0导致的,换成OpenGL ES 1.x 即可

public void ShowChukongPay_Sub(int tmpIAP_ItemID,String tmpIAP_Name, String tmpIAP_Cost, String tmpIAP_Num,int tmpIAP_Chukong_Type)

{

mIAP_ItemID = tmpIAP_ItemID;

mIAP_Name = tmpIAP_Name;

mIAP_Cost = tmpIAP_Cost;

mIAP_Num = tmpIAP_Num;

mIAP_Chukong_Type = tmpIAP_Chukong_Type;

Message msg = new Message();

msg.what = -1000 ;

mHandler.sendMessage(msg);

}

?

private final Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case -1000:

UnityPlayer.UnitySendMessage("Android_IAPManager","SimpleReturn","987:");

mIAP_Chukong.ShowChukongPay(mIAP_Name,mIAP_Cost, mIAP_Num,mIAP_Chukong_Type);

break;

}

}

};

  1. 如果函数出现错误Loop.prepare()什么的话,可以将函数用线程包裹起来

    public void ShowPayUI(final int itemID,final String cost, final String num)

    {

    ??final openframework currentActivity = (openframework)UnityPlayer.currentActivity;

    ? ? ? ??currentActivity.runOnUiThread(new Runnable() {

    ? ? ? ? ??public void run() {

    ? ? ? ?? BuySub(itemID,cost,num);

    ? ? ? ? ??}

    ? ? ? ??});

    }

新工程

  1. 新建Unity工程,并改为Android 命名Bundle IDcom.pcc.appname
  2. 场景里添加GameObject,命名为Manager,并附带Manager.cs脚本。内容如下

using UnityEngine;

using System.Collections;

public class Manager : MonoBehaviour {

AndroidJavaClass jc

AndroidJavaObject jo;

void Start()

{

#if UNITY_ANDROID

jc =?new?AndroidJavaClass("com.unity3d.player.UnityPlayer");

jo = jc.GetStatic("currentActivity");

#endif

}

void OnGUI()

{

if(GUI.Button(new Rect(0,0,100,100),"do"))

{

DO();

}

}

void DO()

{

#if UNITY_ANDROID

jo.Call("StartAct");

#endif

}

}

??

??

  1. 新建Eclipse 工程,直接选 Android Application Project。下一步,注意package Name一定要和之前的Bundle ID对应,之后一直下一步即可。

技术分享

技术分享

  1. 建好工程后,?

    MacUnity图标右键->显示包内容 ? Contents->PlaybackEngines->AndroidPlayer->bin->classes.jar?

    拷至libs下(copy

  • 打开src->package name(BundleID)->主代码。这里是src->com.pcc.appname->MainActivity
  • import com.unity3d.player.UnityPlayerActivity;
  • extends Activity 改为extends UnityPlayerActivity
  • 把类里的代码改为如下

package com.pcc.appname;

?

import android.os.Bundle;

import android.app.Activity;

import android.view.Menu;

import android.util.Log;

?

import com.unity3d.player.UnityPlayerActivity;

?

public class MainActivity extends UnityPlayerActivity {

? ??@Override

? ??public void onCreate(Bundle savedInstanceState) {

? ? ? ??super.onCreate(savedInstanceState);? ? ? ?

? ??}

?

? ??public void StartAct()

? ??{

? ??????Log.e("jj","kk");

? ??}

}

  • Build project
  • u3d里新建Plugins/Android文件夹,拷贝 Eclipse工程下的AndroidManifest.xml文件,libs文件夹,res文件三项至Plugins/Android下。并删除classes.jar.
  • jar:Eclipse工程->bin->classs, ? ?进入mac控制台, cd至该目录,然后运行jar?-cvf?class.jar?*,之后就在Eclipse工程->bin->classs里生成了 class.jarU3d Plugins/Android下新建bin文件夹,把class.jar拖进去windows类似,指令完全一样。只不过需要配置环境变量,并通过控制台进入该目录的方式不同罢了。Mac可以直接cd复制粘贴好的路径,windows得一层一层cd.

2点击Eclipse右上角的DDMS

技术分享

3之后左侧 选择设备,然后点击LogCat

技术分享

4.点击log信息的自动下拉锁定钮

技术分享

之后build, 在真机上运行,点击do按钮,就能在控制台看到输出的红色的信息了

技术分享

?

? ? ? ? ? ? ? ? ? ? ? ? ? UnityAndroid参数

(1)jo.Call 改为jo.Call("StartAct","I am Good",5);

(2)StartAct函数改为

??

  1. ??public void StartAct(String x, int y)
  2. ? ??{
  3. ? ??
  4. ? ?? Log.e(x,"num is:"+y);
  5. ? ??}

(3)Eclipse重新Build project,?

(4)然后到bin->classes,删除class.jar 并在控制台指令重build一个

(5)删除unity里已有的class.jar,把新的拖进去。

?

之后运行,看log,发现字符串参数和整数参数都传了过去

技术分享

?

? ? ? ? ? ? ? ? ? ? ? AndroidUnity参数

(1)unityManager.cs代码改为

??

  1. using UnityEngine;
  2. using System.Collections;
  3. public class Manager : MonoBehaviour {
  4. AndroidJavaClass jc;
  5. AndroidJavaObject jo;
  6. private string txt;
  7. void Start()
  8. {
  9. jc =?new?AndroidJavaClass("com.unity3d.player.UnityPlayer");
  10. jo = jc.GetStatic("currentActivity");
  11. txt = "";
  12. }
  13. void OnGUI()
  14. {
  15. if(GUI.Button(new Rect(0,0,100,50),"do"))
  16. {
  17. DO();
  18. }
  19. GUI.Label(new Rect(0,50,100,50),txt);
  20. }
  21. void DO()
  22. {
  23. #if UNITY_ANDROID
  24. jo.Call("StartAct","I am Good",5);
  25. #endif
  26. }
  27. void AndroidReceive(string content)
  28. {
  29. txt = content;
  30. }
  31. }

(2) Eclipse里的代码改为

??

  1. ? ??public void StartAct(String x, int y)
  2. ? ??{
  3. ? ?? Log.e(x,"num is:"+y);
  4. ? ?? UnityPlayer.UnitySendMessage("Manager","AndroidReceive","OKKKKKK");
  5. ? ??}

?

??

(3)之后如前,替换class.jar

运行时,点击do按钮,下方显示OKKKKKK,表明回传成功!

?

? ? ? ? ? ? ? ? ? ? ? ? ? ?四嵌入SDK

这里以嵌入电信付费SDK为例

Eclipse

(1)SDK拖进libs下,即sms.jar

(2)AndroidManifest

1.Activity

? ?android:name="cn.game189.sms.SMS"??android:theme="@android:style/Theme.Dialog">

2.加权限

? ??android:name="android.permission.SEND_SMS"?/>

? ??android:name="android.permission.READ_PHONE_STATE"?/>

(3)代码里

import cn.game189.sms.SMS;

import cn.game189.sms.SMSListener;

(4)unity调用的函数,如buy(int id)并加入

SMS.checkFee

??

(5)

加入3个回调

smsCancel

??

smsFail

??

smsOK

并在smsOK unity发送成功的加钱函数

Unity

(1)通知Eclipse的调用函数 AddMoney

(2)接收Eclipse的函数 Android_IAP_Finished

代码如下

Eclipse

??

??

  1. package com.pcc.appname;
  2. import android.os.Bundle;
  3. import android.app.Activity;
  4. import android.view.Menu;
  5. import android.util.Log;
  6. import com.unity3d.player.UnityPlayer;
  7. import com.unity3d.player.UnityPlayerActivity;
  8. import cn.game189.sms.SMS;
  9. import cn.game189.sms.SMSListener;
  10. public class MainActivity extends UnityPlayerActivity? implements SMSListener? {
  11. ? ??@Override
  12. ? ??public void onCreate(Bundle savedInstanceState) {
  13. ? ? ? ??super.onCreate(savedInstanceState);? ? ? ?
  14. ? ??}
  15. ? ??public void StartAct(String x, int y)
  16. ? ??{
  17. ? ?? Log.e(x,"num is:"+y);
  18. ? ?? UnityPlayer.UnitySendMessage("Manager","AndroidReceive","StartAct");
  19. ? ??}
  20. public void Buy(int id)
  21. {
  22. UnityPlayer.UnitySendMessage("Manager","AndroidReceive","no id");
  23. if(id== 1)
  24. {
  25. UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 1");
  26. SMS.checkFee("Tier1", this, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "6元兑换6000金币", "已成功购买6000金币",true);
  27. }
  28. if(id== 5)
  29. {
  30. UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 5");
  31. SMS.checkFee("Tier5", this, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "36元兑换36000金币", "已成功购买36000金币",true);
  32. }
  33. }
  34. @Override
  35. public void smsCancel(String arg0, int arg1) {
  36. // TODO Auto-generated method stub
  37. Log.e("lsy: SMS cancel", "SMS cancel");
  38. }
  39. @Override
  40. public void smsFail(String arg0, int arg1) {
  41. // TODO Auto-generated method stub
  42. Log.e("lsy: SMS fail", "SMS fail");
  43. }
  44. @Override
  45. public void smsOK(String feeName) {
  46. // TODO Auto-generated method stub
  47. Log.e("lsy: SMS ok", "SMS ok");
  48. if (feeName.equals("Tier1")) {
  49. Log.e("lsy: SMS bount Tier1", "SMS ok");
  50. UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","1");
  51. }else if(feeName.equals("Tier5")){
  52. Log.e("lsy: SMS bount Tier5", "SMS ok");
  53. UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","5");
  54. }
  55. }
  56. }

??

??

??

Unity

??

??

  1. using UnityEngine;
  2. using System.Collections;
  3. public class Manager : MonoBehaviour {
  4. private string txt;
  5. private int money;
  6. AndroidJavaClass jc;
  7. AndroidJavaObject jo;
  8. void Start()
  9. {
  10. txt = "";
  11. money=0;
  12. #if UNITY_ANDROID
  13. jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
  14. jo = jc.GetStatic("currentActivity");
  15. #endif
  16. }
  17. void OnGUI()
  18. {
  19. if(GUI.Button(new Rect(0,0,100,50),"do"))
  20. {
  21. DO();
  22. }
  23. GUI.Label(new Rect(0,50,100,50),txt);
  24. if(GUI.Button(new Rect(0,200,100,50),"Buy IAP 1"))
  25. {
  26. AddMoney(1);
  27. }
  28. if(GUI.Button(new Rect(0,250,100,50),"Buy IAP 5"))
  29. {
  30. AddMoney(5);
  31. }
  32. GUI.Label(new Rect(0,300,100,50),"Money: "+money);
  33. }
  34. void DO()
  35. {
  36. #if UNITY_ANDROID
  37. jo.Call("StartAct","I am Good",5);
  38. #endif
  39. }
  40. void AndroidReceive(string content)
  41. {
  42. txt = content;
  43. }
  44. void AddMoney(int IAPID)
  45. {
  46. #if UNITY_ANDROID
  47. jo.Call("Buy",IAPID);
  48. #endif
  49. ?
  50. }
  51. void Android_IAP_Finished(int IAPID)
  52. {
  53. if(IAPID ==1)
  54. money += 100;
  55. if(IAPID ==5)
  56. money += 500;
  57. }
  58. }

??

??

??

??

之后运行,点击2Buy按钮会出现信息提示。

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SDK封装入单类

Unity 无任何代码变化。

Eclipse:

??

ChinaTelecomPay.java

??

(1)Activity 并在构造函数中赋值

??

  1. private?Activity?m_Activity;
  2. ?
  3. public?ChinaTelecomPay(Activity tmpActivity)
  4. {
  5. m_Activity?= tmpActivity;
  6. }

(2)

??

??

  1. import com.unity3d.player.UnityPlayer;
  2. import cn.game189.sms.SMS;
  3. import cn.game189.sms.SMSListener;

implements SMSListener

??

(3)加购买处理

??

  1. public void Buy_ChinaTelecom(int id)
  2. {
  3. UnityPlayer.UnitySendMessage("Manager","AndroidReceive","no id");
  4. if(id== 1)
  5. {
  6. UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 1");
  7. SMS.checkFee("Tier1", m_Activity, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "6元兑换6000金币", "已成功购买6000金币",true);
  8. }
  9. if(id== 5)
  10. {
  11. UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 5");
  12. SMS.checkFee("Tier5", m_Activity, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "36元兑换36000金币", "已成功购买36000金币",true);
  13. }
  14. }

(4)加回调

??

??

  1. @Override
  2. public void smsCancel(String arg0, int arg1) {
  3. // TODO Auto-generated method stub
  4. Log.e("lsy: SMS cancel", "SMS cancel");
  5. }
  6. @Override
  7. public void smsFail(String arg0, int arg1) {
  8. // TODO Auto-generated method stub
  9. Log.e("lsy: SMS fail", "SMS fail");
  10. }
  11. @Override
  12. public void smsOK(String feeName) {
  13. // TODO Auto-generated method stub
  14. Log.e("lsy: SMS ok", "SMS ok");
  15. if (feeName.equals("Tier1")) {
  16. Log.e("lsy: SMS bount Tier1", "SMS ok");
  17. UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","1");
  18. }else if(feeName.equals("Tier5")){
  19. Log.e("lsy: SMS bount Tier5", "SMS ok");
  20. UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","5");
  21. }
  22. }

MainActivity.java

(1)

去掉

  1. import?cn.game189.sms.SMS;
  2. import?cn.game189.sms.SMSListener;

去掉?implements SMSListener

去掉 三个回调

(2)ChinaTelecomPay对象 并在 onCreate里构造

??

  1. private ChinaTelecomPay chinaTelecomPay;
  2. ? ??@Override
  3. ? ??public void onCreate(Bundle savedInstanceState) {
  4. ? ? ? ??super.onCreate(savedInstanceState);? ?
  5. ? ? ? ??chinaTelecomPay = new ChinaTelecomPay(this);
  6. ? ??}

?

(3)购买调用

??

  1. public void Buy(int id)
  2. {
  3. chinaTelecomPay.Buy_ChinaTelecom(id);
  4. }

?

代码如下

ChinaTelecomPay.java

?

??

??

  1. package com.pcc.appname;
  2. import android.app.Activity;
  3. import android.util.Log;
  4. import com.unity3d.player.UnityPlayer;
  5. import cn.game189.sms.SMS;
  6. import cn.game189.sms.SMSListener;
  7. public class ChinaTelecomPay implements SMSListener{
  8. private Activity m_Activity;
  9. ?
  10. public ChinaTelecomPay(Activity tmpActivity)
  11. {
  12. m_Activity = tmpActivity;
  13. }
  14. public void Buy_ChinaTelecom(int id)
  15. {
  16. UnityPlayer.UnitySendMessage("Manager","AndroidReceive","no id");
  17. if(id== 1)
  18. {
  19. UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 1");
  20. SMS.checkFee("Tier1", m_Activity, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "6元兑换6000金币", "已成功购买6000金币",true);
  21. }
  22. if(id== 5)
  23. {
  24. UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 5");
  25. SMS.checkFee("Tier5", m_Activity, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "36元兑换36000金币", "已成功购买36000金币",true);
  26. }
  27. }
  28. @Override
  29. public void smsCancel(String arg0, int arg1) {
  30. // TODO Auto-generated method stub
  31. Log.e("lsy: SMS cancel", "SMS cancel");
  32. }
  33. @Override
  34. public void smsFail(String arg0, int arg1) {
  35. // TODO Auto-generated method stub
  36. Log.e("lsy: SMS fail", "SMS fail");
  37. }
  38. @Override
  39. public void smsOK(String feeName) {
  40. // TODO Auto-generated method stub
  41. Log.e("lsy: SMS ok", "SMS ok");
  42. if (feeName.equals("Tier1")) {
  43. Log.e("lsy: SMS bount Tier1", "SMS ok");
  44. UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","1");
  45. }else if(feeName.equals("Tier5")){
  46. Log.e("lsy: SMS bount Tier5", "SMS ok");
  47. UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","5");
  48. }
  49. }
  50. }

??

?

MainActivity.java

??

??

  1. package com.pcc.appname;
  2. import android.os.Bundle;
  3. import android.app.Activity;
  4. import android.view.Menu;
  5. import android.util.Log;
  6. import com.unity3d.player.UnityPlayer;
  7. import com.unity3d.player.UnityPlayerActivity;
  8. import cn.game189.sms.SMS;
  9. import cn.game189.sms.SMSListener;
  10. public class MainActivity extends UnityPlayerActivity {
  11. private ChinaTelecomPay chinaTelecomPay;
  12. ? ? @Override
  13. ? ? public void onCreate(Bundle savedInstanceState) {
  14. ? ? ? ? super.onCreate(savedInstanceState); ??
  15. ? ? ? ? chinaTelecomPay = new ChinaTelecomPay(this);
  16. ? ? }
  17. ? ? public void StartAct(String x, int y)
  18. ? ? {
  19. ? ?? Log.e(x,"num is:"+y);
  20. ? ?? UnityPlayer.UnitySendMessage("Manager","AndroidReceive","StartAct");
  21. ? ? }
  22. public void Buy(int id)
  23. {
  24. chinaTelecomPay.Buy_ChinaTelecom(id);
  25. }
  26. }

?

之后运行,和之前的一样,正常。这样可以方便的进行Android代码按功能分类管理了。

转载自风宇冲Unity3D教程学院

Unity与Android的对调