// // Copyright (C) 2014 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #if UNITY_ANDROID namespace GooglePlayGames { using System; using GooglePlayGames.BasicApi; using UnityEngine; #if UNITY_2017_1_OR_NEWER using UnityEngine.Networking; #endif using UnityEngine.SocialPlatforms; /// /// Delegate for reporting achievement progress. /// /// The achievement ID. /// The progress of the achievement (a value between 0.0 and 100.0). /// A callback to be invoked with a boolean indicating success. internal delegate void ReportProgress(string id, double progress, Action callback); /// /// Represents a Google Play Games achievement. It can be used to report an achievement /// to the API, offering identical functionality as . /// Implements both the and interfaces. /// internal class PlayGamesAchievement : IAchievement, IAchievementDescription { /// /// The callback for reporting progress. /// private readonly ReportProgress mProgressCallback; /// /// The achievement's ID. /// private string mId = string.Empty; /// /// A flag indicating if the achievement is incremental. /// private bool mIsIncremental = false; /// /// The current steps completed for an incremental achievement. /// private int mCurrentSteps = 0; /// /// The total steps required for an incremental achievement. /// private int mTotalSteps = 0; /// /// The percentage of completion. /// private double mPercentComplete = 0.0; /// /// A flag indicating if the achievement is completed (unlocked). /// private bool mCompleted = false; /// /// A flag indicating if the achievement is hidden. /// private bool mHidden = false; /// /// The last time the achievement was modified. /// private DateTime mLastModifiedTime = new DateTime(1970, 1, 1, 0, 0, 0, 0); /// /// The title of the achievement. /// private string mTitle = string.Empty; /// /// The URL for the revealed (locked) achievement image. /// private string mRevealedImageUrl = string.Empty; /// /// The URL for the unlocked achievement image. /// private string mUnlockedImageUrl = string.Empty; #if UNITY_2017_1_OR_NEWER /// /// The web request used to fetch the achievement image. /// private UnityWebRequest mImageFetcher = null; #else /// /// The web request used to fetch the achievement image. /// private WWW mImageFetcher = null; #endif /// /// The downloaded achievement image as a Texture2D. /// private Texture2D mImage = null; /// /// The description of the achievement. /// private string mDescription = string.Empty; /// /// The points awarded for unlocking the achievement. /// private ulong mPoints = 0; /// /// Initializes a new instance of the class. /// Uses the default progress reporting mechanism from . /// internal PlayGamesAchievement() : this(PlayGamesPlatform.Instance.ReportProgress) { } /// /// Initializes a new instance of the class with a custom progress callback. /// /// The callback to use for reporting progress. internal PlayGamesAchievement(ReportProgress progressCallback) { mProgressCallback = progressCallback; } /// /// Initializes a new instance of the class from a object. /// /// The achievement data from the Basic API. internal PlayGamesAchievement(Achievement ach) : this() { this.mId = ach.Id; this.mIsIncremental = ach.IsIncremental; this.mCurrentSteps = ach.CurrentSteps; this.mTotalSteps = ach.TotalSteps; if (ach.IsIncremental) { if (ach.TotalSteps > 0) { this.mPercentComplete = ((double) ach.CurrentSteps / (double) ach.TotalSteps) * 100.0; } else { this.mPercentComplete = 0.0; } } else { this.mPercentComplete = ach.IsUnlocked ? 100.0 : 0.0; } this.mCompleted = ach.IsUnlocked; this.mHidden = !ach.IsRevealed; this.mLastModifiedTime = ach.LastModifiedTime; this.mTitle = ach.Name; this.mDescription = ach.Description; this.mPoints = ach.Points; this.mRevealedImageUrl = ach.RevealedImageUrl; this.mUnlockedImageUrl = ach.UnlockedImageUrl; } /// /// Reveals, unlocks or increments the achievement. /// /// /// This method is equivalent to calling . /// The and properties should be set before calling this method. /// /// An action to be invoked with a value indicating whether the operation was successful. public void ReportProgress(Action callback) { mProgressCallback.Invoke(mId, mPercentComplete, callback); } /// /// Asynchronously loads the achievement's image from its URL. /// /// The image once loaded; otherwise, null. private Texture2D LoadImage() { if (hidden) { // Return null, as hidden achievements do not have images. return null; } string url = completed ? mUnlockedImageUrl : mRevealedImageUrl; // The URL can be null if no image is configured. if (!string.IsNullOrEmpty(url)) { if (mImageFetcher == null || mImageFetcher.url != url) { #if UNITY_2017_1_OR_NEWER mImageFetcher = UnityWebRequestTexture.GetTexture(url); #else mImageFetcher = new WWW(url); #endif mImage = null; } // If we already have the texture, return it to avoid repeated downloads. if (mImage != null) { return mImage; } if (mImageFetcher.isDone) { #if UNITY_2017_1_OR_NEWER mImage = DownloadHandlerTexture.GetContent(mImageFetcher); #else mImage = mImageFetcher.texture; #endif return mImage; } } // If there is no URL or the download is not complete, return null. return null; } /// /// Gets or sets the ID of this achievement. /// /// The achievement ID. public string id { get { return mId; } set { mId = value; } } /// /// Gets a value indicating whether this achievement is incremental. /// /// This value is set by . /// true if incremental; otherwise, false. public bool isIncremental { get { return mIsIncremental; } } /// /// Gets the current number of steps completed for this achievement. /// /// This value is only defined for incremental achievements and is set by . /// The current steps. public int currentSteps { get { return mCurrentSteps; } } /// /// Gets the total number of steps for this achievement. /// /// This value is only defined for incremental achievements and is set by . /// The total steps. public int totalSteps { get { return mTotalSteps; } } /// /// Gets or sets the completion percentage of this achievement. /// /// The percent completed (from 0.0 to 100.0). public double percentCompleted { get { return mPercentComplete; } set { mPercentComplete = value; } } /// /// Gets a value indicating whether this achievement is completed (unlocked). /// /// This value is set by . /// true if completed; otherwise, false. public bool completed { get { return this.mCompleted; } } /// /// Gets a value indicating whether this achievement is hidden. /// /// This value is set by . /// true if hidden; otherwise, false. public bool hidden { get { return this.mHidden; } } /// /// Gets the date and time this achievement was last reported. /// /// The last reported date. public DateTime lastReportedDate { get { return mLastModifiedTime; } } /// /// Gets the title of the achievement. /// /// The title. public String title { get { return mTitle; } } /// /// Gets the image for the achievement, loading it asynchronously if necessary. /// /// The achievement image as a . public Texture2D image { get { return LoadImage(); } } /// /// Gets the description for the achieved state. /// /// The achieved description. public string achievedDescription { get { return mDescription; } } /// /// Gets the description for the unachieved state. /// /// The unachieved description. public string unachievedDescription { get { return mDescription; } } /// /// Gets the point value of the achievement. /// /// The points. public int points { get { return (int) mPoints; } } } } #endif