http://blog.csdn.net/pandawuwyj/article/details/7959335
Unity3D的项目,这周吃亏在宏上了。大背景是项目需要在Unity中用Hudson自动生成不同平台的版本。
程序设计语言的预处理的概念:在编译之前进行的处理。
#if UNITY_WEBPLAYER
BuildTarget target = BuildTarget.WebPlayer;
#elif UNITY_STANDALONE_WIN && UNITY_EDITOR
BuildTarget target = BuildTarget.StandaloneWindows;
#elif UNITY_ANDROID
BuildTarget target = BuildTarget.Android;
#else
BuildTarget target = BuildTarget.iPhone;
#endif
#if UNITY_WEBPLAYER
public const string AssetRootPath = AutomaticBuild.WebPlatFormDataPath + "/";
#elif UNITY_STANDALONE_WIN && UNITY_EDITOR
public const string AssetRootPath = AutomaticBuild.WinPlatFormDataPath + "/";
#elif UNITY_ANDROID
public const string AssetRootPath = AutomaticBuild.AndRoidPlatFormDataPath + "/";
#else
public const string AssetRootPath = AutomaticBuild.IOSPlatFormDataPath + "/";
#endif
如上面两段代码,打开Unity项目(例如PC & Mac Standalone保存的)之后,再打开项目的Script(这里用VS2008+VA),会发现上述加粗行高亮。即Target和AssetRootPath在编译前已然确定,且之后不能对其做出变更。
当采用Unity支持的命令编译时C:program filesUnityEditor>Unity.exe -quit -batchmode -executeMethod MyEditorScript.MyMethod
此时MyMethod可能用了如下代码,
BuildPipeline.BuildPlayer( levels, "WebPlayerBuild", BuildTarget.WebPlayer, BuildOptions.None);
但Target和AssetRootPath并没有赋予应有的Web相应值,会造成生成的Unity3D文件能生成但不对,执行BuildPlayer时会报Runtime Error错。
不禁让我想起Effective C++里的第2个条款:尽量以const, enum, inline替换 #define。果然金科玉律……
我的解决方式如下:
1.在MyMethod中先调用
SwitchActiveBuildTarget (target : BuildTarget)函数。
private static string AssetRootPath = null;
public static string GetAssetRootPath()
{
if (AssetRootPath != null)
return AssetRootPath;
if (EditorUserBuildSettings.activeBuildTarget==BuildTarget.WebPlayer)
{
AssetRootPath = "WebData/LatestData/";
}
else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
{
AssetRootPath = "AndroidData/LatestData/";
}
else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows)
{
AssetRootPath = "WinData/LatestData/";
}
else
{
AssetRootPath = "IOSData/LatestData/";
}
return AssetRootPath;
}
public static BuildTarget GetBuildTarget()
{
return EditorUserBuildSettings.activeBuildTarget;
}
由于需求的小变更,小小地重构了上次的代码:
ClearISingleFileSeries();
ClearDirectorySeries();
/// <summary>
/// 删除单个文件的数组
/// </summary>
static void ClearISingleFileSeries()
{
string[] SingleFileSeries = { Application.dataPath + "/Plugins/I18N.dll", Application.dataPath + "/Plugins/I18N.CJK.dll", Application.dataPath + "/Plugins/I18N.West.dll" };
ClearFiles(SingleFileSeries);
}
/// <summary>
/// 删除filesPath数组内指向的文件
/// </summary>
/// <param name="filesPath"></param>
static void ClearFiles(string[] filesPath)
{
foreach (string singleFilePath in filesPath)
{
if (File.Exists(singleFilePath))
{
try
{
File.Delete(singleFilePath);
}
catch (System.Exception ex)
{
//catch ex
}
}
}
}
/// <summary>
/// 删除目前做Web版本会出现内存问题的Audio资源
/// </summary>
static void ClearDirectorySeries()
{
string[] audioPath = { Application.dataPath + "/Game/Audio/Resources", Application.dataPath + "/Game/Audio/SFX", Application.dataPath + "/Game/MyGUI" };
foreach (string audioDirectory in audioPath)
{
if (Directory.Exists(audioDirectory)) //保护,避免文件目录不存在跳异常
ClearFilesAndDirectory(audioDirectory);
}
}
/// <summary>
/// 删除dataPath文件目录下的所有子文件及子文件夹
/// </summary>
/// <param name="DirectoryPath"></param>
static void ClearFilesAndDirectory(string DirectoryPath)
{
DirectoryInfo dir = new DirectoryInfo(DirectoryPath);
//文件
foreach (FileInfo fChild in dir.GetFiles("*"))
{
if (fChild.Attributes != FileAttributes.Normal)
fChild.Attributes = FileAttributes.Normal;
fChild.Delete();
}
//文件夹
foreach (DirectoryInfo dChild in dir.GetDirectories("*"))
{
if (dChild.Attributes != FileAttributes.Normal)
dChild.Attributes = FileAttributes.Normal;
ClearFilesAndDirectory(dChild.FullName);
dChild.Delete();
}
}