首页 > 代码库 > Unity与Android的对调
Unity与Android的对调
本文结构
- 使用注意
- 新工程
- Unity传Android参数
- Android传Unity参数
- SDK嵌入
- SDK封装入类
?
使用注意
- 安装APK,通常旧的不需要删除,安装后会被覆盖;
- 任何代码文件都可以使用UnityPlayer.UnitySendMessage() 向Unity发消息。只要import com.unity3d.player.UnityPlayer;然后写UnityPlayer.UnitySendMessage()即可;
- Android调用Android的相关方法,参数UnityPlayer.UnitySendMessage("Android_IAPManager","SimpleReturn","555:"+mIAP);参数1:GameObject名称,参数2:函数名,参数3:字符串参数。只能传一个字符串参数,不能传多个,如果需要传多个参数,只能分几个函数调用,或者字符串用‘|‘之类的字符合并传递再拆分接收了。物体上不存在名称为参数2的函数,不会报错,但是参数3不能为null,否则会强制退出;
- Unity调用安卓jo.Call("fun name",pram); 参数是什么格式都行,但是函数签名必须符合,即参数顺序格式必须符合;
- 在调用非MainActivity的类对象里的函数时,由于有UI的处理和回调,所以必须在Unity调用Android的函数内,参数存储在变量里,然后mHandler.sendMessage(),最后在handler里调用。
- 如果NGUI的UI 在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;
}
}
};
- 如果函数出现错误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);
? ? ? ? ??}
? ? ? ??});
}
新工程
- 新建Unity工程,并改为Android, 命名Bundle ID如com.pcc.appname
- 场景里添加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
}
}
??
??
- 新建Eclipse 工程,直接选 Android Application Project。下一步,注意package Name一定要和之前的Bundle ID对应,之后一直下一步即可。
- 建好工程后,?
Mac:Unity图标右键->显示包内容 ? 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.jar,U3d Plugins/Android下新建bin文件夹,把class.jar拖进去windows类似,指令完全一样。只不过需要配置环境变量,并通过控制台进入该目录的方式不同罢了。Mac可以直接cd复制粘贴好的路径,windows得一层一层cd.
2点击Eclipse右上角的DDMS
3之后左侧 选择设备,然后点击LogCat
4.点击log信息的自动下拉锁定钮
之后build, 在真机上运行,点击do按钮,就能在控制台看到输出的红色的信息了
?
? ? ? ? ? ? ? ? ? ? ? ? ? 二 Unity传Android参数
(1)将jo.Call 改为jo.Call("StartAct","I am Good",5);
(2)StartAct函数改为
??
- ??public void StartAct(String x, int y)
- ? ??{
- ? ??
- ? ?? Log.e(x,"num is:"+y);
- ? ??}
(3)Eclipse重新Build project,?
(4)然后到bin->classes,删除class.jar, 并在控制台指令重build一个
(5)删除unity里已有的class.jar,把新的拖进去。
?
之后运行,看log,发现字符串参数和整数参数都传了过去
?
? ? ? ? ? ? ? ? ? ? ?三 Android传Unity参数
(1)unity里Manager.cs代码改为
??
- using UnityEngine;
- using System.Collections;
- public class Manager : MonoBehaviour {
- AndroidJavaClass jc;
- AndroidJavaObject jo;
- private string txt;
- void Start()
- {
- jc =?new?AndroidJavaClass("com.unity3d.player.UnityPlayer");
- jo = jc.GetStatic("currentActivity");
- txt = "";
- }
- void OnGUI()
- {
- if(GUI.Button(new Rect(0,0,100,50),"do"))
- {
- DO();
- }
- GUI.Label(new Rect(0,50,100,50),txt);
- }
- void DO()
- {
- #if UNITY_ANDROID
- jo.Call("StartAct","I am Good",5);
- #endif
- }
- void AndroidReceive(string content)
- {
- txt = content;
- }
- }
(2) Eclipse里的代码改为
??
- ? ??public void StartAct(String x, int y)
- ? ??{
- ? ?? Log.e(x,"num is:"+y);
- ? ?? UnityPlayer.UnitySendMessage("Manager","AndroidReceive","OKKKKKK");
- ? ??}
?
??
(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
??
??
- package com.pcc.appname;
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
- import android.util.Log;
- import com.unity3d.player.UnityPlayer;
- import com.unity3d.player.UnityPlayerActivity;
- import cn.game189.sms.SMS;
- import cn.game189.sms.SMSListener;
- public class MainActivity extends UnityPlayerActivity? implements SMSListener? {
- ? ??@Override
- ? ??public void onCreate(Bundle savedInstanceState) {
- ? ? ? ??super.onCreate(savedInstanceState);? ? ? ?
- ? ??}
- ? ??public void StartAct(String x, int y)
- ? ??{
- ? ?? Log.e(x,"num is:"+y);
- ? ?? UnityPlayer.UnitySendMessage("Manager","AndroidReceive","StartAct");
- ? ??}
- public void Buy(int id)
- {
- UnityPlayer.UnitySendMessage("Manager","AndroidReceive","no id");
- if(id== 1)
- {
- UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 1");
- SMS.checkFee("Tier1", this, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "6元兑换6000金币", "已成功购买6000金币",true);
- }
- if(id== 5)
- {
- UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 5");
- SMS.checkFee("Tier5", this, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "36元兑换36000金币", "已成功购买36000金币",true);
- }
- }
- @Override
- public void smsCancel(String arg0, int arg1) {
- // TODO Auto-generated method stub
- Log.e("lsy: SMS cancel", "SMS cancel");
- }
- @Override
- public void smsFail(String arg0, int arg1) {
- // TODO Auto-generated method stub
- Log.e("lsy: SMS fail", "SMS fail");
- }
- @Override
- public void smsOK(String feeName) {
- // TODO Auto-generated method stub
- Log.e("lsy: SMS ok", "SMS ok");
- if (feeName.equals("Tier1")) {
- Log.e("lsy: SMS bount Tier1", "SMS ok");
- UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","1");
- }else if(feeName.equals("Tier5")){
- Log.e("lsy: SMS bount Tier5", "SMS ok");
- UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","5");
- }
- }
- }
??
??
??
Unity
??
??
- using UnityEngine;
- using System.Collections;
- public class Manager : MonoBehaviour {
- private string txt;
- private int money;
- AndroidJavaClass jc;
- AndroidJavaObject jo;
- void Start()
- {
- txt = "";
- money=0;
- #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,50),"do"))
- {
- DO();
- }
- GUI.Label(new Rect(0,50,100,50),txt);
- if(GUI.Button(new Rect(0,200,100,50),"Buy IAP 1"))
- {
- AddMoney(1);
- }
- if(GUI.Button(new Rect(0,250,100,50),"Buy IAP 5"))
- {
- AddMoney(5);
- }
- GUI.Label(new Rect(0,300,100,50),"Money: "+money);
- }
- void DO()
- {
- #if UNITY_ANDROID
- jo.Call("StartAct","I am Good",5);
- #endif
- }
- void AndroidReceive(string content)
- {
- txt = content;
- }
- void AddMoney(int IAPID)
- {
- #if UNITY_ANDROID
- jo.Call("Buy",IAPID);
- #endif
- ?
- }
- void Android_IAP_Finished(int IAPID)
- {
- if(IAPID ==1)
- money += 100;
- if(IAPID ==5)
- money += 500;
- }
- }
??
??
??
??
之后运行,点击2个Buy按钮会出现信息提示。
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?五 SDK封装入单类
Unity端 无任何代码变化。
Eclipse:
??
ChinaTelecomPay.java
??
(1)加Activity 并在构造函数中赋值
??
- private?Activity?m_Activity;
- ?
- public?ChinaTelecomPay(Activity tmpActivity)
- {
- m_Activity?= tmpActivity;
- }
(2)
??
??
- import com.unity3d.player.UnityPlayer;
- import cn.game189.sms.SMS;
- import cn.game189.sms.SMSListener;
并implements SMSListener
??
(3)加购买处理
??
- public void Buy_ChinaTelecom(int id)
- {
- UnityPlayer.UnitySendMessage("Manager","AndroidReceive","no id");
- if(id== 1)
- {
- UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 1");
- SMS.checkFee("Tier1", m_Activity, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "6元兑换6000金币", "已成功购买6000金币",true);
- }
- if(id== 5)
- {
- UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 5");
- SMS.checkFee("Tier5", m_Activity, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "36元兑换36000金币", "已成功购买36000金币",true);
- }
- }
(4)加回调
??
??
- @Override
- public void smsCancel(String arg0, int arg1) {
- // TODO Auto-generated method stub
- Log.e("lsy: SMS cancel", "SMS cancel");
- }
- @Override
- public void smsFail(String arg0, int arg1) {
- // TODO Auto-generated method stub
- Log.e("lsy: SMS fail", "SMS fail");
- }
- @Override
- public void smsOK(String feeName) {
- // TODO Auto-generated method stub
- Log.e("lsy: SMS ok", "SMS ok");
- if (feeName.equals("Tier1")) {
- Log.e("lsy: SMS bount Tier1", "SMS ok");
- UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","1");
- }else if(feeName.equals("Tier5")){
- Log.e("lsy: SMS bount Tier5", "SMS ok");
- UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","5");
- }
- }
MainActivity.java
(1)
去掉
- import?cn.game189.sms.SMS;
- import?cn.game189.sms.SMSListener;
去掉?implements SMSListener
去掉 三个回调
(2)建ChinaTelecomPay对象 并在 onCreate里构造
??
- private ChinaTelecomPay chinaTelecomPay;
- ? ??@Override
- ? ??public void onCreate(Bundle savedInstanceState) {
- ? ? ? ??super.onCreate(savedInstanceState);? ?
- ? ? ? ??chinaTelecomPay = new ChinaTelecomPay(this);
- ? ??}
?
(3)购买调用
??
- public void Buy(int id)
- {
- chinaTelecomPay.Buy_ChinaTelecom(id);
- }
?
代码如下
ChinaTelecomPay.java
?
??
??
- package com.pcc.appname;
- import android.app.Activity;
- import android.util.Log;
- import com.unity3d.player.UnityPlayer;
- import cn.game189.sms.SMS;
- import cn.game189.sms.SMSListener;
- public class ChinaTelecomPay implements SMSListener{
- private Activity m_Activity;
- ?
- public ChinaTelecomPay(Activity tmpActivity)
- {
- m_Activity = tmpActivity;
- }
- public void Buy_ChinaTelecom(int id)
- {
- UnityPlayer.UnitySendMessage("Manager","AndroidReceive","no id");
- if(id== 1)
- {
- UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 1");
- SMS.checkFee("Tier1", m_Activity, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "6元兑换6000金币", "已成功购买6000金币",true);
- }
- if(id== 5)
- {
- UnityPlayer.UnitySendMessage("Manager","AndroidReceive","IAP 5");
- SMS.checkFee("Tier5", m_Activity, this, "0111C001741102210073711102210072550115174000000000000000000000000000", "36元兑换36000金币", "已成功购买36000金币",true);
- }
- }
- @Override
- public void smsCancel(String arg0, int arg1) {
- // TODO Auto-generated method stub
- Log.e("lsy: SMS cancel", "SMS cancel");
- }
- @Override
- public void smsFail(String arg0, int arg1) {
- // TODO Auto-generated method stub
- Log.e("lsy: SMS fail", "SMS fail");
- }
- @Override
- public void smsOK(String feeName) {
- // TODO Auto-generated method stub
- Log.e("lsy: SMS ok", "SMS ok");
- if (feeName.equals("Tier1")) {
- Log.e("lsy: SMS bount Tier1", "SMS ok");
- UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","1");
- }else if(feeName.equals("Tier5")){
- Log.e("lsy: SMS bount Tier5", "SMS ok");
- UnityPlayer.UnitySendMessage("Manager","Android_IAP_Finished","5");
- }
- }
- }
??
?
MainActivity.java
??
??
- package com.pcc.appname;
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
- import android.util.Log;
- import com.unity3d.player.UnityPlayer;
- import com.unity3d.player.UnityPlayerActivity;
- import cn.game189.sms.SMS;
- import cn.game189.sms.SMSListener;
- public class MainActivity extends UnityPlayerActivity {
- private ChinaTelecomPay chinaTelecomPay;
- ? ? @Override
- ? ? public void onCreate(Bundle savedInstanceState) {
- ? ? ? ? super.onCreate(savedInstanceState); ??
- ? ? ? ? chinaTelecomPay = new ChinaTelecomPay(this);
- ? ? }
- ? ? public void StartAct(String x, int y)
- ? ? {
- ? ?? Log.e(x,"num is:"+y);
- ? ?? UnityPlayer.UnitySendMessage("Manager","AndroidReceive","StartAct");
- ? ? }
- public void Buy(int id)
- {
- chinaTelecomPay.Buy_ChinaTelecom(id);
- }
- }
?
之后运行,和之前的一样,正常。这样可以方便的进行Android代码按功能分类管理了。
转载自风宇冲Unity3D教程学院
Unity与Android的对调