Unityサードパーティ開発デバッグライブラリの動的ロード
目的
ゲームにサードパーティの開発デバッグライブラリを追加しますが、デフォルトでゲームにパッケージ化したくないので、異なるパッケージオプションの場合にのみ追加し、ゲームにダイナミックロードします.
方法
反射の仕方は使用できません.ここではUnity 2018を使用しているので、Assembly Definition機能を利用してプロジェクトで、サードパーティライブラリを呼び出すための補助プラグインを作成します.
補助クラスのコードは大体以下の通りです.
主にマクロによって呼び出しを制御すると、パッケージ化時に必要なプラグインマクロを動的に設定したり、スクリプトを初期シーンに動的に掛けたりする必要があります.そうしないと削除されます.
ゲームにサードパーティの開発デバッグライブラリを追加しますが、デフォルトでゲームにパッケージ化したくないので、異なるパッケージオプションの場合にのみ追加し、ゲームにダイナミックロードします.
方法
反射の仕方は使用できません.ここではUnity 2018を使用しているので、Assembly Definition機能を利用してプロジェクトで、サードパーティライブラリを呼び出すための補助プラグインを作成します.
補助クラスのコードは大体以下の通りです.
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Scripting;
#if ENABLE_A_UWA
#if UNITY_IPHONE
using UWAPlatform = UWA.IOS;
#elif UNITY_ANDROID
using UWAPlatform = UWA.Android;
#elif UNITY_STANDALONE_WIN
using UWAPlatform = UWA.Windows;
#else
using UWAPlatform = UWA;
#endif
#endif
[assembly: AlwaysLinkAssembly]
namespace AAAAAHelper
{
///
/// , 【Scripting Define Symbols】
/// 3 :
/// ENABLE_A_UWA
/// ENABLE_A_REMOTE
/// ENABLE_A_POCO
///
[Preserve]
public class A_Helper : MonoBehaviour
{
#if !UNITY_EDITOR
static A_Helper()
{
Debug.Log("AAAAAHelper is running static");
SceneManager.sceneLoaded += OnSceneLoaded;
}
static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
SceneManager.sceneLoaded -= OnSceneLoaded;
new GameObject("AAAAAHelper").AddComponent<A_Helper>();
Debug.Log("AAAAAHelper is running OnSceneLoaded");
}
[RuntimeInitializeOnLoadMethod]
static void OnRuntimeMethodLoad()
{
Debug.Log("AAAAAHelper is running0");
}
#endif
///
/// , , ,
///
private void EnableThirdParty()
{
Debug.Log("AAAAAHelper is running EnableThirdParty");
EnableHdgRemoteDebug();
}
主にマクロによって呼び出しを制御すると、パッケージ化時に必要なプラグインマクロを動的に設定したり、スクリプトを初期シーンに動的に掛けたりする必要があります.そうしないと削除されます.
///
/// ( 、Native)
///
private static void SetPluginEnable(string dllName, bool isEnable)
{
var importers = PluginImporter.GetAllImporters();
foreach (var importer in importers)
{
if (importer.assetPath.EndsWith("/" + dllName, StringComparison.OrdinalIgnoreCase))
{
Debug.LogFormat("SetPluginEnable : {0} {1}", isEnable, dllName);
importer.SetCompatibleWithPlatform(EditorUserBuildSettings.activeBuildTarget, isEnable);
}
}
}
///
///
///
private static void SetDefineSymbolsEnable(string define, bool isEnable)
{
BuildTargetGroup curBuildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
string existSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(curBuildTargetGroup);
if (isEnable)
{
if (!existSymbols.Contains(define))
{
PlayerSettings.SetScriptingDefineSymbolsForGroup(curBuildTargetGroup, existSymbols + ";" + define);
}
}
else
{
if (existSymbols.Contains(define))
{
PlayerSettings.SetScriptingDefineSymbolsForGroup(curBuildTargetGroup, existSymbols.Replace(";" + define, ""));
}
}
Debug.LogFormat("SetDefineSymbolsEnable : {0} {1}", isEnable, define);
}
///
/// ASMDEF
///
private static void SetAssemblyDefinitionEnable(string assemblyName, bool isEnable)
{
var assetPath = UnityEditor.Compilation.CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName(assemblyName);
if (string.IsNullOrEmpty(assetPath))
{
return;
}
var asset = AssetDatabase.LoadAssetAtPath<AssemblyDefinitionAsset>(assetPath);
if (!asset)
{
return;
}
var platformName = string.Empty;
if (isEnable)
{
var activeBuildTarget = EditorUserBuildSettings.activeBuildTarget;
var platforms = UnityEditor.Compilation.CompilationPipeline.GetAssemblyDefinitionPlatforms();
foreach (var definitionPlatform in platforms)
{
if (definitionPlatform.BuildTarget == activeBuildTarget)
{
platformName = definitionPlatform.Name;
break;
}
}
if (string.IsNullOrEmpty(platformName))
{
return;
}
}
else
{
platformName = "Editor\",\"WindowsStandalone32";
}
var includePlatforms = string.Format("\"includePlatforms\": [\"{0}\"],
", platformName);
var data = asset.text;
var posStart = data.IndexOf("\"includePlatforms\"", StringComparison.Ordinal);
var posEnd = data.IndexOf(" \"excludePlatforms\"", StringComparison.Ordinal);
var newData = string.Format("{0}{1}{2}", data.Substring(0, posStart), includePlatforms, data.Substring(posEnd));
File.WriteAllText(assetPath, newData);
AssetDatabase.ImportAsset(assetPath);
Debug.LogFormat("SetAssemblyDefinitionEnable : {0} {1}", isEnable, assemblyName);
}
///
/// Assembly
///
private static void SetSceneGameObjectAddComponentEnable(string scenePath, string goName, string assemblyName, string typeName, bool isEnable)
{
var assembly = ArrayUtility.Find(AppDomain.CurrentDomain.GetAssemblies(), a => a.GetName().Name == assemblyName);
if (assembly == null)
{
return;
}
var componentType = ArrayUtility.Find(assembly.GetTypes(), t => t.FullName == typeName);
if (componentType == null)
{
return;
}
if (!(EditorSceneManager.loadedSceneCount == 1 && SceneManager.GetActiveScene().path == scenePath))
{
EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
}
var scene = SceneManager.GetActiveScene();
var go = ArrayUtility.Find(scene.GetRootGameObjects(), g => g.name == goName);
if (!go)
{
return;
}
if (isEnable)
{
go.AddComponent(componentType);
}
else
{
var comp = go.GetComponent(componentType);
if (comp)
{
UnityEngine.Object.DestroyImmediate(comp);
}
}
Debug.LogFormat("SetSceneGameObjectAddComponentEnable : {0} {1}", isEnable, scenePath);
}