android代码编译ipa,Unity脚本生成ipa或apk的方法

2016更新:本文写于2014。其中值得注意的是,建议默认使用python编写脚本,对跨平台有好处。而并非下文即将提及的、还不那么好地,使用bat、shell来编写。

基础概念

如果不关心概念只关心使用方法,可略过这里,直接去到“准备环境”、“脚本构建使用方法”。

能够使用Unity进行脚本生成ipa或apk(以下统称app)的核心前提是:

Unity运行时既包括了editor、也包括了compiler;

Unity运行时既能以界面形式运行、也能以命令行方式运行。可参见Unity命令行官方文档;

Unity以命令行方式运行时,能够通过形如-executeMethod MyScript.MyMethod参数,调用Editor脚本工程里面的某一个静态方法,该静态方法可以引用UnityEngine库、UnityEditor库里的任意函数,包括关键的BuildPipeline.BuildPlayer函数。可参考BuildPlayer的官方文档;

也就是说,理论上任何在Unity编辑器里能实现的操作,都能通过命令行实现。(亲可以试一下使用命令行做一个Unity游戏出来:p)

所以,使用Unity进行脚本生成app的核心步骤是:

准备SDK环境。如果是生成apk,则机器(Mac或PC)先准备好Android SDK;如果是生成ipa,则Mac先安装好XCode

调用脚本,生成中间工程文件。脚本实际是运行Unity命令行,调用用户函数比如CommandBuild.Build函数,输入各类参数(比如-ios/-android的平台参数、比如-debug/-release的版本参数)

调用脚本,使用SDK将中间工程文件生成app。如果是生成apk,因为Android的开放性,Unity能够将这一步合到第2步中,所以生成apk也就不需要我们去搞第3步了;但如果是生成ipa,因为苹果限制必须使用XCode生成ipa,所以我们需要再用脚本调用XCode,将工程文件生成ipa。

准备环境

准备生成apk的环境

机器可以是PC或Mac。但这里只讨论PC。

下载java,并且添加java的安装路径到本机环境变量,方法可参考这里。

到Android官网下载最新的Eclipse ADT

注:可能出现点击下载按钮没反应的情况,可以更换浏览器再试试。

注:ADT包括了EclipseIDE和SDK本身。事实上我们的确只需要SDK就好了,但试过下载SDK是不行的,因为缺少了里面的platforms。所以用下载工具下载ADT是个省时的选择。

解压下载好的压缩包,放到合适的地方。

打开Unity,Edit>Preferences>External Tools>Android SDK Location,然后选择你刚才解压文件夹中的sdk文件夹。

完毕。现在可以使用Unity构建了。

注:如果构建中途,出现失败形如Error building Player: Win32Exception: ...zipalign.exe...CommandLine='4"的错误,可以把zipalignexe从sdk\build-tools\(你的版本)文件夹拷到sdk\tool文件夹。

准备生成ipa的环境

机器必须是Mac

到App Store下载并安装最新的XCode

准备好开发者帐号、开发者p12文件。(过程略)

脚本使用方法

生成apk

修改Environment.bat

修改“unity”变量,指定里面的unity路径。

修改“debugParam”变量,指定是-debug或者-release

执行UnityToApk.bat,等待执行完毕

apk生成在KillerProject\Bin\Android文件夹下

生成ipa

修改UnityToXCode.sh里的“debugParam”变量,指定是-debug或者-release。

执行UnityToIPA.sh生成ipa文件。也可以执行SvnUnityToIPA.sh即先更新SVN再生成ipa。

附脚本

apk相关脚本

Environment.bat

:: set your own Unity path

set unity="D:\Program Files (x86)\Unity\Editor\Unity.exe"

:: -debug or -release

set debugParam=-debug

set projectPath=%~dp0

UnityToApk.bat

rmdir /q Bin\Android

mkdir Bin\Android

call Environment.bat

echo "Start Build Unity to Apk"

%unity% -batchmode -projectPath %projectPath% -executeMethod CommandBuild.PreBuild %debugParam% -quit -logFile ./PreBuild.log

%unity% -batchmode -projectPath %projectPath% -executeMethod CommandBuild.Build %debugParam% -android -quit -logFile ./BuildApk.log

echo "End Build,please see log PreBuild.log and BuildApk.log"

ipa相关脚本

UnityToXCode.sh

#!/bin/bash

echo "Remove XCodeProject"

rm -rf XCodeProject

path=`pwd`

#-debug or -release

debugParam="-debug"

echo "Start Build Unity to XCodeProject"

/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -projectPath $path -executeMethod CommandBuild.PreBuild $debugParam -quit -logFile ./PreBuild.log

