Compare commits
14 Commits
WES-131-Re
...
v0.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e63e28173 | ||
|
|
c6faf3bf6f | ||
|
|
17da4e8558 | ||
|
|
cdb600344f | ||
|
|
d94457e246 | ||
|
|
6f72e29564 | ||
|
|
69da4d3def | ||
|
|
be0acbe025 | ||
|
|
b5568a908a | ||
|
|
22e6cb27f8 | ||
|
|
88dc81eb22 | ||
|
|
ee81efc8d9 | ||
|
|
be92ef06f4 | ||
|
|
8a0f506584 |
41
.gitlab/merge_request_templates/Default.md
Normal file
41
.gitlab/merge_request_templates/Default.md
Normal file
@@ -0,0 +1,41 @@
|
||||
## Description
|
||||
|
||||
_Please provide a brief summary of the changes in this merge request._
|
||||
|
||||
_If possible, add a short screengrab or some screenshots of the changes._
|
||||
|
||||
## Testing Instructions
|
||||
|
||||
_Please provide instructions on how the code reviewers can test your changes:_
|
||||
|
||||
1. [Step 1]
|
||||
2. [Step 2]
|
||||
3. [Step 3]
|
||||
4. ...
|
||||
|
||||
_Please include any specific information on test data, configurations, or other requirements that are necessary to properly test the changes._
|
||||
|
||||
Once you've tested the changes, please confirm that they work as expected and that there are no regressions or unexpected side effects. If any issues are discovered during testing, please include detailed steps to reproduce the issue in the merge request comments. Thank you!
|
||||
|
||||
## Related Issues
|
||||
|
||||
_Please list any related issues or pull requests that are relevant to this merge request._
|
||||
_E.g. WES-XXX-..._
|
||||
|
||||
## Known bugs or issues
|
||||
|
||||
_Please list any known bugs or issues related to the changes in this merge request._
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] I have filled in this template.
|
||||
- [ ] I have tested my changes thoroughly (both in the editor + **build and run (ctrl+B)**!).
|
||||
- [ ] I have added appropriate unit tests.
|
||||
- [ ] I have updated the user documentation as necessary.
|
||||
- [ ] Code reviewed by 2 people.
|
||||
|
||||
## Additional Notes
|
||||
|
||||
_Please add any additional notes or comments that may be helpful for reviewers to understand your changes._
|
||||
|
||||
/assign_reviewer @wesign/unityappreviewers
|
||||
@@ -1,11 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
/// <summary>
|
||||
/// This enum is used to identify each of the SignLanguage models
|
||||
/// </summary>
|
||||
public enum ModelIndex
|
||||
{
|
||||
FINGERSPELLING,
|
||||
NONE
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6dbd5e1100bc81648b52206df369d0a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,57 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Unity.Barracuda;
|
||||
/// <summary>
|
||||
/// This scriptable will hold tupples of Courseindices and models
|
||||
/// </summary>
|
||||
[CreateAssetMenu(menuName = "Create new Scriptable/ModelList")]
|
||||
public class ModelList : ScriptableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Small class to link a model to a courseIndex irrespective of its position in a list
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ModelTuple
|
||||
{
|
||||
/// <summary>
|
||||
/// ModelIndex to which the model corresponds
|
||||
/// </summary>
|
||||
public ModelIndex index;
|
||||
/// <summary>
|
||||
/// The model itself
|
||||
/// </summary>
|
||||
public NNModel model;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Index of the currently active model
|
||||
/// </summary>
|
||||
public int currentModelIndex = 0;
|
||||
|
||||
/// <summary>
|
||||
/// A list of all the models
|
||||
/// </summary>
|
||||
public List<ModelTuple> models = new List<ModelTuple>();
|
||||
|
||||
/// <summary>
|
||||
/// Get a model by modelindex
|
||||
/// </summary>
|
||||
/// <param name="modelIndex">ModelIndex of the model</param>
|
||||
/// <returns>Model associated with this index, null if no model was found</returns>
|
||||
public NNModel GetCurrentModel()
|
||||
{
|
||||
return models.Find(x => x.model == models[currentModelIndex].model)?.model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function to find a model-index in the list based on its index
|
||||
/// </summary>
|
||||
/// <param name="title"></param>
|
||||
public void SetCurrentModel(ModelIndex index)
|
||||
{
|
||||
currentModelIndex = models.FindIndex((m) => m.index == index);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78a3f61c93a08c04496c49ffd10b9021
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Unity.Barracuda;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
@@ -23,9 +24,9 @@ public class Theme : ScriptableObject
|
||||
public ThemeIndex index;
|
||||
|
||||
/// <summary>
|
||||
/// The index of the model you want to use
|
||||
/// Reference to the model used in the SignPredictor
|
||||
/// </summary>
|
||||
public ModelIndex modelIndex;
|
||||
public NNModel model;
|
||||
|
||||
/// <summary>
|
||||
/// List of all learnable words/letters
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
"CommonScripts",
|
||||
"InterfacesScripts",
|
||||
"Unity.TextMeshPro",
|
||||
"AccountsScripts",
|
||||
"SignPredictor"
|
||||
"AccountsScripts"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -16,7 +16,6 @@ MonoBehaviour:
|
||||
description: Van vis tot leeuw
|
||||
index: 2
|
||||
model: {fileID: 0}
|
||||
modelIndex: 1
|
||||
learnables:
|
||||
- name: Walvis
|
||||
image: {fileID: 21300000, guid: 2b01165a5836ab14593d7a5862bd6793, type: 3}
|
||||
|
||||
@@ -15,8 +15,6 @@ MonoBehaviour:
|
||||
title: Kleren en Kleuren
|
||||
description: Van rok tot sok
|
||||
index: 1
|
||||
model: {fileID: 0}
|
||||
modelIndex: 1
|
||||
learnables:
|
||||
- name: Blauw
|
||||
image: {fileID: 21300000, guid: 182fb89eba9c64041bef31ca35c4bcd8, type: 3}
|
||||
|
||||
@@ -15,8 +15,6 @@ MonoBehaviour:
|
||||
title: Familie
|
||||
description: Van generatie tot generatie
|
||||
index: 6
|
||||
model: {fileID: 0}
|
||||
modelIndex: 1
|
||||
learnables:
|
||||
- name: Broer
|
||||
image: {fileID: 21300000, guid: eecf67266f150f1489717049489cf16d, type: 3}
|
||||
|
||||
@@ -16,7 +16,6 @@ MonoBehaviour:
|
||||
description: Van kers tot pompoen
|
||||
index: 3
|
||||
model: {fileID: 0}
|
||||
modelIndex: 1
|
||||
learnables:
|
||||
- name: Aardappel
|
||||
image: {fileID: 21300000, guid: 2610cdbc24a125f43ada7fed67d8f51b, type: 3}
|
||||
|
||||
@@ -15,8 +15,6 @@ MonoBehaviour:
|
||||
title: Hobbies
|
||||
description: Van schilderen tot reizen
|
||||
index: 4
|
||||
model: {fileID: 0}
|
||||
modelIndex: 1
|
||||
learnables:
|
||||
- name: Dansen
|
||||
image: {fileID: 21300000, guid: 6d405f607ae817744b49f921f0611088, type: 3}
|
||||
|
||||
@@ -15,8 +15,6 @@ MonoBehaviour:
|
||||
title: Huis beschrijven
|
||||
description: Van zetel tot villa
|
||||
index: 5
|
||||
model: {fileID: 0}
|
||||
modelIndex: 1
|
||||
learnables:
|
||||
- name: Keuken
|
||||
image: {fileID: 21300000, guid: b17ce5bf59092b847b084d3400e7a1b4, type: 3}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||
"GUID:63c63e721f65ebb7d871cb9ef49f4752",
|
||||
"GUID:1631ed2680c61245b8211d943c1639a8",
|
||||
"GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25",
|
||||
"GUID:d0b6b39a21908f94fbbd9f2c196a9725"
|
||||
"GUID:5c2b5ba89f9e74e418232e154bc5cc7a",
|
||||
"GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -56,8 +56,8 @@ public class CourseActivityScreen : MonoBehaviour
|
||||
Course course = courseList.courses[index];
|
||||
|
||||
// vvv TEMPORARY STUFF vvv
|
||||
playButton.SetActive(course.theme.modelIndex != ModelIndex.NONE);
|
||||
previewButton.SetActive(course.theme.modelIndex == ModelIndex.NONE);
|
||||
playButton.SetActive(course.theme.model != null);
|
||||
previewButton.SetActive(course.theme.model == null);
|
||||
// ^^^ TEMPORARY STUFF ^^^
|
||||
|
||||
title.text = course.title;
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
"UnityEngine.TestRunner",
|
||||
"UnityEditor.TestRunner",
|
||||
"CommonScripts",
|
||||
"InterfacesScripts",
|
||||
"Unity.Barracuda",
|
||||
"SignPredictor"
|
||||
"InterfacesScripts"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
using NUnit.Framework;
|
||||
using Unity.Barracuda;
|
||||
using UnityEngine;
|
||||
/// <summary>
|
||||
/// Test the ModelList class
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class ModelListTest
|
||||
{
|
||||
private ModelList modelList;
|
||||
|
||||
/// <summary>
|
||||
/// Setup a ModelList with all possible Models in the enum
|
||||
/// </summary>
|
||||
[SetUp]
|
||||
public void Setup_Model()
|
||||
{
|
||||
modelList = ScriptableObject.CreateInstance<ModelList>();
|
||||
|
||||
// Add a Model for each index in the enum
|
||||
|
||||
// Dumb way to access each index in the enum, couldn't find a different way to do it though
|
||||
foreach (var field in typeof(ModelIndex).GetFields())
|
||||
{
|
||||
if (field.IsLiteral)
|
||||
{
|
||||
ModelIndex value = (ModelIndex)field.GetValue(null);
|
||||
string name = field.Name;
|
||||
ModelList.ModelTuple model = new ModelList.ModelTuple();
|
||||
// This is all we will need to distinguish
|
||||
model.index = value;
|
||||
|
||||
// Insert in front to guarantee that ModelIndex will not line up with listIndex
|
||||
modelList.models.Insert(0, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Check if current model can be correctly gotten as current via GetCurrentModel
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestGetCurrentModel()
|
||||
{
|
||||
System.Random random = new System.Random();
|
||||
ModelIndex value = (ModelIndex)random.Next(modelList.models.Count);
|
||||
modelList.SetCurrentModel(value);
|
||||
|
||||
Assert.AreEqual(modelList.models[modelList.currentModelIndex].model, modelList.GetCurrentModel());
|
||||
|
||||
// Check if empty model fails gracefully (returns null)
|
||||
Assert.IsNull(ScriptableObject.CreateInstance<ModelList>().GetCurrentModel());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if all models can be correctly set as current via SetCurrentModel
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSetCurrentModel()
|
||||
{
|
||||
foreach (var field in typeof(ModelIndex).GetFields())
|
||||
{
|
||||
if (field.IsLiteral)
|
||||
{
|
||||
ModelIndex value = (ModelIndex)field.GetValue(null);
|
||||
string name = field.Name;
|
||||
modelList.SetCurrentModel(value);
|
||||
|
||||
// Fetch the current model and check if its name is the same as the one we made into the current one
|
||||
ModelList.ModelTuple m = modelList.models[modelList.currentModelIndex];
|
||||
|
||||
Assert.AreEqual(m.index, value);
|
||||
Assert.IsTrue(m.model is NNModel || m.model is null);
|
||||
}
|
||||
}
|
||||
ModelList emptyList = ScriptableObject.CreateInstance<ModelList>();
|
||||
emptyList.SetCurrentModel(ModelIndex.FINGERSPELLING);
|
||||
|
||||
Assert.IsTrue(emptyList.currentModelIndex == -1);
|
||||
}
|
||||
}
|
||||
@@ -490,10 +490,6 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 6b3f784c065813a4a8364b1299284816, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
feedbackText: {fileID: 4318122121437849762}
|
||||
feedbackProgress: {fileID: 4318122121437849761}
|
||||
feedbackProgressImage: {fileID: 4318122121437849760}
|
||||
signPredictor: {fileID: 883853268}
|
||||
previewModel: {fileID: 5022602860645237092, guid: e6d85df707405ad4f97c23b07227ee99, type: 3}
|
||||
feedbackProgressBar: {fileID: 4318122121437849759}
|
||||
previewMessage: {fileID: 2070775951}
|
||||
@@ -509,6 +505,7 @@ MonoBehaviour:
|
||||
ResultsDecription: {fileID: 100123246}
|
||||
CoursesButton: {fileID: 839294691}
|
||||
timeSpent: {fileID: 77614869}
|
||||
feedback: {fileID: 1714882683}
|
||||
--- !u!1 &361280475
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1225,8 +1222,8 @@ MonoBehaviour:
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 1335886461}
|
||||
m_TargetAssemblyTypeName: BackButton, CommonScripts
|
||||
- m_Target: {fileID: 301088551}
|
||||
m_TargetAssemblyTypeName: TemplateCourse, Assembly-CSharp
|
||||
m_MethodName: Back
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
@@ -1304,7 +1301,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 043ccd99cf82b3cc9bf2e00956ce2b93, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
modelList: {fileID: 11400000, guid: 39516e4e6e56f0f4f80647d9c4d8034c, type: 2}
|
||||
model: {fileID: 5022602860645237092, guid: e6d85df707405ad4f97c23b07227ee99, type: 3}
|
||||
modelInfoFile: {fileID: 4900000, guid: fb8b51022bdcd654a9f29c054832a1b5, type: 3}
|
||||
configAsset: {fileID: 4900000, guid: 6288c43cdca97374782dac1ea87aa029, type: 3}
|
||||
screen: {fileID: 378145456}
|
||||
@@ -1842,17 +1839,6 @@ RectTransform:
|
||||
m_CorrespondingSourceObject: {fileID: 8299246693487308515, guid: 3bccdf365a4fbea4d8fa1aa461d3dc5c, type: 3}
|
||||
m_PrefabInstance: {fileID: 1335886459}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &1335886461 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4518652150503380115, guid: 3bccdf365a4fbea4d8fa1aa461d3dc5c, type: 3}
|
||||
m_PrefabInstance: {fileID: 1335886459}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c3dd279b546423e4a8a1b28819a6c4a1, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &1383144366
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -2266,6 +2252,17 @@ RectTransform:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122119930585316, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 4318122121437849758}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &1714882683 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122119930585317, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 4318122121437849758}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4318122121437849759}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 44e682a32ee15cc489bf50f3a06f717b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &1773033262
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -2841,10 +2838,6 @@ PrefabInstance:
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4318122119930585317, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
propertyPath: m_Enabled
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4318122119930585317, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
propertyPath: signPredictor
|
||||
value:
|
||||
@@ -2872,36 +2865,3 @@ GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122119930585319, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 4318122121437849758}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &4318122121437849760 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122120334233319, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 4318122121437849758}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &4318122121437849761 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122119968934242, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 4318122121437849758}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &4318122121437849762 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122120222767928, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 4318122121437849758}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
"AccountsScripts",
|
||||
"InterfacesScripts",
|
||||
"SignPredictor",
|
||||
"Unity.Barracuda",
|
||||
"Tween",
|
||||
"SignPredictorInterfaces"
|
||||
"Unity.Barracuda"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using Unity.Barracuda;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Video;
|
||||
using DigitalRuby.Tween;
|
||||
|
||||
/// <summary>
|
||||
/// TemplateCourse scene manager
|
||||
/// </summary>
|
||||
public class TemplateCourse : AbstractFeedback
|
||||
public class TemplateCourse : MonoBehaviour
|
||||
{
|
||||
// vvv TEMPORARY STUFF vvv
|
||||
public NNModel previewModel;
|
||||
@@ -114,37 +112,10 @@ public class TemplateCourse : AbstractFeedback
|
||||
/// </summary>
|
||||
public TMP_Text timeSpent;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the feedback field
|
||||
/// Reference to the feedback script on the Feedback prefab
|
||||
/// </summary>
|
||||
public TMP_Text feedbackText;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress bar
|
||||
/// </summary>
|
||||
public Slider feedbackProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress bar image, so we can add fancy colors
|
||||
/// </summary>
|
||||
public Image feedbackProgressImage;
|
||||
|
||||
/// <summary>
|
||||
/// Timer to keep track of how long a incorrect sign is performed
|
||||
/// </summary>
|
||||
protected DateTime timer;
|
||||
|
||||
/// <summary>
|
||||
/// Current predicted sign
|
||||
/// </summary>
|
||||
protected string predictedSign = null;
|
||||
|
||||
/// <summary>
|
||||
/// Previous incorrect sign, so we can keep track whether the user is wrong or the user is still changing signs
|
||||
/// </summary>
|
||||
protected string previousIncorrectSign = null;
|
||||
|
||||
public Feedback feedback;
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the script is initialised.
|
||||
@@ -153,23 +124,17 @@ public class TemplateCourse : AbstractFeedback
|
||||
/// 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 Start()
|
||||
{
|
||||
StartGameController();
|
||||
|
||||
signPredictor.SetModel(course.theme.modelIndex);
|
||||
AddSelfAsListener();
|
||||
}
|
||||
|
||||
public void StartGameController()
|
||||
void Awake()
|
||||
{
|
||||
// Setting up course
|
||||
course = courselist.courses[courselist.currentCourseIndex];
|
||||
feedback.signPredictor.model = course.theme.model;
|
||||
maxWords = course.theme.learnables.Count;
|
||||
|
||||
// vvv TEMPORARY STUFF vvv
|
||||
feedbackProgressBar.SetActive(course.theme.modelIndex != ModelIndex.NONE);
|
||||
previewMessage.SetActive(course.theme.modelIndex == ModelIndex.NONE);
|
||||
feedbackProgressBar.SetActive(course.theme.model != null);
|
||||
previewMessage.SetActive(course.theme.model == null);
|
||||
feedback.signPredictor.model = previewModel;
|
||||
// ^^^ TEMPORARY STUFF ^^^
|
||||
|
||||
// Create entry in current user for keeping track of progress
|
||||
@@ -198,6 +163,23 @@ public class TemplateCourse : AbstractFeedback
|
||||
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>
|
||||
@@ -304,98 +286,4 @@ public class TemplateCourse : AbstractFeedback
|
||||
progress.AddOrUpdate<float>("courseProgress", 1f);
|
||||
userList.Save();
|
||||
}
|
||||
|
||||
protected override IEnumerator UpdateFeedback()
|
||||
{
|
||||
// Get current sign
|
||||
string currentSign = course.theme.learnables[currentWordIndex].name;
|
||||
// Get the predicted sign
|
||||
if (signPredictor != null && signPredictor.learnableProbabilities != null &&
|
||||
currentSign != null && signPredictor.learnableProbabilities.ContainsKey(currentSign))
|
||||
{
|
||||
float accuracy = signPredictor.learnableProbabilities[currentSign];
|
||||
if (feedbackText != null && feedbackProgressImage != null)
|
||||
{
|
||||
if (accuracy > 0.90)
|
||||
{
|
||||
feedbackText.text = "Goed";
|
||||
feedbackText.color = Color.green;
|
||||
feedbackProgressImage.color = Color.green;
|
||||
}
|
||||
else if (accuracy > 0.80)
|
||||
{
|
||||
feedbackText.text = "Bijna...";
|
||||
Color col = new Color(0xff / 255.0f, 0x66 / 255.0f, 0x00 / 255.0f);
|
||||
feedbackText.color = col;
|
||||
feedbackProgressImage.color = col;
|
||||
}
|
||||
else
|
||||
{
|
||||
feedbackText.text = "Detecteren...";
|
||||
feedbackText.color = Color.red;
|
||||
feedbackProgressImage.color = Color.red;
|
||||
}
|
||||
|
||||
float oldValue = feedbackProgress.value;
|
||||
// use an exponential scale
|
||||
float newValue = Mathf.Exp(4 * (accuracy - 1.0f));
|
||||
feedbackProgress.gameObject.Tween("FeedbackUpdate", oldValue, newValue, 0.2f, TweenScaleFunctions.CubicEaseInOut, (t) =>
|
||||
{
|
||||
if (feedbackProgress != null)
|
||||
{
|
||||
feedbackProgress.value = t.CurrentValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check whether (in)correct sign has high accuracy
|
||||
foreach (var kv in signPredictor.learnableProbabilities)
|
||||
{
|
||||
if (kv.Value > 0.90)
|
||||
{
|
||||
predictedSign = kv.Key;
|
||||
// Correct sign
|
||||
if (predictedSign == currentSign)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
CheckEquality(predictedSign);
|
||||
timer = DateTime.Now;
|
||||
predictedSign = null;
|
||||
previousIncorrectSign = null;
|
||||
}
|
||||
// Incorrect sign
|
||||
else
|
||||
{
|
||||
if (previousIncorrectSign != predictedSign)
|
||||
{
|
||||
timer = DateTime.Now;
|
||||
previousIncorrectSign = predictedSign;
|
||||
}
|
||||
else if (DateTime.Now - timer > TimeSpan.FromSeconds(2.0f))
|
||||
{
|
||||
CheckEquality(predictedSign);
|
||||
timer = DateTime.Now;
|
||||
predictedSign = null;
|
||||
previousIncorrectSign = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (feedbackProgress != null)
|
||||
{
|
||||
|
||||
feedbackProgress.value = 0.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void CheckEquality(string predicted)
|
||||
{
|
||||
if(predicted == course.theme.learnables[currentWordIndex].name)
|
||||
{
|
||||
NextSign();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2570,7 +2570,7 @@ Transform:
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 5
|
||||
m_RootOrder: 4
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &896343212
|
||||
GameObject:
|
||||
@@ -3507,7 +3507,7 @@ RectTransform:
|
||||
- {fileID: 1892638588}
|
||||
- {fileID: 56162990}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 3
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@@ -3526,10 +3526,6 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 2db44635e0eb1e9429a2e6195785364d, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
feedbackText: {fileID: 5233312448025626833}
|
||||
feedbackProgress: {fileID: 5233312447201393291}
|
||||
feedbackProgressImage: {fileID: 5233312447919013134}
|
||||
signPredictor: {fileID: 1991376311}
|
||||
themelist: {fileID: 11400000, guid: a247e2ce790f0f746a3bc521e6ab7d58, type: 2}
|
||||
letterPrefab: {fileID: 4639383499500021565, guid: c3e66e8957864914cb022af914df6a28, type: 3}
|
||||
letterContainer: {fileID: 1870283439}
|
||||
@@ -3554,6 +3550,7 @@ MonoBehaviour:
|
||||
Scoreboard: {fileID: 1007532375}
|
||||
EntriesGrid: {fileID: 1391137944}
|
||||
scoreboardEntry: {fileID: 9154151134820372555, guid: d4a3a228b08d61847acc6da35b44e52c, type: 3}
|
||||
feedback: {fileID: 5233312447513285388}
|
||||
gottogamebutton: {fileID: 1581633295}
|
||||
--- !u!1001 &1290865991
|
||||
PrefabInstance:
|
||||
@@ -6248,7 +6245,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 043ccd99cf82b3cc9bf2e00956ce2b93, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
modelList: {fileID: 11400000, guid: 39516e4e6e56f0f4f80647d9c4d8034c, type: 2}
|
||||
model: {fileID: 5022602860645237092, guid: e6d85df707405ad4f97c23b07227ee99, type: 3}
|
||||
modelInfoFile: {fileID: 4900000, guid: fb8b51022bdcd654a9f29c054832a1b5, type: 3}
|
||||
configAsset: {fileID: 4900000, guid: 6288c43cdca97374782dac1ea87aa029, type: 3}
|
||||
screen: {fileID: 1649505745}
|
||||
@@ -6266,7 +6263,7 @@ Transform:
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 2
|
||||
m_RootOrder: 5
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &2001212056
|
||||
GameObject:
|
||||
@@ -6569,6 +6566,22 @@ GameObject:
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &5233312447513285388
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5233312447513285390}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 44e682a32ee15cc489bf50f3a06f717b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
feedbackText: {fileID: 0}
|
||||
feedbackProgress: {fileID: 0}
|
||||
feedbackProgressImage: {fileID: 0}
|
||||
signPredictor: {fileID: 1991376311}
|
||||
--- !u!224 &5233312447513285389
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -6584,7 +6597,7 @@ RectTransform:
|
||||
- {fileID: 5233312448025626847}
|
||||
- {fileID: 5233312447201393292}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 4
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0}
|
||||
m_AnchorMax: {x: 0.5, y: 0}
|
||||
@@ -6600,6 +6613,7 @@ GameObject:
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5233312447513285389}
|
||||
- component: {fileID: 5233312447513285388}
|
||||
m_Layer: 5
|
||||
m_Name: Feedback
|
||||
m_TagString: Untagged
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DigitalRuby.Tween;
|
||||
|
||||
public class HangmanGameController : AbstractFeedback
|
||||
public class HangmanGameController : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// The scriptable with all the themes, will be used to select a random word for hangman.
|
||||
@@ -202,6 +200,11 @@ public class HangmanGameController : AbstractFeedback
|
||||
/// </summary>
|
||||
public GameObject scoreboardEntry;
|
||||
|
||||
/// <summary>
|
||||
/// Accuracy feeback object
|
||||
/// </summary>
|
||||
public Feedback feedback;
|
||||
|
||||
/// <summary>
|
||||
/// The button to go into the game
|
||||
/// </summary>
|
||||
@@ -212,48 +215,8 @@ public class HangmanGameController : AbstractFeedback
|
||||
/// </summary>
|
||||
private String currentsign = "";
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the feedback field
|
||||
/// </summary>
|
||||
public TMP_Text feedbackText;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress bar
|
||||
/// </summary>
|
||||
public Slider feedbackProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress bar image, so we can add fancy colors
|
||||
/// </summary>
|
||||
public Image feedbackProgressImage;
|
||||
|
||||
/// <summary>
|
||||
/// Timer to keep track of how long a incorrect sign is performed
|
||||
/// </summary>
|
||||
protected DateTime timer;
|
||||
|
||||
/// <summary>
|
||||
/// Current predicted sign
|
||||
/// </summary>
|
||||
protected string predictedSign = null;
|
||||
|
||||
/// <summary>
|
||||
/// Previous incorrect sign, so we can keep track whether the user is wrong or the user is still changing signs
|
||||
/// </summary>
|
||||
protected string previousIncorrectSign = null;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
StartController();
|
||||
|
||||
signPredictor.SetModel(ModelIndex.FINGERSPELLING);
|
||||
AddSelfAsListener();
|
||||
}
|
||||
/// <summary>
|
||||
/// Called at the start of the scene AND when the scene is replayed
|
||||
/// </summary>
|
||||
public void StartController()
|
||||
{
|
||||
// Make sure the mode starts at zero
|
||||
mode = 0;
|
||||
@@ -277,6 +240,16 @@ public class HangmanGameController : AbstractFeedback
|
||||
user.minigames.Add(progress);
|
||||
}
|
||||
userList.Save();
|
||||
|
||||
// Set calllbacks
|
||||
feedback.getSignCallback = () =>
|
||||
{
|
||||
return "A";
|
||||
};
|
||||
feedback.predictSignCallback = (sign) =>
|
||||
{
|
||||
currentsign = sign;
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -305,7 +278,7 @@ public class HangmanGameController : AbstractFeedback
|
||||
DeleteWord();
|
||||
DisplayWord(currentWord);
|
||||
|
||||
replayButton.onClick.AddListener(StartController);
|
||||
replayButton.onClick.AddListener(Start);
|
||||
// Call to display the first image, corresponding to a clean image.
|
||||
ChangeSprite();
|
||||
}
|
||||
@@ -376,7 +349,7 @@ public class HangmanGameController : AbstractFeedback
|
||||
{
|
||||
if (mode == 1)
|
||||
{
|
||||
if (currentsign != "" && currentsign != null)
|
||||
if (currentsign != "")
|
||||
{
|
||||
char letter = currentsign.ToLower()[0];
|
||||
currentsign = "";
|
||||
@@ -417,7 +390,7 @@ public class HangmanGameController : AbstractFeedback
|
||||
// For the first input char given by the user, check if the letter is in the word that needs to be spelled.
|
||||
|
||||
// Check to make sure the inputfield is not empty
|
||||
if (currentsign != null && currentsign != "")
|
||||
if (currentsign != "")
|
||||
{
|
||||
char firstLetter = currentsign.ToLower()[0];
|
||||
currentsign = "";
|
||||
@@ -567,6 +540,21 @@ public class HangmanGameController : AbstractFeedback
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Randomly shuffle the list of words
|
||||
/// </summary>
|
||||
private void ShuffleWords()
|
||||
{
|
||||
for (int i = words.Length - 1; i > 0; i--)
|
||||
{
|
||||
// Generate a random index between 0 and i (inclusive)
|
||||
int j = UnityEngine.Random.Range(0, i + 1);
|
||||
|
||||
// Swap the values at indices i and j
|
||||
(words[j], words[i]) = (words[i], words[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update and save the scores
|
||||
/// </summary>
|
||||
@@ -740,94 +728,4 @@ public class HangmanGameController : AbstractFeedback
|
||||
rank++;
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerator UpdateFeedback()
|
||||
{
|
||||
// Get current sign
|
||||
string currentSign = "A";
|
||||
// Get the predicted sign
|
||||
if (signPredictor != null && signPredictor.learnableProbabilities != null &&
|
||||
currentSign != null && signPredictor.learnableProbabilities.ContainsKey(currentSign))
|
||||
{
|
||||
float accuracy = signPredictor.learnableProbabilities[currentSign];
|
||||
if (feedbackText != null && feedbackProgressImage != null)
|
||||
{
|
||||
if (accuracy > 0.90)
|
||||
{
|
||||
feedbackText.text = "Goed";
|
||||
feedbackText.color = Color.green;
|
||||
feedbackProgressImage.color = Color.green;
|
||||
}
|
||||
else if (accuracy > 0.80)
|
||||
{
|
||||
feedbackText.text = "Bijna...";
|
||||
Color col = new Color(0xff / 255.0f, 0x66 / 255.0f, 0x00 / 255.0f);
|
||||
feedbackText.color = col;
|
||||
feedbackProgressImage.color = col;
|
||||
}
|
||||
else
|
||||
{
|
||||
feedbackText.text = "Detecteren...";
|
||||
feedbackText.color = Color.red;
|
||||
feedbackProgressImage.color = Color.red;
|
||||
}
|
||||
|
||||
float oldValue = feedbackProgress.value;
|
||||
// use an exponential scale
|
||||
float newValue = Mathf.Exp(4 * (accuracy - 1.0f));
|
||||
feedbackProgress.gameObject.Tween("FeedbackUpdate", oldValue, newValue, 0.2f, TweenScaleFunctions.CubicEaseInOut, (t) =>
|
||||
{
|
||||
if (feedbackProgress != null)
|
||||
{
|
||||
feedbackProgress.value = t.CurrentValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check whether (in)correct sign has high accuracy
|
||||
foreach (var kv in signPredictor.learnableProbabilities)
|
||||
{
|
||||
if (kv.Value > 0.90)
|
||||
{
|
||||
predictedSign = kv.Key;
|
||||
// Correct sign
|
||||
if (predictedSign == currentSign)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
CheckEquality(predictedSign);
|
||||
timer = DateTime.Now;
|
||||
predictedSign = null;
|
||||
previousIncorrectSign = null;
|
||||
}
|
||||
// Incorrect sign
|
||||
else
|
||||
{
|
||||
if (previousIncorrectSign != predictedSign)
|
||||
{
|
||||
timer = DateTime.Now;
|
||||
previousIncorrectSign = predictedSign;
|
||||
}
|
||||
else if (DateTime.Now - timer > TimeSpan.FromSeconds(2.0f))
|
||||
{
|
||||
CheckEquality(predictedSign);
|
||||
timer = DateTime.Now;
|
||||
predictedSign = null;
|
||||
previousIncorrectSign = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (feedbackProgress != null)
|
||||
{
|
||||
|
||||
feedbackProgress.value = 0.0f;
|
||||
}
|
||||
|
||||
}
|
||||
private void CheckEquality(string sign)
|
||||
{
|
||||
currentsign = sign;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73c615986873dc246893879daf74c05d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public interface Listener
|
||||
{
|
||||
public IEnumerator ProcessIncomingCall();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4c1da9896d9ba2449549a016b5fd15e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "SignPredictorInterfaces",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f55a02e98b01bc849b30d9650ccd8f15
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -9,6 +9,7 @@ GameObject:
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4318122119930585316}
|
||||
- component: {fileID: 4318122119930585317}
|
||||
m_Layer: 5
|
||||
m_Name: Feedback
|
||||
m_TagString: Untagged
|
||||
@@ -38,6 +39,22 @@ RectTransform:
|
||||
m_AnchoredPosition: {x: 0, y: 200}
|
||||
m_SizeDelta: {x: 500, y: 150}
|
||||
m_Pivot: {x: 0.5, y: 0}
|
||||
--- !u!114 &4318122119930585317
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4318122119930585319}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 44e682a32ee15cc489bf50f3a06f717b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
feedbackText: {fileID: 4318122120222767928}
|
||||
feedbackProgress: {fileID: 4318122119968934242}
|
||||
feedbackProgressImage: {fileID: 4318122120334233319}
|
||||
signPredictor: {fileID: 0}
|
||||
--- !u!1 &4318122119968934244
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 438a3ced42dd6fc4ab38e3a16c1e43a7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,20 +0,0 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 78a3f61c93a08c04496c49ffd10b9021, type: 3}
|
||||
m_Name: ModelList
|
||||
m_EditorClassIdentifier:
|
||||
currentModelIndex: 0
|
||||
models:
|
||||
- index: 0
|
||||
model: {fileID: 5022602860645237092, guid: e6d85df707405ad4f97c23b07227ee99, type: 3}
|
||||
- index: 1
|
||||
model: {fileID: 5022602860645237092, guid: e6d85df707405ad4f97c23b07227ee99, type: 3}
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39516e4e6e56f0f4f80647d9c4d8034c
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,32 +0,0 @@
|
||||
using DigitalRuby.Tween;
|
||||
using Mediapipe.Unity.Tutorial;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Class to display feedback during a course
|
||||
/// </summary>
|
||||
public abstract class AbstractFeedback : MonoBehaviour, Listener
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the sign predictor
|
||||
/// </summary>
|
||||
public SignPredictor signPredictor;
|
||||
|
||||
public IEnumerator ProcessIncomingCall()
|
||||
{
|
||||
yield return StartCoroutine(UpdateFeedback());
|
||||
}
|
||||
|
||||
public void AddSelfAsListener()
|
||||
{
|
||||
signPredictor.listeners.Add(this);
|
||||
}
|
||||
|
||||
protected abstract IEnumerator UpdateFeedback();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b5ac794337a54143a6e3077483d96c9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
182
Assets/MediaPipeUnity/Scripts/Feedback.cs
Normal file
182
Assets/MediaPipeUnity/Scripts/Feedback.cs
Normal file
@@ -0,0 +1,182 @@
|
||||
using DigitalRuby.Tween;
|
||||
using Mediapipe.Unity.Tutorial;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Class to display feedback during a course
|
||||
/// </summary>
|
||||
public class Feedback : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference to the feedback field
|
||||
/// </summary>
|
||||
public TMP_Text feedbackText;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress bar
|
||||
/// </summary>
|
||||
public Slider feedbackProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress bar image, so we can add fancy colors
|
||||
/// </summary>
|
||||
public Image feedbackProgressImage;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the sign predictor
|
||||
/// </summary>
|
||||
public SignPredictor signPredictor;
|
||||
|
||||
/// <summary>
|
||||
/// Callback for getting the correct sign
|
||||
/// </summary>
|
||||
public Func<string> getSignCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Callback to initiate the next sign
|
||||
/// </summary>
|
||||
public UnityAction<string> predictSignCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Timer to keep track of how long a incorrect sign is performed
|
||||
/// </summary>
|
||||
private DateTime timer;
|
||||
|
||||
/// <summary>
|
||||
/// Current predicted sign
|
||||
/// </summary>
|
||||
private string predictedSign = null;
|
||||
|
||||
/// <summary>
|
||||
/// Previous incorrect sign, so we can keep track whether the user is wrong or the user is still changing signs
|
||||
/// </summary>
|
||||
private string previousIncorrectSign = null;
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
// Start the coroutine to update the scale every 200 milliseconds
|
||||
StartCoroutine(UpdateFeedback());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UpdateScale updates the progress bar every 200ms, updated the feedback text, and progress bar color
|
||||
/// If a high enough accuracy is detected, it will go to the next sign
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerator UpdateFeedback()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (getSignCallback != null && predictSignCallback != null)
|
||||
{
|
||||
|
||||
// Get current sign
|
||||
string currentSign = getSignCallback();
|
||||
// Get the predicted sign
|
||||
if (signPredictor != null && signPredictor.learnableProbabilities != null &&
|
||||
currentSign != null && signPredictor.learnableProbabilities.ContainsKey(currentSign))
|
||||
{
|
||||
float accuracy = signPredictor.learnableProbabilities[currentSign];
|
||||
if (feedbackText != null && feedbackProgressImage != null){
|
||||
if (accuracy > 0.98)
|
||||
{
|
||||
// TODO: fix emojis
|
||||
feedbackText.text = "✨ Perfect ✨";
|
||||
Color col = new Color(0xff / 255.0f, 0xcc / 255.0f, 0x00 / 255.0f);
|
||||
feedbackText.color = col;
|
||||
feedbackProgressImage.color = col;
|
||||
}
|
||||
else if (accuracy > 0.95)
|
||||
{
|
||||
feedbackText.text = "Super!";
|
||||
Color col = new Color(0x00 / 255.0f, 0xff / 255.0f, 0xcc / 255.0f);
|
||||
feedbackText.color = col;
|
||||
feedbackProgressImage.color = col;
|
||||
}
|
||||
else if (accuracy > 0.90)
|
||||
{
|
||||
feedbackText.text = "Goed";
|
||||
feedbackText.color = Color.green;
|
||||
feedbackProgressImage.color = Color.green;
|
||||
}
|
||||
else if (accuracy > 0.80)
|
||||
{
|
||||
feedbackText.text = "Bijna...";
|
||||
Color col = new Color(0xff / 255.0f, 0x66 / 255.0f, 0x00 / 255.0f);
|
||||
feedbackText.color = col;
|
||||
feedbackProgressImage.color = col;
|
||||
}
|
||||
else
|
||||
{
|
||||
feedbackText.text = "Detecteren...";
|
||||
feedbackText.color = Color.red;
|
||||
feedbackProgressImage.color = Color.red;
|
||||
}
|
||||
|
||||
float oldValue = feedbackProgress.value;
|
||||
// use an exponential scale
|
||||
float newValue = Mathf.Exp(4 * (accuracy - 1.0f));
|
||||
feedbackProgress.gameObject.Tween("FeedbackUpdate", oldValue, newValue, 0.2f, TweenScaleFunctions.CubicEaseInOut, (t) =>
|
||||
{
|
||||
if (feedbackProgress != null)
|
||||
{
|
||||
feedbackProgress.value = t.CurrentValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check whether (in)correct sign has high accuracy
|
||||
foreach (var kv in signPredictor.learnableProbabilities)
|
||||
{
|
||||
if (kv.Value > 0.90)
|
||||
{
|
||||
predictedSign = kv.Key;
|
||||
// Correct sign
|
||||
if (predictedSign == currentSign)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
predictSignCallback(predictedSign);
|
||||
timer = DateTime.Now;
|
||||
predictedSign = null;
|
||||
previousIncorrectSign = null;
|
||||
}
|
||||
// Incorrect sign
|
||||
else
|
||||
{
|
||||
if (previousIncorrectSign != predictedSign)
|
||||
{
|
||||
timer = DateTime.Now;
|
||||
previousIncorrectSign = predictedSign;
|
||||
}
|
||||
else if (DateTime.Now - timer > TimeSpan.FromSeconds(2.0f))
|
||||
{
|
||||
predictSignCallback(predictedSign);
|
||||
timer = DateTime.Now;
|
||||
predictedSign = null;
|
||||
previousIncorrectSign = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(feedbackProgress != null)
|
||||
{
|
||||
|
||||
feedbackProgress.value = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for 200 milliseconds before updating the scale again
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1313e0cc80244354eb6e2d0c1e891941
|
||||
guid: 44e682a32ee15cc489bf50f3a06f717b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -6,9 +6,7 @@
|
||||
"GUID:5c2b5ba89f9e74e418232e154bc5cc7a",
|
||||
"GUID:04c4d86a70aa56c55a78c61f1ab1a56d",
|
||||
"GUID:edc93f477bb73a743a97d6882ed330b3",
|
||||
"GUID:58e104b97fb3752438ada2902a36dcbf",
|
||||
"GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25",
|
||||
"GUID:f55a02e98b01bc849b30d9650ccd8f15"
|
||||
"GUID:58e104b97fb3752438ada2902a36dcbf"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -19,9 +19,9 @@ namespace Mediapipe.Unity.Tutorial
|
||||
public class SignPredictor : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// ModelList, used to change model using ModelIndex
|
||||
/// Reference to the model used in the SignPredictor
|
||||
/// </summary>
|
||||
public ModelList modelList;
|
||||
public NNModel model;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the model info file
|
||||
@@ -141,8 +141,6 @@ namespace Mediapipe.Unity.Tutorial
|
||||
/// </summary>
|
||||
private Tensor inputTensor;
|
||||
|
||||
public List<Listener> listeners = new List<Listener>();
|
||||
|
||||
/// <summary>
|
||||
/// Google Mediapipe setup & run
|
||||
/// </summary>
|
||||
@@ -209,21 +207,14 @@ namespace Mediapipe.Unity.Tutorial
|
||||
|
||||
|
||||
keypointManager = new KeypointManager(modelInfoFile);
|
||||
|
||||
// check if model exists at path
|
||||
//var model = ModelLoader.Load(Resources.Load<NNModel>("Models/Fingerspelling/model_A-L"));
|
||||
worker = modelList.GetCurrentModel().CreateWorker();
|
||||
worker = model.CreateWorker();
|
||||
|
||||
StartCoroutine(SignRecognitionCoroutine());
|
||||
StartCoroutine(MediapipeCoroutine());
|
||||
}
|
||||
/// <summary>
|
||||
/// Called at the start of course/Minigame, will set the model before the start of SIgnPredictor is called.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the model to be used</param>
|
||||
public void SetModel(ModelIndex index)
|
||||
{
|
||||
this.modelList.SetCurrentModel(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Coroutine which executes the mediapipe pipeline
|
||||
@@ -324,10 +315,6 @@ namespace Mediapipe.Unity.Tutorial
|
||||
learnableProbabilities.Add(((char)(i + 65)).ToString(), softmaxedOutput2[i]);
|
||||
}
|
||||
//Debug.Log($"prob = [{learnableProbabilities.Aggregate(" ", (t, kv) => $"{t}{kv.Key}:{kv.Value} ")}]");
|
||||
foreach(Listener listener in listeners)
|
||||
{
|
||||
yield return listener.ProcessIncomingCall();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
"InterfacesScripts",
|
||||
"Unity.TextMeshPro",
|
||||
"SpellingBeeScripts",
|
||||
"AccountsScripts",
|
||||
"SignPredictor"
|
||||
"AccountsScripts"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -1720,10 +1720,6 @@ PrefabInstance:
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4318122119930585317, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
propertyPath: m_Enabled
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4318122119930585317, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
propertyPath: signPredictor
|
||||
value:
|
||||
@@ -1743,37 +1739,15 @@ RectTransform:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122119930585316, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 967164043}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &967164046 stripped
|
||||
--- !u!114 &967164045 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122120334233319, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_CorrespondingSourceObject: {fileID: 4318122119930585317, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 967164043}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &967164047 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122119968934242, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 967164043}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &967164048 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 4318122120222767928, guid: 7c71c65ecb5fe0449a8b0d178987f016, type: 3}
|
||||
m_PrefabInstance: {fileID: 967164043}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 44e682a32ee15cc489bf50f3a06f717b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &978093274
|
||||
@@ -3170,7 +3144,7 @@ MonoBehaviour:
|
||||
m_Calls:
|
||||
- m_Target: {fileID: 1768150807}
|
||||
m_TargetAssemblyTypeName: GameController, SpellingBeeScripts
|
||||
m_MethodName: StartController
|
||||
m_MethodName: Start
|
||||
m_Mode: 1
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
@@ -3926,7 +3900,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 043ccd99cf82b3cc9bf2e00956ce2b93, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
modelList: {fileID: 11400000, guid: 39516e4e6e56f0f4f80647d9c4d8034c, type: 2}
|
||||
model: {fileID: 5022602860645237092, guid: e6d85df707405ad4f97c23b07227ee99, type: 3}
|
||||
modelInfoFile: {fileID: 4900000, guid: fb8b51022bdcd654a9f29c054832a1b5, type: 3}
|
||||
configAsset: {fileID: 4900000, guid: 6288c43cdca97374782dac1ea87aa029, type: 3}
|
||||
screen: {fileID: 1743003084}
|
||||
@@ -4578,10 +4552,6 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 44fbed5ae228de39b9f727def7578d06, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
feedbackText: {fileID: 967164048}
|
||||
feedbackProgress: {fileID: 967164047}
|
||||
feedbackProgressImage: {fileID: 967164046}
|
||||
signPredictor: {fileID: 1592592444}
|
||||
themeList: {fileID: 11400000, guid: a247e2ce790f0f746a3bc521e6ab7d58, type: 2}
|
||||
userList: {fileID: 11400000, guid: 072bec636a40f7e4e93b0ac624a3bda2, type: 2}
|
||||
minigame: {fileID: 11400000, guid: 8a087d241d652634eb4f6352267ea7dc, type: 2}
|
||||
@@ -4592,6 +4562,7 @@ MonoBehaviour:
|
||||
timerText: {fileID: 1843239267}
|
||||
bonusTimeText: {fileID: 1812475780}
|
||||
Scoreboard: {fileID: 862382568}
|
||||
feedback: {fileID: 967164045}
|
||||
gameEndedPanel: {fileID: 757133117}
|
||||
--- !u!1 &1812475780
|
||||
GameObject:
|
||||
|
||||
@@ -5,9 +5,8 @@ using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DigitalRuby.Tween;
|
||||
|
||||
public partial class GameController : AbstractFeedback
|
||||
public partial class GameController : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// All of the words that can be used in this session
|
||||
@@ -137,53 +136,20 @@ public partial class GameController : AbstractFeedback
|
||||
/// </summary>
|
||||
public Transform Scoreboard;
|
||||
|
||||
/// <summary>
|
||||
/// Accuracy feeback object
|
||||
/// </summary>
|
||||
public Feedback feedback;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the gameEnded panel, so we can update its display
|
||||
/// </summary>
|
||||
public GameObject gameEndedPanel;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the feedback field
|
||||
/// </summary>
|
||||
public TMP_Text feedbackText;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress bar
|
||||
/// </summary>
|
||||
public Slider feedbackProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the progress bar image, so we can add fancy colors
|
||||
/// </summary>
|
||||
public Image feedbackProgressImage;
|
||||
|
||||
/// <summary>
|
||||
/// Timer to keep track of how long a incorrect sign is performed
|
||||
/// </summary>
|
||||
protected DateTime timer;
|
||||
|
||||
/// <summary>
|
||||
/// Current predicted sign
|
||||
/// </summary>
|
||||
protected string predictedSign = null;
|
||||
|
||||
/// <summary>
|
||||
/// Previous incorrect sign, so we can keep track whether the user is wrong or the user is still changing signs
|
||||
/// </summary>
|
||||
protected string previousIncorrectSign = null;
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
StartController();
|
||||
|
||||
signPredictor.SetModel(currentTheme.modelIndex);
|
||||
AddSelfAsListener();
|
||||
}
|
||||
|
||||
public void StartController()
|
||||
{
|
||||
correctLetters = 0;
|
||||
incorrectLetters = 0;
|
||||
@@ -216,10 +182,29 @@ public partial class GameController : AbstractFeedback
|
||||
userList.Save();
|
||||
|
||||
currentTheme = minigame.themeList.themes[minigame.themeList.currentThemeIndex];
|
||||
//feedback.signPredictor.ChangeModel(currentTheme.modelIndex);
|
||||
feedback.signPredictor.model = currentTheme.model;
|
||||
words.AddRange(currentTheme.learnables);
|
||||
ShuffleWords();
|
||||
NextWord();
|
||||
|
||||
// Set calllbacks
|
||||
feedback.getSignCallback = () =>
|
||||
{
|
||||
if (letterIndex < currentWord.Length)
|
||||
{
|
||||
return currentWord[letterIndex].ToString().ToUpper();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
feedback.predictSignCallback = (sign) =>
|
||||
{
|
||||
bool successful = sign.ToUpper() == currentWord[letterIndex].ToString().ToUpper();
|
||||
if (successful)
|
||||
{
|
||||
AddSeconds(secondsPerLetter);
|
||||
}
|
||||
NextLetter(successful);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -468,106 +453,4 @@ public partial class GameController : AbstractFeedback
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(2);
|
||||
}
|
||||
|
||||
protected override IEnumerator UpdateFeedback()
|
||||
{
|
||||
// Get current sign
|
||||
string currentSign = GetSign();
|
||||
// Get the predicted sign
|
||||
if (signPredictor != null && signPredictor.learnableProbabilities != null &&
|
||||
currentSign != null && signPredictor.learnableProbabilities.ContainsKey(currentSign))
|
||||
{
|
||||
float accuracy = signPredictor.learnableProbabilities[currentSign];
|
||||
if (feedbackText != null && feedbackProgressImage != null)
|
||||
{
|
||||
if (accuracy > 0.90)
|
||||
{
|
||||
feedbackText.text = "Goed";
|
||||
feedbackText.color = Color.green;
|
||||
feedbackProgressImage.color = Color.green;
|
||||
}
|
||||
else if (accuracy > 0.80)
|
||||
{
|
||||
feedbackText.text = "Bijna...";
|
||||
Color col = new Color(0xff / 255.0f, 0x66 / 255.0f, 0x00 / 255.0f);
|
||||
feedbackText.color = col;
|
||||
feedbackProgressImage.color = col;
|
||||
}
|
||||
else
|
||||
{
|
||||
feedbackText.text = "Detecteren...";
|
||||
feedbackText.color = Color.red;
|
||||
feedbackProgressImage.color = Color.red;
|
||||
}
|
||||
|
||||
float oldValue = feedbackProgress.value;
|
||||
// use an exponential scale
|
||||
float newValue = Mathf.Exp(4 * (accuracy - 1.0f));
|
||||
feedbackProgress.gameObject.Tween("FeedbackUpdate", oldValue, newValue, 0.2f, TweenScaleFunctions.CubicEaseInOut, (t) =>
|
||||
{
|
||||
if (feedbackProgress != null)
|
||||
{
|
||||
feedbackProgress.value = t.CurrentValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check whether (in)correct sign has high accuracy
|
||||
foreach (var kv in signPredictor.learnableProbabilities)
|
||||
{
|
||||
if (kv.Value > 0.90)
|
||||
{
|
||||
predictedSign = kv.Key;
|
||||
// Correct sign
|
||||
if (predictedSign == currentSign)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
predictSign(predictedSign);
|
||||
timer = DateTime.Now;
|
||||
predictedSign = null;
|
||||
previousIncorrectSign = null;
|
||||
}
|
||||
// Incorrect sign
|
||||
else
|
||||
{
|
||||
if (previousIncorrectSign != predictedSign)
|
||||
{
|
||||
timer = DateTime.Now;
|
||||
previousIncorrectSign = predictedSign;
|
||||
}
|
||||
else if (DateTime.Now - timer > TimeSpan.FromSeconds(2.0f))
|
||||
{
|
||||
predictSign(predictedSign);
|
||||
timer = DateTime.Now;
|
||||
predictedSign = null;
|
||||
previousIncorrectSign = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (feedbackProgress != null)
|
||||
{
|
||||
|
||||
feedbackProgress.value = 0.0f;
|
||||
}
|
||||
yield return null;
|
||||
}
|
||||
|
||||
public string GetSign(){
|
||||
if (letterIndex<currentWord.Length){
|
||||
return currentWord[letterIndex].ToString().ToUpper();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void predictSign(string sign) {
|
||||
bool successful = sign.ToUpper() == currentWord[letterIndex].ToString().ToUpper();
|
||||
if (successful)
|
||||
{
|
||||
AddSeconds(secondsPerLetter);
|
||||
}
|
||||
NextLetter(successful);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
"GUID:3444c67d5a3a93e5a95a48906078c372",
|
||||
"GUID:d0b6b39a21908f94fbbd9f2c196a9725",
|
||||
"GUID:5c2b5ba89f9e74e418232e154bc5cc7a",
|
||||
"GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25",
|
||||
"GUID:58e104b97fb3752438ada2902a36dcbf"
|
||||
"GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
Reference in New Issue
Block a user