ä»åã¯ä½é¨ç/製åçã1ã¤ã®ããã¸ã§ã¯ãã§æ¥½ã«åãã¦ãªãªã¼ã¹ãã«ãããæ¹æ³ãæ¸ãã¾ãã
対å¿ã²ã¼ã
R18ç¦ã®ã²ã¼ã ã§ããã以ä¸ã²ã¼ã ã«ã¦ãã®æ¹æ³ã§ä½é¨ç/製åçããªãªã¼ã¹ãã¦ãã¾ãã
DLSiteä¸ã§ã¯ä½é¨çã¨è£½åçã®ãã¤ããªãµã¤ãºã¯ä¸å³ã®ããã«è¨è¼ããã¦ãã¾ãã
ãã®ããã«ä½é¨çã®ç¯å²ã§å¿
é ãªAssetã ãçµã£ã¦ä½é¨çãã¤ããªãä½ãäºãå¯è½ã§ãã
ç°å¢
ä»åã¯ä»¥ä¸ã®ç°å¢ã§è¡ãã¾ããã
- Unity2022.3.43f1
- Addressables v1.22.2
対å¿æ¹æ³
対å¿æ¹æ³ã¨ãã¦2éãããã¾ãã
ä½é¨çç¨ã®ã¹ã¯ãªããã·ã³ãã«ãè¨å®
Project Setingsãã¥ã¼ãããOther Setings > Scripting Define Symbols ããè¨å®å¯è½ã§ãã
ä¸è¦ãªãã ãããåãããªãããããã¾ãããããã使ã£ã¦ãã以ä¸ã®ãããªDEVELOPMENT_BUILDãUNITY_EDITORã·ã³ãã«ã¨åãã§ãã
#if DEVELOPMENT_BUILD // ããã«ãããã°ãã«ãæã«å®è¡ãããå¦çãæ¸ã #endif #if UNITY_EDITOR // ããã«Unityã¨ãã£ã¿ä¸ã®æã«å®è¡ãããå¦çãæ¸ã #endif
ãã®Scripting Define Symbolsã¯BuildPlayerã§åçã«è¿½å ããäºãå¯è½ãªãããä½é¨çã®æã« DEMO_PLAY çã®ã·ã³ãã«ã追å ãã¦ä»¥ä¸ã®ããã«ä½é¨çã ãéãå¦çãæ¸ããã¨ãå¯è½ã¨ãªãã¾ãã
#if DEMO_PLAY // ä½é¨çã®ç¯å²ãçµãã£ãããé²è¡ä¸è½ã«ãã¦è£½åçã®è³¼å ¥ãèªå°ãã #endif
BuildPlayerã¸è¿½å ããæ¹æ³ãç°¡åã§ããã®é¨åã ãæ¸ãã¨ä»¥ä¸ã®ããã«ãªãã¾ãã
BuildPlayerOptions buildOptions = new BuildPlayerOptions(); (ç¥) buildOptions.extraScriptingDefines = new[] { "DEMO_PLAY" }; (ç¥) BuildPipeline.BuildPlayer(buildOptions);
ãã®æ¹æ³ã¯ä½é¨çã ãã§ã¯ãªããä¾ãã°ä»¥ä¸ã®å ´åã«æç¨ãªæã ã¨æãã¾ãã
- ãåºåããç¡æçãã¨ãåºåãªãææçãã¢ããªãåºãåããã
- é ä¿¡ãã©ãããã©ã¼ã ã«åããã¦ã¹ãã¢ã¸èªå°ããURLãåããã
Addressablesã§ä½é¨çã«å«ããªãAsset Groupãä½ã
製åçã§ã¯ä½¿ãããä½é¨çã§ã¯ä½¿ããªãã®ã§å«ããªãAssetããããã¨æãã¾ãã
ãããã£ããã®ã¯Addressablesã§Asset管çãã¦ããå ´åãGroupåããã¦ããã¨BuildPlayerã§ãå«ããGroupããå«ããªãGroupããåãæ¿ãã¦ãã¤ããªçæããäºãåºæ¥ã¾ãã
â»Addressablesèªä½ã®èª¬æã¯å²æãã¾ããæ¤ç´¢ããã¨æ²¢å±±ããããããã¨æãã¾ãã®ã§ããããåç¥ãªããã°å
ã«èª¿ã¹ã¦ã¿ã¦ãã ããã
ã¡ãªã¿ã«Debugç¨ã®Groupãä½æãã¦åãã¦ããã¨ããªãªã¼ã¹ãã«ãã«ä½è¨ãªã¢ã»ãããç´ããªããªãã¾ãã以éã«Debugã¨è¡¨è¨ããã¦ãããDebugç¨Assetã ã¨æã£ã¦ãã ããã
Groupä½ææé
1. åãããããããã«BaseAssets(å
¨ã¦ã®ãã«ãã§å«ã)/ReleaseAssets(製åçã ãã«å«ã)/ReleaseAssets(DebugBuildæã®ã¿å«ã)ã®3ã¤ãã©ã«ããä½æããAddressable管çä¸ã«é
ç½®
2. Projectãã¥ã¼ããAddressable管çä¸ã®Assetãé¸æããInspectorä¸ã®Selectãæ¼ä¸
3. Addressables Groupsãã¥ã¼ã®å·¦ä¸ã«ãã New > Packed Assets ãé¸æ
4. Groupãæ°è¦ä½æãããã®ã§ãå³ã¯ãªãã¯ããRenameãã¦åãããããå称ã«å¤æ´
5. åæGroup㯠Default Local Group ã«æå±ãã¦ããã®ã§ãæ°è¦ä½æããGroupã¸ç§»åãããå¿
è¦ãããã¾ãã移å対象ã å³ã¯ãªã㯠> Move Addresasbles to Group... é¸æ
移åå
ã®Groupãé¸æ
6. åãããGroupåã ã(3-5)ãç¹°ãè¿ã
ããã§Groupãæ°è¦ä½æããGroupåãã¾ã§ãå®äºãã¾ããã
ãã«ãæã«å«ããGroupãåããã®ã¯ãã¾ãBuildPlayerã§è¡ãã¾ãã
Releaseã製åçã ãå梱ããã³ã¼ãã¯ä»¥ä¸ã®ããã«ãªãã¾ã*1ã
/// <summary> /// Addressablesè¨å®ããã«ãå 容ã«å¿ãã¦å¤æ´ãã /// </summary> /// <param name="isDemo">ä½é¨çã§ããã°true</param> private static void changeAddressableSettings(bool isDemo) var setting = AddressableAssetSettingsDefaultObject.Settings; if (setting != null) { var releaseGroup = setting.FindGroup("Release"); if (releaseGroup != null) { var schema = releaseGroup.GetSchema<BundledAssetGroupSchema>(); if (isDemo) { schema.BuildPath.SetVariableByName(setting, AddressableAssetSettings.kRemoteBuildPath); schema.LoadPath.SetVariableByName(setting, AddressableAssetSettings.kRemoteLoadPath); } else { schema.BuildPath.SetVariableByName(setting, AddressableAssetSettings.kLocalBuildPath); schema.LoadPath.SetVariableByName(setting, AddressableAssetSettings.kLocalLoadPath); } } } }
Groupæ¯ã«ã¢ããªã«å梱(Local)ããããã¢ããªèµ·åæã«Download(Remote)ãã¦ããããè¨å®ããäºãåºæ¥ã¾ãã
Localã¨ãã¹ãè¨å®ããRemoteè¨å®ã«ããäºã§ã¢ããªã¸ã¯å梱ãããªããªãã¨ãã訳ã§ãã
ããåè¿°ããä½é¨çç¨ã®ã·ã³ãã«ã追å ããªãã®ã§ããã°ãRelease Groupã®Assetãåå¨ããããå¤æææã«åºæ¥ã¾ã*2ã
ãªããå½ããåã§ããä½é¨çã®ãã¬ã¤ç¯å²å ã§Release Groupã®Assetã¸ã¢ã¯ã»ã¹ãããã¨ããã¨åå¨ããªãããã¨ã©ã¼ã«ãªãã¾ãããªã®ã§ãä½é¨çã¨è£½åçã®ç¯å²ãæ確ã«ãªã£ã¦ãã対å¿ãã ããã
Tips
Addressables Groupåããè¡ã£ããèªè¾¼é度ãä½ä¸ãã
CRCãã§ãã¯ãæå¹ã«ãã¦ããã¨é
ããªãå ´åãããããã§ãã
Assets/AddressableAssetsData/AssetGroups/(Groupå) ãé¸æããInspectorãã Asset Bundle CRC ã Disabled ã«å¤æ´ããäºã§åé¡ã解決ããããããã¾ããããããONã«ãã¦ããã¨Bundleã®æ´åæ§ãã§ãã¯ãè¡ãããã®ã§ãããã¢ããªå梱Bundleã§ãã§ãã¯ããå¿
è¦æ§ããªãããDisabledã«ãã¦ãåé¡ãªããã¨æããã¾ã*3ã
BuildPipeline.BuildPlayerã®ãã«ã³ã¼ã
Androidã ãã§ããããããã°ç/ä½é¨ç/製åçã§åãã¦ãã«ããã¦apkãã¡ã¤ã«ãæ¸ãåºãã³ã¼ãã¯ä»¥ä¸ã®éãã§ã*4ãAndroidããã¼ã¹ã«iOS/Windowsåãã«æ¸ãæãããã¨ã§ãåãã©ãããã©ã¼ã ã¸ã®Buildã§ãåä½ãããã¨æãã¾ãã
using UnityEngine; using UnityEditor; using UnityEditor.Build.Reporting; using System.IO; using System.Linq; using UnityEditor.AddressableAssets; using UnityEditor.AddressableAssets.Settings; using UnityEditor.AddressableAssets.Settings.GroupSchemas; public class BatchBuild { private const string PRODUCTS_FOLDER_NAME = "Products"; // Android ãããã° ãã«ã [MenuItem("Build/1.Android/Debug")] static void AndroidDebugBuild() { UnityEngine.Debug.Log("====== Android Debug Build Start ======"); AndroidBuid(true); UnityEngine.Debug.Log("====== Android Debug Build End ======"); } // Android ãªãªã¼ã¹ ãã«ã [MenuItem("Build/1.Android/製åç")] static void AndroidReleaseBuild() { UnityEngine.Debug.Log("====== Android Release Build Start ======"); AndroidBuid(false); UnityEngine.Debug.Log("====== Android Release Build End ======"); } // Android ä½é¨çã®ãªãªã¼ã¹ ãã«ã [MenuItem("Build/1.Android/ä½é¨ç")] static void AndroidDemoReleaseBuild() { UnityEngine.Debug.Log("====== Android Demo Release Build Start ======"); AndroidBuid(false, true); UnityEngine.Debug.Log("====== Android Demo Release Build End ======"); } static void AndroidBuid(bool isDebug, bool isDemo = false) { EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Android, BuildTarget.Android); BuildPlayerOptions buildOptions = new BuildPlayerOptions(); buildOptions.scenes = getBuildScenes(); // åºåç¨ã®ãã¡ã¤ã«ãå®ç¾© var outputFile = getAndroidFilePath(isDebug, isDemo); if (File.Exists(outputFile)) { File.Delete(outputFile); } buildOptions.locationPathName = outputFile; buildOptions.target = BuildTarget.Android; if (isDebug) { buildOptions.options = BuildOptions.Development; } else { buildOptions.options = BuildOptions.None; } // ä½é¨ç if (isDemo) { buildOptions.extraScriptingDefines = new[] { "DEMO_PLAY" }; } changeAddressableSettings(isDemo, isDebug); PlayerSettings.SetScriptingBackend(BuildTargetGroup.Android, ScriptingImplementation.IL2CPP); PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64 | AndroidArchitecture.ARMv7; var report = BuildPipeline.BuildPlayer(buildOptions); if (report.summary.result == BuildResult.Succeeded) { if (isDebug) { UnityEngine.Debug.Log("====== Android Debug Build Succeeded ======"); } else { UnityEngine.Debug.Log("====== Android Release Build Succeeded ======"); } } else { if (isDebug) { UnityEngine.Debug.Log("====== Android Debug Build Failed ======"); } else { UnityEngine.Debug.Log("====== Android Release Build Failed ======"); } } } /// <summary> /// Androidãã¤ããªãã¡ã¤ã«ã®ãã¹ãè¿ã /// </summary> private static string getAndroidFilePath(bool isDebug, bool isDemo) { // æ¸ãåºããã¹æå®(ãèªèº«ã®ç°å¢ã§å¤æ´ãã ãã) var outputFile = Application.dataPath + "/../" + PRODUCTS_FOLDER_NAME + "/Android/" + Application.productName; if (isDemo) { outputFile += "_demo.apk"; } else if (isDebug) { outputFile += "_debug.apk"; } else { outputFile += ".apk"; } return outputFile; } /// <summary> /// ãã«ãããSceneãè¿ã /// </summary> /// <returns></returns> private static string[] getBuildScenes() { return EditorBuildSettings.scenes.Where(s => s.enabled).Select(s => s.path).ToArray(); } /// <summary> /// Addressablesè¨å®ããã«ãå 容ã«å¿ãã¦å¤æ´ãã /// </summary> /// <param name="isDemo">ä½é¨çã§ããã°true</param> /// <param name="isDebug">ãããã°çã§ããã°true</param> private static void changeAddressableSettings(bool isDemo, bool isDebug) { var setting = AddressableAssetSettingsDefaultObject.Settings; if (setting != null) { var releaseGroup = setting.FindGroup("Release"); if (releaseGroup != null) { var schema = releaseGroup.GetSchema<BundledAssetGroupSchema>(); if (isDemo) { schema.BuildPath.SetVariableByName(setting, AddressableAssetSettings.kRemoteBuildPath); schema.LoadPath.SetVariableByName(setting, AddressableAssetSettings.kRemoteLoadPath); } else { schema.BuildPath.SetVariableByName(setting, AddressableAssetSettings.kLocalBuildPath); schema.LoadPath.SetVariableByName(setting, AddressableAssetSettings.kLocalLoadPath); } } var debugGroup = setting.FindGroup("Debug"); if (debugGroup != null) { var schema = debugGroup.GetSchema<BundledAssetGroupSchema>(); if (isDebug) { schema.BuildPath.SetVariableByName(setting, AddressableAssetSettings.kLocalBuildPath); schema.LoadPath.SetVariableByName(setting, AddressableAssetSettings.kLocalLoadPath); } else { schema.BuildPath.SetVariableByName(setting, AddressableAssetSettings.kRemoteBuildPath); schema.LoadPath.SetVariableByName(setting, AddressableAssetSettings.kRemoteLoadPath); } } } } }
Buildå¾ã«å¤æ´ããGroupè¨å®ãæ»ãã³ã¼ãã¯ããã¾ãããå¿ è¦ã§ããã°ãèªèº«ã§è¿½å ãã ããã
*1:Debugåãå«ããã¨å¯èªæ§ãè½ã¡ãããé¤å¤ãã¦ãã¾ããå¾ã»ã©ã¹ã¯ãªããå ¨ä½æ²è¼æã®æ¹ã«ã¯æ²è¼ãã¦ããã®ã§ããã¡ããåç §ãã ããã
*2:åå¨ãã§ãã¯ã®ã³ã¹ããèããã¨ã·ã³ãã«ç¨æãè¡ã£ãæ¹ãè¯ããã¨æãã¾ã
*3:DLããå ´åã«ãã§ãã¯ããå¿ è¦ãåºã¦ãã¾ã
*4:aabãã¡ã¤ã«ã¯BuildSettingsãã¾ãç°ãªãç¹ã«æ³¨æãã ãã