/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -projectPath $path -executeMethod CommandBuild.Build $debugParam -ios -quit -logFile ./BuildXCodeProject.log

echo "End Build,please see log PreBuild.log and BuildXCodeProject.log"

XCodeToIPA.sh

#/bin/sh

usage()

{

echo "usage: $0 AppName XCodeProject"

echo "example: $0 Killer XCodeProject"

}

if [ $# -ne 2 ] ;then

usage

exit 1

fi

path=`pwd`

app_name=$1

xcodeproj_dir=$path/$2

#echo $app_name

#echo $xcodeproj_dir

#echo $path

if [ -d $xcodeproj_dir ] ;then

echo "$xcode_dir exist"

else

echo "dir $xcodeproj_dir doesn't exist"

exit 1

fi

cd $xcodeproj_dir

xcodebuild -sdk iphoneos7.1

echo "end xcodebuild"

cd ./build

mkdir -p ipa/Payload

cp -r ./${app_name}.app ./ipa/Payload

cd ipa

echo "zip $app_name"

zip -r $app_name *

app_file=$path/${app_name}_$(date +%m%d_%H%M).ipa

mv ${app_name}.zip $app_file

echo "Build Successed ipa."

echo "$app_file"

通用Editor脚本代码

CommandBuild.cs

using UnityEngine;

using UnityEditor;

public class CommandBuild

{

private static string[] ms_scenes =

{

"Assets/Scenes/KillerStarter.unity"

};

private static bool ms_isDebugBuild = false;

private static BuildTarget ms_buildTarget = BuildTarget.Android;

private static string XCODE_PROJECT_NAME = "XCodeProject";

private static string BUILD_OUTPUT_ANDROID = "Bin/Android/";

private static void UpdateBuildFlag()

{

string[] args = System.Environment.GetCommandLineArgs();

foreach(string oneArg in args)

{

if (oneArg != null && oneArg.Length > 0)

{

if (oneArg.ToLower().Contains("-debug"))

{

Debug.Log("\"-debug\" is detected, switch to debug build.");

ms_isDebugBuild = true;

return;

}

else if (oneArg.ToLower().Contains("-release"))

{

Debug.Log("\"-release\" is detected, switch to release build.");

ms_isDebugBuild = false;

return;

}

}

}

if (ms_isDebugBuild)

{

Debug.Log("neither \"-debug\" nor \"-release\" is detected, current is to debug build.");

}

else

{

Debug.Log("neither \"-debug\" nor \"-release\" is detected, current is to release build.");

}

}

private static void UpdateBuildTarget()

{

string[] args = System.Environment.GetCommandLineArgs();

foreach (string oneArg in args)

{

if (oneArg != null && oneArg.Length > 0)

{

if (oneArg.ToLower().Contains("-android"))

{

Debug.Log("\"-android\" is detected, switch build target to android.");

ms_buildTarget = BuildTarget.Android;

return;

}

else if (oneArg.ToLower().Contains("-iphone"))

{

Debug.Log("\"-iphone\" is detected, switch build target to iphone.");

ms_buildTarget = BuildTarget.iPhone;

return;

}

else if (oneArg.ToLower().Contains("-ios"))

{

Debug.Log("\"-ios\" is detected, switch build target to iphone.");

ms_buildTarget = BuildTarget.iPhone;

return;

}

}

}

Debug.Log("neither \"-android\", \"-ios\" nor \"-iphone\" is detected, current build target is: " + ms_buildTarget);

}

public static void PreBuild()

{

Debug.Log("PreBuild");

UpdateBuildFlag();

SetKgfDebugActive(ms_isDebugBuild);

}

public static void Build()

{

Debug.Log("Build");

UpdateBuildTarget();

BuildOptions buildOption = BuildOptions.None;

if (ms_isDebugBuild)

{

buildOption |= BuildOptions.Development;

buildOption |= BuildOptions.AllowDebugging;

buildOption |= BuildOptions.ConnectWithProfiler;

}

else

{

buildOption |= BuildOptions.None;

}

string locationPathName;

if(BuildTarget.iPhone == ms_buildTarget)

{

locationPathName = XCODE_PROJECT_NAME;

}

else

{

locationPathName = BUILD_OUTPUT_ANDROID;

System.DateTime time = System.DateTime.Now;

locationPathName += "killer_" + time.Month.ToString("D2") + time.Day.ToString("D2") +

"_" + time.Hour.ToString("D2") + time.Minute.ToString("D2") + ".apk";

}

BuildPipeline.BuildPlayer(ms_scenes, locationPathName, ms_buildTarget, buildOption);

}

public static void PostBuild()

{

Debug.Log("PostBuild");

}

private static void SetKgfDebugActive(bool activated)

{

///非重点,略

}

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值