众所周知,unity3d工程可以导出android studio、xcode等平台工程,还需要手动添加一些代码或者修改一些参数后再打包才能满足我们的业务需要。
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是一个软件包,也可以理解成一个插件。开发完成的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工程对应的配置文件中。
实现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文件需要在OnPostprocessBuild
回调中操作,因为这个回调触发时strings.xml文件已经生成了。OnPreprocessBuild
回调触发时还没有生成目标工程。拿到strings.xml文件路径后,使用XmlDocument相关api即可完成xml文件修改。
strings.xml路径:
string stringsPath = targetPath + "/" + PlayerSettings.productName + "/src/main/res/values/strings.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并不满足我们的要求,比如需要配置dependencies{…}脚本以添加第三方依赖。
实际上,在unity3d工程的Assets/Plugins/Android中会存在一个mainTemplate.gradle文件,即是默认导出到android studio工程的build.gradle文件。
所以我们可以在导出监听器中,使用另一个已经编辑好的build.gradle文件替换它即可。使用File.copy(…)即可完成替换。这个已经编辑好的build.gradle我们可以存放在unitypackage中。
将Java代码放在unitypackage中,在导出监听器中复制到android studio工程中即可。