Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
SSBookMinigames
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
SSBookMinigames
Commits
7df88fa9
Commit
7df88fa9
authored
Apr 12, 2026
by
saad
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
standardize ui for all games
parent
0652cde1
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
207 additions
and
274 deletions
+207
-274
TfUI.prefab
My project/Assets/Prefabs/TF/Phone Art/TfUI.prefab
+15
-12
TfGameManager.cs
My project/Assets/ScienceStreet/TF/Scripts/TfGameManager.cs
+8
-7
TfUIManager.cs
My project/Assets/ScienceStreet/TF/Scripts/TfUIManager.cs
+184
-255
No files found.
My project/Assets/Prefabs/TF/Phone Art/TfUI.prefab
View file @
7df88fa9
...
...
@@ -36,7 +36,7 @@ RectTransform:
m_AnchorMin
:
{
x
:
0
,
y
:
1
}
m_AnchorMax
:
{
x
:
0
,
y
:
1
}
m_AnchoredPosition
:
{
x
:
22.572838
,
y
:
-25.96685
}
m_SizeDelta
:
{
x
:
51.9337
,
y
:
51.9337
}
m_SizeDelta
:
{
x
:
0
,
y
:
51.9337
}
m_Pivot
:
{
x
:
0.5
,
y
:
0.5
}
---
!u!222
&9055497536415541340
CanvasRenderer
:
...
...
@@ -871,7 +871,7 @@ RectTransform:
m_AnchorMin
:
{
x
:
0
,
y
:
1
}
m_AnchorMax
:
{
x
:
0
,
y
:
1
}
m_AnchoredPosition
:
{
x
:
144.8642
,
y
:
-25.96685
}
m_SizeDelta
:
{
x
:
51.9337
,
y
:
51.9337
}
m_SizeDelta
:
{
x
:
0
,
y
:
51.9337
}
m_Pivot
:
{
x
:
0.5
,
y
:
0.5
}
---
!u!222
&6316850651786239132
CanvasRenderer
:
...
...
@@ -1213,7 +1213,7 @@ RectTransform:
m_AnchorMin
:
{
x
:
0
,
y
:
1
}
m_AnchorMax
:
{
x
:
0
,
y
:
1
}
m_AnchoredPosition
:
{
x
:
83.71851
,
y
:
-25.96685
}
m_SizeDelta
:
{
x
:
51.9337
,
y
:
51.9337
}
m_SizeDelta
:
{
x
:
0
,
y
:
51.9337
}
m_Pivot
:
{
x
:
0.5
,
y
:
0.5
}
---
!u!222
&6319844450247911941
CanvasRenderer
:
...
...
@@ -1412,7 +1412,7 @@ GameObject:
m_Icon
:
{
fileID
:
0
}
m_NavMeshLayer
:
0
m_StaticEditorFlags
:
0
m_IsActive
:
1
m_IsActive
:
0
---
!u!224
&810524042309484015
RectTransform
:
m_ObjectHideFlags
:
0
...
...
@@ -1523,8 +1523,8 @@ RectTransform:
m_LocalEulerAnglesHint
:
{
x
:
0
,
y
:
0
,
z
:
0
}
m_AnchorMin
:
{
x
:
0.5
,
y
:
0.5
}
m_AnchorMax
:
{
x
:
0.5
,
y
:
0.5
}
m_AnchoredPosition
:
{
x
:
16
,
y
:
25.967
}
m_SizeDelta
:
{
x
:
76.011
,
y
:
51.934
}
m_AnchoredPosition
:
{
x
:
20
,
y
:
25.967
}
m_SizeDelta
:
{
x
:
118.7
,
y
:
51.934
}
m_Pivot
:
{
x
:
0.5
,
y
:
1
}
---
!u!222
&8147257740575675822
CanvasRenderer
:
...
...
@@ -1599,7 +1599,7 @@ GameObject:
m_Icon
:
{
fileID
:
0
}
m_NavMeshLayer
:
0
m_StaticEditorFlags
:
0
m_IsActive
:
0
m_IsActive
:
1
---
!u!224
&5824509147393400757
RectTransform
:
m_ObjectHideFlags
:
0
...
...
@@ -2198,7 +2198,7 @@ RectTransform:
m_AnchorMin
:
{
x
:
0
,
y
:
1
}
m_AnchorMax
:
{
x
:
0
,
y
:
1
}
m_AnchoredPosition
:
{
x
:
206.00986
,
y
:
-25.96685
}
m_SizeDelta
:
{
x
:
51.9337
,
y
:
51.9337
}
m_SizeDelta
:
{
x
:
0
,
y
:
51.9337
}
m_Pivot
:
{
x
:
0.5
,
y
:
0.5
}
---
!u!222
&3778932895135096301
CanvasRenderer
:
...
...
@@ -2395,6 +2395,9 @@ MonoBehaviour:
_timerFill
:
{
fileID
:
2112913333798308398
}
_timerText
:
{
fileID
:
0
}
_maxTime
:
30
_pointsContainer
:
{
fileID
:
5824509147393400757
}
_activePointColor
:
{
r
:
0.99607843
,
g
:
0.8431373
,
b
:
0
,
a
:
1
}
_inactivePointColor
:
{
r
:
0.99607843
,
g
:
0.8431373
,
b
:
0
,
a
:
0.5411765
}
onRestartClicked
:
m_PersistentCalls
:
m_Calls
:
[]
...
...
@@ -2626,7 +2629,7 @@ GameObject:
m_Icon
:
{
fileID
:
0
}
m_NavMeshLayer
:
0
m_StaticEditorFlags
:
0
m_IsActive
:
1
m_IsActive
:
0
---
!u!224
&5776870742342999693
RectTransform
:
m_ObjectHideFlags
:
0
...
...
@@ -2828,7 +2831,7 @@ RectTransform:
m_AnchorMin
:
{
x
:
0
,
y
:
1
}
m_AnchorMax
:
{
x
:
0
,
y
:
1
}
m_AnchoredPosition
:
{
x
:
267.15555
,
y
:
-25.96685
}
m_SizeDelta
:
{
x
:
51.9337
,
y
:
51.9337
}
m_SizeDelta
:
{
x
:
0
,
y
:
51.9337
}
m_Pivot
:
{
x
:
0.5
,
y
:
0.5
}
---
!u!222
&1293769170803587111
CanvasRenderer
:
...
...
@@ -3108,7 +3111,7 @@ GameObject:
m_Icon
:
{
fileID
:
0
}
m_NavMeshLayer
:
0
m_StaticEditorFlags
:
0
m_IsActive
:
1
m_IsActive
:
0
---
!u!224
&7626717906572486054
RectTransform
:
m_ObjectHideFlags
:
0
...
...
@@ -3347,7 +3350,7 @@ GameObject:
m_Icon
:
{
fileID
:
0
}
m_NavMeshLayer
:
0
m_StaticEditorFlags
:
0
m_IsActive
:
1
m_IsActive
:
0
---
!u!224
&4797898653388170541
RectTransform
:
m_ObjectHideFlags
:
0
...
...
My project/Assets/ScienceStreet/TF/Scripts/TfGameManager.cs
View file @
7df88fa9
...
...
@@ -94,7 +94,6 @@ namespace com.al_arcade.tf
protected
override
void
BeginGameplay
()
{
_progress
=
0
;
// Reset base counters
_currentIndex
=
_score
=
_streak
=
_correctCount
=
_wrongCount
=
_totalAsked
=
0
;
_state
=
TfGameState
.
Playing
;
...
...
@@ -102,6 +101,8 @@ namespace com.al_arcade.tf
{
uiManager
.
ShowGameUI
();
uiManager
.
SetProgress
(
0
,
stepsToWin
);
// ✅ NEW: reset points dots
uiManager
.
TickPoints
(
0
);
uiManager
.
EnableScore
(
IsChallengeMode
);
if
(
IsChallengeMode
&&
ChallengeManager
.
Instance
!=
null
)
{
...
...
@@ -133,7 +134,7 @@ namespace com.al_arcade.tf
public
void
ResetGame
()
{
ResetBaseState
();
// clears shared counters + stops coroutines
ResetBaseState
();
_state
=
TfGameState
.
Idle
;
_progress
=
0
;
_questions
=
null
;
...
...
@@ -147,7 +148,6 @@ namespace com.al_arcade.tf
}
// ─── Timer feedback override ──────────────────────────────────────────
// TF adjusts time on correct/wrong, so it needs direct access
public
float
GetTimeLeft
()
=>
_timeLeft
;
// ─── Game loop ────────────────────────────────────────────────────────
...
...
@@ -186,7 +186,7 @@ namespace com.al_arcade.tf
_correctCount
++;
_streak
++;
_progress
++;
_score
+=
CalculateStreakScore
();
// shared helper
_score
+=
CalculateStreakScore
();
if
(
handController
!=
null
)
handController
.
PlayCorrectFeedback
(
playerSaidTrue
);
if
(
productionLine
!=
null
)
yield
return
productionLine
.
MoveForward
(
stepDistance
);
...
...
@@ -200,7 +200,7 @@ namespace com.al_arcade.tf
if
(
particles
!=
null
)
particles
.
PlayCorrectBurst
(
new
Vector3
(-
2
,
6f
,
13
));
UpdateTimerBy
(
4f
);
// shared helper
UpdateTimerBy
(
4f
);
uiManager
?.
UpdateTimer
(
_timeLeft
,
true
);
}
else
...
...
@@ -224,7 +224,7 @@ namespace com.al_arcade.tf
.
SetEase
(
Ease
.
OutQuad
).
SetId
(
"camShake"
);
}
UpdateTimerBy
(-
2f
);
// shared helper
UpdateTimerBy
(-
2f
);
uiManager
?.
UpdateTimer
(
_timeLeft
,
false
);
}
...
...
@@ -235,6 +235,8 @@ namespace com.al_arcade.tf
{
uiManager
.
SetProgress
(
_progress
,
stepsToWin
);
uiManager
.
SetStreak
(
_streak
);
// ✅ NEW: update points dots
uiManager
.
TickPoints
(
_progress
);
}
yield
return
new
WaitForSeconds
(
feedbackDuration
);
...
...
@@ -288,7 +290,6 @@ namespace com.al_arcade.tf
protected
override
IEnumerator
NoChallengeVictorySequence
()
{
yield
return
new
WaitForSeconds
(
1.5f
);
uiManager
?.
ShowResults
(
_score
,
_correctCount
,
_wrongCount
,
true
);
onGameComplete
?.
Invoke
();
}
...
...
My project/Assets/ScienceStreet/TF/Scripts/TfUIManager.cs
View file @
7df88fa9
...
...
@@ -8,6 +8,7 @@ namespace com.al_arcade.tf
{
using
LightSide
;
using
shared
;
using
System.Collections.Generic
;
using
Unity.VisualScripting
;
using
UnityEngine.SceneManagement
;
...
...
@@ -15,38 +16,60 @@ namespace com.al_arcade.tf
{
[
SerializeField
]
private
Canvas
_canvas
;
[
SerializeField
]
private
CanvasGroup
_gameUI
,
_loadingUI
,
_errorUI
,
_resultsUI
;
[
SerializeField
]
private
UniText
_scoreText
,
_streakText
,
_scoreLbl
;
[
SerializeField
]
private
UniText
_scoreText
,
_streakText
,
_scoreLbl
;
[
SerializeField
]
private
ArabicTextMeshProUGUI
_loadingText
,
_errorText
;
[
SerializeField
]
private
UniText
_progressLabel
;
[
SerializeField
]
private
UniText
_resultTitle
,
_resultScore
,
_resultStats
;
[
SerializeField
]
private
Button
_restartButton
;
[
SerializeField
]
protected
Button
_returnToHomeButton
;
[
Header
(
"Timer UI"
)]
[
SerializeField
]
private
Slider
_timerSlider
;
[
SerializeField
]
private
Image
_timerFill
;
[
SerializeField
]
private
UniText
_timerText
;
[
SerializeField
]
private
float
_maxTime
=
30
;
private
bool
_isTweening
;
private
Color
_timerDefaultColor
;
// ✅ NEW: CS-style points dots
[
Header
(
"Points UI"
)]
[
SerializeField
]
private
Transform
_pointsContainer
;
[
SerializeField
]
private
Color
_activePointColor
;
[
SerializeField
]
private
Color
_inactivePointColor
;
[
Header
(
"Events"
)]
public
UnityEvent
onRestartClicked
;
private
bool
_isTweening
;
private
Color
_timerDefaultColor
;
// ✅ NEW: cached point images
private
List
<
Image
>
_pointImages
=
new
();
private
void
Start
()
{
_restartButton
.
onClick
.
AddListener
(
RestartButton
);
if
(
_timerFill
!=
null
)
_timerDefaultColor
=
_timerFill
.
color
;
_returnToHomeButton
.
onClick
.
AddListener
(()
=>
{
SceneManager
.
LoadScene
(
"MainMenu"
);
});
// ✅ NEW: build points images list from container children
if
(
_pointsContainer
!=
null
)
{
_pointImages
.
Clear
();
foreach
(
Transform
child
in
_pointsContainer
)
{
var
img
=
child
.
GetComponent
<
Image
>();
if
(
img
!=
null
)
_pointImages
.
Add
(
img
);
}
}
}
// --- ADDED: Basic timer update (called every frame from GameManager) ---
// ─── Timer UI ─────────────────────────────────────────────────────────
public
void
SetTimer
(
float
time
)
{
if
(
_isTweening
)
return
;
...
...
@@ -62,7 +85,7 @@ namespace com.al_arcade.tf
?
_timerDefaultColor
:
SSColorPalette
.
Danger
;
}
// --- ADDED: Animated timer feedback (bonus or penalty) ---
public
void
UpdateTimer
(
float
time
,
bool
positive
)
{
if
(
_timerSlider
==
null
||
_timerFill
==
null
)
return
;
...
...
@@ -73,13 +96,12 @@ namespace com.al_arcade.tf
_timerSlider
.
transform
.
DOPunchScale
(
Vector3
.
one
*
0.1f
,
0.3f
,
8
,
0.3f
);
// Color tween owns the _isTweening flag — NOT the slider
_timerFill
.
DOColor
(
flashColor
,
0.2f
)
.
OnComplete
(()
=>
{
_timerFill
.
DOColor
(
_timerDefaultColor
,
0.2f
)
.
OnComplete
(()
=>
_isTweening
=
false
);
// ← moved here
.
OnComplete
(()
=>
_isTweening
=
false
);
});
float
targetTime
=
!
positive
?
time
-
0.3f
:
time
;
...
...
@@ -87,41 +109,157 @@ namespace com.al_arcade.tf
_timerSlider
.
DOValue
(
Mathf
.
Min
(
targetTime
/
_maxTime
,
_maxTime
),
0.3f
)
.
SetEase
(
Ease
.
OutQuad
);
// ← removed OnComplete here
}
void
RestartButton
()
// ─── Points dots UI ───────────────────────────────────────────────────
// ✅ NEW: fill dots based on current _progress value
public
void
TickPoints
(
int
count
)
{
TfGameManager
.
Instance
.
ResetGame
();
TfGameManager
.
Instance
.
StartGame
();
for
(
int
i
=
0
;
i
<
_pointImages
.
Count
;
i
++)
{
var
img
=
_pointImages
[
i
];
if
(
i
<
count
)
{
img
.
color
=
_activePointColor
;
img
.
transform
.
DOPunchScale
(
Vector3
.
one
*
0.4f
,
0.4f
)
.
SetEase
(
Ease
.
OutElastic
)
.
SetDelay
(
0.1f
*
i
);
}
else
{
img
.
color
=
SSColorPalette
.
WithAlpha
(
_inactivePointColor
,
0.3f
);
img
.
transform
.
localScale
=
Vector3
.
one
;
}
}
}
public
void
BuildUI
()
// ─── Game UI ──────────────────────────────────────────────────────────
public
void
BuildUI
()
{
}
public
void
ShowGameUI
()
{
var
co
=
new
GameObject
(
"TfCanvas"
);
co
.
transform
.
SetParent
(
transform
);
_gameUI
.
gameObject
.
SetActive
(
true
);
_gameUI
.
DOFade
(
1
,
0.3f
);
}
_canvas
=
co
.
AddComponent
<
Canvas
>();
_canvas
.
renderMode
=
RenderMode
.
ScreenSpaceOverlay
;
_canvas
.
sortingOrder
=
100
;
public
void
SetScore
(
int
s
)
{
if
(
_scoreText
==
null
)
return
;
_scoreText
.
Text
=
s
.
ToString
(
"N0"
);
DOTween
.
Kill
(
_scoreText
.
transform
,
"sp"
);
_scoreText
.
transform
.
DOPunchScale
(
Vector3
.
one
*
0.12f
,
0.2f
,
4
,
0.2f
)
.
SetId
(
"sp"
);
}
var
sc
=
co
.
AddComponent
<
CanvasScaler
>();
sc
.
uiScaleMode
=
CanvasScaler
.
ScaleMode
.
ScaleWithScreenSize
;
sc
.
referenceResolution
=
new
Vector2
(
1920
,
1080
);
sc
.
matchWidthOrHeight
=
0.5f
;
public
void
EnableScore
(
bool
value
)
{
_scoreText
.
enabled
=
value
;
_scoreLbl
.
enabled
=
value
;
_scoreLbl
.
Text
=
value
?
"الوقت الموفر"
:
"النقاط"
;
}
co
.
AddComponent
<
GraphicRaycaster
>();
public
void
SetStreak
(
int
s
)
{
if
(
_streakText
==
null
)
return
;
_streakText
.
Text
=
s
>
1
?
"🔥 × "
+
s
:
""
;
if
(
s
>
1
)
{
DOTween
.
Kill
(
_streakText
.
transform
,
"sk"
);
_streakText
.
transform
.
localScale
=
Vector3
.
one
*
1.4f
;
_streakText
.
transform
.
DOScale
(
1f
,
0.35f
)
.
SetEase
(
Ease
.
OutElastic
)
.
SetId
(
"sk"
);
}
}
BuildGameHUD
(
co
.
transform
);
BuildLoadingPanel
(
co
.
transform
);
BuildErrorPanel
(
co
.
transform
);
BuildResultsPanel
(
co
.
transform
);
public
void
SetProgress
(
int
cur
,
int
total
)
{
if
(
_progressLabel
!=
null
)
_progressLabel
.
Text
=
$"
{
cur
}
/
{
total
}
"
;
}
// ─── Loading / Error ──────────────────────────────────────────────────
public
void
ShowLoading
(
string
m
)
{
_loadingUI
.
gameObject
.
SetActive
(
true
);
if
(
_loadingText
!=
null
)
_loadingText
.
arabicText
=
m
;
_loadingUI
.
DOFade
(
1
,
0.3f
);
}
_gameUI
.
alpha
=
0
;
_gameUI
.
gameObject
.
SetActive
(
false
);
_loadingUI
.
alpha
=
0
;
_loadingUI
.
gameObject
.
SetActive
(
false
);
_
errorUI
.
alpha
=
0
;
_errorUI
.
gameObject
.
SetActive
(
false
);
_resultsUI
.
alpha
=
0
;
_resultsUI
.
gameObject
.
SetActive
(
false
);
public
void
HideLoading
()
{
_
loadingUI
.
DOFade
(
0
,
0.3f
)
.
OnComplete
(()
=>
_loadingUI
.
gameObject
.
SetActive
(
false
)
);
}
public
void
ShowError
(
string
m
)
{
_errorUI
.
gameObject
.
SetActive
(
true
);
if
(
_errorText
!=
null
)
_errorText
.
arabicText
=
m
;
_errorUI
.
DOFade
(
1
,
0.3f
);
}
// ─── Results ──────────────────────────────────────────────────────────
public
void
ShowResults
(
int
score
,
int
correct
,
int
wrong
,
bool
won
)
{
_resultsUI
.
gameObject
.
SetActive
(
true
);
_resultsUI
.
alpha
=
0
;
if
(
_resultTitle
!=
null
)
_resultTitle
.
Text
=
won
?
"نجحت المهمة"
:
"حاول مجدداً"
;
if
(
_resultScore
!=
null
)
_resultScore
.
Text
=
score
.
ToString
(
"N0"
);
if
(
_resultStats
!=
null
)
_resultStats
.
Text
=
$"صح:
{
correct
}
| خطأ:
{
wrong
}
"
;
var
seq
=
DOTween
.
Sequence
();
seq
.
Append
(
_resultsUI
.
DOFade
(
1
,
0.4f
));
}
public
void
HideResults
()
{
_resultsUI
.
DOFade
(
0f
,
0.3f
)
.
OnComplete
(()
=>
_resultsUI
.
gameObject
.
SetActive
(
false
));
}
// ─── Reset ────────────────────────────────────────────────────────────
public
void
ResetUI
()
{
if
(
_gameUI
!=
null
)
_gameUI
.
gameObject
.
SetActive
(
false
);
if
(
_loadingUI
!=
null
)
_loadingUI
.
gameObject
.
SetActive
(
false
);
if
(
_errorUI
!=
null
)
_errorUI
.
gameObject
.
SetActive
(
false
);
if
(
_resultsUI
!=
null
)
_resultsUI
.
gameObject
.
SetActive
(
false
);
if
(
_timerSlider
!=
null
)
_timerSlider
.
value
=
1f
;
if
(
_timerFill
!=
null
)
_timerFill
.
color
=
_timerDefaultColor
;
// ✅ NEW: reset all dots to inactive
TickPoints
(
0
);
_isTweening
=
false
;
SetStreak
(
0
);
_scoreLbl
.
enabled
=
false
;
}
// ─── Button functions ─────────────────────────────────────────────────
void
RestartButton
()
{
TfGameManager
.
Instance
.
ResetGame
();
TfGameManager
.
Instance
.
StartGame
();
}
public
void
BackToMenuButtonFunction
()
{
SceneManager
.
LoadScene
(
"MainMenu"
);
}
// ─── Builder (procedural UI) ──────────────────────────────────────────
private
void
BuildGameHUD
(
Transform
parent
)
{
var
go
=
MkPanel
(
parent
,
"GameUI"
);
...
...
@@ -141,42 +279,11 @@ namespace com.al_arcade.tf
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
PrimaryDark
,
0.82f
);
var
scoreLbl
=
MkTxt
(
topBarObj
.
transform
,
"ScoreLbl"
,
"نقاط"
,
14
,
new
Vector2
(
0
,
0.5f
),
new
Vector2
(
36
,
-
20
),
new
Vector2
(
100
,
22
)
);
topBarObj
.
transform
,
"ScoreLbl"
,
"نقاط"
,
14
,
new
Vector2
(
0
,
0.5f
),
new
Vector2
(
36
,
-
20
),
new
Vector2
(
100
,
22
));
scoreLbl
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.5f
);
scoreLbl
.
alignment
=
TMPro
.
TextAlignmentOptions
.
MidlineLeft
;
var
progBg
=
new
GameObject
(
"ProgressBg"
);
progBg
.
transform
.
SetParent
(
go
.
transform
,
false
);
var
pr
=
progBg
.
AddComponent
<
RectTransform
>();
pr
.
anchorMin
=
new
Vector2
(
0.28f
,
1
);
pr
.
anchorMax
=
new
Vector2
(
0.72f
,
1
);
pr
.
pivot
=
new
Vector2
(
0.5f
,
1
);
pr
.
anchoredPosition
=
new
Vector2
(
0
,
-
78
);
pr
.
sizeDelta
=
new
Vector2
(
0
,
14
);
progBg
.
AddComponent
<
Image
>().
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.08f
);
var
fill
=
new
GameObject
(
"Fill"
);
fill
.
transform
.
SetParent
(
progBg
.
transform
,
false
);
var
fr
=
fill
.
AddComponent
<
RectTransform
>();
fr
.
anchorMin
=
Vector2
.
zero
;
fr
.
anchorMax
=
new
Vector2
(
0
,
1
);
fr
.
pivot
=
new
Vector2
(
0
,
0.5f
);
fr
.
offsetMin
=
Vector2
.
zero
;
fr
.
offsetMax
=
Vector2
.
zero
;
var
hintObj
=
new
GameObject
(
"HintBg"
);
hintObj
.
transform
.
SetParent
(
go
.
transform
,
false
);
...
...
@@ -191,15 +298,8 @@ namespace com.al_arcade.tf
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
PrimaryDark
,
0.6f
);
var
hint
=
MkTxt
(
hintObj
.
transform
,
"Hint"
,
"يسار | يمين"
,
18
,
new
Vector2
(
0.5f
,
0.5f
),
Vector2
.
zero
,
new
Vector2
(
480
,
36
)
);
hintObj
.
transform
,
"Hint"
,
"يسار | يمين"
,
18
,
new
Vector2
(
0.5f
,
0.5f
),
Vector2
.
zero
,
new
Vector2
(
480
,
36
));
hint
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
hint
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.5f
);
}
...
...
@@ -208,55 +308,24 @@ namespace com.al_arcade.tf
{
var
go
=
MkPanel
(
parent
,
"LoadingUI"
);
_loadingUI
=
go
.
AddComponent
<
CanvasGroup
>();
go
.
AddComponent
<
Image
>().
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
PrimaryDark
,
0.9f
);
_loadingText
=
MkTxt
(
go
.
transform
,
"Txt"
,
"جار التحميل..."
,
28
,
new
Vector2
(
0.5f
,
0.5f
),
Vector2
.
zero
,
new
Vector2
(
500
,
50
)
);
_loadingText
=
MkTxt
(
go
.
transform
,
"Txt"
,
"جار التحميل..."
,
28
,
new
Vector2
(
0.5f
,
0.5f
),
Vector2
.
zero
,
new
Vector2
(
500
,
50
));
_loadingText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_loadingText
.
color
=
Color
.
white
;
var
dots
=
MkTxt
(
go
.
transform
,
"Dots"
,
". . ."
,
18
,
new
Vector2
(
0.5f
,
0.5f
),
new
Vector2
(
0
,
-
36
),
new
Vector2
(
200
,
30
)
);
dots
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
dots
.
color
=
SSColorPalette
.
Accent
;
}
private
void
BuildErrorPanel
(
Transform
parent
)
{
var
go
=
MkPanel
(
parent
,
"ErrorUI"
);
_errorUI
=
go
.
AddComponent
<
CanvasGroup
>();
go
.
AddComponent
<
Image
>().
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Danger
,
0.9f
);
_errorText
=
MkTxt
(
go
.
transform
,
"Txt"
,
"خطأ"
,
24
,
new
Vector2
(
0.5f
,
0.5f
),
Vector2
.
zero
,
new
Vector2
(
600
,
90
)
);
_errorText
=
MkTxt
(
go
.
transform
,
"Txt"
,
"خطأ"
,
24
,
new
Vector2
(
0.5f
,
0.5f
),
Vector2
.
zero
,
new
Vector2
(
600
,
90
));
_errorText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_errorText
.
color
=
Color
.
white
;
_errorText
.
enableWordWrapping
=
true
;
...
...
@@ -266,9 +335,8 @@ namespace com.al_arcade.tf
{
var
go
=
MkPanel
(
parent
,
"ResultsUI"
);
_resultsUI
=
go
.
AddComponent
<
CanvasGroup
>();
var
bg
=
go
.
AddComponent
<
Image
>();
bg
.
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
PrimaryDark
,
0.94f
);
go
.
AddComponent
<
Image
>().
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
PrimaryDark
,
0.94f
);
var
card
=
new
GameObject
(
"Card"
);
card
.
transform
.
SetParent
(
go
.
transform
,
false
);
...
...
@@ -298,20 +366,11 @@ namespace com.al_arcade.tf
{
_resultsUI
.
DOFade
(
0
,
0.3f
)
.
OnComplete
(()
=>
_resultsUI
.
gameObject
.
SetActive
(
false
));
onRestartClicked
?.
Invoke
();
});
var
btnTxt
=
MkTxt
(
btnObj
.
transform
,
"BtnTxt"
,
"إعادة البداية"
,
22
,
Vector2
.
zero
,
Vector2
.
zero
,
Vector2
.
zero
);
var
btnTxt
=
MkTxt
(
btnObj
.
transform
,
"BtnTxt"
,
"إعادة البداية"
,
22
,
Vector2
.
zero
,
Vector2
.
zero
,
Vector2
.
zero
);
btnTxt
.
rectTransform
.
anchorMin
=
Vector2
.
zero
;
btnTxt
.
rectTransform
.
anchorMax
=
Vector2
.
one
;
btnTxt
.
rectTransform
.
offsetMin
=
btnTxt
.
rectTransform
.
offsetMax
=
Vector2
.
zero
;
...
...
@@ -320,163 +379,33 @@ namespace com.al_arcade.tf
btnTxt
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
}
public
void
ShowGameUI
()
{
_gameUI
.
gameObject
.
SetActive
(
true
);
_gameUI
.
DOFade
(
1
,
0.3f
);
}
public
void
SetScore
(
int
s
)
{
if
(
_scoreText
==
null
)
return
;
_scoreText
.
Text
=
s
.
ToString
(
"N0"
);
DOTween
.
Kill
(
_scoreText
.
transform
,
"sp"
);
_scoreText
.
transform
.
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
;
_streakText
.
Text
=
s
>
1
?
"🔥 × "
+
s
:
""
;
if
(
s
>
1
)
{
DOTween
.
Kill
(
_streakText
.
transform
,
"sk"
);
_streakText
.
transform
.
localScale
=
Vector3
.
one
*
1.4f
;
_streakText
.
transform
.
DOScale
(
1f
,
0.35f
)
.
SetEase
(
Ease
.
OutElastic
)
.
SetId
(
"sk"
);
}
}
public
void
SetProgress
(
int
cur
,
int
total
)
{
if
(
_progressLabel
!=
null
)
_progressLabel
.
Text
=
$"
{
cur
}
/
{
total
}
"
;
}
public
void
ShowLoading
(
string
m
)
{
_loadingUI
.
gameObject
.
SetActive
(
true
);
if
(
_loadingText
!=
null
)
_loadingText
.
arabicText
=
m
;
_loadingUI
.
DOFade
(
1
,
0.3f
);
}
public
void
HideLoading
()
{
_loadingUI
.
DOFade
(
0
,
0.3f
)
.
OnComplete
(()
=>
_loadingUI
.
gameObject
.
SetActive
(
false
));
}
public
void
ShowError
(
string
m
)
{
_errorUI
.
gameObject
.
SetActive
(
true
);
if
(
_errorText
!=
null
)
_errorText
.
arabicText
=
m
;
_errorUI
.
DOFade
(
1
,
0.3f
);
}
public
void
ShowResults
(
int
score
,
int
correct
,
int
wrong
,
bool
won
)
{
_resultsUI
.
gameObject
.
SetActive
(
true
);
_resultsUI
.
alpha
=
0
;
if
(
_resultTitle
!=
null
)
_resultTitle
.
Text
=
won
?
"نجحت المهمة"
:
"حاول مجدداً"
;
if
(
_resultScore
!=
null
)
_resultScore
.
Text
=
score
.
ToString
(
"N0"
);
if
(
_resultStats
!=
null
)
_resultStats
.
Text
=
$"صح:
{
correct
}
| خطأ:
{
wrong
}
"
;
var
seq
=
DOTween
.
Sequence
();
seq
.
Append
(
_resultsUI
.
DOFade
(
1
,
0.4f
));
}
public
void
ResetUI
()
{
if
(
_gameUI
!=
null
)
_gameUI
.
gameObject
.
SetActive
(
false
);
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
;
if
(
_timerFill
!=
null
)
_timerFill
.
color
=
_timerDefaultColor
;
_isTweening
=
false
;
_scoreLbl
.
enabled
=
false
;
}
private
GameObject
MkPanel
(
Transform
p
,
string
n
)
{
var
go
=
new
GameObject
(
n
);
go
.
transform
.
SetParent
(
p
,
false
);
var
r
=
go
.
AddComponent
<
RectTransform
>();
r
.
anchorMin
=
Vector2
.
zero
;
r
.
anchorMax
=
Vector2
.
one
;
r
.
sizeDelta
=
Vector2
.
zero
;
return
go
;
}
private
ArabicTextMeshProUGUI
MkTxt
(
Transform
p
,
string
n
,
string
text
,
float
size
,
Vector2
anchor
,
Vector2
pos
,
Vector2
sz
)
Transform
p
,
string
n
,
string
text
,
float
size
,
Vector2
anchor
,
Vector2
pos
,
Vector2
sz
)
{
var
go
=
new
GameObject
(
n
);
go
.
transform
.
SetParent
(
p
,
false
);
var
r
=
go
.
AddComponent
<
RectTransform
>();
r
.
anchorMin
=
r
.
anchorMax
=
anchor
;
r
.
pivot
=
anchor
;
r
.
anchoredPosition
=
pos
;
r
.
sizeDelta
=
sz
;
var
t
=
go
.
AddComponent
<
ArabicTextMeshProUGUI
>();
t
.
arabicText
=
text
;
t
.
fontSize
=
size
;
t
.
enableWordWrapping
=
true
;
SSFontManager
.
Apply
(
t
);
return
t
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment