Commit 7e083792 authored by saad's avatar saad

add basemanager class

parent 0a10504d
fileFormatVersion: 2
guid: 745e9c17df962b24a80a69d5da8e5d38
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: d308d9efe86ef6242a75802e1f37de49
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: e5036f96e3c15ea49b96f7ee989dd3c1
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 9e9f7f46a1ba34c338eb95b193ae1327
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: b18b93d4b5d00384ba417df18aeac5a3
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 92a80e6f6cd90464b8f87b98fc72999a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
...@@ -211,8 +211,7 @@ Transform: ...@@ -211,8 +211,7 @@ Transform:
m_LocalPosition: {x: 0, y: 1, z: -10} m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: m_Children: []
- {fileID: 1399870137}
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &603037699 --- !u!114 &603037699
...@@ -517,76 +516,6 @@ Transform: ...@@ -517,76 +516,6 @@ Transform:
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &1399870136
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 603037698}
m_Modifications:
- target: {fileID: 5575199186091687107, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: ShapeModule.radius.value
value: 40
objectReference: {fileID: 0}
- target: {fileID: 5575199186091687107, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: InitialModule.startSize.scalar
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalPosition.x
value: -0.08737
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalPosition.y
value: 10.40678
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalPosition.z
value: 108
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalRotation.w
value: 0.7071068
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalRotation.x
value: -0.7071068
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: -90
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8015466945648444578, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
propertyPath: m_Name
value: DotFloating
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
--- !u!4 &1399870137 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 6955428004947038011, guid: 81b128416c1c2356c8d645340d865e65, type: 3}
m_PrefabInstance: {fileID: 1399870136}
m_PrefabAsset: {fileID: 0}
--- !u!1 &1878716305 --- !u!1 &1878716305
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
......
...@@ -23,29 +23,19 @@ namespace com.al_arcade.cs ...@@ -23,29 +23,19 @@ namespace com.al_arcade.cs
Complete, Complete,
} }
public class CsGameManager : MonoBehaviour, IChallengeGame public class CsGameManager : BaseGameManager, IChallengeGame
{ {
public static CsGameManager Instance { get; private set; } public static CsGameManager Instance { get; private set; }
[Header("Settings")] [Header("Settings")]
[SerializeField] [SerializeField] private float sentenceShowDelay = 0.5f;
private float sentenceShowDelay = 0.5f; [SerializeField] private float feedbackDuration = 1.5f;
[SerializeField] private float wordClickCooldown = 0.3f;
[SerializeField]
private float feedbackDuration = 1.5f;
[SerializeField]
private float wordClickCooldown = 0.3f;
[Header("Arc Settings")] [Header("Arc Settings")]
[SerializeField] [SerializeField] private float arcRadius = 15f;
private float arcRadius = 15f; [SerializeField] private float arcSpanDegrees = 120f;
[SerializeField] private float wordGap = 0.2f;
[SerializeField]
private float arcSpanDegrees = 120f;
[SerializeField]
private float wordGap = 0.2f;
[Header("References")] [Header("References")]
public CsBotController bot; public CsBotController bot;
...@@ -54,105 +44,126 @@ namespace com.al_arcade.cs ...@@ -54,105 +44,126 @@ namespace com.al_arcade.cs
private CsGameState _state = CsGameState.Idle; private CsGameState _state = CsGameState.Idle;
private CsQuestion[] _questions; private CsQuestion[] _questions;
private int _currentIndex;
private int _score,
_streak,
_correctCount,
_wrongCount,
_wrongClicks;
private int _wrongClicks;
private List<CsWordButton> _wordButtons = new(); private List<CsWordButton> _wordButtons = new();
private CsWordButton _wrongWordButton; private CsWordButton _wrongWordButton;
private bool _wordClickLocked; private bool _wordClickLocked;
[Header("Events")] [Header("CS Events")]
public UnityEvent onGameStart;
public UnityEvent<bool> onAnswerGiven;
public UnityEvent<int> onGameComplete; public UnityEvent<int> onGameComplete;
private Action<bool> _onOptionDropped; private Action<bool> _onOptionDropped;
private bool _isTicking;
private float _timeLeft; private int _deltaChangeInSize;
private bool isTicking; private bool _showHint = true;
private DateTime gameStartTime;
// if it reaches 5, you win the game;
int _deltaChangeInSize;
bool showHint = true;
CinemachineTargetGroup _targetGroup; CinemachineTargetGroup _targetGroup;
CinemachineGroupFraming _groupFraming; CinemachineGroupFraming _groupFraming;
public event Action<bool, float> OnGameCompleted; public event Action<bool, float> OnGameCompleted;
private void Awake() // ─── Singleton ────────────────────────────────────────────────────────
protected override void Awake()
{ {
if (Instance != null && Instance != this) if (Instance != null && Instance != this) { Destroy(gameObject); return; }
{
Destroy(gameObject);
return;
}
Instance = this; Instance = this;
base.Awake();
_targetGroup = FindFirstObjectByType<CinemachineTargetGroup>(); _targetGroup = FindFirstObjectByType<CinemachineTargetGroup>();
_groupFraming = FindFirstObjectByType<CinemachineGroupFraming>(); _groupFraming = FindFirstObjectByType<CinemachineGroupFraming>();
} }
private void Update() // ─── BaseGameManager implementation ──────────────────────────────────
protected override string GameTypeKey => "cs";
protected override IEnumerator FetchQuestions(Action<string> onError)
{ {
if (_state == CsGameState.WaitingForWordClick || _state == CsGameState.WaitingForDrop) var session = SSGameSession.EnsureInstance();
{ var api = SSApiManager.EnsureInstance();
_timeLeft -= Time.deltaTime;
if (_timeLeft <= 0)
{
_timeLeft = 0;
_state = CsGameState.Complete;
StartCoroutine(LoseSequence());
}
if (_timeLeft < 4f && !isTicking) if (uiManager != null && uiManager.isMusicOn)
{ SSAudioManager.EnsureInstance().PlayMusic();
isTicking = true;
var audio = SSAudioManager.Instance;
audio.Tick(true);
}
else if (_timeLeft >= 4f && isTicking)
{
isTicking = false;
var audio = SSAudioManager.Instance;
audio.Tick(false);
}
uiManager.SetTimer(_timeLeft); yield return api.FetchCs(
} session.buildType, session.classCode,
session.questionCount, session.gradeId,
qs => _questions = qs,
err => onError(err)
);
} }
protected override bool HasValidQuestions() =>
_questions != null && _questions.Length > 0;
void UpdateTimer(int delta) protected override void OnShowLoading() =>
uiManager?.ShowLoading("جاري تحميل الأسئلة...");
protected override void OnHideLoading() =>
uiManager?.HideLoading();
protected override void OnShowError(string message)
{ {
_timeLeft += delta; uiManager?.ShowError(message);
_timeLeft = Mathf.Clamp(_timeLeft, 0, CsPrefabBuilder.Instance.startTime); _state = CsGameState.Idle;
}
protected override IEnumerator OnBeforeBeginGameplay()
{
if (uiManager != null)
yield return uiManager.ShowCountDown();
}
if (_timeLeft < 4f && !isTicking) protected override void OnTimerTick(float timeLeft)
{
// Ticking sound when under 4 seconds
if (timeLeft < 4f && !_isTicking)
{ {
isTicking = true; _isTicking = true;
var audio = SSAudioManager.Instance; SSAudioManager.Instance?.Tick(true);
audio.Tick(true);
} }
else if (_timeLeft >= 4f && isTicking) else if (timeLeft >= 4f && _isTicking)
{ {
isTicking = false; _isTicking = false;
var audio = SSAudioManager.Instance; SSAudioManager.Instance?.Tick(false);
audio.Tick(false);
} }
uiManager.UpdateTimer(_timeLeft, delta > 0); uiManager?.SetTimer(timeLeft);
} }
protected override IEnumerator OnTimeUp()
{
_state = CsGameState.Complete;
yield return LoseSequence();
}
protected override void BeginGameplay()
{
_currentIndex = _score = _streak = _correctCount = _wrongCount = 0;
_deltaChangeInSize = 0;
_timeLeft = CsPrefabBuilder.Instance.startTime; // CS uses its own start time
_timerRunning = true;
if (uiManager != null)
{
uiManager.ShowGameUI();
uiManager.SetScore(0);
uiManager.SetProgress(0, _questions.Length);
}
public void StartGame() => StartCoroutine(StartGameRoutine()); onGameStart?.Invoke();
StartCoroutine(QuestionLoop());
}
// ─── Update: CS also needs the state guard from original ─────────────
protected override void Update()
{
// Only tick timer when waiting for player input
if (_state == CsGameState.WaitingForWordClick || _state == CsGameState.WaitingForDrop)
base.Update();
}
// ─── Public API ───────────────────────────────────────────────────────
public void StartWithQuestions(CsQuestion[] questions) public void StartWithQuestions(CsQuestion[] questions)
{ {
_questions = questions; _questions = questions;
...@@ -161,51 +172,38 @@ namespace com.al_arcade.cs ...@@ -161,51 +172,38 @@ namespace com.al_arcade.cs
public void ResetGame() public void ResetGame()
{ {
StopAllCoroutines(); ResetBaseState();
_deltaChangeInSize = 0; _deltaChangeInSize = 0;
_state = CsGameState.Idle; _state = CsGameState.Idle;
_currentIndex = _score = _streak = _correctCount = _wrongCount = 0; _isTicking = false;
ClearWordButtons(); ClearWordButtons();
if (uiManager != null) uiManager?.ResetUI();
uiManager.ResetUI(); bot?.ResetBot();
if (bot != null)
bot.ResetBot();
} }
public void OnWordClicked(CsWordButton wordButton) public void OnWordClicked(CsWordButton wordButton)
{ {
if (_state != CsGameState.WaitingForWordClick) if (_state != CsGameState.WaitingForWordClick) return;
return; if (_wordClickLocked) return;
if (_wordClickLocked)
return;
if (wordButton.IsWrong) if (wordButton.IsWrong)
{ {
_wrongWordButton = wordButton; _wrongWordButton = wordButton;
wordButton.Highlight(true); wordButton.Highlight(true);
var audio = SSAudioManager.Instance; SSAudioManager.Instance?.PlayCorrectChoice();
if (audio != null) SSParticleManager.Instance?.PlaySparks(wordButton.transform.position, SSColorPalette.Accent);
audio.PlayCorrectChoice();
var particles = SSParticleManager.Instance;
if (particles != null)
particles.PlaySparks(wordButton.transform.position, SSColorPalette.Accent);
_state = CsGameState.WaitingForDrop; _state = CsGameState.WaitingForDrop;
ShowOptions(); ShowOptions();
} }
else else
{ {
UpdateTimer(-CsPrefabBuilder.Instance.wrongAnswerPenaltyTime); AdjustTimer(-CsPrefabBuilder.Instance.wrongAnswerPenaltyTime);
_wrongClicks++; _wrongClicks++;
_wordClickLocked = true; _wordClickLocked = true;
wordButton.ShakeWrong(); wordButton.ShakeWrong();
SSAudioManager.Instance?.PlayWrongBeep();
var audio = SSAudioManager.Instance;
if (audio != null)
audio.PlayWrongBeep();
StartCoroutine(UnlockAfterCooldown()); StartCoroutine(UnlockAfterCooldown());
} }
} }
...@@ -215,78 +213,34 @@ namespace com.al_arcade.cs ...@@ -215,78 +213,34 @@ namespace com.al_arcade.cs
_onOptionDropped?.Invoke(isCorrectOption); _onOptionDropped?.Invoke(isCorrectOption);
} }
private IEnumerator StartGameRoutine() // ─── Timer helpers ────────────────────────────────────────────────────
{ private void AdjustTimer(float delta)
_state = CsGameState.Loading;
if (uiManager != null)
uiManager.ShowLoading("جاري تحميل الأسئلة...");
var session = SSGameSession.EnsureInstance();
var api = SSApiManager.EnsureInstance();
if (uiManager.isMusicOn)
SSAudioManager.EnsureInstance().PlayMusic();
string error = null;
yield return api.FetchCs(
session.buildType,
session.classCode,
session.questionCount,
session.gradeId,
qs => _questions = qs,
err => error = err
);
if (error != null || _questions == null || _questions.Length == 0)
{
if (uiManager != null)
uiManager.ShowError(error ?? "لا توجد أسئلة");
_state = CsGameState.Idle;
yield break;
}
if (uiManager != null)
uiManager.HideLoading();
yield return uiManager.ShowCountDown();
gameStartTime = DateTime.Now;
BeginGameplay();
}
private void BeginGameplay()
{ {
_currentIndex = _score = _streak = _correctCount = _wrongCount = 0; UpdateTimerBy(delta);
_timeLeft = CsPrefabBuilder.Instance.startTime; _timeLeft = Mathf.Clamp(_timeLeft, 0, CsPrefabBuilder.Instance.startTime);
if (uiManager != null) // Re-check tick state after adjustment
{ if (_timeLeft < 4f && !_isTicking)
uiManager.ShowGameUI(); { _isTicking = true; SSAudioManager.Instance?.Tick(true); }
uiManager.SetScore(0); else if (_timeLeft >= 4f && _isTicking)
uiManager.SetProgress(0, _questions.Length); { _isTicking = false; SSAudioManager.Instance?.Tick(false); }
}
onGameStart?.Invoke(); uiManager?.UpdateTimer(_timeLeft, delta > 0);
StartCoroutine(QuestionLoop());
} }
// ─── Game loop ────────────────────────────────────────────────────────
private IEnumerator QuestionLoop() private IEnumerator QuestionLoop()
{ {
while (_currentIndex < _questions.Length) while (_currentIndex < _questions.Length)
{ {
if (_state == CsGameState.Complete) if (_state == CsGameState.Complete) yield break;
yield break;
yield return PresentQuestion(_questions[_currentIndex]); yield return PresentQuestion(_questions[_currentIndex]);
_currentIndex++; _currentIndex++;
if (uiManager != null) uiManager?.SetProgress(_currentIndex, _questions.Length);
uiManager.SetProgress(_currentIndex, _questions.Length);
} }
if (_state == CsGameState.Complete) if (_state == CsGameState.Complete) yield break;
yield break;
_state = CsGameState.Complete; _state = CsGameState.Complete;
yield return LoseSequence(); yield return LoseSequence();
...@@ -298,9 +252,7 @@ namespace com.al_arcade.cs ...@@ -298,9 +252,7 @@ namespace com.al_arcade.cs
_wrongClicks = 0; _wrongClicks = 0;
_wrongWordButton = null; _wrongWordButton = null;
if (bot != null) bot?.ShowSpeechBubble();
bot.ShowSpeechBubble();
ClearWordButtons(); ClearWordButtons();
yield return new WaitForSeconds(sentenceShowDelay); yield return new WaitForSeconds(sentenceShowDelay);
...@@ -308,8 +260,7 @@ namespace com.al_arcade.cs ...@@ -308,8 +260,7 @@ namespace com.al_arcade.cs
yield return new WaitForSeconds(1.3f); yield return new WaitForSeconds(1.3f);
_state = CsGameState.WaitingForWordClick; _state = CsGameState.WaitingForWordClick;
if (showHint) if (_showHint) uiManager?.ShowHint("انقر على الكلمة الخاطئة في الجملة");
uiManager.ShowHint("انقر على الكلمة الخاطئة في الجملة");
bool questionComplete = false; bool questionComplete = false;
_onOptionDropped = null; _onOptionDropped = null;
...@@ -321,8 +272,7 @@ namespace com.al_arcade.cs ...@@ -321,8 +272,7 @@ namespace com.al_arcade.cs
bool? result = null; bool? result = null;
_onOptionDropped = correct => result = correct; _onOptionDropped = correct => result = correct;
while (result == null) while (result == null) yield return null;
yield return null;
if (result == true) if (result == true)
{ {
...@@ -340,8 +290,7 @@ namespace com.al_arcade.cs ...@@ -340,8 +290,7 @@ namespace com.al_arcade.cs
} }
} }
if (uiManager != null) uiManager?.HideOptions();
uiManager.HideOptions();
yield return new WaitForSeconds(0.5f); yield return new WaitForSeconds(0.5f);
} }
...@@ -351,12 +300,10 @@ namespace com.al_arcade.cs ...@@ -351,12 +300,10 @@ namespace com.al_arcade.cs
_correctCount++; _correctCount++;
_streak++; _streak++;
_deltaChangeInSize++; _deltaChangeInSize++;
UpdateTimer(CsPrefabBuilder.Instance.correctAnswerBonusTime); AdjustTimer(CsPrefabBuilder.Instance.correctAnswerBonusTime);
int points = Mathf.Max(100 - _wrongClicks * 15, 25); int points = Mathf.Max(100 - _wrongClicks * 15, 25);
if (_streak >= 3) if (_streak >= 3) points += (_streak - 2) * 25;
points += (_streak - 2) * 25;
_score += points; _score += points;
if (_wrongWordButton != null) if (_wrongWordButton != null)
...@@ -372,26 +319,20 @@ namespace com.al_arcade.cs ...@@ -372,26 +319,20 @@ namespace com.al_arcade.cs
SSAudioManager.Instance.PlayCorrectDrag(); SSAudioManager.Instance.PlayCorrectDrag();
yield return new WaitForSeconds(0.4f); yield return new WaitForSeconds(0.4f);
if (bot != null) bot?.PlayHappy();
bot.PlayHappy(); uiManager?.HideHint();
uiManager.HideHint();
var particles = SSParticleManager.Instance; if (SSParticleManager.Instance != null && _wrongWordButton != null)
if (particles != null && _wrongWordButton != null) SSParticleManager.Instance.PlayCorrectBurst(_wrongWordButton.transform.position);
particles.PlayCorrectBurst(_wrongWordButton.transform.position);
uiManager.TickPoints(_deltaChangeInSize);
uiManager?.TickPoints(_deltaChangeInSize);
onAnswerGiven?.Invoke(true); onAnswerGiven?.Invoke(true);
yield return new WaitForSeconds(0.8f); yield return new WaitForSeconds(0.8f);
if (_deltaChangeInSize == 5) if (_deltaChangeInSize == 5)
{ {
// Win
_state = CsGameState.Complete; _state = CsGameState.Complete;
yield return VictorySequence(); yield return VictorySequence();
yield break;
} }
} }
...@@ -399,12 +340,9 @@ namespace com.al_arcade.cs ...@@ -399,12 +340,9 @@ namespace com.al_arcade.cs
{ {
_wrongClicks++; _wrongClicks++;
_streak = 0; _streak = 0;
_deltaChangeInSize = Mathf.Max(0, _deltaChangeInSize - 1);
_deltaChangeInSize--; AdjustTimer(-CsPrefabBuilder.Instance.wrongAnswerPenaltyTime);
if (_deltaChangeInSize < 0)
_deltaChangeInSize = 0;
UpdateTimer(-CsPrefabBuilder.Instance.wrongAnswerPenaltyTime);
if (uiManager != null) if (uiManager != null)
{ {
...@@ -415,8 +353,7 @@ namespace com.al_arcade.cs ...@@ -415,8 +353,7 @@ namespace com.al_arcade.cs
SSAudioManager.Instance.PlayWrong(); SSAudioManager.Instance.PlayWrong();
yield return new WaitForSeconds(0.4f); yield return new WaitForSeconds(0.4f);
if (bot != null) bot?.PlaySad();
bot.PlaySad();
if (Camera.main != null) if (Camera.main != null)
{ {
...@@ -424,30 +361,60 @@ namespace com.al_arcade.cs ...@@ -424,30 +361,60 @@ namespace com.al_arcade.cs
Camera.main.transform.DOShakePosition(0.3f, 0.15f, 10).SetId("csShake"); Camera.main.transform.DOShakePosition(0.3f, 0.15f, 10).SetId("csShake");
} }
uiManager.TickPoints(_deltaChangeInSize); uiManager?.TickPoints(_deltaChangeInSize);
yield return new WaitForSeconds(0.8f); yield return new WaitForSeconds(0.8f);
} }
private void SpawnWords(CsQuestion question) // ─── End sequences ────────────────────────────────────────────────────
private IEnumerator VictorySequence()
{
var audio = SSAudioManager.Instance;
audio.PlayVictory();
StartCoroutine(DelayedAction(0.7f, () => audio.PlayCheer())); // shared helper
SSParticleManager.Instance?.PlayScreenConfetti();
bot?.PlayVictoryDance();
yield return new WaitForSeconds(1f);
uiManager?.ShowResults(_score, _correctCount, _wrongClicks, _questions.Length, _streak);
onGameComplete?.Invoke(_score);
SSAudioManager.Instance.StopMusic();
ClearWordButtons();
RecordGameHistory(); // shared helper
OnGameCompleted?.Invoke(true, _timeLeft);
yield return new WaitForSeconds(5f);
SceneManager.LoadScene("App");
}
private IEnumerator LoseSequence()
{ {
var fullQuestion = question.words != null SSAudioManager.Instance.PlayDefeat();
? string.Join(" ", Array.ConvertAll(question.words, w => w.word_text))
: ""; uiManager?.ShowResults(_score, _correctCount, _wrongClicks, _questions.Length, _streak, false);
if (question.words == null || question.words.Length == 0) onGameComplete?.Invoke(_score);
return; SSAudioManager.Instance.StopMusic();
ClearWordButtons();
OnGameCompleted?.Invoke(false, _timeLeft);
yield return null;
}
// ─── Word / UI helpers ────────────────────────────────────────────────
private void SpawnWords(CsQuestion question)
{
if (question.words == null || question.words.Length == 0) return;
ClearWordButtons(); ClearWordButtons();
_groupFraming.CenterOffset = new Vector2(0f, -0.1f); _groupFraming.CenterOffset = new Vector2(0f, -0.1f);
// Spawn Full Sentence
var sentenceObj = new GameObject("FullQuestion"); var sentenceObj = new GameObject("FullQuestion");
sentenceObj.transform.SetParent(wordContainer); sentenceObj.transform.SetParent(wordContainer);
var sentenceWb = sentenceObj.AddComponent<CsSentence>(); var sentenceWb = sentenceObj.AddComponent<CsSentence>();
sentenceWb.Initialize(question); sentenceWb.Initialize(question);
return;
} }
private void ShowOptions() private void ShowOptions()
...@@ -456,10 +423,10 @@ namespace com.al_arcade.cs ...@@ -456,10 +423,10 @@ namespace com.al_arcade.cs
if (uiManager != null) if (uiManager != null)
{ {
uiManager.ShowOptions(question.options, _wrongWordButton); uiManager.ShowOptions(question.options, _wrongWordButton);
if (showHint) if (_showHint)
{ {
uiManager.ShowHint("اسحب الإجابة الصحيحة إلى الكلمة الخاطئة"); uiManager.ShowHint("اسحب الإجابة الصحيحة إلى الكلمة الخاطئة");
showHint = false; _showHint = false;
} }
} }
} }
...@@ -468,10 +435,8 @@ namespace com.al_arcade.cs ...@@ -468,10 +435,8 @@ namespace com.al_arcade.cs
{ {
foreach (Transform child in wordContainer) foreach (Transform child in wordContainer)
{ {
child.transform.DOScale(Vector3.zero, 0.3f).SetEase(Ease.InBack).OnComplete(() => child.transform.DOScale(Vector3.zero, 0.3f).SetEase(Ease.InBack)
{ .OnComplete(() => Destroy(child.gameObject));
Destroy(child.gameObject);
});
} }
if (_targetGroup.Targets.Count > 2) if (_targetGroup.Targets.Count > 2)
...@@ -490,75 +455,7 @@ namespace com.al_arcade.cs ...@@ -490,75 +455,7 @@ namespace com.al_arcade.cs
_wordClickLocked = false; _wordClickLocked = false;
} }
private IEnumerator VictorySequence() // ─── Challenge mode ───────────────────────────────────────────────────
{
var audio = SSAudioManager.Instance;
audio.PlayVictory();
StartCoroutine(DelayedAction(0.7f, () =>
{
audio.PlayCheer();
}));
var particles = SSParticleManager.Instance;
if (particles != null)
particles.PlayScreenConfetti();
if (bot != null)
bot.PlayVictoryDance();
yield return new WaitForSeconds(1f);
if (uiManager != null)
uiManager.ShowResults(
_score,
_correctCount,
_wrongClicks,
_questions.Length,
_streak
);
onGameComplete?.Invoke(_score);
SSAudioManager.Instance.StopMusic();
ClearWordButtons();
GameHistoryService.Instance.AddGame("cs", _score, gameStartTime, DateTime.Now);
OnGameCompleted?.Invoke(true, _timeLeft);
yield return new WaitForSeconds(5f);
SceneManager.LoadScene("App");
}
private IEnumerator DelayedAction(float delay, Action action)
{
yield return new WaitForSeconds(delay);
action?.Invoke();
}
private IEnumerator LoseSequence()
{
var audio = SSAudioManager.Instance;
audio.PlayDefeat();
if (uiManager != null)
uiManager.ShowResults(
_score,
_correctCount,
_wrongClicks,
_questions.Length,
_streak,
false
);
onGameComplete?.Invoke(_score);
SSAudioManager.Instance.StopMusic();
ClearWordButtons();
OnGameCompleted?.Invoke(false, _timeLeft);
yield return null;
}
public int Score => _score;
private ChallengeManager _challengeManager; private ChallengeManager _challengeManager;
private bool _challengeChecked; private bool _challengeChecked;
...@@ -575,5 +472,4 @@ namespace com.al_arcade.cs ...@@ -575,5 +472,4 @@ namespace com.al_arcade.cs
} }
} }
} }
}
} \ No newline at end of file
using DG.Tweening;
using UnityEngine;
public class FutureCar : MonoBehaviour
{
[Header("Main Settings")]
[Tooltip("Check to float in place, uncheck to move back and forth.")]
public bool isFloatingInPlace = true;
[Header("Floating Options (Only used if checked above)")]
public float floatSpeed = 1f;
public float floatAmplitude = 0.5f;
[Header("Moving Options (Only used if unchecked above)")]
public float moveSpeed = 5f;
public float travelDistance = 20f;
public float rotationSpeed = 3f;
private Vector3 startPosition;
private Vector3 targetPosition;
private bool movingToTarget = true;
private float initialY;
void Start()
{
// Store the starting spot
startPosition = transform.position;
initialY = transform.position.y;
// Calculate the end of the patrol path based on the car's initial forward direction
targetPosition = startPosition + (transform.forward * travelDistance);
ApplyFloatingMotion();
}
// void Update()
// {
// if (isFloatingInPlace)
// {
// ApplyFloatingMotion();
// }
// else
// {
// ApplyPatrolMotion();
// }
// }
private void ApplyFloatingMotion()
{
var randomDelay = Random.Range(0f, 1f);
transform.DOMoveY(initialY + floatAmplitude, floatSpeed)
.SetEase(Ease.InOutSine)
.SetDelay(randomDelay)
.SetLoops(-1, LoopType.Yoyo);
}
private void ApplyPatrolMotion()
{
// Determine which end of the line we are headed to
Vector3 destination = movingToTarget ? targetPosition : startPosition;
// 1. Move the car
transform.position = Vector3.MoveTowards(transform.position, destination, moveSpeed * Time.deltaTime);
// 2. Rotate the car to face the current destination
Vector3 direction = (destination - transform.position).normalized;
if (direction != Vector3.zero)
{
Quaternion lookRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * rotationSpeed);
}
// 3. If we are very close to the destination, flip the boolean to go the other way
if (Vector3.Distance(transform.position, destination) < 0.1f)
{
movingToTarget = !movingToTarget;
}
}
// This helps you see the path in the Scene View without pressing play
private void OnDrawGizmosSelected()
{
if (!isFloatingInPlace)
{
Gizmos.color = Color.cyan;
Vector3 endPoint = Application.isPlaying ? targetPosition : transform.position + (transform.forward * travelDistance);
Vector3 startPoint = Application.isPlaying ? startPosition : transform.position;
Gizmos.DrawLine(startPoint, endPoint);
Gizmos.DrawWireSphere(endPoint, 0.5f);
}
}
}
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
namespace com.al_arcade.shared
{
/// <summary>
/// Abstract base class for all game managers (TF, MCQ, CS, ...).
/// Handles: singleton wiring, score/streak/counts, timer, API loading
/// skeleton, game history recording, and shared UnityEvents.
///
/// Subclasses MUST:
/// - Declare their own static Instance property
/// - Call base.Awake() (or replicate the guard) in their own Awake()
/// - Implement all abstract members
/// </summary>
public abstract class BaseGameManager : MonoBehaviour
{
// ─── Timer ───────────────────────────────────────────────────────────
[Header("Timer Settings")]
[SerializeField] protected float maxTimePerQuestion = 30f;
protected float _timeLeft;
protected bool _timerRunning;
// ─── Shared runtime state ────────────────────────────────────────────
protected int _score;
protected int _streak;
protected int _correctCount;
protected int _wrongCount;
protected int _currentIndex;
protected int _totalAsked;
protected DateTime gameStartTime;
// ─── Shared UnityEvents ──────────────────────────────────────────────
[Header("Base Events")]
public UnityEvent onGameStart;
public UnityEvent<bool> onAnswerGiven;
// ─────────────────────────────────────────────────────────────────────
// Abstract API – every subclass must implement these
// ─────────────────────────────────────────────────────────────────────
/// <summary>
/// Fetch questions from the API and store them internally.
/// Yield inside to wait for the network call.
/// Set 'error' to a non-null string if something goes wrong.
/// </summary>
protected abstract IEnumerator FetchQuestions(Action<string> onError);
/// <summary>
/// Returns true if the fetch result is considered valid
/// (e.g. questions array is non-null and non-empty).
/// </summary>
protected abstract bool HasValidQuestions();
/// <summary>Called after questions load successfully — start your game loop here.</summary>
protected abstract void BeginGameplay();
/// <summary>Called when the countdown timer hits zero.</summary>
protected abstract IEnumerator OnTimeUp();
/// <summary>
/// The game-type key passed to GameHistoryService (e.g. "tf", "mcq", "cs").
/// </summary>
protected abstract string GameTypeKey { get; }
// ─────────────────────────────────────────────────────────────────────
// Singleton wiring (subclass keeps its own typed static Instance)
// ─────────────────────────────────────────────────────────────────────
protected virtual void Awake()
{
// Subclasses that need extra Awake logic should call base.Awake()
// THEN do their own work.
}
// ─────────────────────────────────────────────────────────────────────
// Timer
// ─────────────────────────────────────────────────────────────────────
protected virtual void Update()
{
if (!_timerRunning) return;
_timeLeft -= Time.deltaTime;
OnTimerTick(_timeLeft);
if (_timeLeft <= 0f)
{
_timeLeft = 0f;
_timerRunning = false;
StartCoroutine(OnTimeUp());
}
}
/// <summary>
/// Called every frame while the timer is running.
/// Override to push the value to your UI manager.
/// </summary>
protected virtual void OnTimerTick(float timeLeft) { }
/// <summary>Add or subtract time and clamp to [0, maxTimePerQuestion].</summary>
protected void UpdateTimerBy(float delta)
{
_timeLeft = Mathf.Clamp(_timeLeft + delta, 0f, maxTimePerQuestion);
}
/// <summary>Ratio 0–1 of time remaining (useful for timer bars).</summary>
public float GetCurrentTimeRatio()
{
if (maxTimePerQuestion <= 0f) return 0f;
return _timeLeft / maxTimePerQuestion;
}
// ─────────────────────────────────────────────────────────────────────
// Shared StartGame / loading skeleton
// ─────────────────────────────────────────────────────────────────────
/// <summary>
/// Starts the full loading + gameplay flow.
/// Call this from your UI "Start" button.
/// </summary>
public virtual void StartGame()
{
StartCoroutine(StartGameRoutine());
}
/// <summary>
/// Shared loading routine: show loader → fetch → handle error → begin.
/// Override OnBeforeBeginGameplay() to insert game-specific steps
/// (e.g. countdown animation) between loading and BeginGameplay().
/// </summary>
protected virtual IEnumerator StartGameRoutine()
{
OnShowLoading();
string error = null;
yield return FetchQuestions(err => error = err);
if (!HasValidQuestions() || error != null)
{
OnShowError(error ?? "لا توجد أسئلة");
yield break;
}
OnHideLoading();
yield return OnBeforeBeginGameplay();
gameStartTime = DateTime.Now;
_timeLeft = maxTimePerQuestion;
_timerRunning = true;
BeginGameplay();
}
/// <summary>Override to call uiManager.ShowLoading(...).</summary>
protected virtual void OnShowLoading() { }
/// <summary>Override to call uiManager.HideLoading().</summary>
protected virtual void OnHideLoading() { }
/// <summary>Override to call uiManager.ShowError(...).</summary>
protected virtual void OnShowError(string message) { }
/// <summary>
/// Hook between loading and BeginGameplay.
/// Use it for countdowns, intro animations, etc.
/// Base implementation does nothing.
/// </summary>
protected virtual IEnumerator OnBeforeBeginGameplay() { yield break; }
// ─────────────────────────────────────────────────────────────────────
// Shared score helpers
// ─────────────────────────────────────────────────────────────────────
/// <summary>
/// Standard streak-based score calculation used by TF and MCQ:
/// base 100 pts + 25 per streak step above the threshold.
/// </summary>
protected int CalculateStreakScore(int streakThreshold = 2)
{
return 100 + (_streak > streakThreshold ? (_streak - streakThreshold) * 25 : 0);
}
// ─────────────────────────────────────────────────────────────────────
// Game history
// ─────────────────────────────────────────────────────────────────────
/// <summary>
/// Records the completed session to GameHistoryService.
/// Call at the end of VictorySequence / GameOverSequence.
/// </summary>
protected void RecordGameHistory()
{
GameHistoryService.Instance.AddGame(GameTypeKey, _score, gameStartTime, DateTime.Now);
}
// ─────────────────────────────────────────────────────────────────────
// Shared reset helpers
// ─────────────────────────────────────────────────────────────────────
/// <summary>
/// Resets all shared counters and timer state.
/// Call at the start of ResetGame() in your subclass.
/// </summary>
protected void ResetBaseState()
{
StopAllCoroutines();
_score = _streak = _correctCount = _wrongCount = _currentIndex = _totalAsked = 0;
_timeLeft = 0f;
_timerRunning = false;
}
// ─────────────────────────────────────────────────────────────────────
// Utility
// ─────────────────────────────────────────────────────────────────────
/// <summary>Runs an action after a delay without blocking a coroutine.</summary>
protected IEnumerator DelayedAction(float delay, Action action)
{
yield return new WaitForSeconds(delay);
action?.Invoke();
}
// ─────────────────────────────────────────────────────────────────────
// Public read-only accessors (common across all games)
// ─────────────────────────────────────────────────────────────────────
public int Score => _score;
public int Streak => _streak;
public int CorrectCount => _correctCount;
public int WrongCount => _wrongCount;
public int CurrentQuestionIndex => _currentIndex;
}
}
fileFormatVersion: 2 fileFormatVersion: 2
guid: c7f3fdf6e62442c5485a9ff394896b54 guid: 42fbf78681728ed4d92e5b86342792b3
\ No newline at end of file \ No newline at end of file
...@@ -6,13 +6,12 @@ using DG.Tweening; ...@@ -6,13 +6,12 @@ using DG.Tweening;
namespace com.al_arcade.tf namespace com.al_arcade.tf
{ {
using Microsoft.IdentityModel.Tokens;
using shared; using shared;
public enum TfGameState public enum TfGameState
{ Idle, Loading, Playing, Feedback, Complete, GameOver } { Idle, Loading, Playing, Feedback, Complete, GameOver }
public class TfGameManager : MonoBehaviour public class TfGameManager : BaseGameManager
{ {
public static TfGameManager Instance { get; private set; } public static TfGameManager Instance { get; private set; }
...@@ -20,6 +19,7 @@ namespace com.al_arcade.tf ...@@ -20,6 +19,7 @@ namespace com.al_arcade.tf
[SerializeField] private int stepsToWin = 5; [SerializeField] private int stepsToWin = 5;
[SerializeField] private float feedbackDuration = 1.2f; [SerializeField] private float feedbackDuration = 1.2f;
[SerializeField] private float stepDistance = 3f; [SerializeField] private float stepDistance = 3f;
[SerializeField] private float feedbackTime = 5f;
[Header("References")] [Header("References")]
public TfHandController handController; public TfHandController handController;
...@@ -29,108 +29,67 @@ namespace com.al_arcade.tf ...@@ -29,108 +29,67 @@ namespace com.al_arcade.tf
private TfGameState _state = TfGameState.Idle; private TfGameState _state = TfGameState.Idle;
private TfQuestion[] _questions; private TfQuestion[] _questions;
private int _currentIndex, _progress, _score, _streak; private int _progress;
private int _correctCount, _wrongCount, _totalAsked;
private bool _waitingForAnswer; private bool _waitingForAnswer;
private int _pendingAnswer = -1; private int _pendingAnswer = -1;
private DateTime gameStartTime; [Header("TF Events")]
[Header("Events")]
public UnityEvent onGameStart;
public UnityEvent<bool> onAnswerGiven;
public UnityEvent<int> onProgressChanged; public UnityEvent<int> onProgressChanged;
public UnityEvent onGameComplete; public UnityEvent onGameComplete;
public UnityEvent onGameOver; public UnityEvent onGameOver;
// --- ADDED: Timer Settings --- // ─── Singleton ────────────────────────────────────────────────────────
[SerializeField] private float maxTimePerQuestion = 30f; protected override void Awake()
[SerializeField] private float feedbackTime = 5;
private float _currentTime;
private bool _timerRunning;
public float GetCurrentTimeRatio()
{
if (maxTimePerQuestion <= 0f)
return 0f;
return _currentTime / maxTimePerQuestion;
}
private void Awake()
{ {
if (Instance != null && Instance != this) { Destroy(gameObject); return; } if (Instance != null && Instance != this) { Destroy(gameObject); return; }
Instance = this; Instance = this;
base.Awake();
} }
public void StartGame() // ─── BaseGameManager implementation ──────────────────────────────────
{ protected override string GameTypeKey => "tf";
StartCoroutine(StartGameRoutine());
_currentTime = maxTimePerQuestion;
_timerRunning = true;
}
public void StartWithQuestions(TfQuestion[] questions)
{ _questions = questions; BeginGameplay(); }
public void SubmitAnswer(bool answer)
{
if (!_waitingForAnswer) return;
_waitingForAnswer = false;
_pendingAnswer = answer ? 1 : 0;
}
public void ResetGame()
{
StopAllCoroutines();
_state = TfGameState.Idle;
_currentIndex = _progress = _score = _streak = 0;
_correctCount = _wrongCount = _totalAsked = 0;
_questions = null;
_waitingForAnswer = false;
_pendingAnswer = -1;
_timerRunning = false;
_currentTime = 0f;
if (productionLine != null) productionLine.ResetLine();
if (questionScreen != null) questionScreen.Clear();
if (handController != null) handController.Reset();
if (uiManager != null) uiManager.ResetUI();
}
private IEnumerator StartGameRoutine() protected override IEnumerator FetchQuestions(Action<string> onError)
{ {
_state = TfGameState.Loading;
if (uiManager != null) uiManager.ShowLoading("جاري تحميل الأسئلة...");
var session = SSGameSession.EnsureInstance(); var session = SSGameSession.EnsureInstance();
var api = SSApiManager.EnsureInstance(); var api = SSApiManager.EnsureInstance();
string error = null;
yield return api.FetchTf( yield return api.FetchTf(
session.buildType, session.classCode, session.buildType, session.classCode,
session.questionCount, session.gradeId, session.questionCount, session.gradeId,
qs => _questions = qs, qs => _questions = qs,
err => error = err err => onError(err)
); );
}
if (error != null || _questions == null || _questions.Length == 0) protected override bool HasValidQuestions() =>
{ _questions != null && _questions.Length > 0;
if (uiManager != null) uiManager.ShowError(error ?? "لا توجد أسئلة");
_state = TfGameState.Idle;
yield break;
}
if (uiManager != null) uiManager.HideLoading(); protected override void OnShowLoading() =>
uiManager?.ShowLoading("جاري تحميل الأسئلة...");
gameStartTime = DateTime.Now; protected override void OnHideLoading() =>
BeginGameplay(); uiManager?.HideLoading();
protected override void OnShowError(string message)
{
uiManager?.ShowError(message);
_state = TfGameState.Idle;
}
protected override void OnTimerTick(float timeLeft) =>
uiManager?.SetTimer(timeLeft);
protected override IEnumerator OnTimeUp()
{
yield return HandleTimeUp();
} }
private void BeginGameplay() protected override void BeginGameplay()
{ {
_currentIndex = _progress = _score = _streak = 0; _progress = 0;
_correctCount = _wrongCount = _totalAsked = 0; // Reset base counters
_currentIndex = _score = _streak = _correctCount = _wrongCount = _totalAsked = 0;
_state = TfGameState.Playing; _state = TfGameState.Playing;
if (uiManager != null) if (uiManager != null)
...@@ -144,40 +103,40 @@ namespace com.al_arcade.tf ...@@ -144,40 +103,40 @@ namespace com.al_arcade.tf
StartCoroutine(GameLoop()); StartCoroutine(GameLoop());
} }
private void Update() // ─── Public API ───────────────────────────────────────────────────────
public void StartWithQuestions(TfQuestion[] questions)
{ {
if (!_timerRunning) return; _questions = questions;
BeginGameplay();
_currentTime -= Time.deltaTime;
if (uiManager != null)
uiManager.SetTimer(_currentTime);
if (_currentTime <= 0f)
{
_currentTime = 0f;
_timerRunning = false;
StartCoroutine(HandleTimeUp());
}
} }
private IEnumerator HandleTimeUp()
{
Debug.Log("Handle Time UP");
_state = TfGameState.GameOver; public void SubmitAnswer(bool answer)
_timerRunning = false; {
if (!_waitingForAnswer) return;
_waitingForAnswer = false;
_pendingAnswer = answer ? 1 : 0;
}
if (productionLine != null && productionLine.machineVFXController != null) public void ResetGame()
productionLine.machineVFXController.PlayExplosion(); {
ResetBaseState(); // clears shared counters + stops coroutines
_state = TfGameState.Idle;
_progress = 0;
_questions = null;
_waitingForAnswer = false;
_pendingAnswer = -1;
yield return new WaitForSeconds(1f); if (productionLine != null) productionLine.ResetLine();
if (questionScreen != null) questionScreen.Clear();
if (handController != null) handController.Reset();
if (uiManager != null) uiManager.ResetUI();
}
if (uiManager != null) // ─── Timer feedback override ──────────────────────────────────────────
uiManager.ShowResults(_score, _correctCount, _wrongCount, false); // TF adjusts time on correct/wrong, so it needs direct access
public float GetTimeLeft() => _timeLeft;
onGameOver?.Invoke(); // ─── Game loop ────────────────────────────────────────────────────────
}
private IEnumerator GameLoop() private IEnumerator GameLoop()
{ {
while (_progress < stepsToWin && _currentIndex < _questions.Length) while (_progress < stepsToWin && _currentIndex < _questions.Length)
...@@ -189,13 +148,11 @@ namespace com.al_arcade.tf ...@@ -189,13 +148,11 @@ namespace com.al_arcade.tf
_waitingForAnswer = true; _waitingForAnswer = true;
_pendingAnswer = -1; _pendingAnswer = -1;
_state = TfGameState.Playing; _state = TfGameState.Playing;
// --- ADDED: Start timer for this question ---
if (handController != null) handController.SetReady(true); if (handController != null) handController.SetReady(true);
while (_pendingAnswer < 0) while (_pendingAnswer < 0)
{ {
if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A)) if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A))
SubmitAnswer(true); SubmitAnswer(true);
if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)) if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D))
...@@ -215,7 +172,7 @@ namespace com.al_arcade.tf ...@@ -215,7 +172,7 @@ namespace com.al_arcade.tf
_correctCount++; _correctCount++;
_streak++; _streak++;
_progress++; _progress++;
_score += 100 + (_streak > 2 ? (_streak - 2) * 25 : 0); _score += CalculateStreakScore(); // shared helper
if (handController != null) handController.PlayCorrectFeedback(playerSaidTrue); if (handController != null) handController.PlayCorrectFeedback(playerSaidTrue);
if (productionLine != null) yield return productionLine.MoveForward(stepDistance); if (productionLine != null) yield return productionLine.MoveForward(stepDistance);
...@@ -226,10 +183,11 @@ namespace com.al_arcade.tf ...@@ -226,10 +183,11 @@ namespace com.al_arcade.tf
{ if (audio.sfxCorrect != null) audio.PlayCorrect(); else audio.PlayCorrectBeep(); } { if (audio.sfxCorrect != null) audio.PlayCorrect(); else audio.PlayCorrectBeep(); }
var particles = SSParticleManager.Instance; var particles = SSParticleManager.Instance;
if (particles != null && Camera.main != null) if (particles != null)
particles.PlayCorrectBurst(new Vector3(-2, 6f, 13)); particles.PlayCorrectBurst(new Vector3(-2, 6f, 13));
_currentTime += 4;
uiManager?.UpdateTimer(_currentTime, true); UpdateTimerBy(4f); // shared helper
uiManager?.UpdateTimer(_timeLeft, true);
} }
else else
{ {
...@@ -251,12 +209,14 @@ namespace com.al_arcade.tf ...@@ -251,12 +209,14 @@ namespace com.al_arcade.tf
Camera.main.transform.DOShakePosition(0.4f, 0.3f, 15) Camera.main.transform.DOShakePosition(0.4f, 0.3f, 15)
.SetEase(Ease.OutQuad).SetId("camShake"); .SetEase(Ease.OutQuad).SetId("camShake");
} }
_currentTime -= 2;
uiManager?.UpdateTimer(_currentTime, false); UpdateTimerBy(-2f); // shared helper
uiManager?.UpdateTimer(_timeLeft, false);
} }
onAnswerGiven?.Invoke(isCorrect); onAnswerGiven?.Invoke(isCorrect);
onProgressChanged?.Invoke(_progress); onProgressChanged?.Invoke(_progress);
if (uiManager != null) if (uiManager != null)
{ {
uiManager.SetProgress(_progress, stepsToWin); uiManager.SetProgress(_progress, stepsToWin);
...@@ -276,11 +236,23 @@ namespace com.al_arcade.tf ...@@ -276,11 +236,23 @@ namespace com.al_arcade.tf
} }
} }
private IEnumerator VictorySequence() // ─── End sequences ────────────────────────────────────────────────────
private IEnumerator HandleTimeUp()
{ {
Debug.Log("victorySequance"); _state = TfGameState.GameOver;
if (productionLine?.machineVFXController != null)
productionLine.machineVFXController.PlayExplosion();
yield return new WaitForSeconds(1f);
uiManager?.ShowResults(_score, _correctCount, _wrongCount, false);
onGameOver?.Invoke();
}
private IEnumerator VictorySequence()
{
_timerRunning = false; _timerRunning = false;
var audio = SSAudioManager.Instance; var audio = SSAudioManager.Instance;
if (audio != null) if (audio != null)
{ if (audio.sfxVictory != null) audio.PlayVictory(); else audio.PlaySuccessJingle(); } { if (audio.sfxVictory != null) audio.PlayVictory(); else audio.PlaySuccessJingle(); }
...@@ -292,15 +264,14 @@ namespace com.al_arcade.tf ...@@ -292,15 +264,14 @@ namespace com.al_arcade.tf
productionLine.machineVFXController.StopAllVFX(); productionLine.machineVFXController.StopAllVFX();
yield return new WaitForSeconds(1.5f); yield return new WaitForSeconds(1.5f);
if (uiManager != null) uiManager?.ShowResults(_score, _correctCount, _wrongCount, true);
uiManager.ShowResults(_score, _correctCount, _wrongCount, true); onGameComplete?.Invoke();
GameHistoryService.Instance.AddGame("tf", _score, gameStartTime, DateTime.Now);
RecordGameHistory(); // shared helper
} }
// ─── Extra public accessors ───────────────────────────────────────────
public int Progress => _progress; public int Progress => _progress;
public int StepsToWin => stepsToWin; public int StepsToWin => stepsToWin;
public int Score => _score;
} }
} }
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Correct The Sentence</title>
<!-- ═══ ANTI-CACHE ═══ -->
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<!-- ═══ PRECONNECT TO CDN — speeds up HLS chunk fetching ═══ -->
<!-- Replace with your actual PeerTube domain -->
<link rel="preconnect" href="https://your-peertube-instance.com" crossorigin>
<link rel="dns-prefetch" href="https://your-peertube-instance.com">
<!-- ═══ PRELOAD HLS.js — starts downloading before Unity even loads ═══ -->
<link rel="preload" href="https://cdn.jsdelivr.net/npm/hls.js@1.5.17/dist/hls.min.js" as="script" crossorigin>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
/* Prevent pull-to-refresh on mobile */
overscroll-behavior: none;
touch-action: none;
}
#unity-container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #000;
}
#unity-canvas {
background: #000;
/* Prevent blurry scaling */
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
}
/* ═══ LOADING SCREEN ═══ */
#loading-screen {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 1000;
transition: opacity 0.5s ease;
}
#loading-screen.fade-out {
opacity: 0;
pointer-events: none;
}
#loading-logo {
max-width: 200px;
max-height: 200px;
margin-bottom: 40px;
animation: logoPulse 2s ease-in-out infinite;
}
@keyframes logoPulse {
0%, 100% { transform: scale(1); opacity: 0.9; }
50% { transform: scale(1.05); opacity: 1; }
}
#loading-bar-container {
width: 280px;
height: 6px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
overflow: hidden;
margin-bottom: 16px;
}
#loading-bar {
width: 0%;
height: 100%;
background: #FED700;
border-radius: 3px;
transition: width 0.3s ease;
box-shadow: 0 0 10px rgba(254, 215, 0, 0.4);
}
#loading-text {
color: rgba(255, 255, 255, 0.5);
font-size: 13px;
letter-spacing: 0.5px;
}
</style>
</head>
<body>
<div id="unity-container">
<canvas id="unity-canvas" tabindex="-1"></canvas>
</div>
<div id="loading-screen">
<img id="loading-logo" src="logo.png" alt="Loading">
<div id="loading-bar-container">
<div id="loading-bar"></div>
</div>
<div id="loading-text">Loading...</div>
</div>
<script>
// ═══ 16:9 ASPECT RATIO LOCK ═══
function resizeCanvas() {
var container = document.getElementById('unity-container');
var canvas = document.getElementById('unity-canvas');
var windowW = window.innerWidth;
var windowH = window.innerHeight;
var targetAspect = 16 / 9;
var windowAspect = windowW / windowH;
var canvasW, canvasH;
if (windowAspect > targetAspect) {
canvasH = windowH;
canvasW = Math.floor(windowH * targetAspect);
} else {
canvasW = windowW;
canvasH = Math.floor(windowW / targetAspect);
}
canvas.style.width = canvasW + 'px';
canvas.style.height = canvasH + 'px';
canvas.width = canvasW;
canvas.height = canvasH;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
// ═══ PRELOAD HLS.js INTO CACHE BEFORE UNITY BOOTS ═══
// This way when the jslib calls ensureHls(), it's already loaded
(function() {
var hlsScript = document.createElement('script');
hlsScript.src = 'https://cdn.jsdelivr.net/npm/hls.js@1.5.17/dist/hls.min.js';
hlsScript.async = true;
document.head.appendChild(hlsScript);
})();
// ═══ UNITY LOADER ═══
var loadingBar = document.getElementById('loading-bar');
var loadingText = document.getElementById('loading-text');
var loadingScreen = document.getElementById('loading-screen');
// Cache-bust the loader URL in development
// Remove the timestamp parameter for production
var buildUrl = "Build";
var cacheBust = ""; // Set to "?t=" + Date.now() during development
var loaderUrl = buildUrl + "/CS Build.loader.js" + cacheBust;
var config = {
dataUrl: buildUrl + "/CS Build.data",
frameworkUrl: buildUrl + "/CS Build.framework.js",
codeUrl: buildUrl + "/CS Build.wasm",
streamingAssetsUrl: "StreamingAssets",
companyName: "DefaultCompany",
productName: "Correct The Sentence",
productVersion: "0.1.0",
// ═══ MEMORY SETTINGS ═══
// Match what you set in Player Settings
// These override if present
};
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = function () {
createUnityInstance(
document.getElementById("unity-canvas"),
config,
function (progress) {
var pct = Math.round(progress * 100);
loadingBar.style.width = pct + '%';
loadingText.textContent = pct < 100 ? 'Loading... ' + pct + '%' : 'Starting...';
}
).then(function (instance) {
loadingScreen.classList.add('fade-out');
setTimeout(function () {
loadingScreen.style.display = 'none';
}, 600);
resizeCanvas();
// ═══ PREVENT ACCIDENTAL NAVIGATION ═══
window.addEventListener('beforeunload', function(e) {
e.preventDefault();
e.returnValue = '';
});
}).catch(function (message) {
loadingText.textContent = 'Error: ' + message;
loadingBar.style.background = '#ff3333';
console.error(message);
});
};
document.body.appendChild(script);
// ═══ PREVENT CONTEXT MENU ON CANVAS ═══
document.getElementById('unity-canvas').addEventListener('contextmenu', function(e) {
e.preventDefault();
});
// ═══ FOCUS CANVAS ON CLICK (fixes keyboard input) ═══
document.addEventListener('click', function() {
document.getElementById('unity-canvas').focus();
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Correct The Sentence</title>
<!-- ═══ ANTI-CACHE ═══ -->
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<!-- ═══ PRECONNECT TO CDN — speeds up HLS chunk fetching ═══ -->
<!-- Replace with your actual PeerTube domain -->
<link rel="preconnect" href="https://your-peertube-instance.com" crossorigin>
<link rel="dns-prefetch" href="https://your-peertube-instance.com">
<!-- ═══ PRELOAD HLS.js — starts downloading before Unity even loads ═══ -->
<link rel="preload" href="https://cdn.jsdelivr.net/npm/hls.js@1.5.17/dist/hls.min.js" as="script" crossorigin>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
/* Prevent pull-to-refresh on mobile */
overscroll-behavior: none;
touch-action: none;
}
#unity-container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #000;
}
#unity-canvas {
background: #000;
/* Prevent blurry scaling */
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
}
/* ═══ LOADING SCREEN ═══ */
#loading-screen {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 1000;
transition: opacity 0.5s ease;
}
#loading-screen.fade-out {
opacity: 0;
pointer-events: none;
}
#loading-logo {
max-width: 200px;
max-height: 200px;
margin-bottom: 40px;
animation: logoPulse 2s ease-in-out infinite;
}
@keyframes logoPulse {
0%, 100% { transform: scale(1); opacity: 0.9; }
50% { transform: scale(1.05); opacity: 1; }
}
#loading-bar-container {
width: 280px;
height: 6px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
overflow: hidden;
margin-bottom: 16px;
}
#loading-bar {
width: 0%;
height: 100%;
background: #FED700;
border-radius: 3px;
transition: width 0.3s ease;
box-shadow: 0 0 10px rgba(254, 215, 0, 0.4);
}
#loading-text {
color: rgba(255, 255, 255, 0.5);
font-size: 13px;
letter-spacing: 0.5px;
}
</style>
</head>
<body>
<div id="unity-container">
<canvas id="unity-canvas" tabindex="-1"></canvas>
</div>
<div id="loading-screen">
<img id="loading-logo" src="logo.png" alt="Loading">
<div id="loading-bar-container">
<div id="loading-bar"></div>
</div>
<div id="loading-text">Loading...</div>
</div>
<script>
// ═══ 16:9 ASPECT RATIO LOCK ═══
function resizeCanvas() {
var container = document.getElementById('unity-container');
var canvas = document.getElementById('unity-canvas');
var windowW = window.innerWidth;
var windowH = window.innerHeight;
var targetAspect = 16 / 9;
var windowAspect = windowW / windowH;
var canvasW, canvasH;
if (windowAspect > targetAspect) {
canvasH = windowH;
canvasW = Math.floor(windowH * targetAspect);
} else {
canvasW = windowW;
canvasH = Math.floor(windowW / targetAspect);
}
canvas.style.width = canvasW + 'px';
canvas.style.height = canvasH + 'px';
canvas.width = canvasW;
canvas.height = canvasH;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
// ═══ PRELOAD HLS.js INTO CACHE BEFORE UNITY BOOTS ═══
// This way when the jslib calls ensureHls(), it's already loaded
(function() {
var hlsScript = document.createElement('script');
hlsScript.src = 'https://cdn.jsdelivr.net/npm/hls.js@1.5.17/dist/hls.min.js';
hlsScript.async = true;
document.head.appendChild(hlsScript);
})();
// ═══ UNITY LOADER ═══
var loadingBar = document.getElementById('loading-bar');
var loadingText = document.getElementById('loading-text');
var loadingScreen = document.getElementById('loading-screen');
// Cache-bust the loader URL in development
// Remove the timestamp parameter for production
var buildUrl = "Build";
var cacheBust = ""; // Set to "?t=" + Date.now() during development
var loaderUrl = buildUrl + "/CS Build.loader.js" + cacheBust;
var config = {
dataUrl: buildUrl + "/CS Build.data",
frameworkUrl: buildUrl + "/CS Build.framework.js",
codeUrl: buildUrl + "/CS Build.wasm",
streamingAssetsUrl: "StreamingAssets",
companyName: "DefaultCompany",
productName: "Correct The Sentence",
productVersion: "0.1.0",
// ═══ MEMORY SETTINGS ═══
// Match what you set in Player Settings
// These override if present
};
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = function () {
createUnityInstance(
document.getElementById("unity-canvas"),
config,
function (progress) {
var pct = Math.round(progress * 100);
loadingBar.style.width = pct + '%';
loadingText.textContent = pct < 100 ? 'Loading... ' + pct + '%' : 'Starting...';
}
).then(function (instance) {
loadingScreen.classList.add('fade-out');
setTimeout(function () {
loadingScreen.style.display = 'none';
}, 600);
resizeCanvas();
// ═══ PREVENT ACCIDENTAL NAVIGATION ═══
window.addEventListener('beforeunload', function(e) {
e.preventDefault();
e.returnValue = '';
});
}).catch(function (message) {
loadingText.textContent = 'Error: ' + message;
loadingBar.style.background = '#ff3333';
console.error(message);
});
};
document.body.appendChild(script);
// ═══ PREVENT CONTEXT MENU ON CANVAS ═══
document.getElementById('unity-canvas').addEventListener('contextmenu', function(e) {
e.preventDefault();
});
// ═══ FOCUS CANVAS ON CLICK (fixes keyboard input) ═══
document.addEventListener('click', function() {
document.getElementById('unity-canvas').focus();
});
</script>
</body>
</html>
...@@ -66,14 +66,14 @@ ...@@ -66,14 +66,14 @@
"url": "https://packages.unity.com" "url": "https://packages.unity.com"
}, },
"com.unity.collections": { "com.unity.collections": {
"version": "2.6.5", "version": "2.6.2",
"depth": 1, "depth": 1,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {
"com.unity.burst": "1.8.27", "com.unity.burst": "1.8.23",
"com.unity.mathematics": "1.3.2", "com.unity.mathematics": "1.3.2",
"com.unity.test-framework": "1.4.6", "com.unity.test-framework": "1.4.6",
"com.unity.nuget.mono-cecil": "1.11.6", "com.unity.nuget.mono-cecil": "1.11.5",
"com.unity.test-framework.performance": "3.0.3" "com.unity.test-framework.performance": "3.0.3"
}, },
"url": "https://packages.unity.com" "url": "https://packages.unity.com"
...@@ -217,7 +217,7 @@ ...@@ -217,7 +217,7 @@
} }
}, },
"com.unity.splines": { "com.unity.splines": {
"version": "2.8.4", "version": "2.8.2",
"depth": 1, "depth": 1,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {
......
...@@ -8,41 +8,35 @@ EditorUserSettings: ...@@ -8,41 +8,35 @@ EditorUserSettings:
GraphicsSettingsInspector_UserSettings: GraphicsSettingsInspector_UserSettings:
value: 18134705175a055722080a3115371d4a0d55006876786860616b0471b8b2656eacb72ba5a52a362c3c0ee63201181433fe3e101bf3250b06144ca74c24f1190708e016c213c61a52f91c12cac80fd8edd298e1e4d1fde2cacddeacbcc1fee7eef0e3b6faa69af9ceaeaaec81a6d2c2c8c8c4b2e5dfd5ccd3f8cf value: 18134705175a055722080a3115371d4a0d55006876786860616b0471b8b2656eacb72ba5a52a362c3c0ee63201181433fe3e101bf3250b06144ca74c24f1190708e016c213c61a52f91c12cac80fd8edd298e1e4d1fde2cacddeacbcc1fee7eef0e3b6faa69af9ceaeaaec81a6d2c2c8c8c4b2e5dfd5ccd3f8cf
flags: 0 flags: 0
QuickInstaller_com.unity.purchasing_installRecorded:
value: 2550581500
flags: 0
QuickInstaller_com.unity.services.levelplay_installRecorded:
value: 2550581500
flags: 0
RecentlyUsedSceneGuid-0: RecentlyUsedSceneGuid-0:
value: 545005025c000d0b0f5c087516715944424e4d7b747e2568287e4c64b6e1316e value: 5208560200560f090f5d5e2743730e444516192b757e23667b7e4863b4e36c39
flags: 0 flags: 0
RecentlyUsedSceneGuid-1: RecentlyUsedSceneGuid-1:
value: 0003525055055d020e0b0a7216755d444215417e787d27362e2f4866b2e1323e value: 5200570406560d58095e5c75432609124f154e737a2d2432787e4b62b4e1366a
flags: 0 flags: 0
RecentlyUsedSceneGuid-2: RecentlyUsedSceneGuid-2:
value: 5305515503010a0e0f580977147208444e151a78787b726775711931bbe1613e value: 545005025c000d0b0f5c087516715944424e4d7b747e2568287e4c64b6e1316e
flags: 0 flags: 0
RecentlyUsedSceneGuid-3: RecentlyUsedSceneGuid-3:
value: 5304575f5c0c51035d5a5e771271594417154e7c2d7b70647b7b4c35bbe1646d value: 5305515503010a0e0f580977147208444e151a78787b726775711931bbe1613e
flags: 0 flags: 0
RecentlyUsedSceneGuid-4: RecentlyUsedSceneGuid-4:
value: 0752035101010f0c54595b2046760e44134e4e7a7f7d71677c2c4836b7b4633e value: 52080c51560d5f03580b5e7242700c4446164f7d2e7f77612c281f32e0b8603d
flags: 0 flags: 0
RecentlyUsedSceneGuid-5: RecentlyUsedSceneGuid-5:
value: 5701055506000a030f5c542744260844404f4d73797975367c2c1e6ab7e2653d value: 060203560401505a595d0a7345200d44404e1b7e2d707e617b7f4d63e7b6606b
flags: 0 flags: 0
RecentlyUsedSceneGuid-6: RecentlyUsedSceneGuid-6:
value: 060203560401505a595d0a7345200d44404e1b7e2d707e617b7f4d63e7b6606b value: 0003525055055d020e0b0a7216755d444215417e787d27362e2f4866b2e1323e
flags: 0 flags: 0
RecentlyUsedSceneGuid-7: RecentlyUsedSceneGuid-7:
value: 550051035503595d5d0a5975167a0e44144e40797a7924632b7c456bb7b23260 value: 5701055506000a030f5c542744260844404f4d73797975367c2c1e6ab7e2653d
flags: 0 flags: 0
RecentlyUsedSceneGuid-8: RecentlyUsedSceneGuid-8:
value: 52080c51560d5f03580b5e7242700c4446164f7d2e7f77612c281f32e0b8603d value: 0752035101010f0c54595b2046760e44134e4e7a7f7d71677c2c4836b7b4633e
flags: 0 flags: 0
RecentlyUsedSceneGuid-9: RecentlyUsedSceneGuid-9:
value: 51070402040250035b0d097b42250e44434e19737d7b7f617c7b4c63e3b33068 value: 5304575f5c0c51035d5a5e771271594417154e7c2d7b70647b7b4c35bbe1646d
flags: 0 flags: 0
UnityEditor.ShaderGraph.Blackboard: UnityEditor.ShaderGraph.Blackboard:
value: 18135939215a0a5004000b0e15254b524c030a3f2964643d120d1230e9e93a3fd6e826abbd2e2d293c4ead313b08042de6030a0afa240c0d020be94c4ba75e435d8715fa32c70d15d11612dacc11fee5d3c5d1fe9ab1bf968e93e2ffcbc3e7e2f0b3ffe0e8b0be9af8ffaeffff8e85dd8390e3949c8899daa7 value: 18135939215a0a5004000b0e15254b524c030a3f2964643d120d1230e9e93a3fd6e826abbd2e2d293c4ead313b08042de6030a0afa240c0d020be94c4ba75e435d8715fa32c70d15d11612dacc11fee5d3c5d1fe9ab1bf968e93e2ffcbc3e7e2f0b3ffe0e8b0be9af8ffaeffff8e85dd8390e3949c8899daa7
......
...@@ -19,12 +19,12 @@ MonoBehaviour: ...@@ -19,12 +19,12 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 36 y: 36
width: 1918 width: 1536
height: 932 height: 716.8
m_MinSize: {x: 300, y: 112} m_MinSize: {x: 300, y: 112}
m_MaxSize: {x: 24288, y: 16192} m_MaxSize: {x: 24288, y: 16192}
vertical: 0 vertical: 0
controlID: 37 controlID: 3930
draggingID: 0 draggingID: 0
--- !u!114 &2 --- !u!114 &2
MonoBehaviour: MonoBehaviour:
...@@ -42,15 +42,15 @@ MonoBehaviour: ...@@ -42,15 +42,15 @@ MonoBehaviour:
m_MaxSize: {x: 4000, y: 4000} m_MaxSize: {x: 4000, y: 4000}
m_TitleContent: m_TitleContent:
m_Text: Game m_Text: Game
m_Image: {fileID: -6423792434712278376, guid: 0000000000000000d000000000000000, type: 0} m_Image: {fileID: 4621777727084837110, guid: 0000000000000000d000000000000000, type: 0}
m_Tooltip: m_Tooltip:
m_TextWithWhitespace: "Game\u200B" m_TextWithWhitespace: "Game\u200B"
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 358 x: 286.4
y: 87 y: 79.200005
width: 1105 width: 884.4
height: 573 height: 355.6
m_SerializedDataModeController: m_SerializedDataModeController:
m_DataMode: 0 m_DataMode: 0
m_PreferredDataMode: 0 m_PreferredDataMode: 0
...@@ -70,7 +70,7 @@ MonoBehaviour: ...@@ -70,7 +70,7 @@ MonoBehaviour:
m_ShowGizmos: 0 m_ShowGizmos: 0
m_TargetDisplay: 0 m_TargetDisplay: 0
m_ClearColor: {r: 0, g: 0, b: 0, a: 0} m_ClearColor: {r: 0, g: 0, b: 0, a: 0}
m_TargetSize: {x: 1080, y: 2400} m_TargetSize: {x: 1080, y: 1920}
m_TextureFilterMode: 0 m_TextureFilterMode: 0
m_TextureHideFlags: 61 m_TextureHideFlags: 61
m_RenderIMGUI: 1 m_RenderIMGUI: 1
...@@ -79,16 +79,16 @@ MonoBehaviour: ...@@ -79,16 +79,16 @@ MonoBehaviour:
m_VSyncEnabled: 0 m_VSyncEnabled: 0
m_Gizmos: 0 m_Gizmos: 0
m_Stats: 0 m_Stats: 0
m_SelectedSizes: 07000000000000000000000000000000000000000000000000000000000000000000000000000000 m_SelectedSizes: 08000000000000000000000000000000000000000000000000000000000000000000000000000000
m_ZoomArea: m_ZoomArea:
m_HRangeLocked: 0 m_HRangeLocked: 0
m_VRangeLocked: 0 m_VRangeLocked: 0
hZoomLockedByDefault: 0 hZoomLockedByDefault: 0
vZoomLockedByDefault: 0 vZoomLockedByDefault: 0
m_HBaseRangeMin: -540 m_HBaseRangeMin: -432
m_HBaseRangeMax: 540 m_HBaseRangeMax: 432
m_VBaseRangeMin: -1200 m_VBaseRangeMin: -768
m_VBaseRangeMax: 1200 m_VBaseRangeMax: 768
m_HAllowExceedBaseRangeMin: 1 m_HAllowExceedBaseRangeMin: 1
m_HAllowExceedBaseRangeMax: 1 m_HAllowExceedBaseRangeMax: 1
m_VAllowExceedBaseRangeMin: 1 m_VAllowExceedBaseRangeMin: 1
...@@ -97,7 +97,7 @@ MonoBehaviour: ...@@ -97,7 +97,7 @@ MonoBehaviour:
m_HSlider: 0 m_HSlider: 0
m_VSlider: 0 m_VSlider: 0
m_IgnoreScrollWheelUntilClicked: 0 m_IgnoreScrollWheelUntilClicked: 0
m_EnableMouseInput: 1 m_EnableMouseInput: 0
m_EnableSliderZoomHorizontal: 0 m_EnableSliderZoomHorizontal: 0
m_EnableSliderZoomVertical: 0 m_EnableSliderZoomVertical: 0
m_UniformScale: 1 m_UniformScale: 1
...@@ -106,23 +106,23 @@ MonoBehaviour: ...@@ -106,23 +106,23 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 21 y: 21
width: 1105 width: 884.4
height: 552 height: 334.6
m_Scale: {x: 0.23, y: 0.23} m_Scale: {x: 0.21783854, y: 0.21783854}
m_Translation: {x: 552.5, y: 276} m_Translation: {x: 442.2, y: 167.3}
m_MarginLeft: 0 m_MarginLeft: 0
m_MarginRight: 0 m_MarginRight: 0
m_MarginTop: 0 m_MarginTop: 0
m_MarginBottom: 0 m_MarginBottom: 0
m_LastShownAreaInsideMargins: m_LastShownAreaInsideMargins:
serializedVersion: 2 serializedVersion: 2
x: -2402.1738 x: -2029.9438
y: -1200 y: -768
width: 4804.3477 width: 4059.8877
height: 2400 height: 1536
m_MinimalGUI: 1 m_MinimalGUI: 1
m_defaultScale: 0.23 m_defaultScale: 0.21783854
m_LastWindowPixelSize: {x: 1105, y: 573} m_LastWindowPixelSize: {x: 1105.5, y: 444.5}
m_ClearInEditMode: 1 m_ClearInEditMode: 1
m_NoCameraWarning: 1 m_NoCameraWarning: 1
m_LowResolutionForAspectRatios: 01000000000000000000 m_LowResolutionForAspectRatios: 01000000000000000000
...@@ -148,12 +148,12 @@ MonoBehaviour: ...@@ -148,12 +148,12 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 0 y: 0
width: 1464 width: 1172.8
height: 932 height: 716.8
m_MinSize: {x: 200, y: 112} m_MinSize: {x: 200, y: 112}
m_MaxSize: {x: 16192, y: 16192} m_MaxSize: {x: 16192, y: 16192}
vertical: 1 vertical: 1
controlID: 38 controlID: 3931
draggingID: 0 draggingID: 0
--- !u!114 &4 --- !u!114 &4
MonoBehaviour: MonoBehaviour:
...@@ -174,12 +174,12 @@ MonoBehaviour: ...@@ -174,12 +174,12 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 0 y: 0
width: 1464 width: 1172.8
height: 599 height: 381.6
m_MinSize: {x: 200, y: 56} m_MinSize: {x: 200, y: 56}
m_MaxSize: {x: 16192, y: 8096} m_MaxSize: {x: 16192, y: 8096}
vertical: 0 vertical: 0
controlID: 39 controlID: 3932
draggingID: 0 draggingID: 0
--- !u!114 &5 --- !u!114 &5
MonoBehaviour: MonoBehaviour:
...@@ -198,8 +198,8 @@ MonoBehaviour: ...@@ -198,8 +198,8 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 0 y: 0
width: 357 width: 286.4
height: 599 height: 381.6
m_MinSize: {x: 201, y: 226} m_MinSize: {x: 201, y: 226}
m_MaxSize: {x: 4001, y: 4026} m_MaxSize: {x: 4001, y: 4026}
m_ActualView: {fileID: 6} m_ActualView: {fileID: 6}
...@@ -223,15 +223,15 @@ MonoBehaviour: ...@@ -223,15 +223,15 @@ MonoBehaviour:
m_MaxSize: {x: 4000, y: 4000} m_MaxSize: {x: 4000, y: 4000}
m_TitleContent: m_TitleContent:
m_Text: Hierarchy m_Text: Hierarchy
m_Image: {fileID: 7966133145522015247, guid: 0000000000000000d000000000000000, type: 0} m_Image: {fileID: -3734745235275155857, guid: 0000000000000000d000000000000000, type: 0}
m_Tooltip: m_Tooltip:
m_TextWithWhitespace: "Hierarchy\u200B" m_TextWithWhitespace: "Hierarchy\u200B"
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 1 x: 0
y: 87 y: 79.200005
width: 356 width: 285.4
height: 573 height: 355.6
m_SerializedDataModeController: m_SerializedDataModeController:
m_DataMode: 0 m_DataMode: 0
m_PreferredDataMode: 0 m_PreferredDataMode: 0
...@@ -249,12 +249,19 @@ MonoBehaviour: ...@@ -249,12 +249,19 @@ MonoBehaviour:
m_TreeViewState: m_TreeViewState:
scrollPos: {x: 0, y: 0} scrollPos: {x: 0, y: 0}
m_SelectedIDs: m_SelectedIDs:
- m_Data: 59072 - m_Data: 64640
m_LastClickedID: m_LastClickedID:
m_Data: 0 m_Data: 0
m_ExpandedIDs: m_ExpandedIDs:
- m_Data: -2498 - m_Data: -54772
- m_Data: -1512 - m_Data: -53964
- m_Data: -21446
- m_Data: -19514
- m_Data: -16700
- m_Data: -15986
- m_Data: -3176
- m_Data: -3004
- m_Data: -1588
m_RenameOverlay: m_RenameOverlay:
m_UserAcceptedRename: 0 m_UserAcceptedRename: 0
m_Name: m_Name:
...@@ -295,10 +302,10 @@ MonoBehaviour: ...@@ -295,10 +302,10 @@ MonoBehaviour:
m_Children: [] m_Children: []
m_Position: m_Position:
serializedVersion: 2 serializedVersion: 2
x: 357 x: 286.4
y: 0 y: 0
width: 1107 width: 886.4
height: 599 height: 381.6
m_MinSize: {x: 202, y: 226} m_MinSize: {x: 202, y: 226}
m_MaxSize: {x: 4002, y: 4026} m_MaxSize: {x: 4002, y: 4026}
m_ActualView: {fileID: 2} m_ActualView: {fileID: 2}
...@@ -323,15 +330,15 @@ MonoBehaviour: ...@@ -323,15 +330,15 @@ MonoBehaviour:
m_MaxSize: {x: 4000, y: 4000} m_MaxSize: {x: 4000, y: 4000}
m_TitleContent: m_TitleContent:
m_Text: Scene m_Text: Scene
m_Image: {fileID: 2593428753322112591, guid: 0000000000000000d000000000000000, type: 0} m_Image: {fileID: 8634526014445323508, guid: 0000000000000000d000000000000000, type: 0}
m_Tooltip: m_Tooltip:
m_TextWithWhitespace: "Scene\u200B" m_TextWithWhitespace: "Scene\u200B"
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 355 x: 286.4
y: 61 y: 79.200005
width: 1097 width: 884.4
height: 606 height: 355.6
m_SerializedDataModeController: m_SerializedDataModeController:
m_DataMode: 0 m_DataMode: 0
m_PreferredDataMode: 0 m_PreferredDataMode: 0
...@@ -388,12 +395,12 @@ MonoBehaviour: ...@@ -388,12 +395,12 @@ MonoBehaviour:
displayed: 1 displayed: 1
id: unity-scene-view-toolbar id: unity-scene-view-toolbar
index: 0 index: 0
contents: '{"m_Layout":4,"m_Collapsed":false,"m_Folded":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":-322.0,"y":25.0},"m_SnapOffsetDelta":{"x":0.0,"y":0.0},"m_FloatingSnapCorner":1,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}' contents: '{"m_Layout":4,"m_Collapsed":false,"m_Folded":false,"m_Floating":false,"m_FloatingSnapOffset":{"x":-322.0,"y":-331.0},"m_SnapOffsetDelta":{"x":0.0,"y":0.0},"m_FloatingSnapCorner":3,"m_Size":{"x":0.0,"y":0.0},"m_SizeOverridden":false}'
floating: 0 floating: 0
collapsed: 0 collapsed: 0
snapOffset: {x: -322, y: 25} snapOffset: {x: -322, y: -331}
snapOffsetDelta: {x: 0, y: 0} snapOffsetDelta: {x: 0, y: 0}
snapCorner: 1 snapCorner: 3
layout: 4 layout: 4
size: {x: 0, y: 0} size: {x: 0, y: 0}
sizeOverridden: 0 sizeOverridden: 0
...@@ -916,9 +923,9 @@ MonoBehaviour: ...@@ -916,9 +923,9 @@ MonoBehaviour:
m_AudioPlay: 0 m_AudioPlay: 0
m_DebugDrawModesUseInteractiveLightBakingData: 0 m_DebugDrawModesUseInteractiveLightBakingData: 0
m_Position: m_Position:
m_Target: {x: 254.03662, y: 356.294, z: 0} m_Target: {x: 540, y: 960, z: 0}
speed: 2 speed: 2
m_Value: {x: 632.0484, y: 1166.8389, z: -2.3196595} m_Value: {x: 540, y: 960, z: 0}
m_RenderMode: 0 m_RenderMode: 0
m_CameraMode: m_CameraMode:
drawMode: 0 drawMode: 0
...@@ -931,10 +938,10 @@ MonoBehaviour: ...@@ -931,10 +938,10 @@ MonoBehaviour:
showFog: 1 showFog: 1
showSkybox: 1 showSkybox: 1
showFlares: 1 showFlares: 1
showImageEffects: 0 showImageEffects: 1
showParticleSystems: 1 showParticleSystems: 1
showVisualEffectGraphs: 1 showVisualEffectGraphs: 1
m_FxEnabled: 1 m_FxEnabled: 0
m_Grid: m_Grid:
xGrid: xGrid:
m_Fade: m_Fade:
...@@ -968,9 +975,9 @@ MonoBehaviour: ...@@ -968,9 +975,9 @@ MonoBehaviour:
speed: 2 speed: 2
m_Value: {x: 0, y: 0, z: 0, w: 1} m_Value: {x: 0, y: 0, z: 0, w: 1}
m_Size: m_Size:
m_Target: 76.6172 m_Target: 1142.1276
speed: 2 speed: 2
m_Value: 311.54352 m_Value: 1142.1276
m_Ortho: m_Ortho:
m_Target: 1 m_Target: 1
speed: 2 speed: 2
...@@ -1020,9 +1027,9 @@ MonoBehaviour: ...@@ -1020,9 +1027,9 @@ MonoBehaviour:
m_Position: m_Position:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 599 y: 381.6
width: 1464 width: 1172.8
height: 333 height: 335.19998
m_MinSize: {x: 231, y: 276} m_MinSize: {x: 231, y: 276}
m_MaxSize: {x: 10001, y: 10026} m_MaxSize: {x: 10001, y: 10026}
m_ActualView: {fileID: 10} m_ActualView: {fileID: 10}
...@@ -1049,15 +1056,15 @@ MonoBehaviour: ...@@ -1049,15 +1056,15 @@ MonoBehaviour:
m_MaxSize: {x: 10000, y: 10000} m_MaxSize: {x: 10000, y: 10000}
m_TitleContent: m_TitleContent:
m_Text: Project m_Text: Project
m_Image: {fileID: -5467254957812901981, guid: 0000000000000000d000000000000000, type: 0} m_Image: {fileID: -5179483145760003458, guid: 0000000000000000d000000000000000, type: 0}
m_Tooltip: m_Tooltip:
m_TextWithWhitespace: "Project\u200B" m_TextWithWhitespace: "Project\u200B"
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 1 x: 0
y: 686 y: 460.80002
width: 1463 width: 1171.8
height: 307 height: 309.19998
m_SerializedDataModeController: m_SerializedDataModeController:
m_DataMode: 0 m_DataMode: 0
m_PreferredDataMode: 0 m_PreferredDataMode: 0
...@@ -1082,7 +1089,7 @@ MonoBehaviour: ...@@ -1082,7 +1089,7 @@ MonoBehaviour:
m_SkipHidden: 0 m_SkipHidden: 0
m_SearchArea: 1 m_SearchArea: 1
m_Folders: m_Folders:
- Assets/AppUI/Scenes - Assets/Scenes/MCQ
m_Globs: [] m_Globs: []
m_ProductIds: m_ProductIds:
m_AnyWithAssetOrigin: 0 m_AnyWithAssetOrigin: 0
...@@ -1092,24 +1099,22 @@ MonoBehaviour: ...@@ -1092,24 +1099,22 @@ MonoBehaviour:
m_ViewMode: 1 m_ViewMode: 1
m_StartGridSize: 96 m_StartGridSize: 96
m_LastFolders: m_LastFolders:
- Assets/AppUI/Scenes - Assets/Scenes/MCQ
m_LastFoldersGridSize: 96 m_LastFoldersGridSize: 96
m_LastProjectPath: D:\Dev\Projects\SSBookMinigames\My project m_LastProjectPath: D:\saad work\Unity project\SSbookminigames\My project
m_LockTracker: m_LockTracker:
m_IsLocked: 0 m_IsLocked: 0
m_LastLocalAssetsSearchArea: 1 m_LastLocalAssetsSearchArea: 1
m_FolderTreeState: m_FolderTreeState:
scrollPos: {x: 0, y: 79} scrollPos: {x: 0, y: 298.71942}
m_SelectedIDs: m_SelectedIDs:
- m_Data: 59058 - m_Data: 57302
m_LastClickedID: m_LastClickedID:
m_Data: 59058 m_Data: 57302
m_ExpandedIDs: m_ExpandedIDs:
- m_Data: 0 - m_Data: 0
- m_Data: 58550 - m_Data: 56834
- m_Data: 58882 - m_Data: 57232
- m_Data: 1000000000
- m_Data: 2147483647
m_RenameOverlay: m_RenameOverlay:
m_UserAcceptedRename: 0 m_UserAcceptedRename: 0
m_Name: m_Name:
...@@ -1142,7 +1147,7 @@ MonoBehaviour: ...@@ -1142,7 +1147,7 @@ MonoBehaviour:
m_Data: 0 m_Data: 0
m_ExpandedIDs: m_ExpandedIDs:
- m_Data: 0 - m_Data: 0
- m_Data: 58550 - m_Data: 56834
m_RenameOverlay: m_RenameOverlay:
m_UserAcceptedRename: 0 m_UserAcceptedRename: 0
m_Name: m_Name:
...@@ -1170,9 +1175,9 @@ MonoBehaviour: ...@@ -1170,9 +1175,9 @@ MonoBehaviour:
m_ResourceFile: m_ResourceFile:
m_ListAreaState: m_ListAreaState:
m_SelectedInstanceIDs: m_SelectedInstanceIDs:
- m_Data: 59072 - m_Data: 64640
m_LastClickedInstanceID: 59072 m_LastClickedInstanceID: 64640
m_HadKeyboardFocusLastEvent: 1 m_HadKeyboardFocusLastEvent: 0
m_ExpandedInstanceIDs: m_ExpandedInstanceIDs:
- m_Data: 46526 - m_Data: 46526
- m_Data: 61214 - m_Data: 61214
...@@ -1222,15 +1227,15 @@ MonoBehaviour: ...@@ -1222,15 +1227,15 @@ MonoBehaviour:
m_MaxSize: {x: 4000, y: 4000} m_MaxSize: {x: 4000, y: 4000}
m_TitleContent: m_TitleContent:
m_Text: Console m_Text: Console
m_Image: {fileID: -4327648978806127646, guid: 0000000000000000d000000000000000, type: 0} m_Image: {fileID: -4950941429401207979, guid: 0000000000000000d000000000000000, type: 0}
m_Tooltip: m_Tooltip:
m_TextWithWhitespace: "Console\u200B" m_TextWithWhitespace: "Console\u200B"
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 1 x: 0
y: 686 y: 460.80002
width: 1463 width: 1171.8
height: 307 height: 309.19998
m_SerializedDataModeController: m_SerializedDataModeController:
m_DataMode: 0 m_DataMode: 0
m_PreferredDataMode: 0 m_PreferredDataMode: 0
...@@ -1260,15 +1265,15 @@ MonoBehaviour: ...@@ -1260,15 +1265,15 @@ MonoBehaviour:
m_MaxSize: {x: 4000, y: 4000} m_MaxSize: {x: 4000, y: 4000}
m_TitleContent: m_TitleContent:
m_Text: Animation m_Text: Animation
m_Image: {fileID: -8166618308981325432, guid: 0000000000000000d000000000000000, type: 0} m_Image: {fileID: -3237396543322336831, guid: 0000000000000000d000000000000000, type: 0}
m_Tooltip: m_Tooltip:
m_TextWithWhitespace: "Animation\u200B" m_TextWithWhitespace: "Animation\u200B"
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 1 x: 0
y: 678 y: 460.80002
width: 1464 width: 1171.8
height: 349 height: 309.19998
m_SerializedDataModeController: m_SerializedDataModeController:
m_DataMode: 0 m_DataMode: 0
m_PreferredDataMode: 0 m_PreferredDataMode: 0
...@@ -1284,7 +1289,7 @@ MonoBehaviour: ...@@ -1284,7 +1289,7 @@ MonoBehaviour:
m_DynamicPanelBehavior: 0 m_DynamicPanelBehavior: 0
m_LockTracker: m_LockTracker:
m_IsLocked: 0 m_IsLocked: 0
m_LastSelectedObjectID: 0 m_LastSelectedObjectID: 64640
--- !u!114 &13 --- !u!114 &13
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 52 m_ObjectHideFlags: 52
...@@ -1301,15 +1306,15 @@ MonoBehaviour: ...@@ -1301,15 +1306,15 @@ MonoBehaviour:
m_MaxSize: {x: 4000, y: 4000} m_MaxSize: {x: 4000, y: 4000}
m_TitleContent: m_TitleContent:
m_Text: Animator m_Text: Animator
m_Image: {fileID: -1673928668082335149, guid: 0000000000000000d000000000000000, type: 0} m_Image: {fileID: 1711060831702674872, guid: 0000000000000000d000000000000000, type: 0}
m_Tooltip: m_Tooltip:
m_TextWithWhitespace: "Animator\u200B" m_TextWithWhitespace: "Animator\u200B"
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 680 y: 460.80002
width: 1466 width: 1171.8
height: 359 height: 309.19998
m_SerializedDataModeController: m_SerializedDataModeController:
m_DataMode: 0 m_DataMode: 0
m_PreferredDataMode: 0 m_PreferredDataMode: 0
...@@ -1355,10 +1360,10 @@ MonoBehaviour: ...@@ -1355,10 +1360,10 @@ MonoBehaviour:
m_Children: [] m_Children: []
m_Position: m_Position:
serializedVersion: 2 serializedVersion: 2
x: 1464 x: 1172.8
y: 0 y: 0
width: 454 width: 363.19995
height: 932 height: 716.8
m_MinSize: {x: 276, y: 76} m_MinSize: {x: 276, y: 76}
m_MaxSize: {x: 4001, y: 4026} m_MaxSize: {x: 4001, y: 4026}
m_ActualView: {fileID: 15} m_ActualView: {fileID: 15}
...@@ -1382,15 +1387,15 @@ MonoBehaviour: ...@@ -1382,15 +1387,15 @@ MonoBehaviour:
m_MaxSize: {x: 4000, y: 4000} m_MaxSize: {x: 4000, y: 4000}
m_TitleContent: m_TitleContent:
m_Text: Inspector m_Text: Inspector
m_Image: {fileID: -2667387946076563598, guid: 0000000000000000d000000000000000, type: 0} m_Image: {fileID: -440750813802333266, guid: 0000000000000000d000000000000000, type: 0}
m_Tooltip: m_Tooltip:
m_TextWithWhitespace: "Inspector\u200B" m_TextWithWhitespace: "Inspector\u200B"
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 1465 x: 1172.8
y: 87 y: 79.200005
width: 453 width: 362.19995
height: 906 height: 690.8
m_SerializedDataModeController: m_SerializedDataModeController:
m_DataMode: 0 m_DataMode: 0
m_PreferredDataMode: 0 m_PreferredDataMode: 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment