本人是Android SDK方向的开发者,在游戏发行公司工作,因公司业务需求经常与Unity进行交互,借此机会让大家伙了解下Unity与Android交互的一些基础知识。
Unity和Android Studio所涉及到的SDK、JDK、NDK安装步骤新建工程等操作的不做说明
Android Studio(AS)版本: 3.2.1
Unity版本: 2018.2.0f2 破解版
Unity调用Andoroid网游OPPO SDK API 实现 登录 支付 退出 等交互 效果如下图
要在Unity游戏项目中调用安卓API,有两种方式:
Unity项目导出为Android工程(Build System选择Gradle),然后在AS中进行二次开发,添加交互功能。这样的方式开发起来很灵活,改动起来也很方便,但是就是很麻烦,因为每次改动都要打一回安卓工程。
将扩展功能打成jar包,然后将jar包导入到Unity中,直接使用。这样的方式,一次性写好通用交互层 ,不用频繁打安卓工程。
下面给大家说下第二种方式
1.既然要和Android oppo SDK交互 ,需要去开发者申请对应参数和 SDK资源文档
OPPO开发者网游SDK下载地址:https://open.oppomobile.com/wiki/doc#id=10470
2.AS新建一个工程,因为需要和Unity交互(用到其中的类),因此需要把它提供的class.jar包放到AS工程libs下
我Unity安装默认路径在D盘 D:\Unity 所以下面路径取决你Unity安装路径
D:\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Classes\class.jar
3.需要按oppo 开发者文档要求 放入oppo资源(assets、libs和AndroidManifest.xml),然后可以按文档接口接入
清单文件配置一定要有,
不然会有莫名其妙的奇怪问题
首先需要让MainActivity继承UnityPlayerActivity,因为Unity导出的app的视图展示需要在UnityPlayerActivity下。
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;
import com.nearme.game.sdk.GameCenterSDK;
import com.nearme.game.sdk.callback.ApiCallback;
import com.nearme.game.sdk.callback.GameExitCallback;
import com.nearme.game.sdk.common.model.biz.PayInfo;
import com.nearme.game.sdk.common.model.biz.ReportUserGameInfoParam;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/**
*android 与Unity交互层 数据均为模拟游戏数据
*/
public class MainActivity extends UnityPlayerActivity {
private static String appSecret = ""; //此处应该填写 oppo后台申请下来的appSecret参数
public final String TAG="UnityForOppo";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
doInit();
}
/**
* 初始化
*/
public void doInit(){
Log.i(TAG,"doInit");
GameCenterSDK.init(appSecret, this);
Toast.makeText(MainActivity.this,"初始化成功",Toast.LENGTH_LONG).show();
}
/**
* 登录
*/
public void doLogin(){
Log.i(TAG,"doLogin");
GameCenterSDK.getInstance().doLogin(this, new ApiCallback() {
//登录成功的回调
@Override
public void onSuccess(String msg) {
Toast.makeText(MainActivity.this,"获取登录状态:====="+msg.toString(),Toast.LENGTH_LONG).show();
GameCenterSDK.getInstance().doGetTokenAndSsoid(new ApiCallback() {
@Override
public void onSuccess(String resultMsg) {
Log.i(TAG,"登录成功获取的msg:====="+resultMsg.toString());
String jsonString = "";
try {
JSONObject json = new JSONObject(resultMsg);
String token = json.getString("token");
String ssoid = json.getString("ssoid");
json.put("token", URLEncoder.encode(token, "UTF-8"));
json.put("ssoid",json.getString("ssoid"));
jsonString=json.toString();
Log.i(TAG,"登录成功向Unity发送消息:====="+jsonString);
/**
* 向Unity传递消息
* 第1个参数为Unity场景中用于接收android消息的对象名称
* 第2个参数为对象上的脚本的一个成员方法名称(脚本名称不限制)
* 第3个参数为Unity方法的参数
*/
UnityPlayer.UnitySendMessage("AndroidSDKListener", "LoginCallback", jsonString);
} catch (JSONException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(String resultMsg, int code) {
UnityPlayer.UnitySendMessage("AndroidSDKListener", "LoginCallback", resultMsg);
}
});
}
//登录失败的回调
@Override
public void onFailure(String msg, int code) {
//回调oppo登录失败,把失败的消息发给Unity
UnityPlayer.UnitySendMessage("AndroidSDKListener", "LoginCallback", msg);
}
});
}
/**
* 支付(唤起支付参数为模拟数据 真实应该由游戏服务器端传入)
*/
public void doPay(){
Log.i(TAG,"doPay");
String orderId=System.currentTimeMillis()+"";//订单号 建议由游戏服务器提供
String productDesc="优惠月礼包"; //商品描述
String productName="钻石"; //商品名称
String GAME_OPPO_URL="http://192.168.1.1:8080/order/oppo";//支付回调地址,由服务器提供
//参数1 游戏订单号 参数2 附加参数 传什么都可以 这里传入订单号 参数3 为支付金额 单位分
PayInfo payInfo = new PayInfo(orderId, orderId, 1);
payInfo.setProductDesc(productDesc);
payInfo.setProductName(productName);
payInfo.setCallbackUrl(GAME_OPPO_URL);
GameCenterSDK.getInstance().doPay(this, payInfo, new ApiCallback() {
@Override
public void onSuccess(String msg) {
Log.i(TAG,"PAY SUC");
}
@Override
public void onFailure(String msg, int code) {
Log.i(TAG,"PAY Fail========"+msg);
}
});
}
/**
* 上报游戏数据 给OPPO
*/
public void doSubUserInfo (){
Map mRoleInfo =new HashMap();
mRoleInfo.put("type", "createRole");// 以下场景必传[enterServer(登录),levelUp(升级),createRole(创建角色),exitServer(退出)]
mRoleInfo.put("roleId", "123456");// 当前登录的玩家角色ID,若无,可传入userid
mRoleInfo.put("roleName", "天下第一");// 当前登录的玩家角色名,不能空
mRoleInfo.put("roleLevel", "10");// 当前登录的玩家角色等级,不能为空,必须为数字,且不能为null,若无,传入0
mRoleInfo.put("serverId", "1001");// 当前登录的游戏区服ID,不能为空,必须为数字,若无,传入0
mRoleInfo.put("serverName", "Oppo32服");// 当前登录的游戏区服名称,不能为空,长度不超过50,不能为null,若无,传入“无”
if (mRoleInfo != null && "createRole".equals(mRoleInfo.get("type")) || ("enterServer".equals(mRoleInfo.get("type"))) || ("levelUp".equals(mRoleInfo.get("type")))) {
String serverId = mRoleInfo.get("serverId");
String serverName = mRoleInfo.get("serverName");
String roleId = mRoleInfo.get("roleId");
String roleName = mRoleInfo.get("roleName");
String roleLevel = mRoleInfo.get("roleLevel");
GameCenterSDK.getInstance().doReportUserGameInfoData(new ReportUserGameInfoParam(roleId, roleName, Integer.valueOf(roleLevel), roleId, roleName, "", new TreeMap()), new ApiCallback() {
@Override
public void onSuccess(String msg) {
}
@Override
public void onFailure(String msg, int code) {
}
});
}
}
/**
* 退出游戏
*/
public void doExitGame(){
Log.i(TAG,"DoExitGame");
GameCenterSDK.getInstance().onExit(this,new GameExitCallback() {
@Override
public void exitGame() {
finish();
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
}
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.i(TAG, "onKeyDown");
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
Log.i(TAG, "DoExitGameDoExitGameDoExitGame");
doExitGame();
return false;
} else {
return super.onKeyDown(keyCode, event);
}
}
app/build.gradle 下加入生成jar包Task
task makeJar(type: Copy) {
def jarPath = 'build/intermediates/packaged-classes/debug/'
def jarName = 'classes.jar'
from(jarPath)
into('build/outputs/') //输出路径为outputs/
include(jarName)
rename(jarName, 'unityPlug-1.4.jar') //重名为xxx.jar
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class btnClick : MonoBehaviour
{
private AndroidJavaClass jc;
private AndroidJavaObject jo;
private Button btnLogin;
private Button btnPay;
private Button btnExitGame;
public void Start()
{
//固定写法
jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
jo = jc.GetStatic("currentActivity");
btnLogin = transform.Find("BtnLogin").GetComponent
File ----Build Settings----Android----Player Settings -----Build System-----选择Internal (直接生成APK整包)
配置好签名(jdk sdk ndk均早配置好了) 选择bulid 静候几秒 完整的APK就搞定了
登录、支付、 退出效果 上面已经展示了,看下安卓登录回调成功后向Unity发送的消息
记录下自己的学习和工作经验,分享给有需要的人。如果有那里写的不对或者不理解,欢迎大家的指正。