unity二次开发 接第三方sdk

我看到过很多unity接sdk的方式,但是主要分为两种

1.以unity工程为主,导入sdk的jar包和修改配置AndroidManifest.xml,这种方式优点就是不脱离unity,但是这样接sdk的资料太少,而且如果sdk过多不方便。

2.我今天主要说第二种方式,导出Android工程在esplise里进行接入并且进行二次开发,因为第二种方式需要对esplise和java有一定程度的了解,对我而言第二种方式更适合长期的投资。今天我就把我这三个月学习经验向大家分享一下。

因为今天这篇文章涉及的不仅仅是unity,大体的东西我就都说一下,如果有疑问的地方可以留言或者自己找资料。

一.要做sdk接入首先要知道,unity是如何与Android通信的,这个知识点网上有很多,我在这里就举一个简单的例子(补充已经这个脚本是要挂到场景内部的)


这里一共两句代码,先解释第一句代码,这句代码无非是找到esplise里com.example.testcommunicate下的PlatformContext类

第二句代码留个悬念,然后再unity内部留出测试接口


二.进行esplise内部接口的实现,也就是unity与Android通信的第二步。说到这里呢,com.example.testcommunicate.PlatformContext就能用上了。


这就是我esplise的目录结构,多余的脚本会后续解释。第一步我们已经确定了Android内部的通信类PlatformContext,我们来实现它内部的通信接口。

通常来说这个PlatformContext我们都定义为抽象类,方便以后开发,我先给出抽象类,再给出实现的子类

package com.example.testcommunicate;

import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.util.Log;

import com.unity3d.player.UnityPlayer;

public abstract class PlatformContext {
protected static PlatformContext m_instance;
	
private Context m_ctx;
private Activity m_activity;

protected String m_target;

protected JSONObject m_config;

protected String m_tag;
	
protected String m_userId;
protected String m_nickname;

protected String m_channelUserInfo;

protected String m_channelSid;


protected String m_orderUrl;
protected String m_devilerUrl;

protected String m_imei;

protected String m_pkgid;
protected String m_packageName;
protected String m_version;

protected String m_serverId;
protected String m_serverName;
protected abstract void initContext(String config);
public abstract boolean destroyContext();
public abstract void login(int nParam);
public abstract void logout();
public abstract void switchAccount();
public abstract boolean isLogin();

protected abstract String getSession();
protected abstract String getGameId();
	public static PlatformContext getInstance()
	{
		
		return m_instance;
	}
	
	protected void setGameObject(String name) {
		m_target = name;
	}

	
	protected PlatformContext(String tag) 
	{
		m_instance = this;
		m_activity = UnityPlayer.currentActivity;
		m_ctx = m_activity.getApplicationContext();
		
		
		m_pkgid = m_activity.getClass().getPackage().getName();
		m_packageName = m_activity.getPackageName();
		
		try {
			m_version = m_activity.getPackageManager().getPackageInfo(m_packageName, 0).versionName;
		} catch (Exception e) {
			m_version = "0";
		}
	}
	
	protected PlatformContext(String target,String tag) 
	{
		m_instance = this;
		m_activity = UnityPlayer.currentActivity;
		m_ctx = m_activity.getApplicationContext();
		

		
		m_pkgid = m_activity.getClass().getPackage().getName();
		m_packageName = m_activity.getPackageName();
		
		try {
			m_version = m_activity.getPackageManager().getPackageInfo(m_packageName, 0).versionName;
		} catch (Exception e) {
			m_version = "0";
		}

	}
}

package com.example.testcommunicate;

import java.util.HashMap;
import android.util.Log;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Handler;
import android.os.Looper;


import com.unity3d.player.UnityPlayer;


public class TSPlatformContext extends PlatformContext {

	int m_cpId;
	int m_gameId;
	boolean m_debug = false;
	boolean m_blogin;
	boolean m_enableGameAccount = false;
	String m_gameAccountTitle;
	String m_channalID;
	String m_uid;
	String m_name;
	String Timestamp;
	String m_token;
	//String m_channelID;
	String rsa = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArSULL4MRYI8wxLDLCWxQRXiEx61E7Dm9cbMHHY2l3lb3Axi0VEuLI/9Ee0zYF2/jXBfnE1mZAd2pnMHcyOT5yS76uqDQrMRRPUYrTV1zzRPK7pBbGwKdpWWlEwYXEdBvZrQaJQdF9NPBx/KluKs6s0wV2OhU+sRGqW2ohlfNvaL0ji5OOsBeG2d6uRkY7Zh+ZWNJuD/W3zMOb6d13FDsfKPtXpxe6lhZewH/jJz9w925z2HBG9hfjs7gOeIzsCJZS3kYEpeFTWPIGY4FFhRd3Vr3xwhPqyf945+cn43S+o0ZhTabVRwuG5Apk0gWMc8BimnL82GBEz0HzUOyvgydEwIDAQAB";
	String roleId = null;
	String roleName = null;
	String roleLevel;
	String zoneId ;
	String zoneName = null;
	String balance ;
	String vip ;
	String partyName = null;
	public static int tempTypeGame = 1;
	public TSPlatformContext(String target) {
		super(target,"KZ");
		 m_blogin = false;
	}
	public static void Init()
	{
		if(m_instance==null) {
			TSPlatformContext ucctx = new TSPlatformContext("");
			ucctx.initPlatform();
		}
		return;
	}
	
	
	protected void initPlatform() {
		// TODO Auto-generated method stub
		 Log.d("", "initPlatform...");
		
		
	
	}
	
