unity publicacion play modo integradas iap google firmar compras c# unity3d service import in-app-purchase

c# - publicacion - ¿Dónde se encuentra el paquete Unity IAP?



unity google play (1)

Cuando habilite IAP y haga clic en Importar, ocurrirá lo siguiente:

1. La unidad generará un nombre de archivo aleatorio con

FileUtil.GetUniqueTempPathInProject()

2. Un camino completo se construirá así:

<ProjectName>Temp/FileUtil.GetUniqueTempPathInProject()

3 .Unity luego agregará .unitypackage al final de ese nombre de archivo aleatorio.

Ahora, tienes algo como:

<ProjectName>Temp/FileUtil.GetUniqueTempPathInProject()+".unitypackage";

4. El paquete .IAP luego se descargará y almacenará en la ruta desde el n . ° 3 .

Ilustración de cómo se ve:

5. El archivo se copia a

<ProjectName>Temp/TarGZ

Se guarda con el nombre de archivo generado desde el # 2 . No. Paquete de la unidad al final como # 3 .

UnityEngine.Cloud.Purchasing

6. Después de eso, Unity lo importa con AssetDatabase.ImportPackage not AssetDatabase.ImportAsset(path,false) como se menciona en su pregunta.

Ahora puede ver dónde se encuentra el paquete Unity IAP, pero hay pocos problemas en lo que intenta hacer :

1. Para que el paquete IAP esté presente, se debe hacer clic en el botón importar de la pestaña Servicios . Estoy seguro de que quiere que esto se automatice.

2. El nombre del archivo no es estático, lo que hace que la ruta sea difícil de recuperar. Como puede ver en la imagen de arriba, también hay otros archivos en esta carpeta. No sabemos cuál es el paquete de AIP .

3. Cuando reinicie Unity, la carpeta temporal será eliminada. Por lo tanto, el paquete IAP descargado se perderá .

La mejor forma de obtener el paquete Unity IAP es descargarlo directamente del servidor de Unity y luego guardarlo en su ubicación preferida. El siguiente código descargará el paquete IAP y lo almacenará en: <ProjectName>/UnityEngine.Cloud.Purchasing.unitypackage También lo importará y luego, lo habilitará. Para que AIP funcione, Analytics debe estar habilitado también. Este código también hará eso.

Traté de ocultar la url AIP para que no se abuse de ella y la Unidad no lo haya cambiado.

Si desea volver a hacer esto en otra cosa, las dos funciones más importantes a tener en cuenta son downloadAndInstallAIP() y deleteAndDisableAIP() .

Código 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 <ProjectName>/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); } }

Actualmente estoy trabajando en un script de editor que facilitará mi transición entre freemium y versiones de pago de mi juego. Me gustaría importar manualmente el archivo .unitypackage que se importa cuando hago clic en el botón importar en Servicios -> Compras en la aplicación .

AssetDatabase.ImportAsset(path) la función AssetDatabase.ImportAsset(path) pero primero necesito la ruta del paquete.

¡Gracias por adelantado!