Wes xx build fix
This commit is contained in:
committed by
Louis Adriaens
parent
601cf38c61
commit
2fa54620ef
79
Assets/Accounts/Scripts/Progress.cs
Normal file
79
Assets/Accounts/Scripts/Progress.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using UnityEngine;
|
||||
|
||||
[Serializable]
|
||||
// Can not be created from Editor
|
||||
public class Progress
|
||||
{
|
||||
[Serializable]
|
||||
// Helper class to serialize into byte[]
|
||||
protected class DataEntry
|
||||
{
|
||||
public string key;
|
||||
public List<byte> bytes = new List<byte>();
|
||||
|
||||
public DataEntry(string key, byte[] data)
|
||||
{
|
||||
this.key = key;
|
||||
this.bytes = new List<byte>(data);
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Course or Minigame")]
|
||||
[SerializeField]
|
||||
// values belonging to a certain key, in List (which can be serialized)
|
||||
private List<DataEntry> entries = new List<DataEntry>();
|
||||
|
||||
|
||||
// Add new `key` := `value`, returns `true` if successful
|
||||
public bool AddOrUpdate<T>(string key, T data)
|
||||
{
|
||||
if (data == null)
|
||||
return false;
|
||||
|
||||
DataEntry entry = entries.Find(x => x.key == key);
|
||||
|
||||
// Hacky serialization stuff
|
||||
BinaryFormatter bf = new BinaryFormatter();
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
bf.Serialize(ms, data);
|
||||
if (entry != null)
|
||||
{
|
||||
entry.bytes.Clear();
|
||||
entry.bytes.AddRange(ms.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
entries.Add(new DataEntry(key, ms.ToArray()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the value of type `T` belonging to `key`
|
||||
public T Get<T>(string key)
|
||||
{
|
||||
BinaryFormatter bf = new BinaryFormatter();
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
// Find the correct key
|
||||
foreach (DataEntry entry in entries)
|
||||
{
|
||||
if (entry.key == key)
|
||||
{
|
||||
// Hacky serialization stuff
|
||||
byte[] data = entry.bytes.ToArray();
|
||||
ms.Write(data, 0, data.Length);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
return (T)bf.Deserialize(ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Raise an exception when key is not found
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/Progress.cs.meta
Normal file
11
Assets/Accounts/Scripts/Progress.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d887bc641cc7a8f4abf9d4eb34d26923
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
62
Assets/Accounts/Scripts/User.cs
Normal file
62
Assets/Accounts/Scripts/User.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[Serializable]
|
||||
public class User
|
||||
{
|
||||
[Header("Personal data")]
|
||||
// User nickname
|
||||
public string username;
|
||||
// User avatar
|
||||
public Sprite avatar;
|
||||
|
||||
[Header("Personal settings")]
|
||||
// TODO: set personal settings and preferences
|
||||
|
||||
[Header("Progress")]
|
||||
// Total playtime
|
||||
public double playtime;
|
||||
[SerializeField]
|
||||
// List of courses a user started/completed
|
||||
public List<Progress> courses = new List<Progress>();
|
||||
[SerializeField]
|
||||
// List of minigames a user played
|
||||
public List<Progress> minigames = new List<Progress>();
|
||||
|
||||
// Get a list of all recently started courses, returns a list of tuples of `<CourseIndex idx, float courseProgress>`
|
||||
public List<Tuple<CourseIndex, float>> GetRecentCourses()
|
||||
{
|
||||
// TODO: return better results (for now only return all courses)
|
||||
List<Tuple<CourseIndex, float>> recentCourses = new List<Tuple<CourseIndex, float>>();
|
||||
foreach (Progress courseProgress in courses)
|
||||
{
|
||||
CourseIndex idx = courseProgress.Get<CourseIndex>("courseIndex");
|
||||
float progress = courseProgress.Get<float>("courseProgress");
|
||||
recentCourses.Add(Tuple.Create<CourseIndex, float>(idx, progress));
|
||||
}
|
||||
return recentCourses;
|
||||
}
|
||||
|
||||
// Get a list of all recommended courses, returns a list of tuples of `<CourseIndex idx, float courseProgress>`
|
||||
public List<Tuple<CourseIndex, float>> GetRecommendedCourses()
|
||||
{
|
||||
List<Tuple<CourseIndex, float>> recommenedCourses = new List<Tuple<CourseIndex, float>>();
|
||||
if (courses.Count == 0)
|
||||
{
|
||||
recommenedCourses.Add(Tuple.Create<CourseIndex, float>(CourseIndex.FINGERSPELLING, 0.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: return better results (for now only return all courses)
|
||||
foreach (Progress courseProgress in courses)
|
||||
{
|
||||
CourseIndex idx = courseProgress.Get<CourseIndex>("courseIndex");
|
||||
float progress = courseProgress.Get<float>("courseProgress");
|
||||
recommenedCourses.Add(Tuple.Create<CourseIndex, float>(idx, progress));
|
||||
}
|
||||
}
|
||||
|
||||
return recommenedCourses;
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/User.cs.meta
Normal file
11
Assets/Accounts/Scripts/User.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae6d59a84b340534f8bbfc7101ce4a2f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
98
Assets/Accounts/Scripts/UserCreationScreen.cs
Normal file
98
Assets/Accounts/Scripts/UserCreationScreen.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class UserCreationScreen : MonoBehaviour
|
||||
{
|
||||
// Max length of a username
|
||||
private const int MAX_USERNAME_LENGTH = 12;
|
||||
|
||||
[Header("UI References")]
|
||||
// Reference to the input text field for username
|
||||
public TMP_InputField inputName;
|
||||
// Reference to the avatar-list container
|
||||
public Transform avatarsContainer;
|
||||
|
||||
[Header("Prefab")]
|
||||
// Avatar prefab
|
||||
public GameObject avatarPrefab;
|
||||
// List of all sprites that are supported as avatars
|
||||
public List<Sprite> sprites = new List<Sprite>();
|
||||
|
||||
[Header("Users List")]
|
||||
// Reference to the UserList ScriptableObject
|
||||
public UserList users;
|
||||
|
||||
[SerializeField]
|
||||
// Current selected avatar
|
||||
private int selectedAvatar = 0;
|
||||
// List of references to avatar background sprites (so we can color them nicely)
|
||||
private List<Image> avatars = new List<Image>();
|
||||
|
||||
|
||||
void Start()
|
||||
{
|
||||
for (int i = 0; i < sprites.Count; i++)
|
||||
{
|
||||
// Create instance of prefab
|
||||
GameObject instance = GameObject.Instantiate(avatarPrefab, avatarsContainer);
|
||||
|
||||
// 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(() => UpdateAvatar(x));
|
||||
|
||||
// Store reference to image for fancy coloring
|
||||
Image background = instance.GetComponent<Image>();
|
||||
avatars.Add(background);
|
||||
// Set background color
|
||||
background.color = selectedAvatar == i ? Color.blue : Color.gray;
|
||||
// Find correct component for setting the sprite
|
||||
foreach (Image img in background.GetComponentsInChildren<Image>())
|
||||
if (img != background)
|
||||
{
|
||||
img.sprite = sprites[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current selected avatar
|
||||
private void UpdateAvatar(int newAvatar)
|
||||
{
|
||||
avatars[selectedAvatar].color = Color.gray;
|
||||
selectedAvatar = newAvatar;
|
||||
avatars[selectedAvatar].color = Color.blue;
|
||||
}
|
||||
|
||||
// Check if a given string is a correct username (using Regex)
|
||||
static public bool IsValidUsername(string username)
|
||||
{
|
||||
return new Regex($@"^[abcdefghijklmnopqrstuvwxyz]{{1,{MAX_USERNAME_LENGTH}}}$").IsMatch(username);
|
||||
}
|
||||
|
||||
// Create a new user (will be called by button)
|
||||
public void CreateUser()
|
||||
{
|
||||
string username = inputName.text;
|
||||
if (IsValidUsername(username))
|
||||
{
|
||||
if (users.GetUserByUsername(username) == null)
|
||||
{
|
||||
// Create a new entry in the UserList ScriptableObject
|
||||
users.CreateAndAddNewUser(username, sprites[selectedAvatar]);
|
||||
// TODO: change scene, for now just change to StartScreen
|
||||
SceneManager.LoadScene("Common/Scenes/StartScreen");
|
||||
}
|
||||
// TODO: give more feedback to user
|
||||
// Warn user that username already exists
|
||||
else Debug.LogWarning($"Username '{username}' already exists!");
|
||||
}
|
||||
// TODO: give more feedback to user
|
||||
// Warn user that username is invalid
|
||||
else Debug.LogWarning($"Invalid username '{username}'!");
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/UserCreationScreen.cs.meta
Normal file
11
Assets/Accounts/Scripts/UserCreationScreen.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc3902e35c042b14f83b24498d31d587
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
89
Assets/Accounts/Scripts/UserList.cs
Normal file
89
Assets/Accounts/Scripts/UserList.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
[CreateAssetMenu(menuName = "Create new Scriptable/UserList")]
|
||||
public class UserList : ScriptableObject
|
||||
{
|
||||
// Serializable UserList content
|
||||
[Serializable]
|
||||
public class StoredUserList
|
||||
{
|
||||
public int currentUserIndex;
|
||||
public List<User> storedUsers = new List<User>();
|
||||
}
|
||||
[Header("Users")]
|
||||
[SerializeField]
|
||||
// Reference to serializable version of UserList
|
||||
private StoredUserList storedUserList = new StoredUserList();
|
||||
|
||||
// Path to .json file
|
||||
public static string PATH = null;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
PATH = $"{Application.dataPath}/users.json";
|
||||
Load();
|
||||
}
|
||||
|
||||
// Create a new User
|
||||
public User CreateNewUser(string name, Sprite avatar)
|
||||
{
|
||||
User user = new User();
|
||||
user.username = name;
|
||||
user.avatar = avatar;
|
||||
return user;
|
||||
}
|
||||
|
||||
// Create a new User and add to list
|
||||
public User CreateAndAddNewUser(string name, Sprite avatar)
|
||||
{
|
||||
User user = CreateNewUser(name, avatar);
|
||||
storedUserList.storedUsers.Add(user);
|
||||
Save();
|
||||
return user;
|
||||
}
|
||||
|
||||
// Get user by username, returns `null` if no user can be found with such name
|
||||
public User GetUserByUsername(string username)
|
||||
{
|
||||
foreach (User user in storedUserList.storedUsers)
|
||||
if (user.username == username) return user;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get a list of all users
|
||||
public List<User> GetUsers()
|
||||
{
|
||||
return storedUserList.storedUsers;
|
||||
}
|
||||
|
||||
// Get the current active user
|
||||
public User GetCurrentUser()
|
||||
{
|
||||
return storedUserList.storedUsers[storedUserList.currentUserIndex];
|
||||
}
|
||||
|
||||
// Save the userList
|
||||
public void Save()
|
||||
{
|
||||
string json = JsonUtility.ToJson(storedUserList);
|
||||
File.CreateText(PATH).Close();
|
||||
File.WriteAllText(PATH, json);
|
||||
}
|
||||
|
||||
// Load the userList into this object
|
||||
public void Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
storedUserList.storedUsers.Clear();
|
||||
|
||||
string text = File.ReadAllText(PATH);
|
||||
storedUserList = JsonUtility.FromJson<StoredUserList>(text);
|
||||
}
|
||||
catch (FileNotFoundException) { Debug.Log($"Path '{PATH}' not found"); }
|
||||
}
|
||||
}
|
||||
11
Assets/Accounts/Scripts/UserList.cs.meta
Normal file
11
Assets/Accounts/Scripts/UserList.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f3d6d68c3c3db64e91cf5ec9537ccda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user