Commit a7f8360f authored by Yousef Sameh's avatar Yousef Sameh

Merge remote-tracking branch 'origin/pt_minigames' into NewUI

# Conflicts:
#	My project/Assets/AppUI/NewAppUI/Scene/Login.unity
#	My project/Assets/ScienceStreet/Features/Challenge/ChallengeManager.cs
parents 9807f3e4 0652cde1
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:
This diff is collapsed.
This diff is collapsed.
......@@ -7,10 +7,8 @@ using UnityEngine.Events;
namespace com.al_arcade.cs
{
using System.Linq;
using shared;
using Unity.Cinemachine;
using UnityEngine.SceneManagement;
public enum CsGameState
{
......@@ -151,8 +149,16 @@ namespace com.al_arcade.cs
if (uiManager != null)
{
uiManager.ShowGameUI();
uiManager.SetScore(0);
uiManager.SetProgress(0, _questions.Length);
uiManager.EnableScore(IsChallengeMode);
if (IsChallengeMode && ChallengeManager.Instance != null)
{
uiManager.SetScore(ChallengeManager.Instance.TimeSaved);
}
else
{
uiManager.SetScore(0);
}
}
onGameStart?.Invoke();
......@@ -316,7 +322,6 @@ namespace com.al_arcade.cs
if (uiManager != null)
{
uiManager.ShowFeedback($"ممتاز! {points}+", true);
uiManager.SetScore(_score);
uiManager.SetStreak(_streak);
}
......
......@@ -198,7 +198,6 @@ namespace com.al_arcade.cs
Debug.LogError("[CS] Canvas prefab is missing CsUIManager!");
yield break;
}
}
else
{
......
......@@ -20,7 +20,7 @@ namespace com.al_arcade.cs
[SerializeField] protected CanvasGroup _optionsPanel, _feedbackGroup;
[SerializeField] protected UniText _progressText;
[SerializeField] protected UniText _hintText, _scoreText, _streakText;
[SerializeField] protected UniText _hintText, _scoreText, _streakText , _scoreLbl;
[SerializeField] protected UniText _feedbackText;
[SerializeField] protected Image _feedbackBg, _timerFill;
......@@ -508,7 +508,19 @@ namespace com.al_arcade.cs
_timerSlider.value = time / 30f;
_timerFill.color = time > 4f ? _timerDefaultColor : SSColorPalette.Danger;
}
public void EnableScore(bool value)
{
_scoreText.enabled = value;
_scoreLbl.enabled = value;
if (value)
{
_scoreLbl.Text = "الوقت الموفر";
}
else
{
_scoreLbl.Text = "النقاط";
}
}
public void UpdateTimer(float time, bool pos)
{
isTweening = true;
......@@ -548,6 +560,7 @@ namespace com.al_arcade.cs
TickPoints(0);
SetStreak(0);
ClearOptions();
_scoreLbl.enabled = false;
}
public void TickPoints(int count)
......
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using com.al_arcade.shared;
......@@ -7,10 +7,11 @@ using EasyTransition;
using Unity.VisualScripting;
using UnityEngine;
// Spawns three games one after the other.
// Move to next game when the current game is won, if lost end the challenge and show results.
public class ChallengeManager : MonoBehaviour
{
// ✅ NEW: Singleton
public static ChallengeManager Instance { get; private set; }
[SerializeField] private List<string> gameSceneNames = new();
[SerializeField] private TransitionSettings transitionSettings;
......@@ -18,51 +19,63 @@ public class ChallengeManager : MonoBehaviour
[SerializeField] private int timeSavedBonusMultiplier = 2;
[SerializeField] private List<int> penaltiesPerGame = new() { 200, 150, 100 };
[SerializeField] private AudioClip transitionSFX;
// Time saved for bonus if won the challenge
private int timeSaved = 0;
private int currentGameIndex = 0;
private DateTime startTime;
IChallengeGame currentGame = null;
BaseGameManager baseGameManager = null;
private UniTaskCompletionSource transitionEndCompletionSource = null;
[SerializeField] private ChallengeCanvas challengeCanvas;
// ✅ NEW: public read-only accessor so any game can read time saved
public int TimeSaved => timeSaved;
// ✅ NEW: time bonus from the PREVIOUS game to give to the NEXT game
// this is the timeLeft value passed from OnGameCompleted
private float _lastGameTimeLeft = 0f;
public float LastGameTimeLeft => _lastGameTimeLeft;
void Awake()
// ─── Singleton ────────────────────────────────────────────────────────
private void Awake()
{
// ✅ NEW: singleton guard — only one ChallengeManager ever exists
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
[ContextMenu("Start Challenge")]
public void StartChallengeButton()
private void OnDestroy()
{
StartChallenge().Forget();
// ✅ NEW: clear singleton ref when destroyed
if (Instance == this)
Instance = null;
}
// ─── Context Menu helpers ─────────────────────────────────────────────
[ContextMenu("Start Challenge")]
public void StartChallengeButton() => StartChallenge().Forget();
[ContextMenu("Load Next")]
public void LoadNextButton()
{
LoadNextGameAndListen().Forget();
}
public void LoadNextButton() => LoadNextGameAndListen().Forget();
[ContextMenu("Fake win")]
public void Fakewin()
{
OnGameCompleted(true, 30, 100);
}
public void Fakewin() => OnGameCompleted(true, 30, 100);
// ─── Challenge flow ───────────────────────────────────────────────────
public async UniTask StartChallenge()
{
startTime = DateTime.UtcNow;
currentGameIndex = 0;
timeSaved = 0;
// ✅ NEW: reset last game time left at start of fresh challenge
_lastGameTimeLeft = 0f;
currentGame = null;
await LoadNextGameAndListen();
......@@ -80,14 +93,16 @@ public class ChallengeManager : MonoBehaviour
return;
}
// Add time left to the saved time for the next game
// ✅ NEW: store timeLeft so the next game can use it as a bonus
_lastGameTimeLeft = timeLeft;
// Add time left to total saved time
timeSaved += Mathf.RoundToInt(timeLeft);
currentGameIndex++;
if (currentGameIndex >= gameSceneNames.Count)
{
var pointsEarnedTotal = winningPoints + (timeSaved * timeSavedBonusMultiplier);
WonChallenge(timeSaved, pointsEarnedTotal).Forget();
return;
}
......@@ -97,29 +112,27 @@ public class ChallengeManager : MonoBehaviour
private async UniTask LoadNextGameAndListen()
{
if (transitionSFX != null)
{
SSAudioManager.EnsureInstance();
SSAudioManager.Instance.Play(transitionSFX);
}
TransitionManager.Instance().Transition(
gameSceneNames[currentGameIndex], transitionSettings, 0);
TransitionManager.Instance().Transition(gameSceneNames[currentGameIndex], transitionSettings, 0);
await UniTask.WaitUntil(() =>
baseGameManager == null || baseGameManager.IsDestroyed());
// Wait until the old game is destroyed and the new game is loaded and ready
await UniTask.WaitUntil(() => baseGameManager == null || baseGameManager.IsDestroyed());
await UniTask.WaitUntil(() =>
{
currentGame = FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None)
.OfType<IChallengeGame>()
.FirstOrDefault();
return currentGame != null;
});
baseGameManager = currentGame as BaseGameManager;
print("Current game: " + baseGameManager.name);
await UniTask.WaitForSeconds(0.5f);
// ✅ NEW: pass the saved time bonus to the game before starting it
// each game type checks ChallengeManager.Instance.LastGameTimeLeft
// in their own BeginGameplay() — no casting needed here
baseGameManager.StartGame();
currentGame.OnGameCompleted += OnGameCompleted;
}
......@@ -127,24 +140,22 @@ public class ChallengeManager : MonoBehaviour
private async UniTask LostChallenge()
{
Debug.Log("Challenge failed.");
// Show results, reset challenge, etc.
challengeCanvas.ShowChallengeResult(false, 0, penaltiesPerGame[currentGameIndex]);
await ChallengeService.Instance.AddChallenge(false, 0, -penaltiesPerGame[currentGameIndex], startTime, DateTime.UtcNow);
challengeCanvas.ShowChallengeResult(
false, 0, penaltiesPerGame[currentGameIndex]);
await ChallengeService.Instance.AddChallenge(
false, 0, -penaltiesPerGame[currentGameIndex], startTime, DateTime.UtcNow);
}
private async UniTask WonChallenge(int timeSaved, int pointsEarned)
{
Debug.Log("Challenge completed! Total time saved: " + timeSaved);
challengeCanvas.ShowChallengeResult(true, timeSaved, pointsEarned);
await ChallengeService.Instance.AddChallenge(true, timeSaved, pointsEarned, startTime, DateTime.UtcNow);
await ChallengeService.Instance.AddChallenge(
true, timeSaved, pointsEarned, startTime, DateTime.UtcNow);
}
public void EndChallenge()
{
Destroy(gameObject, 2);
Destroy(gameObject, 5);
}
}
\ No newline at end of file
......@@ -52,6 +52,7 @@ public class McqCompetitor : MonoBehaviour
_manager = manager;
manager.onAnswerGiven?.AddListener(ChangeZLevel);
manager.onGameOver.AddListener(Stop);
manager.onWin?.AddListener(Stop);
}
private void ChangeZLevel(bool correct)
......
......@@ -60,6 +60,7 @@ namespace com.al_arcade.mcq
_manager = manager;
manager.onAnswerGiven?.AddListener(PlayAnimation);
manager.onGameOver?.AddListener(Stop);
manager.onWin?.AddListener(Stop);
}
private void PlayAnimation(bool correct)
......
......@@ -7,12 +7,14 @@ using TMPro;
namespace com.al_arcade.mcq
{
using com.al_arcade.cs;
using shared;
[AddComponentMenu("Science Street/MCQ Prefab Builder")]
public class McqPrefabBuilder : MonoBehaviour
{
public static McqPrefabBuilder Instance { get; private set; }
[Header("Scene Environment")]
[Tooltip("Your full road/environment prefab. Spawned at origin.")]
......@@ -92,6 +94,11 @@ namespace com.al_arcade.mcq
[SerializeField] private float runSpeed = 12f;
[SerializeField] private int lives = 3;
[Header("Timer Settings")]
public int startTime = 30;
public int correctAnswerBonusTime = 3;
public int wrongAnswerPenaltyTime = 2;
[Header("Debug")]
[SerializeField] private bool useOfflineTestData = false;
......@@ -104,6 +111,7 @@ namespace com.al_arcade.mcq
private void Start()
{
Instance = this;
DOTween.Init();
if (arabicFont != null) SSFontManager.Font = arabicFont;
StartCoroutine(BuildEverything());
......
......@@ -102,7 +102,15 @@ namespace com.al_arcade.tf
{
uiManager.ShowGameUI();
uiManager.SetProgress(0, stepsToWin);
uiManager.SetScore(0);
uiManager.EnableScore(IsChallengeMode);
if (IsChallengeMode && ChallengeManager.Instance != null)
{
uiManager.SetScore(ChallengeManager.Instance.TimeSaved);
}
else
{
uiManager.SetScore(0);
}
}
onGameStart?.Invoke();
......@@ -226,7 +234,6 @@ namespace com.al_arcade.tf
if (uiManager != null)
{
uiManager.SetProgress(_progress, stepsToWin);
uiManager.SetScore(_score);
uiManager.SetStreak(_streak);
}
......
......@@ -15,7 +15,7 @@ namespace com.al_arcade.tf
{
[SerializeField] private Canvas _canvas;
[SerializeField] private CanvasGroup _gameUI, _loadingUI, _errorUI, _resultsUI;
[SerializeField] private UniText _scoreText, _streakText;
[SerializeField] private UniText _scoreText, _streakText , _scoreLbl;
[SerializeField] private ArabicTextMeshProUGUI _loadingText, _errorText;
[SerializeField] private UniText _progressLabel;
[SerializeField] private UniText _resultTitle, _resultScore, _resultStats;
......@@ -338,7 +338,19 @@ namespace com.al_arcade.tf
.DOPunchScale(Vector3.one * 0.12f, 0.2f, 4, 0.2f)
.SetId("sp");
}
public void EnableScore(bool value)
{
_scoreText.enabled = value;
_scoreLbl.enabled = value;
if (value)
{
_scoreLbl.Text = "الوقت الموفر";
}
else
{
_scoreLbl.Text = "النقاط";
}
}
public void SetStreak(int s)
{
if (_streakText == null) return;
......@@ -415,6 +427,7 @@ namespace com.al_arcade.tf
if (_loadingUI != null) _loadingUI.gameObject.SetActive(false);
if (_errorUI != null) _errorUI.gameObject.SetActive(false);
if (_resultsUI != null) _resultsUI.gameObject.SetActive(false);
// --- ADDED: Reset timer UI ---
if (_timerSlider != null)
_timerSlider.value = 1f;
......@@ -423,6 +436,7 @@ namespace com.al_arcade.tf
_timerFill.color = _timerDefaultColor;
_isTweening = false;
_scoreLbl.enabled = false;
}
private GameObject MkPanel(Transform p, string n)
......
This diff is collapsed.
fileFormatVersion: 2
guid: b9d0cd1c5778d1b479da3c3b554ed822
guid: c180291be00c6ac4091f2e5f8b379018
DefaultImporter:
externalObjects: {}
userData:
......
......@@ -66,14 +66,14 @@
"url": "https://packages.unity.com"
},
"com.unity.collections": {
"version": "2.6.5",
"version": "2.6.2",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.burst": "1.8.27",
"com.unity.burst": "1.8.23",
"com.unity.mathematics": "1.3.2",
"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"
},
"url": "https://packages.unity.com"
......@@ -217,7 +217,7 @@
}
},
"com.unity.splines": {
"version": "2.8.4",
"version": "2.8.2",
"depth": 1,
"source": "registry",
"dependencies": {
......
m_EditorVersion: 6000.3.12f1
m_EditorVersionWithRevision: 6000.3.12f1 (fca03ac9b0d5)
m_EditorVersion: 6000.3.9f1
m_EditorVersionWithRevision: 6000.3.9f1 (7a9955a4f2fa)
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