345 lines
11 KiB (Stored with Git LFS)
C#
345 lines
11 KiB (Stored with Git LFS)
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Superlazy;
|
|
using Superlazy.Loader;
|
|
using UnityEditor;
|
|
using UnityEditor.AddressableAssets;
|
|
using UnityEditor.AddressableAssets.Build;
|
|
using UnityEditor.AddressableAssets.Settings;
|
|
using UnityEditor.Callbacks;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
#if UNITY_IOS
|
|
using UnityEditor.iOS.Xcode;
|
|
#endif
|
|
|
|
public class SLAppBuild
|
|
{
|
|
public static string dataAssetPath = "Addressables/Data";
|
|
private static readonly SLEntity options = SLEntity.Empty;
|
|
|
|
private enum SLAppBuildTarget
|
|
{
|
|
NONE = -1,
|
|
iOS = 0,
|
|
Android = 4,
|
|
Android_x86 = 5,
|
|
iOS_Cheat = 8,
|
|
Android_Cheat = 9
|
|
}
|
|
|
|
private static void ParseCommandLine()
|
|
{
|
|
var args = Environment.GetCommandLineArgs();
|
|
|
|
for (var i = 0; i < args.Length; ++i)
|
|
{
|
|
if (args[i].IsLeft("-"))
|
|
{
|
|
if (args[i + 1].Contains(","))
|
|
{
|
|
var splits = args[i + 1].Split(',');
|
|
|
|
for (var j = 0; j < splits.Count(); ++j)
|
|
{
|
|
options[args[i].Replace("-", "")][j.ToString()] = splits[j];
|
|
}
|
|
|
|
++i;
|
|
}
|
|
else
|
|
{
|
|
options[args[i].Replace("-", "")] = args[i + 1];
|
|
++i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void BuildAndroidAPK()
|
|
{
|
|
PreBuild();
|
|
|
|
PlayerSettings.Android.bundleVersionCode = options["BuildSettings"]["BuildVersion"];
|
|
|
|
PlayerSettings.Android.keystorePass = options["BuildSettings"]["Android"]["KeystorePass"];
|
|
PlayerSettings.Android.keyaliasName = options["BuildSettings"]["Android"]["KeyaliasName"];
|
|
PlayerSettings.Android.keyaliasPass = options["BuildSettings"]["Android"]["KeyaliasPass"];
|
|
|
|
EditorUserBuildSettings.buildAppBundle = false;
|
|
var outputName = Application.productName + ".apk";
|
|
|
|
GenericBuild(outputName, BuildTargetGroup.Android, BuildTarget.Android, BuildOptions.None);
|
|
}
|
|
|
|
public static void BuildiOSIPA()
|
|
{
|
|
PreBuild();
|
|
|
|
var targetDir = "./build";
|
|
|
|
PlayerSettings.iOS.buildNumber = options["BuildSettings"]["BuildVersion"];
|
|
|
|
var opt = BuildOptions.None;
|
|
|
|
PlayerSettings.statusBarHidden = true;
|
|
|
|
if (Directory.Exists(targetDir))
|
|
{
|
|
Directory.Delete(targetDir, true);
|
|
}
|
|
|
|
if (Directory.Exists(targetDir) == false)
|
|
{
|
|
Directory.CreateDirectory(targetDir);
|
|
}
|
|
|
|
GenericBuild(targetDir, BuildTargetGroup.iOS, BuildTarget.iOS, opt);
|
|
}
|
|
|
|
public static void PreBuild()
|
|
{
|
|
LoadBuildSettings();
|
|
ParseCommandLine();
|
|
|
|
UpdateDataScript();
|
|
UpdateAddressable();
|
|
|
|
UpdateLoaderID();
|
|
}
|
|
|
|
private static void GenericBuild(string target_path, BuildTargetGroup buildTargetGroup, BuildTarget build_target, BuildOptions build_options)
|
|
{
|
|
var levels = GetLevelsFromBuildSettings();
|
|
EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, build_target);
|
|
|
|
// TODO: NamedBuildTarget으로 개선
|
|
if (options["Def"])
|
|
{
|
|
// 기존 심볼들
|
|
var existingDefs = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup)
|
|
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(d => d.Trim())
|
|
.ToHashSet();
|
|
|
|
// 새로 추가할 심볼들
|
|
var newDefs = options["Def"].ToString()
|
|
.Split(";", StringSplitOptions.RemoveEmptyEntries)
|
|
.Select(d => d.Trim());
|
|
|
|
// 병합 후 중복 제거
|
|
foreach (var def in newDefs)
|
|
existingDefs.Add(def);
|
|
|
|
// 최종 적용
|
|
var mergedDefs = string.Join(";", existingDefs);
|
|
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, mergedDefs);
|
|
}
|
|
|
|
var res = BuildPipeline.BuildPlayer(levels, target_path, build_target, build_options);
|
|
|
|
if (res.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded)
|
|
{
|
|
throw new Exception("BuildPlayer failure: " + res.summary.ToString());
|
|
}
|
|
}
|
|
|
|
private static string[] GetLevelsFromBuildSettings()
|
|
{
|
|
var levels = new List<string>();
|
|
|
|
foreach (var scene in EditorBuildSettings.scenes)
|
|
{
|
|
levels.Add(scene.path);
|
|
}
|
|
|
|
return levels.ToArray();
|
|
}
|
|
|
|
public static void LoadBuildSettings()
|
|
{
|
|
var path = Path.Combine(Application.dataPath, "SLBuild", "BuildSettings.json");
|
|
|
|
options["BuildSettings"] = JsonLoader.LoadJson(File.ReadAllText(path))["BuildSettings"];
|
|
}
|
|
|
|
public static void UpdateDataScript()
|
|
{
|
|
FileUtil.DeleteFileOrDirectory("Assets/Addressables/Data/");
|
|
|
|
var destDir = Path.Combine(Application.dataPath, dataAssetPath);
|
|
|
|
Directory.CreateDirectory(destDir);
|
|
|
|
var loader = SLSystemUtility.CreateInstance<SLDataLoader>("SLWindowsLoader");
|
|
var system = SLSystemUtility.CreateInstance<SLSystem>("SLSystem");
|
|
system.Init(loader, DateTime.UtcNow);
|
|
loader.Load();
|
|
|
|
foreach (var session in SLSystem.Data)
|
|
{
|
|
var fileName = session.ID + ".json";
|
|
var paths = Path.Combine(destDir, fileName).Split(Path.DirectorySeparatorChar);
|
|
var path = "";
|
|
|
|
for (var i = 0; i < paths.Length - 1; ++i)
|
|
{
|
|
path += paths[i] + Path.DirectorySeparatorChar;
|
|
if (Directory.Exists(path) == false)
|
|
{
|
|
Directory.CreateDirectory(path);
|
|
}
|
|
}
|
|
|
|
var saveData = SLEntity.Empty;
|
|
saveData[session.ID] = session;
|
|
var text = JsonLoader.SaveToJson(saveData);
|
|
SLFileUtility.MakeFolderFromFilePath(Path.Combine(destDir, fileName));
|
|
File.WriteAllText(Path.Combine(destDir, fileName), text, Encoding.UTF8);
|
|
}
|
|
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
private static void UpdateAddressable()
|
|
{
|
|
AssetDatabase.ImportAsset("Assets/Addressables", ImportAssetOptions.ImportRecursive);
|
|
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
|
|
|
|
var settings
|
|
= AddressableAssetSettingsDefaultObject.Settings;
|
|
|
|
settings.activeProfileId
|
|
= settings.profileSettings.GetProfileId("Default");
|
|
var builder
|
|
= AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/AddressableAssetsData/DataBuilders/BuildScriptPackedMode.asset") as IDataBuilder;
|
|
|
|
settings.ActivePlayerDataBuilderIndex
|
|
= settings.DataBuilders.IndexOf((ScriptableObject)builder);
|
|
|
|
AddressableAssetSettings.BuildPlayerContent(out var result);
|
|
|
|
if (!string.IsNullOrEmpty(result.Error))
|
|
throw new Exception(result.Error);
|
|
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
|
|
}
|
|
|
|
public static void UpdateLoaderID()
|
|
{
|
|
EditorSceneManager.OpenScene("Assets/Scenes/Game.unity");
|
|
var slunity = UnityEngine.Object.FindFirstObjectByType<SLUnity>();
|
|
if (slunity != null)
|
|
{
|
|
slunity.loaderID = "SLUnityDataLoader";
|
|
}
|
|
|
|
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
|
|
}
|
|
|
|
[PostProcessBuild(999)]
|
|
public static void OnPostProcessBuild(BuildTarget buildTarget, string path)
|
|
{
|
|
if (buildTarget == BuildTarget.StandaloneWindows64)
|
|
{
|
|
var folderPath = SLFileUtility.FolderPath(path);
|
|
|
|
var backupFolder = folderPath + "/" + Application.productName + "_BackUpThisFolder_ButDontShipItWithYourGame";
|
|
if (Directory.Exists(backupFolder))
|
|
{
|
|
Directory.Delete(backupFolder, true);
|
|
}
|
|
|
|
var burstDebugFolder = folderPath + "/" + Application.productName + "_BurstDebugInformation_DoNotShip";
|
|
if (Directory.Exists(burstDebugFolder))
|
|
{
|
|
Directory.Delete(burstDebugFolder, true);
|
|
}
|
|
|
|
var fileName = Application.productName;
|
|
if (options["FileName"])
|
|
{
|
|
fileName = options["FileName"];
|
|
}
|
|
|
|
if (File.Exists(folderPath + $"/../{fileName}.zip"))
|
|
{
|
|
File.Delete(folderPath + $"/../{fileName}.zip");
|
|
}
|
|
|
|
;
|
|
ZipFile.CreateFromDirectory(folderPath, $"./{fileName}.zip");
|
|
}
|
|
|
|
if (buildTarget == BuildTarget.iOS)
|
|
{
|
|
#if UNITY_IOS
|
|
string projectPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";
|
|
|
|
UnityEditor.iOS.Xcode.PBXProject pbxProject = new UnityEditor.iOS.Xcode.PBXProject();
|
|
pbxProject.ReadFromFile(projectPath);
|
|
|
|
string target = pbxProject.GetUnityMainTargetGuid();
|
|
pbxProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO");
|
|
pbxProject.SetBuildProperty(target, "DEBUG_INFORMATION_FORMAT", "dwarf");
|
|
|
|
if (options["iOSProvisionID"])
|
|
{
|
|
pbxProject.SetBuildProperty(target, "PROVISIONING_PROFILE", options["iOSProvisionID"]);
|
|
}
|
|
|
|
if (options["iOSProfileSpecifier"])
|
|
{
|
|
pbxProject.SetBuildProperty(target, "PROVISIONING_PROFILE_SPECIFIER", options["iOSProfileSpecifier"]);
|
|
}
|
|
|
|
if (options["iOSTeamID"])
|
|
{
|
|
pbxProject.SetBuildProperty(target, "DEVELOPMENT_TEAM", options["iOSTeamID"]);
|
|
}
|
|
|
|
if (options["iOSDistribution"])
|
|
{
|
|
pbxProject.SetBuildProperty(target, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "iPhone Distribution");
|
|
}
|
|
|
|
pbxProject.WriteToFile(projectPath);
|
|
|
|
{
|
|
string plistPath = path + "/Info.plist";
|
|
PlistDocument plist = new PlistDocument();
|
|
plist.ReadFromString(File.ReadAllText(plistPath));
|
|
|
|
PlistElementDict rootDict = plist.root;
|
|
rootDict.SetBoolean("ITSAppUsesNonExemptEncryption", false);
|
|
|
|
File.WriteAllText(plistPath, plist.WriteToString());
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
public static void BuildWindows()
|
|
{
|
|
PreBuild();
|
|
|
|
var targetDir = "./build";
|
|
|
|
if (Directory.Exists(targetDir))
|
|
{
|
|
Directory.Delete(targetDir, true);
|
|
}
|
|
|
|
if (Directory.Exists(targetDir) == false)
|
|
{
|
|
Directory.CreateDirectory(targetDir);
|
|
}
|
|
|
|
GenericBuild(targetDir + "/" + Application.productName + ".exe", BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows64, BuildOptions.None);
|
|
}
|
|
} |