众所周知,unity3d工程可以导出android studio、xcode等平台工程,但是导出后的as或xocde工程并不能直接使用,还需要手动添加对应平台的一些代码或者修改一些工程配置,再打包才能满足我们的业务需要。是否存在一种方式,导出对应平台工程后,可以直接出包使用呢?
很多游戏需要接入第三方SDK,有些SDK提供了unity版本、android studio和xcode版本,有些SDK没有unity版本,只有as和xcode版本。而且一些SDK接入了unity版本后,导出的android studio或xcode工程自动完成了相应的平台配置。本文就是讲述如何实现这种自动化功能。
目前市面上个别SDK实现了这种自动化功能,像Mob SDK(以前叫Share SDK)已经实现这种功能。在接入unity版本的sdk后,在unity上经过简单的参数配置,导出android studio或xcode平台工程后,即可直接运行。不过,经过笔者对友盟SDK、极光SDK、个推SDK的调研,发现他们有点落后,没有完成unity自动化过程。
默认导出的AS工程存在的不足
1、导出后的as工程根目录中没有gradle文件夹和gradlew脚本文件;
使用as打开工程虽然可以自动添加,但是gradle版本号默认使用最新的,有时需要指定成一个版本。
2、 需要再手动在AndroidManifest.xml中添加项目需要的配置,比如permission、meta-data、activity等等;
3、需要在strings.xml添加第三方SDK需要的参数;
4、自动生成的build.gradle文件比较简陋,需要手动添加第三方依赖。
5、还需要手动配置签名文件
其实这些东西可以通过编写unity package来解决,达到导出as工程后,不需要再做其它修改,直接运行即可。
Unity Package简介
unity package是一个软件包,也可以理解成一个插件。开发完成的package包的后缀名是.unitypackage。
实际上任何unity3d工程的代码都可以导出成一个package包。
如何导出呢?选中Assets目录,右键点击Export Package即可导出成package包。
导出并命名后是这样的:
当点击这种.package包后,会弹出界面让你选择是否需要导入package里的代码到你的unity项目中。
可以选择全部或部分导入。
当Unity3d工程导出成AS工程,会触发一个回调操作,使用c#编写回调实现代码即可完成自动配置AS工程。
所以我们可以开发出一种unity package包,导入到你的unity3d工程后,就自动完成了相关配置。
在可视化界面上修改变量值
unity3d有一个挂载的概念,当完成一个MonoBehaviour子类开发后,需要挂载到场景上才能生效。
先选中一个场景:
然后点击添加组件。
添加后即完成了组件挂载。
组件中的成员变量还可以通过可视化界面来修改值。
比如NewBehaviourScript中有四个成员变量:
public class NewBehaviourScript : MonoBehaviour {
public string param1;
public string param2;
public int param3;
public bool param4;
}
挂载到一个场景后就可以在界面中编辑它们的值:
所以有些参数,我们可以在可视化界面上修改,再通过c#代码写入到AS工程对应的配置文件中。
监听导出AS工程
实现IPreprocessBuild,IPostprocessBuild两个接口即可监听导出工程动作:
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.Text;
using System.Reflection;
using System.Xml;
public class Test :IPreprocessBuild,IPostprocessBuild{
//生成目标工程前调用
public void OnPreprocessBuild(BuildTarget target, string targetPath)
{
Debug.Log ("OnPreprocessBuild:path=" + targetPath);
if (target != BuildTarget.Android) {
Debug.LogWarning ("Target is not Android");
return;
}
}
//生成目标工程后调用
public void OnPostprocessBuild(BuildTarget target, string targetPath)
{
Debug.Log ("OnPostprocessBuild:path=" + targetPath);
//示例:获取导出后的strings.xml文件路径,'PlayerSettings.productName'是工程名称
string stringsPath = targetPath + "/" + PlayerSettings.productName + "/src/main/res/values/strings.xml";
}
}
在对应的回调函数中实现我们功能即可。
修改strings.xml文件
修改strings.xml文件需要在OnPostprocessBuild
回调中操作,因为这个回调触发时strings.xml文件已经生成了。OnPreprocessBuild
回调触发时还没有生成目标工程。拿到strings.xml文件路径后,使用XmlDocument相关api即可完成xml文件修改。
strings.xml路径:
string stringsPath = targetPath + "/" + PlayerSettings.productName + "/src/main/res/values/strings.xml";
修改AndroidManifest.xml文件
跟strings.xml一样,拿到它的路径后,使用XmlDocument修改即可。
修改AndroidManifest.xml文件的例子,在我的另一篇文章中已经写过:
【Unity3d】C#使用XmlDocument读写xml含冒号的节点(含命名空间)
值得一提的是,如果已经有一个编辑好的AndroidManifest.xml模板,把它放在unity3d工程的Assets/Plugins/Android目录下,导出工程后,就会被自动复制到Android Studio工程中。不过这样的话,有些参数无法替换成unity3d中的参数,比如activity的包名。需要事先手动编辑好AndroidManifest.xml文件。所以最好还是通过c#代码实现自动化。
修改build.gradle文件
默认生成的build.gradle并不满足我们的要求,比如需要配置dependencies{…}脚本以添加第三方依赖。
实际上,在unity3d工程的Assets/Plugins/Android中会存在一个mainTemplate.gradle文件,即是默认导出到android studio工程的build.gradle文件。
所以我们可以在导出监听器中,使用另一个已经编辑好的build.gradle文件替换它即可。使用File.copy(…)即可完成替换。这个已经编辑好的build.gradle我们可以存放在unitypackage中。
添加Java代码
将Java代码放在unitypackage中,在导出监听器中复制到android studio工程中即可。