	public void initContext(String config) {
		 Log.d("", "initContext config:"+config);
		UnityPlayer.UnitySendMessage("PlatformHelper", "AtoUnity", "sucess");//这个其实就是Android向unity内的反向通信,"PlatformHelper"是unity场景内挂着AndroidTestCommunication的物体名称

		
	}
	@Override
	public boolean destroyContext() {
		// TODO Auto-generated method stub
        Log.d("", "destroyContext...");
		return false;
	}
	@Override
	public void login(int nParam) {
		 Log.d("", "login...");
		
	}
	@Override
	public void logout() {
		 Log.d("", "logout...");
	}
	@Override
	public void switchAccount() {
		 Log.d("", "switchAccount...");
	}
	@Override
	public boolean isLogin() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	protected String getSession() {
		// TODO Auto-generated method stub
		return  "";
	}

	@Override
	protected String getGameId() {
		// TODO Auto-generated method stub
		return "";
	}
	
   
}

unity内部的完成demo代码

using UnityEngine;
using System.Collections;

public class AndroidTestCommunication : MonoBehaviour
{
    AndroidJavaObject m_sdkobj;
	// Use this for initialization
    AndroidJavaObject klass;
	void Awake ()
    {
#if NORMAL
#else
        // Debug.LogError("AndroidJavaObject Init");
         klass = new AndroidJavaClass("com.example.testcommunicate.PlatformContext");
        m_sdkobj = klass.CallStatic<AndroidJavaObject>("getInstance");//这句就是通过一个简单的单例获取Android内部的PlatformContext类的实例对象

       /// m_sdkobj.Call("setGameObject", name);
#endif
        //Debug.LogError(klass);
        //Debug.LogError(m_sdkobj);
    }

//这里我添加了开机动画很简单的
    IEnumerator Start()
    {
        Debug.LogError("Start");
        if (Handheld.PlayFullScreenMovie("Heroes_Kingdom_ingame1280.mp4", Color.black, FullScreenMovieControlMode.CancelOnInput))
            yield return new WaitForEndOfFrame();
        yield break;
    }
	// Update is called once per frame
	void Update () {
	
	}
    void OnGUI()
    {
        if (GUILayout.Button("button1",GUILayout.Height(Screen.height*0.4f),GUILayout.Width(Screen.height*0.4f)))
        {
            Debug.LogError("onclick button1");
            m_sdkobj.Call("initContext", "success");
        }
    }

    public void AtoUnity(string succes)
    {
        Debug.LogError("come back:" + succes);
    }
}
这里也看到了,我只是实现了一个初始化通信接口 initContext,其实如果接第三方sdk,登录支付接口实现的都是一个道理。


上面把通信说了,可是是怎么个二次开发的呢,其实很简单首先导出unity的esplise包,3个地方

导出后的工程文件夹,将assert下的bin文件和文件拷到新建的Android工程assert文件夹中。还有lib文件夹下的.so文件也同样拷到Android工程的lib文件夹下



然后就是进行esplise内Android工程的修改了,第一步Android工程内lib文件夹下引用


下面这个红色的代码是现成的,在unity里有直接拷贝过来就可以了


最后一步就是进行的修改,我这里给一个通用版,需要修改的地方会标注

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testcommunicate"//这里也是包名对应
    android:versionCode="1"
    android:versionName="1.0" >


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
       <activity android:label="@string/app_name" android:screenOrientation="sensorLandscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" android:name="com.example.testcommunicate.UnityPlayerNativeActivity">//这里要和你自己的包名对应上
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
      <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
    </activity>
    
       
    </application>
  <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
  <uses-feature android:glEsVersion="0x00020000" />
  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  <uses-feature android:name="android.hardware.sensor.accelerometer" />
  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  <uses-permission android:name="android.permission.GET_TASKS" />
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  <uses-permission android:name="android.permission.SEND_SMS" />
  <uses-permission android:name="android.permission.VIBRATE" />
 
 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

</manifest>
需要改的地方都好了,剩下就是出包测试了。刚开始写文章,感觉思路优点混乱,可以随时纠正一起学习。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值