Resolve WES-95 "User progress"
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@@ -18,6 +17,11 @@ public class ChangeUserScreen : MonoBehaviour
|
||||
/// </summary>
|
||||
public Transform usersContainer;
|
||||
|
||||
/// <summary>
|
||||
/// UI Reference to the error GameObject to display an error message
|
||||
/// </summary>
|
||||
public GameObject error;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the user list
|
||||
/// </summary>
|
||||
@@ -38,6 +42,20 @@ public class ChangeUserScreen : MonoBehaviour
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
error.SetActive(false);
|
||||
DisplayUsers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add all users to the container to display them
|
||||
/// </summary>
|
||||
private void DisplayUsers()
|
||||
{
|
||||
foreach (Transform child in usersContainer)
|
||||
{
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
|
||||
List<User> users = userList.GetUsers();
|
||||
currentUserIndex = userList.GetCurrentUserIndex();
|
||||
for (int i = 0; i < users.Count; i++)
|
||||
@@ -49,18 +67,18 @@ public class ChangeUserScreen : MonoBehaviour
|
||||
|
||||
// Store value of i so we can use it the callback (else it would get the value of sprites.Count)
|
||||
int x = i;
|
||||
// Add onClick callback
|
||||
instance.GetComponent<Button>().onClick.AddListener(() => UpdateSelection(x));
|
||||
// Set username
|
||||
instance.GetComponentInChildren<TMP_Text>().text = user.username;
|
||||
// Add user content
|
||||
UserCard card = instance.GetComponent<UserCard>();
|
||||
card.user = user;
|
||||
card.selectUser = () => UpdateSelection(x);
|
||||
card.updateUserCardContainer = DisplayUsers;
|
||||
card.displayError = () => error.SetActive(true);
|
||||
|
||||
// Store reference to image for fancy coloring
|
||||
Image background = instance.GetComponent<Image>();
|
||||
userBackgrounds.Add(background);
|
||||
// Set background color
|
||||
background.color = i == currentUserIndex ? Color.blue : Color.gray;
|
||||
// Find correct component for setting the sprite
|
||||
instance.transform.Find("Avatar").GetComponent<Image>().sprite = user.avatar;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
58
Assets/Accounts/Scripts/CourseProgressCard.cs
Normal file
58
Assets/Accounts/Scripts/CourseProgressCard.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Class to handle course progress card display
|
||||
/// </summary>
|
||||
public class CourseProgressCard : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Callback to the UpdateSelection
|
||||
/// </summary>
|
||||
public UnityAction selectActivity;
|
||||
|
||||
/// <summary>
|
||||
/// Button to place to callback on
|
||||
/// </summary>
|
||||
public Button button;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress so we can display a progress bar
|
||||
/// </summary>
|
||||
public Progress courseProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the list of courses so we can query the correct course
|
||||
/// </summary>
|
||||
public CourseList courseList;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the thumbnail of the course
|
||||
/// </summary>
|
||||
public Image thumbnail;
|
||||
|
||||
/// <summary>
|
||||
/// UI refeerence to the title of the course
|
||||
/// </summary>
|
||||
public TMP_Text title;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress bar for the course
|
||||
/// </summary>
|
||||
public Slider progressBar;
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
Course course = courseList.GetCourseByIndex(courseProgress.Get<CourseIndex>("courseIndex"));
|
||||
|
||||
thumbnail.sprite = course.thumbnail;
|
||||
title.text = course.title;
|
||||
progressBar.value = courseProgress.Get<float>("courseProgress");
|
||||
button.onClick.AddListener(selectActivity);
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/CourseProgressCard.cs.meta
Normal file
11
Assets/Accounts/Scripts/CourseProgressCard.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7f1ef892112fd243929d40c896c9b7b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
59
Assets/Accounts/Scripts/MinigameProgressCard.cs
Normal file
59
Assets/Accounts/Scripts/MinigameProgressCard.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Class to handle minigame progress card display
|
||||
/// </summary>
|
||||
public class MinigameProgressCard : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Callback to the UpdateSelection
|
||||
/// </summary>
|
||||
public UnityAction selectActivity;
|
||||
|
||||
/// <summary>
|
||||
/// Button to place the callback on
|
||||
/// </summary>
|
||||
public Button button;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the minigame progress
|
||||
/// </summary>
|
||||
public Progress minigameProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the minigame list
|
||||
/// </summary>
|
||||
public MinigameList minigameList;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the minigame thumbnail
|
||||
/// </summary>
|
||||
public Image thumbnail;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the minigame title
|
||||
/// </summary>
|
||||
public TMP_Text title;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the user's highscore
|
||||
/// </summary>
|
||||
public TMP_Text highscore;
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
Minigame minigame = minigameList.GetMinigameByIndex(minigameProgress.Get<MinigameIndex>("minigameIndex"));
|
||||
|
||||
thumbnail.sprite = minigame.thumbnail;
|
||||
title.text = minigame.title;
|
||||
highscore.text = $"Topscore: {minigameProgress.Get<List<Score>>("highestScores")[0].scoreValue}";
|
||||
button.onClick.AddListener(selectActivity);
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/MinigameProgressCard.cs.meta
Normal file
11
Assets/Accounts/Scripts/MinigameProgressCard.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2f3fceaa7f21164eaea98a63fa7d8e5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
78
Assets/Accounts/Scripts/UserCard.cs
Normal file
78
Assets/Accounts/Scripts/UserCard.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Class to display user info in the ChangeUserScreen scene
|
||||
/// </summary>
|
||||
public class UserCard : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference to the userlist
|
||||
/// </summary>
|
||||
public UserList userList;
|
||||
|
||||
/// <summary>
|
||||
/// User to upload info into this card
|
||||
/// </summary>
|
||||
public User user;
|
||||
|
||||
/// <summary>
|
||||
/// Callback to the UpdateSelection in the ChangeUserScreen
|
||||
/// </summary>
|
||||
public UnityAction selectUser;
|
||||
|
||||
/// <summary>
|
||||
/// Callback to the update hte users container in the ChangeUserScreen scene
|
||||
/// </summary>
|
||||
public UnityAction updateUserCardContainer;
|
||||
|
||||
/// <summary>
|
||||
/// Callback to display an error message in the ChangeUserScreen scene
|
||||
/// </summary>
|
||||
public UnityAction displayError;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the selectio button
|
||||
/// </summary>
|
||||
public Button button;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the avatar
|
||||
/// </summary>
|
||||
public Image avatar;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the username
|
||||
/// </summary>
|
||||
public TMP_Text username;
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
avatar.sprite = user.avatar;
|
||||
username.text = user.username;
|
||||
button.onClick.AddListener(selectUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete the user from the userlist
|
||||
/// </summary>
|
||||
public void DeleteUser()
|
||||
{
|
||||
if (userList.DeleteUser(user))
|
||||
{
|
||||
// User is removed, update and save
|
||||
userList.Save();
|
||||
updateUserCardContainer();
|
||||
}
|
||||
else
|
||||
{
|
||||
// User is not removed, display an error
|
||||
displayError();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/UserCard.cs.meta
Normal file
11
Assets/Accounts/Scripts/UserCard.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 172fcacd3bd90f442a6b94f0ff43a76a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -133,6 +133,35 @@ public class UserList : ScriptableObject
|
||||
storedUserList.currentUserIndex = storedUserList.storedUsers.IndexOf(user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the user
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the user in the userlist</param>
|
||||
/// <returns>true if user was successful removed, false otherwise</returns>
|
||||
public bool DeleteUser(int index)
|
||||
{
|
||||
return DeleteUser(storedUserList.storedUsers[index]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// I am inevitable, *snap*
|
||||
/// </summary>
|
||||
/// <param name="user">Reference to the user to be removed</param>
|
||||
/// <returns>true if the user was successful removed, false otherwise</returns>
|
||||
public bool DeleteUser(User user)
|
||||
{
|
||||
if (1 < storedUserList.storedUsers.Count)
|
||||
{
|
||||
if (storedUserList.currentUserIndex == storedUserList.storedUsers.Count - 1)
|
||||
{
|
||||
storedUserList.currentUserIndex--;
|
||||
}
|
||||
|
||||
return storedUserList.storedUsers.Remove(user);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the users
|
||||
/// </summary>
|
||||
|
||||
369
Assets/Accounts/Scripts/UserProgressScreen.cs
Normal file
369
Assets/Accounts/Scripts/UserProgressScreen.cs
Normal file
@@ -0,0 +1,369 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// UserProgressScreen scene manager
|
||||
/// </summary>
|
||||
public class UserProgressScreen : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference to the userlist
|
||||
/// </summary>
|
||||
public UserList userList;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the current user
|
||||
/// </summary>
|
||||
private User user;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the username
|
||||
/// </summary>
|
||||
public TMP_Text username;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the user's avatar
|
||||
/// </summary>
|
||||
public Image avatar;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the user total playtime
|
||||
/// </summary>
|
||||
public TMP_Text playtime;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of the highscore marker to display on the graph
|
||||
/// </summary>
|
||||
public GameObject highscoreMarker;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of a course card
|
||||
/// </summary>
|
||||
public GameObject courseCardPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the container holding all course cards
|
||||
/// </summary>
|
||||
public GameObject coursesContainer;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the message that displays when no course progress is present
|
||||
/// </summary>
|
||||
public GameObject emptyCourses;
|
||||
|
||||
/// <summary>
|
||||
/// Prefab of a minigame card
|
||||
/// </summary>
|
||||
public GameObject minigameCardPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the container holding all the minigame cards
|
||||
/// </summary>
|
||||
public GameObject minigamesContainer;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the message that displays when no minigame progress is present
|
||||
/// </summary>
|
||||
public GameObject emptyMinigames;
|
||||
|
||||
/// <summary>
|
||||
/// UI reference to the plot
|
||||
/// </summary>
|
||||
public RawImage progressGraph;
|
||||
|
||||
/// <summary>
|
||||
/// Left and right padding of the graph
|
||||
/// </summary>
|
||||
private const int GRAPH_PADDING_X_PX = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Top and bottom padding of the graph
|
||||
/// </summary>
|
||||
private const int GRAPH_PADDING_Y_PX = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Radius of the point on the graph
|
||||
/// </summary>
|
||||
private const int GRAPH_POINT_RADIUS = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Size of the line on the graph
|
||||
/// </summary>
|
||||
private const int GRAPH_LINE_SIZE = 4;
|
||||
|
||||
/// <summary>
|
||||
/// Current selected activity draw to the graph
|
||||
/// </summary>
|
||||
private int selectedActivity = -1;
|
||||
|
||||
/// <summary>
|
||||
/// List of activity backgrounds and indices
|
||||
/// </summary>
|
||||
private List<Tuple<Image, int>> activities = new List<Tuple<Image, int>>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
// Assign the current user
|
||||
user = userList.GetCurrentUser();
|
||||
|
||||
// Set correct displayed items
|
||||
username.text = user.username;
|
||||
avatar.sprite = user.avatar;
|
||||
// TODO: implement total playtime
|
||||
//playtime.text = $"Totale speeltijd: {user.playtime.ToString("0.00")}";
|
||||
|
||||
// Set graph inactive
|
||||
progressGraph.gameObject.SetActive(false);
|
||||
|
||||
int i = 0;
|
||||
// Display courses
|
||||
coursesContainer.SetActive(user.courses.Count > 0);
|
||||
emptyCourses.SetActive(user.courses.Count <= 0);
|
||||
foreach (Progress courseProgress in user.courses)
|
||||
{
|
||||
// Create instance of prefab
|
||||
GameObject instance = GameObject.Instantiate(courseCardPrefab, coursesContainer.transform.Find("Viewport").Find("Content").transform);
|
||||
int j = i++;
|
||||
|
||||
// Initialize card
|
||||
CourseProgressCard cpc = instance.GetComponent<CourseProgressCard>();
|
||||
cpc.courseProgress = courseProgress;
|
||||
cpc.selectActivity = () => UpdateSelection(j);
|
||||
|
||||
// Store reference to background so we can apply fancy coloring
|
||||
Image background = instance.GetComponent<Image>();
|
||||
background.color = Color.gray;
|
||||
activities.Add(Tuple.Create(background, (int)courseProgress.Get<CourseIndex>("courseIndex")));
|
||||
}
|
||||
|
||||
// Display minigames
|
||||
minigamesContainer.SetActive(user.minigames.Count > 0);
|
||||
emptyMinigames.SetActive(user.minigames.Count <= 0);
|
||||
foreach (Progress minigameProgress in user.minigames)
|
||||
{
|
||||
// Create instance of prefab
|
||||
GameObject instance = GameObject.Instantiate(minigameCardPrefab, minigamesContainer.transform.Find("Viewport").Find("Content").transform);
|
||||
int j = i++;
|
||||
|
||||
// Initialize card
|
||||
MinigameProgressCard mpc = instance.GetComponent<MinigameProgressCard>();
|
||||
mpc.minigameProgress = minigameProgress;
|
||||
mpc.selectActivity = () => UpdateSelection(j);
|
||||
|
||||
// Store reference to background so we can apply fancy coloring
|
||||
Image background = instance.GetComponent<Image>();
|
||||
background.color = Color.gray;
|
||||
activities.Add(Tuple.Create(background, (int)minigameProgress.Get<MinigameIndex>("minigameIndex")));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the current selected activity
|
||||
/// </summary>
|
||||
/// <param name="newActivity">Index to the new activity</param>
|
||||
private void UpdateSelection(int newActivity)
|
||||
{
|
||||
if (selectedActivity < 0)
|
||||
{
|
||||
progressGraph.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
activities[selectedActivity].Item1.color = Color.gray;
|
||||
}
|
||||
|
||||
selectedActivity = newActivity;
|
||||
activities[selectedActivity].Item1.color = Color.blue;
|
||||
if (selectedActivity < user.courses.Count)
|
||||
{
|
||||
// TODO: create a better graph
|
||||
//DisplayCourseGraph((CourseIndex)activities[selectedActivity].Item2);
|
||||
// For now: just deactivate graph rendering
|
||||
progressGraph.gameObject.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayMinigameGraph((MinigameIndex)activities[selectedActivity].Item2);
|
||||
// TODO: remove line, this is only because courses deactivates the graph
|
||||
progressGraph.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Plot the graph of a course
|
||||
/// </summary>
|
||||
/// <param name="index">Index of the course</param>
|
||||
/// <remarks>TODO: create a better plot</remarks>
|
||||
private void DisplayCourseGraph(CourseIndex index) { }
|
||||
|
||||
/// <summary>
|
||||
/// Plot the graph of a minigame
|
||||
/// </summary>
|
||||
/// <param name="minigameIndex">Index of the minigame</param>
|
||||
private void DisplayMinigameGraph(MinigameIndex minigameIndex)
|
||||
{
|
||||
Progress progress = user.GetMinigameProgress(minigameIndex);
|
||||
List<Score> scores = progress.Get<List<Score>>("latestScores");
|
||||
PlotGraph(scores.ConvertAll<double>((s) => (double)s.scoreValue), progress.Get<List<Score>>("highestScores")[0].scoreValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Plot points and a highscore on the graph
|
||||
/// </summary>
|
||||
/// <param name="scores">List of score values to plot</param>
|
||||
/// <param name="highscore">Highscore value (this will be plotted in a fancy color)</param>
|
||||
private void PlotGraph(List<double> scores, double highscore)
|
||||
{
|
||||
// Remove previous marker(s)
|
||||
foreach (Transform child in progressGraph.gameObject.transform)
|
||||
{
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
|
||||
// Get texture reference
|
||||
Texture2D tex = progressGraph.texture as Texture2D;
|
||||
if (tex == null)
|
||||
{
|
||||
RectTransform rt = progressGraph.gameObject.transform as RectTransform;
|
||||
tex = new Texture2D(
|
||||
width: (int)rt.sizeDelta.x,
|
||||
height: (int)rt.sizeDelta.y,
|
||||
textureFormat: TextureFormat.ARGB32,
|
||||
mipCount: 3,
|
||||
linear: true
|
||||
);
|
||||
}
|
||||
tex.filterMode = FilterMode.Point;
|
||||
|
||||
// calculate positions and offsets
|
||||
int x0 = GRAPH_PADDING_X_PX, x1 = tex.width - GRAPH_PADDING_X_PX;
|
||||
int y0 = GRAPH_PADDING_Y_PX, y1 = tex.height - GRAPH_PADDING_Y_PX;
|
||||
double min = scores.Min();
|
||||
double max = scores.Max();
|
||||
|
||||
List<Tuple<int, int>> points = new List<Tuple<int, int>>();
|
||||
for (int i = 0; i < scores.Count; i++)
|
||||
{
|
||||
int x = x0 + (scores.Count > 1 ? i * ((x1 - x0) / (scores.Count - 1)) : (x1 - x0) / 2);
|
||||
int y = y0 + (int)((y1 - y0) * (min != max ? (scores[i] - min) / (max - min) : 0.5));
|
||||
points.Add(Tuple.Create(x, y));
|
||||
}
|
||||
|
||||
// Calculate scaling
|
||||
int mag = (int)Math.Round(Math.Log10(max));
|
||||
int MAG = (int)Math.Pow(10, mag);
|
||||
double c = max / MAG;
|
||||
|
||||
// Draw axes
|
||||
if (min != max)
|
||||
{
|
||||
for (double d = c / 5.0; d < c; d += 0.2 * c)
|
||||
{
|
||||
int y = y0 + (int)((y1 - y0) * (MAG * d - min) / (max - min));
|
||||
DrawLine(tex, x0, y, x1, y, 2, Color.gray);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int y = y0 + (int)((y1 - y0) * 0.5);
|
||||
DrawLine(tex, x0, y0, x1, y0, 2, Color.gray);
|
||||
DrawLine(tex, x0, y, x1, y, 2, Color.gray);
|
||||
DrawLine(tex, x0, y1, x1, y1, 2, Color.gray);
|
||||
}
|
||||
|
||||
// Draw highscore
|
||||
if (min <= highscore && highscore <= max)
|
||||
{
|
||||
int y = y0 + (int)((y1 - y0) * (min != max ? (highscore - min) / (max - min) : 0.5));
|
||||
DrawLine(tex, x0, y, x1, y, 3, new Color(255, 192, 0));
|
||||
GameObject marker = GameObject.Instantiate(highscoreMarker, progressGraph.gameObject.transform);
|
||||
RectTransform rect = marker.GetComponent<RectTransform>();
|
||||
rect.localPosition = new Vector3(0, y - 25, 0);
|
||||
}
|
||||
|
||||
// Draw points
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
Tuple<int, int> p = points[i];
|
||||
if (0 < i)
|
||||
{
|
||||
Tuple<int, int> q = points[i - 1];
|
||||
DrawLine(tex, p.Item1, p.Item2, q.Item1, q.Item2, GRAPH_LINE_SIZE, Color.blue);
|
||||
}
|
||||
DrawPoint(tex, p.Item1, p.Item2, GRAPH_POINT_RADIUS, Color.blue);
|
||||
}
|
||||
|
||||
// Apply to graph GameObject
|
||||
tex.Apply();
|
||||
progressGraph.texture = tex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a point to a texture
|
||||
/// </summary>
|
||||
/// <param name="tex">Texture2D to plot point on</param>
|
||||
/// <param name="xc">Center x-pos</param>
|
||||
/// <param name="yc">Center y-pos</param>
|
||||
/// <param name="r">Radius (aka width and height)</param>
|
||||
/// <param name="color">Color of the point</param>
|
||||
private void DrawPoint(Texture2D tex, int xc, int yc, int r, Color color)
|
||||
{
|
||||
for (int y = yc - r; y < yc + r; y++)
|
||||
{
|
||||
for (int x = xc - r; x < xc + r; x++)
|
||||
{
|
||||
tex.SetPixel(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a line to a texture
|
||||
/// </summary>
|
||||
/// <param name="tex">Texture2D to plot line on</param>
|
||||
/// <param name="x0">Starting x-pos</param>
|
||||
/// <param name="y0">Strating y-pos</param>
|
||||
/// <param name="x1">Ending x-pos</param>
|
||||
/// <param name="y1">Ending y-pos</param>
|
||||
/// <param name="size">Size of the line (width)</param>
|
||||
/// <param name="color">Color of the line</param>
|
||||
private void DrawLine(Texture2D tex, int x0, int y0, int x1, int y1, int size, Color color)
|
||||
{
|
||||
int w = x1 - x0;
|
||||
int h = y1 - y0;
|
||||
|
||||
int length = Mathf.Abs(x1 - x0);
|
||||
if (Mathf.Abs(y1 - y0) > length)
|
||||
{
|
||||
length = Mathf.Abs(h);
|
||||
}
|
||||
|
||||
double dx = w / (double)length;
|
||||
double dy = h / (double)length;
|
||||
|
||||
double x = x0;
|
||||
double y = y0;
|
||||
double r = size / 2;
|
||||
for (int i = 0; i <= length; i++)
|
||||
{
|
||||
for (int j = (int)(y - r); j < y + r; j++)
|
||||
{
|
||||
for (int k = (int)(x - r); k < x + r; k++)
|
||||
{
|
||||
tex.SetPixel(k, j, color);
|
||||
}
|
||||
}
|
||||
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/UserProgressScreen.cs.meta
Normal file
11
Assets/Accounts/Scripts/UserProgressScreen.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a59f8e8c48fbd4444a41df01694d13a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user