Unity中IOS打包教程 VR资源

卫宫士郎 2017-10-31 18:57:38
iOS打包需要的流程


整个打包流程与打包是类似的。
难点主要集中在插入必要的FrameWork,修改Plist
在.x上Unity官方已经帮我们提供了一套API用来对Xcode工程的处理。并且提供了[PostProcessBuild]这个标签来完成插入工作。
在Unity4.x上使用这套API可以去下载Unity官方提供的代码 Unity-Technologies / XcodeAPI - Bitbucket

Unity导出前的准备
手上的项目分多个地区,所以在导出前会有不同的资源切换和资源删除
 
代码如下:
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
static void ExportiOSHFProject_Online() {
        getCMDArgs();
        PlayerSettings.defaultInterfaceOrientation = UIOrientation.AutoRotation;
        PlayerSettings.productName = "xxxx"; //设置韩服的Name
        //设置Deployment Target
        PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.iOS, "TWSDK;EXCLUDE_SHARESDK;KOREAN");
        if (OnlySetScriptingDefineSymbols)
        {
            Debug.Log("本次打开Unity只是设置全局宏,打包请再次调用");
            return;
        }
        string[] NeedToDel = {""};//指定要删除的目录
        doDelWithRelativePath(NeedToDel);
        _LanguageBar.ToTraditionForAntBuild(_LanguageBar.UNIRES_KOREA); //切换语言版本
        ExportProject(ExportPath, BuildTarget.iOS, BuildOptions.None);
    }
    static void ExportProject(string path,BuildTarget target,BuildOptions options)
    {
 
        if (path.Length != 0)
        {
            foreach (EditorBuildSettingsScene scene in EditorBuildSettings.scenes)
            {
                if (!scene.enabled) continue;
                levels.Add(scene.path);
            }
 
            float time = Time.realtimeSinceStartup;
            AssetDatabase.Refresh();
            try
            {
                BuildPipeline.BuildPlayer(levels.ToArray(), path, target, options);
            }
            catch (System.Exception m)
            {
                Debug.LogError(m.Message);
            }
            time = Time.realtimeSinceStartup - time;
            Debug.Log("打包完成,共计耗时" + time);
        }
 
    }
踩坑注意点
  • 1.OnlySetScriptingDefineSymbols
    这个是在命令行打包时候外部传过来的值,为了判断是来导出工程还是设置宏。
    本处这样设置是因为,在一开始我的打包脚本也是用宏来区分执行切换哪部分资源的,
    但是后来出现了一个奇怪的问题,如果我刚刚Checkout出来的Unity默认宏是A的话, 但是我想打包的是B。
    我直接设置PlayerSettings.SetScriptingDefineSymbolsForGroup为B,
    确实非Editor和非[PostProcessBuild]标签的脚本都被编译了为B。
    但是在我Unity内部打包脚本的宏没有切换,也就导致了我Unity脚本都切换了为B,但是我资源等切换都还是停留在A上,
    所以这里设置为第一次打开Unity设置PlayerSettings.SetScriptingDefineSymbolsForGroup为B,然后关闭再打开Unity这样所有的脚本都被切换到B了。
    这个问题我自己被坑了挺久,当然也有可能是自己的设计有问题,希望大家有更加好的解决办法,或则是我的错误,希望大家能分享一下。
  • 2.BuildPipeline.BuildPlayer()
    options ios需要切换到BuildOptions.None,这个参数我也并没有特别的明白,但是如果选择其他或则与Android的类似,会出现些问题。

     

插入FrameWork和Plis

 

接下来肯定是大家最关注的点了,我把代码直接贴出来吧,隐去了设置的的参数,宏因为是公司项目有些修改,可以根据自己的来修改。
 
 
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
public class AntXcodeProjectProcess : MonoBehaviour {
 
