Unity IAP包位于何处?

我目前正在编写一个编辑器脚本,这将简化我在我的游戏的免费增值和付费版本之间的转换。我想手动导入当我单击服务 – >应用程序内购买下的导入按钮时导入的.unitypackage文件。

我知道函数AssetDatabase.ImportAsset(path)但我首先需要包的路径。

提前致谢!

启用IAP并单击“导入”后,将发生以下情况:

1.Unity将生成随机文件名

 FileUtil.GetUniqueTempPathInProject() 

2,完整路径将如下构建:

 Temp\FileUtil.GetUniqueTempPathInProject() 

3.然后,Unity会将.unitypackage添加到该随机文件名的末尾。

现在,你有类似的东西:

 Temp\FileUtil.GetUniqueTempPathInProject()+".unitypackage"; 

4.然后将下载IAP包并将其存储到#3的路径中。

它看起来像是什么样的插图:

在此处输入图像描述

5.然后将文件复制到

 Temp\TarGZ 

它与#2生成的文件名一起保存。 没有.unitypackage在最后像#3

 UnityEngine.Cloud.Purchasing 

6.之后 ,Unity会根据您的问题中提到的AssetDatabase.ImportPackage 而不是 AssetDatabase.ImportAsset(path,false)导入它。

现在您可以看到Unity IAP软件包所在的位置,但您尝试执行的操作几乎没有问题

1.对于要存在的IAP程序包,必须单击“ 服务”选项卡中的导入按钮。 我相信你希望这是自动化的。

2.文件名不是静态的,因此难以检索路径。 从上图中可以看出,此文件夹中还有其他文件。 我们不知道哪一个是AIP包。

3.重新启动Unity时,将删除临时文件夹。 因此下载的IAP包将丢失

获取Unity IAP软件包的最佳方法是直接从Unity服务器下载它,然后将其保存到您首选的位置。 下面的代码将下载IAP包并将其存储在: /UnityEngine.Cloud.Purchasing.unitypackage它还将导入它然后启用它。 要使AIP正常运行,还必须启用Google Analytics 。 这段代码也会这样做。

我试图隐藏AIP url以免它被滥用,Unity也不会改变它。

如果你想将它重新翻译成其他东西,那么要看的两个最重要的函数是downloadAndInstallAIP()deleteAndDisableAIP()

在此处输入图像描述

AIPDownloader代码:

 using System; using System.ComponentModel; using System.IO; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; using UnityEditor; using UnityEditor.Analytics; using UnityEditor.Purchasing; using UnityEngine; [ExecuteInEditMode] public class AIPDownloader : MonoBehaviour { static string projectDirectory = Environment.CurrentDirectory; static string aipFileName = "UnityEngine.Cloud.Purchasing.unitypackage"; static string etagName = "UnityEngine.Cloud.PurchasingETAG.text"; static string aipfullPath = ""; static string eTagfullPath = ""; static EditorApplication.CallbackFunction doneEvent; [MenuItem("AIP/Enable AIP")] public static void downloadAndInstallAIP() { //Make AIP fullpath aipfullPath = null; aipfullPath = Path.Combine(projectDirectory, aipFileName); //Make AIP Etag fullpath eTagfullPath = null; eTagfullPath = Path.Combine(projectDirectory, etagName); /*If the AIP File already exist at /UnityEngine.Cloud.Purchasing.unitypackage, * there is no need to re-download it. Re-import the package */ if (File.Exists(aipfullPath)) { Debug.Log("AIP Package already exist. There is no need to re-download it"); if (saveETag(null, true)) { importAIP(aipfullPath); return; } } string[] uLink = { "aHR0cHM=", "Oi8vcHVibGljLWNkbg==", "LmNsb3Vk", "LnVuaXR5M2Q=", "LmNvbQ==", "L1VuaXR5RW5naW5l", "LkNsb3Vk", "LlB1cmNoYXNpbmc=", "LnVuaXR5cGFja2FnZQ==" }; prepare(uLink); try { ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate); WebClient client = new WebClient(); client.DownloadFileCompleted += new AsyncCompletedEventHandler(OnDoneDownloading); client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(OnDownloadProgressChanged); client.DownloadFileAsync(new Uri(calc(uLink)), aipfullPath); } catch (Exception e) { Debug.LogError("Error: " + e.Message); } } [MenuItem("AIP/Disable AIP")] public static void deleteAndDisableAIP() { FileUtil.DeleteFileOrDirectory("Assets/Plugins/UnityPurchasing"); //Disable AIP PurchasingSettings.enabled = false; //Disable Analytics AnalyticsSettings.enabled = false; } private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) { return true; } public bool isAIPEnabled() { return PurchasingSettings.enabled; } private static bool saveETag(WebClient client, bool alreadyDownloadedAIP = false) { string contents = ""; if (alreadyDownloadedAIP) { //Load Etag from file try { contents = File.ReadAllText(eTagfullPath); return _saveEtag(contents, alreadyDownloadedAIP); } catch (Exception e) { Debug.LogWarning("File does not exist!: " + e.Message); } return false; //Failed } else { //Load Etag from downloaded WebClient contents = client.ResponseHeaders.Get("ETag"); return _saveEtag(contents, alreadyDownloadedAIP); } } static bool _saveEtag(string contents, bool alreadyDownloadedAIP = false) { if (contents != null) { try { //Save if not downloaded if (!alreadyDownloadedAIP) { Directory.CreateDirectory(Path.GetDirectoryName(eTagfullPath)); File.WriteAllText(eTagfullPath, contents); } //Save to the etag to AIP directory Directory.CreateDirectory(Path.GetDirectoryName("Assets/Plugins/UnityPurchasing/ETag")); File.WriteAllText("Assets/Plugins/UnityPurchasing/ETag", contents); return true;//Success } catch (Exception e) { Debug.LogWarning("Failed to write to file: " + e.Message); return false; //Failed } } else { return false; //Failed } } public static void OnDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { Debug.Log("Downloading: " + e.ProgressPercentage); } public static void OnDoneDownloading(object sender, AsyncCompletedEventArgs args) { WebClient wc = (WebClient)sender; if (wc == null || args.Error != null) { Debug.Log("Failed to Download AIP!"); return; } Debug.Log("In Download Thread. Done Downloading"); saveETag(wc, false); doneEvent = null; doneEvent = new EditorApplication.CallbackFunction(AfterDownLoading); //Add doneEvent function to call back! EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Combine(EditorApplication.update, doneEvent); } static void AfterDownLoading() { //Remove doneEvent function from call back! EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Remove(EditorApplication.update, doneEvent); Debug.Log("Back to Main Thread. Done Downloading!"); importAIP(aipfullPath); } //Import or Install AIP public static void importAIP(string path) { AssetDatabase.ImportPackage(path, false); Debug.Log("Done Importing AIP package"); //Enable Analytics AnalyticsSettings.enabled = true; //Enable AIP PurchasingSettings.enabled = true; } private static void prepare(string[] uLink) { for (int i = 5; i < uLink.Length; i++) { byte[] textAsBytes = System.Convert.FromBase64String(uLink[i]); uLink[i] = Encoding.UTF8.GetString(textAsBytes); } for (int i = 0; i < uLink.Length; i++) { byte[] textAsBytes = System.Convert.FromBase64String(uLink[i]); uLink[i] = Encoding.UTF8.GetString(textAsBytes); if (i == 4) { break; } } } private static string calc(string[] uLink) { return string.Join("", uLink); } }