Integrate minigame and courses

This commit is contained in:
Dries Van Schuylenbergh
2023-03-08 19:07:57 +00:00
parent 7e98fea538
commit 852a17b0b4
56 changed files with 1431 additions and 1300 deletions

View File

@@ -7,12 +7,11 @@ using UnityEngine.UI;
public class CourseItem : MonoBehaviour
{
// TODO: change to ScriptableObject Course;
[Header("ScriptableObject Course")]
public string courseTitle;
public float courseProgress;
public Sprite courseThumbnail;
public string courseScene;
[Header("Course")]
// Reference to the course
public Course course;
// Progress of the current user on this course
public float progress;
[Header("UI references")]
// Reference to thumbnail object
@@ -36,16 +35,16 @@ public class CourseItem : MonoBehaviour
public void GenerateContent()
{
// Set appearance
thumbnail.sprite = courseThumbnail;
title.text = courseTitle;
thumbnail.sprite = course.thumbnail;
title.text = course.title;
// Set progress
float progress = Mathf.Clamp01(courseProgress);
progress = Mathf.Clamp01(progress);
completed.SetActive(1.0f <= progress);
slider.SetActive(0.0f < progress && progress < 1.0f);
slider.SetActive(0.0f <= progress && progress < 1.0f);
slider.GetComponent<Slider>().value = progress;
// Add click functionality
button.onClick.AddListener(() => SceneManager.LoadScene(courseScene));
button.onClick.AddListener(() => SceneManager.LoadScene("Courses/Scenes/Course_0"));
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class CourseListManager : MonoBehaviour
{
[Header("Course list UI components")]
// Reference to course-list holder object
public Transform courseContainer;
[Header("Prefabs")]
// Prefab of item
public GameObject courseItemPrefab;
[Header("Courses")]
// Reference to the list of all courses
public CourseList courseList;
void Start()
{
foreach (Course course in courseList.courses)
{
// Create instance of prefab
GameObject instance = GameObject.Instantiate(courseItemPrefab, courseContainer);
// Dynamically load appearance
CourseItem item = instance.GetComponent<CourseItem>();
item.course = course;
}
}
// Method used as callback for on click events
public void LoadScene(string sceneName)
{
SceneManager.LoadScene(sceneName);
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@@ -9,57 +10,49 @@ public class CourseScreenManager : MonoBehaviour
// Reference to text that displays when there are no recent courses
public GameObject noRecentCourses;
// Reference to recent-courses-list holder object
public Transform recentCourses;
public Transform recentCoursesContainer;
// Reference to recommended-courses-list holder object
public Transform recommendedCourses;
public Transform recommendedCoursesContainer;
[Header("Prefabs")]
// CourseItem prefab
public GameObject course_item;
public GameObject courseItem;
// TODO: change to ScriptableObject;
[Header("ScriptableObjects")]
public int numberOfRecentCourses;
public string[] recentCourseTitle;
public float[] recentCourseProgress;
public Sprite[] recentCourseThumbnail;
public string[] recentCourseScene;
public int numberOfRecommendedCourses;
public string[] recommendedCourseTitle;
public float[] recommendedCourseProgress;
public Sprite[] recommendedCourseThumbnail;
public string[] recommendedCourseScene;
[Header("User")]
// Reference to the users so we can get the current user;
public UserList userList;
// Reference to the courses
public CourseList courseList;
void Start()
{
// Recent courses
noRecentCourses.SetActive(numberOfRecentCourses <= 0);
User user = userList.users[userList.currentUserIndex];
for (int i = 0; i < numberOfRecentCourses; i++)
// Recent courses
List<Tuple<CourseIndex, float>> recentCourses = user.GetRecentCourses();
noRecentCourses.SetActive(recentCourses.Count <= 0);
foreach (Tuple<CourseIndex, float> course in recentCourses)
{
// Create instance of prefab
GameObject instance = GameObject.Instantiate(course_item, recentCourses);
GameObject instance = GameObject.Instantiate(courseItem, recentCoursesContainer);
// Dynamically load appearance
CourseItem item = instance.GetComponent<CourseItem>();
item.courseTitle = recentCourseTitle[i];
item.courseThumbnail = recentCourseThumbnail[i];
item.courseProgress = recentCourseProgress[i];
item.courseScene = recentCourseScene[i];
item.course = courseList.courses.Find((j) => j.index == course.Item1);
item.progress = course.Item2;
}
// Recommended courses
for (int i = 0; i < numberOfRecommendedCourses; i++)
List<Tuple<CourseIndex, float>> recommenedCourses = user.GetRecommendedCourses();
foreach (Tuple<CourseIndex, float> course in recommenedCourses)
{
// Create instance of prefab
GameObject instance = GameObject.Instantiate(course_item, recommendedCourses);
GameObject instance = GameObject.Instantiate(courseItem, recommendedCoursesContainer);
// Dynamically load appearance
CourseItem item = instance.GetComponent<CourseItem>();
item.courseTitle = recommendedCourseTitle[i];
item.courseThumbnail = recommendedCourseThumbnail[i];
item.courseProgress = 0.0f; // So progress bar doesn't show
item.courseScene = recommendedCourseScene[i];
item.course = courseList.courses.Find((j) => j.index == course.Item1);
item.progress = course.Item2;
}
}

View File

@@ -1,46 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ListScreenManager : MonoBehaviour
{
[Header("List Screen Components")]
// Reference to item-list holder object
public Transform itemContainer;
[Header("Prefabs")]
// Prefab of item
public GameObject itemPrefab;
// TODO: change to ScriptableObject;
[Header("ScriptableObjects")]
public int numberOfItems;
public string[] itemTitle;
public float[] itemProgress;
public Sprite[] itemThumbnail;
public string[] itemScene;
void Start()
{
for (int i = 0; i < numberOfItems; i++)
{
// Create instance of prefab
GameObject instance = GameObject.Instantiate(itemPrefab, itemContainer);
// Dynamically load appearance
CourseItem item = instance.GetComponent<CourseItem>();
item.courseTitle = itemTitle[i];
item.courseThumbnail = itemThumbnail[i];
item.courseProgress = itemProgress[i];
item.courseScene = itemScene[i];
}
}
// Method used as callback for on click events
public void LoadScene(string sceneName)
{
SceneManager.LoadScene(sceneName);
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "Create new Scriptable/Minigame")]
public class Minigame : ScriptableObject
{
[Header("Minigame info")]
// Minigame index
public MinigameIndex index;
// Minigame title
public string title;
// Short desciption of the course
public string description;
// Thumbnail of the course
public Sprite thumbnail;
[Header("Scene")]
// Reference to the minigame starting scene
public string minigameEntryPoint;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7809d135a59849458ccb29ffad535c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// TODO: add other courses
public enum MinigameIndex
{
SPELLING_BEE,
HANGMAN,
JUST_SIGN
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44a1fb926248fe240bed2d5c3820630b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class MinigameItem : MonoBehaviour
{
// TODO: change to ScriptableObject Minigame;
[Header("ScriptableObject Course")]
public Minigame minigame;
[Header("UI references")]
// Reference to thumbnail object
public Image thumbnail;
// Reference to title object
public TMP_Text title;
// Refetence to object so correct callback can be trigger on click
public Button button;
void Start()
{
// Use public function so that this component can get Instantiated
GenerateContent();
}
public void GenerateContent()
{
// Set appearance
thumbnail.sprite = minigame.thumbnail;
title.text = minigame.title;
// Add click functionality
button.onClick.AddListener(() => SceneManager.LoadScene(minigame.minigameEntryPoint));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0f9d201a28e32264993cc2b8f8055b33
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "Create new Scriptable/MinigameList")]
public class MinigameList : ScriptableObject
{
[Header("Current Minigame")]
// Index of the current course
public int currentMinigameIndex = 0;
[Header("Minigames")]
// List of minigames
public List<Minigame> minigames = new List<Minigame>();
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3976e4310b716de4eb24f1916c10ff3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MinigameListManager : MonoBehaviour
{
[Header("Minigame list UI components")]
// Reference to minigame-list holder object
public Transform minigameContainer;
[Header("Prefabs")]
// Prefab of item
public GameObject minigameItemPrefab;
[Header("Minigames")]
// Reference to the list of all minigames
public MinigameList minigameList;
void Start()
{
foreach (Minigame minigame in minigameList.minigames)
{
// Create instance of prefab
GameObject instance = GameObject.Instantiate(minigameItemPrefab, minigameContainer);
// Dynamically load appearance
MinigameItem item = instance.GetComponent<MinigameItem>();
item.minigame = minigame;
}
}
// Method used as callback for on click events
public void LoadScene(string sceneName)
{
SceneManager.LoadScene(sceneName);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2dd453d411c3b3e458a7b133764c6b64
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -5,8 +5,8 @@ using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
[Serializable]
// Can not be created from Editor
public class Progress
{
[Serializable]
@@ -23,39 +23,34 @@ public class Progress
}
}
// 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)
public bool AddOrUpdate<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;
}
}
DataEntry entry = entries.Find(x => x.key == key);
// Hacky serialization stuff
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, data);
entries.Add(new DataEntry(key, ms.ToArray()));
if (entry != null)
{
entry.bytes.Clear();
entry.bytes.AddRange(ms.ToArray());
}
else
{
entries.Add(new DataEntry(key, ms.ToArray()));
}
return true;
}
}

View File

@@ -3,7 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "Create new Scriptable/User/User")]
[CreateAssetMenu(menuName = "Create new Scriptable/User")]
public class User : ScriptableObject
{
[Header("Personal data")]
@@ -24,4 +24,40 @@ public class User : ScriptableObject
[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;
}
}

View File

@@ -0,0 +1,25 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class UserButton : MonoBehaviour
{
[Header("User")]
// Reference to the user list, so we can extract the current user
public UserList userList;
[Header("UI References")]
// Reference to the avatar object
public Image avatar;
// Reference to the username object
public TMP_Text username;
void Start()
{
User user = userList.users[userList.currentUserIndex];
avatar.sprite = user.avatar;
username.text = user.username;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7b8b159dda1a6104793946dc46f84f3a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -3,7 +3,7 @@ using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
[CreateAssetMenu(menuName = "Create new Scriptable/User/List")]
[CreateAssetMenu(menuName = "Create new Scriptable/UserList")]
public class UserList : ScriptableObject
{
[Header("Template")]
@@ -13,6 +13,8 @@ public class UserList : ScriptableObject
[Header("Users")]
// List of users
public List<User> users = new List<User>();
// Current user
public int currentUserIndex = 0;
// Create a new User
public User CreateNewUser(string name, Sprite avatar)