Implement simple user creation system
This commit is contained in:
committed by
Victor Mylle
parent
7ed5a959e2
commit
a351182aa1
85
Assets/Common/Scripts/Progress.cs
Normal file
85
Assets/Common/Scripts/Progress.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
[Serializable]
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: use inheritance to create seperate MinigameProgress and CourseProgress
|
||||
[Header("Course or Minigame")]
|
||||
// TODO: change to course/minigame ScriptableObject reference
|
||||
// Index of item in courses/minigame list object
|
||||
public int index;
|
||||
|
||||
[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 Add<T>(string key, T data)
|
||||
{
|
||||
if (data == null)
|
||||
return false;
|
||||
|
||||
// Search for already existing key
|
||||
foreach (DataEntry entry in entries)
|
||||
{
|
||||
if (entry.key == key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Hacky serialization stuff
|
||||
BinaryFormatter bf = new BinaryFormatter();
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
bf.Serialize(ms, data);
|
||||
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/Common/Scripts/Progress.cs.meta
Normal file
11
Assets/Common/Scripts/Progress.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 183eab19332f33a48a745b7b264611fc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Assets/Common/Scripts/User.cs
Normal file
27
Assets/Common/Scripts/User.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[CreateAssetMenu(menuName = "Create new Scriptable/User/User")]
|
||||
public class User : ScriptableObject
|
||||
{
|
||||
[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>();
|
||||
}
|
||||
11
Assets/Common/Scripts/User.cs.meta
Normal file
11
Assets/Common/Scripts/User.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c6c5919d9f747143b377c2bc34cd28b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
101
Assets/Common/Scripts/UserCreationScreen.cs
Normal file
101
Assets/Common/Scripts/UserCreationScreen.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
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))
|
||||
{
|
||||
// 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/Common/Scripts/UserCreationScreen.cs.meta
Normal file
11
Assets/Common/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:
|
||||
45
Assets/Common/Scripts/UserList.cs
Normal file
45
Assets/Common/Scripts/UserList.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[CreateAssetMenu(menuName = "Create new Scriptable/User/List")]
|
||||
public class UserList : ScriptableObject
|
||||
{
|
||||
[Header("Template")]
|
||||
// Reference to User template
|
||||
public ScriptableObject userTemplate;
|
||||
|
||||
[Header("Users")]
|
||||
// List of users
|
||||
public List<User> users = new List<User>();
|
||||
|
||||
// Create a new User
|
||||
public User CreateNewUser(string name, Sprite avatar)
|
||||
{
|
||||
User user = ScriptableObject.CreateInstance<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);
|
||||
users.Add(user);
|
||||
EditorUtility.SetDirty(this);
|
||||
AssetDatabase.CreateAsset(user, $"Assets/Common/ScriptableObjects/Users/{name}.asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
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 users)
|
||||
if (user.username == username) return user;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
11
Assets/Common/Scripts/UserList.cs.meta
Normal file
11
Assets/Common/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