-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
718316d
commit b829889
Showing
16 changed files
with
781 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,40 @@ | ||
using UnityEngine; | ||
|
||
[CreateAssetMenu(fileName = "GameConfig", menuName = "DoggoNogo/GameConfig")] | ||
public class GameConfig : ScriptableObject { | ||
[SerializeField] private int defaultTrials = 60; | ||
[SerializeField] private float baseThreshold = 0.5f; | ||
[SerializeField] private float timeoutDuration = 5f; | ||
|
||
public int DefaultTrials => defaultTrials; | ||
public float BaseThreshold => baseThreshold; | ||
public float TimeoutDuration => timeoutDuration; | ||
} | ||
public class GameConfig : ScriptableObject | ||
{ | ||
[Header("Trial Settings")] | ||
[SerializeField] private int defaultTrialCount = 60; | ||
[SerializeField] private int minTrialsPerLevel = 10; | ||
[SerializeField] private Vector2 isiRange = new(1f, 4f); | ||
|
||
[Header("Reaction Time Settings")] | ||
[SerializeField] private float minReactionTime = 0.15f; | ||
[SerializeField] private float maxReactionTime = 0.6f; | ||
[SerializeField] private float initialMedianRT = 0.375f; // (maxRT + minRT) / 2 | ||
|
||
[Header("Scoring Settings")] | ||
[SerializeField] private int minScore = 100; | ||
[SerializeField] private int maxScore = 200; | ||
[SerializeField] private int penaltyScore = -100; | ||
|
||
// Public accessors | ||
public int DefaultTrialCount => defaultTrialCount; | ||
public int MinTrialsPerLevel => minTrialsPerLevel; | ||
public Vector2 ISIRange => isiRange; | ||
public float MinReactionTime => minReactionTime; | ||
public float MaxReactionTime => maxReactionTime; | ||
public float InitialMedianRT => initialMedianRT; | ||
public int MinScore => minScore; | ||
public int MaxScore => maxScore; | ||
public int PenaltyScore => penaltyScore; | ||
} | ||
|
||
/* | ||
To create and use this in Unity: | ||
1. Right-click in Project window | ||
2. Select Create > DoggoNogo > GameConfig | ||
3. Name it something like "DefaultGameConfig" | ||
4. Modify values in Inspector | ||
5. Drag into your GameController component reference | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using UnityEngine; | ||
using System.Threading.Tasks; | ||
|
||
public class UIAnimationController : MonoBehaviour | ||
{ | ||
[SerializeField] private float defaultFadeDuration = 0.3f; | ||
|
||
public async Task FadeIn(GameObject target) | ||
{ | ||
await Fade(target, 0f, 1f); | ||
} | ||
|
||
public async Task FadeOut(GameObject target) | ||
{ | ||
await Fade(target, 1f, 0f); | ||
} | ||
|
||
private async Task Fade(GameObject target, float startAlpha, float endAlpha) | ||
{ | ||
CanvasGroup canvasGroup = target.GetComponent<CanvasGroup>(); | ||
if (canvasGroup == null) | ||
canvasGroup = target.AddComponent<CanvasGroup>(); | ||
|
||
float elapsed = 0; | ||
canvasGroup.alpha = startAlpha; | ||
|
||
while (elapsed < defaultFadeDuration) | ||
{ | ||
elapsed += Time.deltaTime; | ||
canvasGroup.alpha = Mathf.Lerp(startAlpha, endAlpha, elapsed / defaultFadeDuration); | ||
await Task.Yield(); | ||
} | ||
|
||
canvasGroup.alpha = endAlpha; | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
using UnityEngine; | ||
using UnityEngine.UI; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
|
||
public class BoneView : MonoBehaviour | ||
{ | ||
[Header("References")] | ||
[SerializeField] private Image boneImage; | ||
[SerializeField] private Image dogImage; | ||
[SerializeField] private Canvas canvas; | ||
[SerializeField] private GameObject scoreContainer; | ||
[SerializeField] private AudioSource boneThrowSound; | ||
|
||
public void Hide() | ||
{ | ||
boneImage.enabled = false; | ||
} | ||
|
||
public bool Hidden() | ||
{ | ||
return !boneImage.enabled; | ||
} | ||
|
||
public Dictionary<string, float> Show() | ||
{ | ||
RandomTransform(); | ||
Dictionary<string, float> stimSpec = GetTransform(); | ||
boneImage.enabled = true; | ||
return stimSpec; | ||
} | ||
|
||
private void RandomTransform() | ||
{ | ||
RectTransform boneRectTransform = boneImage.rectTransform; | ||
|
||
// Random scale | ||
float randomScale = Random.Range(0.3f, 0.7f); | ||
boneRectTransform.localScale = new Vector3(randomScale, randomScale, 0f); | ||
|
||
// Random rotation | ||
boneRectTransform.Rotate(new Vector3(0, 0, Random.Range(0, 360))); | ||
|
||
// Random position | ||
boneRectTransform.localPosition = RandomPosition(); | ||
} | ||
|
||
public Dictionary<string, float> GetTransform() | ||
{ | ||
RectTransform boneRectTransform = boneImage.rectTransform; | ||
RectTransform canvasRectTransform = canvas.GetComponent<RectTransform>(); | ||
|
||
return new Dictionary<string, float> | ||
{ | ||
// Canvas | ||
{"canvasWidth", canvasRectTransform.rect.width}, | ||
{"canvasHeight", canvasRectTransform.rect.height}, | ||
{"canvasScale", canvasRectTransform.localScale.x}, | ||
// Bone | ||
{"x", boneRectTransform.localPosition.x}, | ||
{"y", boneRectTransform.localPosition.y}, | ||
{"scale", boneRectTransform.localScale.x}, | ||
{"rotation", boneRectTransform.rotation.z} | ||
}; | ||
} | ||
|
||
private Vector2 RandomPosition() | ||
{ | ||
// Get component references and calculate offsets | ||
RectTransform boneRectTransform = boneImage.rectTransform; | ||
RectTransform dogRectTransform = dogImage.rectTransform; | ||
RectTransform canvasRectTransform = canvas.GetComponent<RectTransform>(); | ||
RectTransform scoringRectTransform = scoreContainer.GetComponent<RectTransform>(); | ||
|
||
// Calculate bounds and offsets | ||
float boneOffset = (boneRectTransform.rect.width * boneRectTransform.localScale.x) / 2f; | ||
float dogOffset = (dogRectTransform.rect.width * dogRectTransform.localScale.x) / 2f; | ||
float dogLocationX = dogRectTransform.localPosition.x; | ||
|
||
// Canvas bounds | ||
float xBound = canvasRectTransform.rect.width / 2f; | ||
float yBound = canvasRectTransform.rect.height / 2f; | ||
|
||
// Calculate X position (avoiding dog) | ||
float randomX; | ||
if (Random.value < 0.5f) | ||
{ | ||
// Left side | ||
float leftStart = -xBound + boneOffset; | ||
float leftBound = dogLocationX - dogOffset - boneOffset; | ||
randomX = Random.Range(leftStart, leftBound); | ||
} | ||
else | ||
{ | ||
// Right side | ||
float rightStart = dogLocationX + dogOffset + boneOffset; | ||
float rightBound = xBound - boneOffset; | ||
randomX = Random.Range(rightStart, rightBound); | ||
} | ||
|
||
// Calculate Y position (below score card) | ||
float scoringOffset = (scoringRectTransform.rect.height * scoringRectTransform.localScale.y) / 2f; | ||
float scoringBottom = scoringRectTransform.localPosition.y - scoringOffset; | ||
float randomY = Random.Range(-yBound + boneOffset, scoringBottom - (boneOffset * 2f)); | ||
|
||
return new Vector2(randomX, randomY); | ||
} | ||
|
||
public void Throw() | ||
{ | ||
boneThrowSound.Play(); | ||
StartCoroutine(ThrowAnimation()); | ||
} | ||
|
||
public void Eat() | ||
{ | ||
StartCoroutine(EatAnimation()); | ||
} | ||
|
||
private IEnumerator ThrowAnimation() | ||
{ | ||
Vector3 initialScale = transform.localScale; | ||
float duration = 1f; | ||
float spinSpeed = 360f; | ||
float timer = 0f; | ||
|
||
while (timer < duration) | ||
{ | ||
timer += Time.deltaTime; | ||
transform.localScale = Vector3.Lerp(initialScale, Vector3.zero, timer / duration); | ||
transform.Rotate(Vector3.forward, spinSpeed * Time.deltaTime); | ||
yield return null; | ||
} | ||
|
||
transform.localScale = Vector3.zero; | ||
} | ||
|
||
private IEnumerator EatAnimation() | ||
{ | ||
Vector3 targetScale = new Vector3(0.1f, 0.1f, 0.1f); | ||
|
||
// Calculate mouth position relative to dog | ||
RectTransform dogRectTransform = dogImage.rectTransform; | ||
float mouthXFromCentre = ((dogRectTransform.rect.width/2) - 121f) * dogRectTransform.localScale.x; | ||
float mouthYFromCentre = ((dogRectTransform.rect.height/2) - 219f) * dogRectTransform.localScale.y; | ||
Vector3 targetPosition = new Vector3( | ||
dogRectTransform.localPosition.x - mouthXFromCentre, | ||
dogRectTransform.localPosition.y + mouthYFromCentre, | ||
0 | ||
); | ||
|
||
float duration = 0.3f; | ||
float elapsed = 0f; | ||
Vector3 startPosition = boneImage.rectTransform.localPosition; | ||
Vector3 startScale = boneImage.rectTransform.localScale; | ||
|
||
while (elapsed < duration) | ||
{ | ||
elapsed += Time.deltaTime; | ||
float t = elapsed / duration; | ||
|
||
boneImage.rectTransform.localPosition = Vector3.Lerp(startPosition, targetPosition, t); | ||
boneImage.rectTransform.localScale = Vector3.Lerp(startScale, targetScale, t); | ||
|
||
yield return null; | ||
} | ||
|
||
Hide(); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.