    [PostProcessScene]
    public static void OnPostprocessScene()
    {
         
#if UNITY_ADS
        AdvertisementSettings.enabled = true;
        AdvertisementSettings.initializeOnStartup = false;
#endif
    }
    [PostProcessBuild(100)]
    public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
    {
        if (buildTarget == BuildTarget.iOS)
        {
                        //plist
                        string plistPath = Path.Combine(path, "info.plist");
                        PlistDocument plist = new PlistDocument ();
                        plist.ReadFromFile (plistPath);
            plist.root.SetString ("CFBundleDevelopmentRegion", "zh_CN");
                        plist.root.SetString("NSCameraUsageDescription", "直播相关");
                        plist.root.SetString("NSAppleMusicUsageDescription", "直播相关");
 
#if TWSDK && !KOREAN
            plist.root.SetString("FacebookAppID", "");
            plist.root.SetString("FacebookDisplayName","");
            plist.root.CreateArray("CFBundleURLTypes").AddDict().CreateArray("CFBundleURLSchemes").AddString("");
            string[] LSApplicationQueriesSchemesValueList = { "starcoin", "fbapi", "", "", "", "", "", "" ,"","","","","" ,""};
            PlistElementArray LSApplicationQueriesSchemesArray = plist.root.CreateArray("LSApplicationQueriesSchemes");
            for (int i = 0; i < LSApplicationQueriesSchemesValueList.Length; i++) {
                LSApplicationQueriesSchemesArray.AddString(LSApplicationQueriesSchemesValueList);
            }
            plist.root.SetString("NSPhotoLibraryUsageDescription", "允許授權后遊戲體驗會更豐富");
 
#elif TWSDK && KOREAN
            plist.root.SetString("FacebookAppID", "");
            plist.root.SetString("FacebookDisplayName", "");
            plist.root.CreateArray("CFBundleURLTypes").AddDict().CreateArray("CFBundleURLSchemes").AddString("");
            string[] LSApplicationQueriesSchemesValueList = { "starcoin", "fbapi", "", "", "", "", "", "" ,"","","","","" ,""};
            PlistElementArray LSApplicationQueriesSchemesArray = plist.root.CreateArray("LSApplicationQueriesSchemes");
            for (int i = 0; i < LSApplicationQueriesSchemesValueList.Length; i++) {
                LSApplicationQueriesSchemesArray.AddString(LSApplicationQueriesSchemesValueList);
            }
            plist.root.SetString("NSPhotoLibraryUsageDescription", "允許授權后遊戲體驗會更豐富");
#endif
            PlistElementDict dictTransportSecurity = plist.root ["NSAppTransportSecurity"].AsDict ();
                        dictTransportSecurity.SetBoolean("NSAllowsArbitraryLoads",true);
 
#if !EXCLUDE_SHARESDK
            plist.root.CreateArray("LSApplicationQueriesSchemes").AddString("weixin"); // 微信分享
                        plist.root.CreateArray("CFBundleURLTypes").AddDict().CreateArray("CFBundleURLSchemes").AddString("");
#endif
                        plist.WriteToFile (plistPath);
             
            //project
            string projPath = PBXProject.GetPBXProjectPath(path);
            PBXProject proj = new PBXProject();
            proj.ReadFromString(File.ReadAllText(projPath));
            string target = proj.TargetGuidByName("Unity-iPhone");
#if TWSDK && !KOREAN
            proj.SetTargetAttributes("ProvisioningStyle", "Manual");//关闭自动证书管理
#elif TWSDK && KOREAN
            proj.SetTargetAttributes("ProvisioningStyle", "Manual");//关闭自动证书管理
#endif
 
            //add common framework start
            proj.AddFrameworkToProject(target, "ReplayKit.framework", true);
            proj.AddFrameworkToProject(target, "ImageIO.framework", true);
            proj.AddFrameworkToProject(target, "Storekit.framework", false);
            proj.AddFrameworkToProject(target, "JavaScriptCore.framework", true);
            if (proj.ContainsFramework(target, "Metal.framework")){
                proj.RemoveFrameworkFromProject(target, "Metal.framework");
                proj.AddFrameworkToProject(target, "Metal.framework", true);
            }
            //add common framework end
            proj.AddBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", "$(SRCROOT)");
            proj.AddBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", "$(SRCROOT)/Libraries");
 
            string[] addBuildProperty = { "$(SRCROOT)/Libraries", "$(SRCROOT)" };
            string[] removeBuildProperty = { "\"$(SRCROOT)/Libraries\"", "\"$(SRCROOT)\"" };
            proj.UpdateBuildProperty(target, "LIBRARY_SEARCH_PATHS", addBuildProperty, removeBuildProperty);
 
            proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC");
 
            //custom frameworl start
 
 
 
#if SDK
            proj.AddFileToBuild(target, proj.AddFile