//
// 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;
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 .
///
internal class PlayGamesAchievement : IAchievement, IAchievementDescription
{
private readonly ReportProgress mProgressCallback;
private string mId = string.Empty;
private bool mIsIncremental = false;
private int mCurrentSteps = 0;
private int mTotalSteps = 0;
private double mPercentComplete = 0.0;
private bool mCompleted = false;
private bool mHidden = false;
private DateTime mLastModifiedTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
private string mTitle = string.Empty;
private string mRevealedImageUrl = string.Empty;
private string mUnlockedImageUrl = string.Empty;
#if UNITY_2017_1_OR_NEWER
private UnityWebRequest mImageFetcher = null;
#else
private WWW mImageFetcher = null;
#endif
private Texture2D mImage = null;
private string mDescription = string.Empty;
private ulong mPoints = 0;
internal PlayGamesAchievement()
: this(PlayGamesPlatform.Instance.ReportProgress)
{
}
internal PlayGamesAchievement(ReportProgress progressCallback)
{
mProgressCallback = progressCallback;
}
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 increment achievement.
///
///
/// Call after setting , ,
/// as well as and
/// for incremental achievements. Equivalent to calling
/// .
///
public void ReportProgress(Action callback)
{
mProgressCallback.Invoke(mId, mPercentComplete, callback);
}
///
/// Loads the local user's image from the url. Loading urls
/// is asynchronous so the return from this call is fast,
/// the image is returned once it is loaded. null is returned
/// up to that point.
///
private Texture2D LoadImage()
{
if (hidden)
{
// return null, we dont have images for hidden achievements.
return null;
}
string url = completed ? mUnlockedImageUrl : mRevealedImageUrl;
// the url can be null if the image is not 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 have the texture, just return, this avoids excessive
// memory usage calling www.texture repeatedly.
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, always return null.
return null;
}
///
/// Gets or sets the id of this achievement.
///
///
/// The identifier.
///
public string id
{
get { return mId; }
set { mId = value; }
}
///
/// Gets a value indicating whether this achievement is incremental.
///
///
/// This value is only set by PlayGamesPlatform.LoadAchievements
///
/// true if incremental; otherwise, false.
public bool isIncremental
{
get { return mIsIncremental; }
}
///
/// Gets the current steps completed of this achievement.
///
///
/// Undefined for standard (i.e. non-incremental) achievements.
/// This value is only set by PlayGamesPlatform.LoadAchievements, changing the
/// percentComplete will not affect this.
///
/// The current steps.
public int currentSteps
{
get { return mCurrentSteps; }
}
///
/// Gets the total steps of this achievement.
///
///
/// Undefined for standard (i.e. non-incremental) achievements.
/// This value is only set by PlayGamesPlatform.LoadAchievements, changing the
/// percentComplete will not affect this.
///
/// The total steps.
public int totalSteps
{
get { return mTotalSteps; }
}
///
/// Gets or sets the percent completed.
///
///
/// The percent completed.
///
public double percentCompleted
{
get { return mPercentComplete; }
set { mPercentComplete = value; }
}
///
/// Gets a value indicating whether this achievement is completed.
///
///
/// This value is only set by PlayGamesPlatform.LoadAchievements, changing the
/// percentComplete will not affect this.
///
/// true if completed; otherwise, false.
public bool completed
{
get { return this.mCompleted; }
}
///
/// Gets a value indicating whether this achievement is hidden.
///
/// true if hidden; otherwise, false.
public bool hidden
{
get { return this.mHidden; }
}
public DateTime lastReportedDate
{
get { return mLastModifiedTime; }
}
public String title
{
get { return mTitle; }
}
public Texture2D image
{
get { return LoadImage(); }
}
public string achievedDescription
{
get { return mDescription; }
}
public string unachievedDescription
{
get { return mDescription; }
}
public int points
{
get { return (int) mPoints; }
}
}
}
#endif