最近在研究Unity3D腳本批量打包,比如在Android平台下各種不同分辨率和不同內存大小的機器,可能還有不同的渠道包,不同渠道可能用的SDK都不一樣,這一切的一切都表明你的代碼無法做到自適應的,除非批量打包提供各個平台的預定義標簽#define 。
Unity默認提供了一些預定義標簽如:
UNITY_EDITOR : 編輯器模式下。
UNITY_STANDALONE:PC Mac Linux模型下。
UNITY_IPHONE:IOS模式下。
UNITY_ANDROID:ANDROID模式下。
還有很多預定義標簽、大家可以在這里看到:http://docs.unity3d.com/Documentation/Manual/PlatformDependentCompilation.html
官方提供的標簽屬於比較大的范圍標簽,比如我希望在UNITY_ANDROID下面在寫一些自定義的標簽、類似 QQ UC CMCC這樣的渠道標簽該如何呢?如下圖所示,ProjectSetting打包界面每個平台都會有Scripting Define Symbols這個選項,可以在這里添加每個平台下對應的自定義標簽(多個標簽用“;”號隔開),這里我設置的是Android平台,如果IOS也需要打這樣的渠道標簽那么也要在IOS頁面Scripting Define Symbols選項處添加對應的標簽。
標簽做出來了就好辦了,然后在代碼中我們可以這樣來寫。如果在Scripting Define Symbols中沒有出現的標簽默認是不啟用的,就像 #define Test 一樣,會自動被注釋掉。
然后我們看看如何實現腳本批量打包。
|
1
2
3
4
5
6
7
8
9
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
public class MyEditorScript
{
//得到工程中所有場景名稱
static string[] SCENES = FindEnabledEditorScenes();
//一系列批量build的操作
[MenuItem ("Custom/Build Android QQ")]
static void PerformAndroidQQBuild ()
{
BulidTarget("QQ","Android");
}
[MenuItem ("Custom/Build Android UC")]
static void PerformAndroidUCBuild ()
{
BulidTarget("UC","Android");
}
[MenuItem ("Custom/Build Android CMCC")]
static void PerformAndroidCMCCBuild ()
{
BulidTarget("CMCC","Android");
}
[MenuItem ("Custom/Build Android ALL")]
static void PerformAndroidALLBuild ()
{
BulidTarget("QQ","Android");
BulidTarget("UC","Android");
BulidTarget("CMCC","Android");
}
[MenuItem ("Custom/Build iPhone QQ")]
static void PerformiPhoneQQBuild ()
{
BulidTarget("QQ","IOS");
}
[MenuItem ("Custom/Build iPhone QQ")]
static void PerformiPhoneUCBuild ()
{
BulidTarget("UC","IOS");
}
[MenuItem ("Custom/Build iPhone CMCC")]
static void PerformiPhoneCMCCBuild ()
{
BulidTarget("CMCC","IOS");
}
[MenuItem ("Custom/Build iPhone ALL")]
static void PerformiPhoneALLBuild ()
{
BulidTarget("QQ","IOS");
BulidTarget("UC","IOS");
BulidTarget("CMCC","IOS");
}
//這里封裝了一個簡單的通用方法。
static void BulidTarget(string name,string target)
{
string app_name = name;
string target_dir = Application.dataPath + "/TargetAndroid";
string target_name = app_name + ".apk";
BuildTargetGroup targetGroup = BuildTargetGroup.Android;
BuildTarget buildTarget = BuildTarget.Android;
string applicationPath = Application.dataPath.Replace("/Assets","");
if(target == "Android")
{
target_dir = applicationPath + "/TargetAndroid";
target_name = app_name + ".apk";
targetGroup = BuildTargetGroup.Android;
}
if(target == "IOS")
{
target_dir = applicationPath + "/TargetIOS";
target_name = app_name;
targetGroup = BuildTargetGroup.iPhone;
buildTarget = BuildTarget.iPhone;
}
//每次build刪除之前的殘留
if(Directory.Exists(target_dir))
{
if (File.Exists(target_name))
{
File.Delete(target_name);
}
}else
{
Directory.CreateDirectory(target_dir);
}
//==================這里是比較重要的東西=======================
switch(name)
{
case "QQ":
PlayerSettings.bundleIdentifier = "com.game.qq";
PlayerSettings.bundleVersion = "v0.0.1";
PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup,"QQ");
break;
case "UC":
PlayerSettings.bundleIdentifier = "com.game.uc";
PlayerSettings.bundleVersion = "v0.0.1";
PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup,"UC");
break;
case "CMCC":
PlayerSettings.bundleIdentifier = "com.game.cmcc";
PlayerSettings.bundleVersion = "v0.0.1";
PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup,"CMCC");
break;
}
//==================這里是比較重要的東西=======================
//開始Build場景,等待吧~
GenericBuild(SCENES, target_dir + "/" + target_name, buildTarget,BuildOptions.None);
}
private static string[] FindEnabledEditorScenes() {
List<string> EditorScenes = new List<string>();
foreach(EditorBuildSettingsScene scene in EditorBuildSettings.scenes) {
if (!scene.enabled) continue;
EditorScenes.Add(scene.path);
}
return EditorScenes.ToArray();
}
static void GenericBuild(string[] scenes, string target_dir, BuildTarget build_target, BuildOptions build_options)
{
EditorUserBuildSettings.SwitchActiveBuildTarget(build_target);
string res = BuildPipeline.BuildPlayer(scenes,target_dir,build_target,build_options);
if (res.Length > 0) {
throw new Exception("BuildPlayer failure: " + res);
}
}
}
|
這里面忘說了一點,如果我們希望在性能高的手機上用一套好的資源,在性能低的手機上用一套差一點的資源該怎么辦?那么首先我們先搞清楚Unity會把什么資源打包,什么資源不打包?
1.Resources文件夾
Resources文件夾是一個只讀的文件夾,通過Resources.Load()來讀取對象。因為這個文件夾下的所有資源都可以運行時來加載,所以Resources文件夾下的所有東西都會被無條件的打到發布包中。建議這個文件夾下只放Prefab或者一些Object對象,因為Prefab會自動過濾掉對象上不需要的資源。舉個例子我把模型文件還有貼圖文件都放在了Resources文件夾下,但是我有兩張貼圖是沒有在模型上用的,那么此時這兩張沒用的貼圖也會被打包到發布包中。假如這里我用Prefab,那么Prefab會自動過濾到這兩張不被用的貼圖,這樣發布包就會小一些了。
2.StreamingAssets
StreamingAssets文件夾也是一個只讀的文件夾,但是它和Resources有點區別,Resources文件夾下的資源會進行一次壓縮,而且也會加密,不使用點特殊辦法是拿不到原始資源的。但是StreamingAssets文件夾就不一樣了,它下面的所有資源不會被加密,然后是原封不動的打包到發布包中,這樣很容易就拿到里面的文件。所以StreamingAssets適合放一些二進制文件,而Resources更適合放一些GameObject和Object文件。StreamingAssets 只能用過www類來讀取!!
3. 最后凡是在Hierarchy視圖對象引用過的資源文件也會被無條件打包到發布包中。如果有一部分文件可能沒有在Resources文件夾下也沒有在StreamingAssets文件夾下,也沒有被Hierarchy視圖游戲對象引用,那么這類資源是不會被打包到發布包中的。
OK!搞清楚這一點就好辦了!在處理不同包對應不同資源包的時候,盡量讓可配置的資源放在Resources 或StreamingAssets文件夾下,運行的時候程序動態的來讀取它們,最后顯示在游戲中就可以了。在批量打包前,在Project視圖下創建不同包的資源文件夾, 然后腳本 AssetDatabase 動態的將資源拷貝至Resources或StreamingAssets 文件夾中,
http://docs.unity3d.com/Documentation/Manual/StreamingAssets.html
|
1
2
3
4
5
6
7
8
|
[MenuItem ("Custom/Build Android QQ")]
static void PerformAndroidQQBuild ()
{
//先把資源拷貝到Resources或者StreamingAssets
AssetDatabase.CopyAsset("path","newPath");
//然后開始編譯版本
BulidTarget("QQ","Android");
}
|
代碼中說到還有一個重要的東西就是PlayerSettings類。因為在Build的時候不同平台下可能會有一些PlatformSettings是不一樣的,所以需要在腳本里面動態的設置它,強大的參數列表在這里:http://docs.unity3d.com/Documentation/ScriptReference/PlayerSettings.html。根據情況來批量構建自己的工程吧~
另外,由於IOS工程比較特殊,使用這樣的方法我們只能生成出來多個IOS的工程文件,但是這並不是最終發布的版本。如果想一鍵生成.ipa文件的話。
1.通過命令行來Build IOS http://docs.unity3d.com/Documentation/Manual/CommandLineArguments.html
2.通過shell來自動打包 1生成的xcode工程,最終生成渠道包。
這兩種方法我已經在網上找到了答案,今天太晚了就不在研究了,下一篇的時候我在補上。 祝大家學習愉快!!不早了,晚安!歡迎大家一起來討論與學習,嘿嘿!!!
代碼下載地址:http://vdisk.weibo.com/s/HUf2W
- 本文固定鏈接: http://www.xuanyusong.com/archives/2418
- 轉載請注明: 雨松MOMO 2013年06月29日 於 雨松MOMO程序研究院 發表



