//
// 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