Merge branch 'WES-145-Consistency-controllers' into 'development'
Resolve WES-145 "Consistency controllers" See merge request wesign/unity-application!68
This commit was merged in pull request #68.
This commit is contained in:
290
Assets/Courses/Scripts/CoursesController.cs
Normal file
290
Assets/Courses/Scripts/CoursesController.cs
Normal file
@@ -0,0 +1,290 @@
|
||||
using System;
|
||||
using TMPro;
|
||||
using Unity.Barracuda;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Video;
|
||||
|
||||
/// <summary>
|
||||
/// TemplateCourse scene manager
|
||||
/// </summary>
|
||||
public class CoursesController : MonoBehaviour
|
||||
{
|
||||
// vvv TEMPORARY STUFF vvv
|
||||
public NNModel previewModel;
|
||||
public GameObject feedbackProgressBar;
|
||||
public GameObject previewMessage;
|
||||
// ^^^ TEMPORARY STUFF ^^^
|
||||
|
||||
/// <summary>
|
||||
/// Reference to instructional video player
|
||||
/// </summary>
|
||||
public VideoPlayer player;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to pause button
|
||||
/// </summary>
|
||||
public Button button;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to sprite for the pause button
|
||||
/// </summary>
|
||||
public Sprite pauseSprite;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the image for displaying the current words sprite
|
||||
/// </summary>
|
||||
public Image wordImage;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the text object for displaying the current word
|
||||
/// </summary>
|
||||
public TMP_Text title;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to user list to get current user
|
||||
/// </summary>
|
||||
public UserList userList;
|
||||
|
||||
/// <summary>
|
||||
/// The current user
|
||||
/// </summary>
|
||||
private User user;
|
||||
|
||||
/// <summary>
|
||||
/// Current user progress for this course
|
||||
/// </summary>
|
||||
private Progress progress = null;
|
||||
|
||||
/// <summary>
|
||||
/// ScriptableObject with list of all courses
|
||||
/// </summary>
|
||||
public CourseList courselist;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to Course ScriptableObject
|
||||
/// </summary>
|
||||
private Course course;
|
||||
|
||||
/// <summary>
|
||||
/// Index of the current word/letter in the course.learnables list
|
||||
/// </summary>
|
||||
private int currentWordIndex = 0;
|
||||
|
||||
/// <summary>
|
||||
/// This holds the amount of words in the course
|
||||
/// </summary>
|
||||
private int maxWords;
|
||||
|
||||
/// <summary>
|
||||
/// Number of correct words so far
|
||||
/// (can be modified to a list or something like that to give better feedback)
|
||||
/// </summary>
|
||||
private int correctWords = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The "finished" screen
|
||||
/// </summary>
|
||||
public GameObject ResultPanel;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the title on the results panel
|
||||
/// </summary>
|
||||
public TMP_Text ResultsTitle;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the description on the results panel
|
||||
/// </summary>
|
||||
public TMP_Text ResultsDecription;
|
||||
|
||||
/// <summary>
|
||||
/// Button to go back to courses list
|
||||
/// </summary>
|
||||
public Button CoursesButton;
|
||||
|
||||
/// <summary>
|
||||
/// DateTime containint the start moment
|
||||
/// </summary>
|
||||
private DateTime startMoment;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the timeSpent UI
|
||||
/// </summary>
|
||||
public TMP_Text timeSpent;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the feedback script on the Feedback prefab
|
||||
/// </summary>
|
||||
public Feedback feedback;
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the script is initialised.
|
||||
/// It inactivatis the popup, finds a webcam to use and links it via the WebcamTexture to the display RawImage.
|
||||
/// It takes the correct course from the courselist, using the courseIndex.
|
||||
/// Then it checks whether or not the User has started the course yet, to possibly create a new progress atribute for the course.
|
||||
/// Then it sets up the course-screen to display relevant information from the course-scriptable.
|
||||
/// </summary>
|
||||
void Awake()
|
||||
{
|
||||
// Setting up course
|
||||
course = courselist.courses[courselist.currentCourseIndex];
|
||||
feedback.signPredictor.ChangeModel(course.theme.modelIndex);
|
||||
maxWords = course.theme.learnables.Count;
|
||||
|
||||
// vvv TEMPORARY STUFF vvv
|
||||
feedbackProgressBar.SetActive(course.theme.modelIndex != ModelIndex.NONE);
|
||||
previewMessage.SetActive(course.theme.modelIndex == ModelIndex.NONE);
|
||||
// Instead, the NONE-modelIndex points to Fingerspelling, which gives the same result
|
||||
//feedback.signPredictor.model = previewModel;
|
||||
// ^^^ TEMPORARY STUFF ^^^
|
||||
|
||||
// Create entry in current user for keeping track of progress
|
||||
userList.Load();
|
||||
user = userList.GetCurrentUser();
|
||||
progress = user.GetCourseProgress(course.index);
|
||||
if (progress == null)
|
||||
{
|
||||
progress = new Progress();
|
||||
progress.AddOrUpdate<CourseIndex>("courseIndex", course.index);
|
||||
progress.AddOrUpdate<float>("courseProgress", -1.0f);
|
||||
user.courses.Add(progress);
|
||||
}
|
||||
userList.Save();
|
||||
|
||||
// Force the videoplayer to add bars to preserve aspect ratio
|
||||
player.aspectRatio = VideoAspectRatio.FitInside;
|
||||
|
||||
// Setup UI
|
||||
button.image.sprite = pauseSprite;
|
||||
title.text = course.title;
|
||||
NextVideo();
|
||||
NextImage();
|
||||
|
||||
// Hide the result panel
|
||||
ResultPanel.SetActive(false);
|
||||
// Set the startTime
|
||||
startMoment = DateTime.Now;
|
||||
|
||||
// Set callbacks
|
||||
feedback.getSignCallback = () =>
|
||||
{
|
||||
if (currentWordIndex < course.theme.learnables.Count)
|
||||
{
|
||||
return course.theme.learnables[currentWordIndex].name;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
feedback.predictSignCallback = (sign) =>
|
||||
{
|
||||
if (sign == course.theme.learnables[currentWordIndex].name)
|
||||
{
|
||||
NextSign();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function uses the word_i integer to grab the correct video from the course.learnabels.
|
||||
/// When it has this video, it will load it into the videoplayer and set it to start.
|
||||
/// </summary>
|
||||
private void NextVideo()
|
||||
{
|
||||
player.clip = course.theme.learnables[currentWordIndex].clip;
|
||||
// This loads first frame, so that it can be used as a sort-of preview for the video
|
||||
player.Play();
|
||||
// As the video will start playiing -> hide button
|
||||
Color col = button.image.color;
|
||||
col.a = 0;
|
||||
button.image.color = col;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function uses the word_i integer to grab the correct image from the course.learnabels.
|
||||
/// Then it simply loads it into wordImage so that it can be displayed.
|
||||
/// </summary>
|
||||
private void NextImage()
|
||||
{
|
||||
wordImage.sprite = course.theme.learnables[currentWordIndex].image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the pause-button is pressed on the video.
|
||||
/// It switches between playing and pausing the video.
|
||||
/// It then makes the button invisible when the video is playing, or visible when it's paused.
|
||||
/// </summary>
|
||||
public void Pause()
|
||||
{
|
||||
if (!player.isPlaying)
|
||||
{
|
||||
// Play video and hide button
|
||||
player.Play();
|
||||
Color col = button.image.color;
|
||||
col.a = 0;
|
||||
button.image.color = col;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pause video and show button
|
||||
player.Pause();
|
||||
Color col = button.image.color;
|
||||
col.a = 255;
|
||||
button.image.color = col;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the next-sign button is pressed.
|
||||
/// It increased the wordindex and fetches new videos/images if index<max, because then the coure is not fincished yet.
|
||||
/// If the maximum is reached, finishcourse is called to save the "finished" progress to the user.
|
||||
/// </summary>
|
||||
public void NextSign()
|
||||
{
|
||||
// If the currentindex >= maxwords, it indicated that the course is already finished, running the next code is the meaningless.
|
||||
if (currentWordIndex >= maxWords) { return; }
|
||||
|
||||
// Goto the next word/letter
|
||||
currentWordIndex++;
|
||||
|
||||
// TODO: fix correct word count
|
||||
correctWords++;
|
||||
progress.AddOrUpdate<float>("courseProgress", (float)correctWords / (float)maxWords);
|
||||
userList.Save();
|
||||
|
||||
// Update UI if course is not finished yet
|
||||
if (currentWordIndex < maxWords)
|
||||
{
|
||||
NextVideo();
|
||||
NextImage();
|
||||
}
|
||||
// Finish course and record progress
|
||||
else
|
||||
{
|
||||
FinishCourse();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// finishcourse is called to save the "finished" progress to the user.
|
||||
/// </summary>
|
||||
public void FinishCourse()
|
||||
{
|
||||
// Show the "finished" screen
|
||||
ResultPanel.SetActive(true);
|
||||
|
||||
// Set the correct title
|
||||
ResultsTitle.text = course.title + " voltooid!";
|
||||
|
||||
// Set the correct description
|
||||
ResultsDecription.text = "Goed gedaan! Je kan nu spelletjes spelen met " + course.title + " om verder te oefenen!";
|
||||
|
||||
// Set the total time spent UI
|
||||
TimeSpan time = DateTime.Now - startMoment;
|
||||
timeSpent.text = time.ToString(@"hh\:mm\:ss");
|
||||
|
||||
// Link button
|
||||
CoursesButton.onClick.AddListener(() => { SystemController.GetInstance().BackToPreviousScene(); });
|
||||
|
||||
progress.AddOrUpdate<float>("courseProgress", 1f);
|
||||
userList.Save();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user