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
c336f670
Commit
c336f670
authored
Feb 22, 2026
by
Mahmoud Aglan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SAAAAADDDD START WORKING
parent
9833ad6e
Changes
30
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
26831 additions
and
21411 deletions
+26831
-21411
Hakawaty.asset
My project/Assets/Hakawaty.asset
+26441
-20304
CsBotController.cs
...roject/Assets/ScienceStreet/CS/Scripts/CsBotController.cs
+7
-8
CsDemoBuilder.cs
My project/Assets/ScienceStreet/CS/Scripts/CsDemoBuilder.cs
+21
-30
CsGameManager.cs
My project/Assets/ScienceStreet/CS/Scripts/CsGameManager.cs
+10
-20
CsOptionDraggable.cs
...ject/Assets/ScienceStreet/CS/Scripts/CsOptionDraggable.cs
+21
-31
CsPrefabBuilder.cs
...roject/Assets/ScienceStreet/CS/Scripts/CsPrefabBuilder.cs
+16
-54
CsUIManager.cs
My project/Assets/ScienceStreet/CS/Scripts/CsUIManager.cs
+4
-19
CsWordButton.cs
My project/Assets/ScienceStreet/CS/Scripts/CsWordButton.cs
+9
-13
McqDemoBuilder.cs
...roject/Assets/ScienceStreet/MCQ/Scripts/McqDemoBuilder.cs
+19
-27
McqGameManager.cs
...roject/Assets/ScienceStreet/MCQ/Scripts/McqGameManager.cs
+2
-8
McqGateController.cs
...ect/Assets/ScienceStreet/MCQ/Scripts/McqGateController.cs
+8
-10
McqPrefabBuilder.cs
...ject/Assets/ScienceStreet/MCQ/Scripts/McqPrefabBuilder.cs
+12
-47
McqQuestionDisplay.cs
...ct/Assets/ScienceStreet/MCQ/Scripts/McqQuestionDisplay.cs
+6
-7
McqUIManager.cs
My project/Assets/ScienceStreet/MCQ/Scripts/McqUIManager.cs
+3
-10
SSApiManager.cs
...oject/Assets/ScienceStreet/Shared/Scripts/SSApiManager.cs
+4
-27
SSAudioManager.cs
...ect/Assets/ScienceStreet/Shared/Scripts/SSAudioManager.cs
+8
-15
SSColorPalette.cs
...ect/Assets/ScienceStreet/Shared/Scripts/SSColorPalette.cs
+28
-31
SSDataModels.cs
...oject/Assets/ScienceStreet/Shared/Scripts/SSDataModels.cs
+6
-15
SSFontManager.cs
...ject/Assets/ScienceStreet/Shared/Scripts/SSFontManager.cs
+3
-5
SSGameSession.cs
...ject/Assets/ScienceStreet/Shared/Scripts/SSGameSession.cs
+7
-15
SSParticleManager.cs
.../Assets/ScienceStreet/Shared/Scripts/SSParticleManager.cs
+6
-11
TfDemoBuilder.cs
My project/Assets/ScienceStreet/TF/Scripts/TfDemoBuilder.cs
+28
-37
TfHandController.cs
...oject/Assets/ScienceStreet/TF/Scripts/TfHandController.cs
+12
-15
TfPrefabBuilder.cs
...roject/Assets/ScienceStreet/TF/Scripts/TfPrefabBuilder.cs
+10
-42
TfProductionLine.cs
...oject/Assets/ScienceStreet/TF/Scripts/TfProductionLine.cs
+15
-16
TfQuestionScreen.cs
...oject/Assets/ScienceStreet/TF/Scripts/TfQuestionScreen.cs
+19
-24
TfUIManager.cs
My project/Assets/ScienceStreet/TF/Scripts/TfUIManager.cs
+18
-31
collectcodebase.sh
My project/Assets/ScienceStreet/collectcodebase.sh
+0
-529
cs_comments_backup_20260222_185359.meta
...ets/ScienceStreet/cs_comments_backup_20260222_185359.meta
+2
-1
LiberationSans SDF - Fallback.asset
...ces/Fonts & Materials/LiberationSans SDF - Fallback.asset
+86
-9
No files found.
My project/Assets/Hakawaty.asset
View file @
c336f670
This diff is collapsed.
Click to expand it.
My project/Assets/ScienceStreet/CS/Scripts/CsBotController.cs
View file @
c336f670
...
@@ -20,7 +20,7 @@ namespace com.al_arcade.cs
...
@@ -20,7 +20,7 @@ namespace com.al_arcade.cs
var
shader
=
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
var
shader
=
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
// ── Body ─────────────────────────────────────────────────
_body
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Capsule
);
_body
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Capsule
);
_body
.
name
=
"Body"
;
_body
.
name
=
"Body"
;
_body
.
transform
.
SetParent
(
transform
);
_body
.
transform
.
SetParent
(
transform
);
...
@@ -30,7 +30,7 @@ namespace com.al_arcade.cs
...
@@ -30,7 +30,7 @@ namespace com.al_arcade.cs
_bodyMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Primary
};
_bodyMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Primary
};
_body
.
GetComponent
<
Renderer
>().
material
=
_bodyMat
;
_body
.
GetComponent
<
Renderer
>().
material
=
_bodyMat
;
// ── Head ─────────────────────────────────────────────────
_head
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Sphere
);
_head
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Sphere
);
_head
.
name
=
"Head"
;
_head
.
name
=
"Head"
;
_head
.
transform
.
SetParent
(
transform
);
_head
.
transform
.
SetParent
(
transform
);
...
@@ -40,7 +40,7 @@ namespace com.al_arcade.cs
...
@@ -40,7 +40,7 @@ namespace com.al_arcade.cs
_headMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Accent
};
_headMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Accent
};
_head
.
GetComponent
<
Renderer
>().
material
=
_headMat
;
_head
.
GetComponent
<
Renderer
>().
material
=
_headMat
;
// ── Eyes ─────────────────────────────────────────────────
var
eyeMat
=
new
Material
(
shader
)
{
color
=
Color
.
white
};
var
eyeMat
=
new
Material
(
shader
)
{
color
=
Color
.
white
};
var
pupilMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
TextDark
};
var
pupilMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
TextDark
};
...
@@ -65,7 +65,7 @@ namespace com.al_arcade.cs
...
@@ -65,7 +65,7 @@ namespace com.al_arcade.cs
pupil
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
pupilMat
);
pupil
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
pupilMat
);
}
}
// ── Mouth ────────────────────────────────────────────────
_mouth
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_mouth
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_mouth
.
name
=
"Mouth"
;
_mouth
.
name
=
"Mouth"
;
_mouth
.
transform
.
SetParent
(
_head
.
transform
);
_mouth
.
transform
.
SetParent
(
_head
.
transform
);
...
@@ -75,7 +75,7 @@ namespace com.al_arcade.cs
...
@@ -75,7 +75,7 @@ namespace com.al_arcade.cs
_mouthMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Danger
};
_mouthMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Danger
};
_mouth
.
GetComponent
<
Renderer
>().
material
=
_mouthMat
;
_mouth
.
GetComponent
<
Renderer
>().
material
=
_mouthMat
;
// ── Arms ─────────────────────────────────────────────────
for
(
int
side
=
-
1
;
side
<=
1
;
side
+=
2
)
for
(
int
side
=
-
1
;
side
<=
1
;
side
+=
2
)
{
{
var
arm
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Capsule
);
var
arm
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Capsule
);
...
@@ -89,7 +89,7 @@ namespace com.al_arcade.cs
...
@@ -89,7 +89,7 @@ namespace com.al_arcade.cs
new
Material
(
shader
)
{
color
=
SSColorPalette
.
PrimaryDark
};
new
Material
(
shader
)
{
color
=
SSColorPalette
.
PrimaryDark
};
}
}
// ── Feet ─────────────────────────────────────────────────
for
(
int
side
=
-
1
;
side
<=
1
;
side
+=
2
)
for
(
int
side
=
-
1
;
side
<=
1
;
side
+=
2
)
{
{
var
foot
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
foot
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
...
@@ -160,7 +160,6 @@ namespace com.al_arcade.cs
...
@@ -160,7 +160,6 @@ namespace com.al_arcade.cs
}
}
}
}
// ── Reactions ────────────────────────────────────────────────
public
void
PlayHappy
()
public
void
PlayHappy
()
{
{
...
@@ -183,7 +182,7 @@ namespace com.al_arcade.cs
...
@@ -183,7 +182,7 @@ namespace com.al_arcade.cs
.
OnComplete
(()
=>
_headMat
.
DOColor
(
SSColorPalette
.
Accent
,
0.4f
));
.
OnComplete
(()
=>
_headMat
.
DOColor
(
SSColorPalette
.
Accent
,
0.4f
));
}
}
// Reset mouth after delay
DOTween
.
Sequence
().
SetDelay
(
1f
).
OnComplete
(()
=>
DOTween
.
Sequence
().
SetDelay
(
1f
).
OnComplete
(()
=>
{
{
if
(
_mouth
==
null
)
return
;
if
(
_mouth
==
null
)
return
;
...
...
My project/Assets/ScienceStreet/CS/Scripts/CsDemoBuilder.cs
View file @
c336f670
...
@@ -44,7 +44,7 @@ namespace com.al_arcade.cs
...
@@ -44,7 +44,7 @@ namespace com.al_arcade.cs
Debug
.
Log
(
" Correct-the-Sentence Game"
);
Debug
.
Log
(
" Correct-the-Sentence Game"
);
Debug
.
Log
(
"═══════════════════════════════════════════"
);
Debug
.
Log
(
"═══════════════════════════════════════════"
);
// ── EventSystem ──────────────────────────────────────────
if
(
FindObjectOfType
<
EventSystem
>()
==
null
)
if
(
FindObjectOfType
<
EventSystem
>()
==
null
)
{
{
var
es
=
new
GameObject
(
"EventSystem"
);
var
es
=
new
GameObject
(
"EventSystem"
);
...
@@ -52,7 +52,7 @@ namespace com.al_arcade.cs
...
@@ -52,7 +52,7 @@ namespace com.al_arcade.cs
es
.
AddComponent
<
StandaloneInputModule
>();
es
.
AddComponent
<
StandaloneInputModule
>();
}
}
// ── Managers ─────────────────────────────────────────────
SSApiManager
.
EnsureInstance
();
SSApiManager
.
EnsureInstance
();
SSAudioManager
.
EnsureInstance
();
SSAudioManager
.
EnsureInstance
();
SSParticleManager
.
EnsureInstance
();
SSParticleManager
.
EnsureInstance
();
...
@@ -64,49 +64,49 @@ namespace com.al_arcade.cs
...
@@ -64,49 +64,49 @@ namespace com.al_arcade.cs
session
.
classCode
=
classCode
;
session
.
classCode
=
classCode
;
yield
return
null
;
yield
return
null
;
// ── Scene ────────────────────────────────────────────────
BuildScene
();
BuildScene
();
yield
return
null
;
yield
return
null
;
// ── Camera ───────────────────────────────────────────────
SetupCamera
();
SetupCamera
();
yield
return
null
;
yield
return
null
;
// ── Bot ──────────────────────────────────────────────────
var
botObj
=
new
GameObject
(
"Bot"
);
var
botObj
=
new
GameObject
(
"Bot"
);
botObj
.
transform
.
position
=
new
Vector3
(
0
,
0
,
0
);
botObj
.
transform
.
position
=
new
Vector3
(
0
,
0
,
0
);
_bot
=
botObj
.
AddComponent
<
CsBotController
>();
_bot
=
botObj
.
AddComponent
<
CsBotController
>();
_bot
.
Build
();
_bot
.
Build
();
yield
return
null
;
yield
return
null
;
// ── Word Container ───────────────────────────────────────
var
wordContainer
=
new
GameObject
(
"WordContainer"
);
var
wordContainer
=
new
GameObject
(
"WordContainer"
);
wordContainer
.
transform
.
position
=
Vector3
.
zero
;
wordContainer
.
transform
.
position
=
Vector3
.
zero
;
yield
return
null
;
yield
return
null
;
// ── UI ───────────────────────────────────────────────────
var
uiObj
=
new
GameObject
(
"CsUI"
);
var
uiObj
=
new
GameObject
(
"CsUI"
);
_uiManager
=
uiObj
.
AddComponent
<
CsUIManager
>();
_uiManager
=
uiObj
.
AddComponent
<
CsUIManager
>();
_uiManager
.
BuildUI
();
_uiManager
.
BuildUI
();
// ★ FIX: Initialize the UnityEvent if null
if
(
_uiManager
.
onRestartClicked
==
null
)
if
(
_uiManager
.
onRestartClicked
==
null
)
_uiManager
.
onRestartClicked
=
new
UnityEvent
();
_uiManager
.
onRestartClicked
=
new
UnityEvent
();
yield
return
null
;
yield
return
null
;
// ── Game Manager ─────────────────────────────────────────
var
gmObj
=
new
GameObject
(
"CsGameManager"
);
var
gmObj
=
new
GameObject
(
"CsGameManager"
);
_gm
=
gmObj
.
AddComponent
<
CsGameManager
>();
_gm
=
gmObj
.
AddComponent
<
CsGameManager
>();
_gm
.
bot
=
_bot
;
_gm
.
bot
=
_bot
;
_gm
.
uiManager
=
_uiManager
;
_gm
.
uiManager
=
_uiManager
;
_gm
.
wordContainer
=
wordContainer
.
transform
;
_gm
.
wordContainer
=
wordContainer
.
transform
;
// ★ FIX: Safe listener via named method
_uiManager
.
onRestartClicked
.
AddListener
(
OnRestartClicked
);
_uiManager
.
onRestartClicked
.
AddListener
(
OnRestartClicked
);
yield
return
null
;
yield
return
null
;
// ── Lighting ─────────────────────────────────────────────
SetupLighting
();
SetupLighting
();
yield
return
null
;
yield
return
null
;
...
@@ -118,16 +118,13 @@ namespace com.al_arcade.cs
...
@@ -118,16 +118,13 @@ namespace com.al_arcade.cs
yield
return
new
WaitForSeconds
(
0.5f
);
yield
return
new
WaitForSeconds
(
0.5f
);
// ── Start ────────────────────────────────────────────────
if
(
useOfflineTestData
)
if
(
useOfflineTestData
)
_gm
.
StartWithQuestions
(
GetTestQuestions
());
_gm
.
StartWithQuestions
(
GetTestQuestions
());
else
else
_gm
.
StartGame
();
_gm
.
StartGame
();
}
}
// ════════════════════════════════════════════════════════════
// RESTART HANDLER
// ════════════════════════════════════════════════════════════
private
void
OnRestartClicked
()
private
void
OnRestartClicked
()
{
{
...
@@ -135,9 +132,6 @@ namespace com.al_arcade.cs
...
@@ -135,9 +132,6 @@ namespace com.al_arcade.cs
if
(
_gm
!=
null
)
_gm
.
StartGame
();
if
(
_gm
!=
null
)
_gm
.
StartGame
();
}
}
// ════════════════════════════════════════════════════════════
// SCENE
// ════════════════════════════════════════════════════════════
private
void
BuildScene
()
private
void
BuildScene
()
{
{
...
@@ -146,7 +140,7 @@ namespace com.al_arcade.cs
...
@@ -146,7 +140,7 @@ namespace com.al_arcade.cs
var
shader
=
GetShader
();
var
shader
=
GetShader
();
// Ground
var
ground
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
ground
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
ground
.
name
=
"Ground"
;
ground
.
name
=
"Ground"
;
ground
.
transform
.
position
=
new
Vector3
(
0
,
-
0.05f
,
0
);
ground
.
transform
.
position
=
new
Vector3
(
0
,
-
0.05f
,
0
);
...
@@ -154,7 +148,7 @@ namespace com.al_arcade.cs
...
@@ -154,7 +148,7 @@ namespace com.al_arcade.cs
ground
.
GetComponent
<
Renderer
>().
material
=
ground
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
new
Color32
(
40
,
40
,
65
,
255
)
};
new
Material
(
shader
)
{
color
=
new
Color32
(
40
,
40
,
65
,
255
)
};
// Circular platform
var
platform
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
var
platform
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
platform
.
name
=
"Platform"
;
platform
.
name
=
"Platform"
;
platform
.
transform
.
position
=
new
Vector3
(
0
,
0.05f
,
0
);
platform
.
transform
.
position
=
new
Vector3
(
0
,
0.05f
,
0
);
...
@@ -163,7 +157,7 @@ namespace com.al_arcade.cs
...
@@ -163,7 +157,7 @@ namespace com.al_arcade.cs
platform
.
GetComponent
<
Renderer
>().
material
=
platform
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Primary
,
0.6f
)
};
new
Material
(
shader
)
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Primary
,
0.6f
)
};
// Outer ring with pulse
var
ring
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
var
ring
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
ring
.
name
=
"Ring"
;
ring
.
name
=
"Ring"
;
ring
.
transform
.
position
=
new
Vector3
(
0
,
0.04f
,
0
);
ring
.
transform
.
position
=
new
Vector3
(
0
,
0.04f
,
0
);
...
@@ -175,7 +169,7 @@ namespace com.al_arcade.cs
...
@@ -175,7 +169,7 @@ namespace com.al_arcade.cs
ringMat
.
DOFade
(
0.1f
,
1.5f
).
SetEase
(
Ease
.
InOutSine
)
ringMat
.
DOFade
(
0.1f
,
1.5f
).
SetEase
(
Ease
.
InOutSine
)
.
SetLoops
(-
1
,
LoopType
.
Yoyo
);
.
SetLoops
(-
1
,
LoopType
.
Yoyo
);
// Background decorations
for
(
int
i
=
0
;
i
<
20
;
i
++)
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
{
var
deco
=
GameObject
.
CreatePrimitive
(
var
deco
=
GameObject
.
CreatePrimitive
(
...
@@ -213,7 +207,7 @@ namespace com.al_arcade.cs
...
@@ -213,7 +207,7 @@ namespace com.al_arcade.cs
.
SetLoops
(-
1
,
LoopType
.
Incremental
).
SetEase
(
Ease
.
Linear
);
.
SetLoops
(-
1
,
LoopType
.
Incremental
).
SetEase
(
Ease
.
Linear
);
}
}
// Grid lines on ground
for
(
float
x
=
-
9
;
x
<=
9
;
x
+=
3
)
for
(
float
x
=
-
9
;
x
<=
9
;
x
+=
3
)
{
{
var
line
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
line
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
...
@@ -235,7 +229,7 @@ namespace com.al_arcade.cs
...
@@ -235,7 +229,7 @@ namespace com.al_arcade.cs
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Primary
,
0.08f
)
};
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Primary
,
0.08f
)
};
}
}
// Floor label
var
floorText
=
new
GameObject
(
"FloorLabel"
);
var
floorText
=
new
GameObject
(
"FloorLabel"
);
floorText
.
transform
.
position
=
new
Vector3
(
0
,
0.02f
,
-
3
);
floorText
.
transform
.
position
=
new
Vector3
(
0
,
0.02f
,
-
3
);
floorText
.
transform
.
rotation
=
Quaternion
.
Euler
(
90
,
0
,
0
);
floorText
.
transform
.
rotation
=
Quaternion
.
Euler
(
90
,
0
,
0
);
...
@@ -276,7 +270,7 @@ namespace com.al_arcade.cs
...
@@ -276,7 +270,7 @@ namespace com.al_arcade.cs
dirLight
.
intensity
=
0.9f
;
dirLight
.
intensity
=
0.9f
;
dirLight
.
shadows
=
LightShadows
.
Soft
;
dirLight
.
shadows
=
LightShadows
.
Soft
;
// Accent light on bot
var
accent
=
new
GameObject
(
"AccentLight"
);
var
accent
=
new
GameObject
(
"AccentLight"
);
var
aLight
=
accent
.
AddComponent
<
Light
>();
var
aLight
=
accent
.
AddComponent
<
Light
>();
aLight
.
type
=
LightType
.
Point
;
aLight
.
type
=
LightType
.
Point
;
...
@@ -285,7 +279,7 @@ namespace com.al_arcade.cs
...
@@ -285,7 +279,7 @@ namespace com.al_arcade.cs
aLight
.
intensity
=
0.8f
;
aLight
.
intensity
=
0.8f
;
aLight
.
color
=
SSColorPalette
.
Accent
;
aLight
.
color
=
SSColorPalette
.
Accent
;
// Blue back light
var
back
=
new
GameObject
(
"BackLight"
);
var
back
=
new
GameObject
(
"BackLight"
);
var
bLight
=
back
.
AddComponent
<
Light
>();
var
bLight
=
back
.
AddComponent
<
Light
>();
bLight
.
type
=
LightType
.
Point
;
bLight
.
type
=
LightType
.
Point
;
...
@@ -298,9 +292,6 @@ namespace com.al_arcade.cs
...
@@ -298,9 +292,6 @@ namespace com.al_arcade.cs
RenderSettings
.
ambientLight
=
new
Color32
(
40
,
42
,
60
,
255
);
RenderSettings
.
ambientLight
=
new
Color32
(
40
,
42
,
60
,
255
);
}
}
// ════════════════════════════════════════════════════════════
// TEST DATA
// ════════════════════════════════════════════════════════════
private
CsQuestion
[]
GetTestQuestions
()
private
CsQuestion
[]
GetTestQuestions
()
{
{
...
@@ -418,4 +409,4 @@ namespace com.al_arcade.cs
...
@@ -418,4 +409,4 @@ namespace com.al_arcade.cs
??
Shader
.
Find
(
"Unlit/Color"
);
??
Shader
.
Find
(
"Unlit/Color"
);
}
}
}
}
}
}
\ No newline at end of file
My project/Assets/ScienceStreet/CS/Scripts/CsGameManager.cs
View file @
c336f670
...
@@ -29,7 +29,7 @@ namespace com.al_arcade.cs
...
@@ -29,7 +29,7 @@ namespace com.al_arcade.cs
public
CsUIManager
uiManager
;
public
CsUIManager
uiManager
;
public
Transform
wordContainer
;
public
Transform
wordContainer
;
// State
private
CsGameState
_state
=
CsGameState
.
Idle
;
private
CsGameState
_state
=
CsGameState
.
Idle
;
private
CsQuestion
[]
_questions
;
private
CsQuestion
[]
_questions
;
private
int
_currentIndex
;
private
int
_currentIndex
;
...
@@ -52,9 +52,6 @@ namespace com.al_arcade.cs
...
@@ -52,9 +52,6 @@ namespace com.al_arcade.cs
Instance
=
this
;
Instance
=
this
;
}
}
// ═══════════════════════════════════════════════════════════
// PUBLIC API
// ═══════════════════════════════════════════════════════════
public
void
StartGame
()
=>
StartCoroutine
(
StartGameRoutine
());
public
void
StartGame
()
=>
StartCoroutine
(
StartGameRoutine
());
...
@@ -112,9 +109,6 @@ namespace com.al_arcade.cs
...
@@ -112,9 +109,6 @@ namespace com.al_arcade.cs
_onOptionDropped
?.
Invoke
(
isCorrectOption
);
_onOptionDropped
?.
Invoke
(
isCorrectOption
);
}
}
// ═══════════════════════════════════════════════════════════
// GAME FLOW
// ═══════════════════════════════════════════════════════════
private
IEnumerator
StartGameRoutine
()
private
IEnumerator
StartGameRoutine
()
{
{
...
@@ -277,9 +271,6 @@ namespace com.al_arcade.cs
...
@@ -277,9 +271,6 @@ namespace com.al_arcade.cs
yield
return
new
WaitForSeconds
(
0.8f
);
yield
return
new
WaitForSeconds
(
0.8f
);
}
}
// ═══════════════════════════════════════════════════════════
// WORD SPAWNING — ★ Dynamic sizing, no overlaps
// ═══════════════════════════════════════════════════════════
private
void
SpawnWords
(
CsQuestion
question
)
private
void
SpawnWords
(
CsQuestion
question
)
{
{
...
@@ -288,23 +279,23 @@ namespace com.al_arcade.cs
...
@@ -288,23 +279,23 @@ namespace com.al_arcade.cs
int
wordCount
=
question
.
words
.
Length
;
int
wordCount
=
question
.
words
.
Length
;
// ★ Calculate total width needed based on actual text lengths
float
padding
=
0.6f
;
// extra padding per word card
float
padding
=
0.6f
;
float
gapBetween
=
0.25f
;
// gap between cards
float
gapBetween
=
0.25f
;
float
charWidth
=
0.32f
;
// approx width per character
float
charWidth
=
0.32f
;
float
[]
wordWidths
=
new
float
[
wordCount
];
float
[]
wordWidths
=
new
float
[
wordCount
];
float
totalWidth
=
0
;
float
totalWidth
=
0
;
for
(
int
i
=
0
;
i
<
wordCount
;
i
++)
for
(
int
i
=
0
;
i
<
wordCount
;
i
++)
{
{
float
w
=
question
.
words
[
i
].
word_text
.
Length
*
charWidth
+
padding
;
float
w
=
question
.
words
[
i
].
word_text
.
Length
*
charWidth
+
padding
;
w
=
Mathf
.
Max
(
w
,
1.0f
);
// minimum width
w
=
Mathf
.
Max
(
w
,
1.0f
);
wordWidths
[
i
]
=
w
;
wordWidths
[
i
]
=
w
;
totalWidth
+=
w
;
totalWidth
+=
w
;
}
}
totalWidth
+=
(
wordCount
-
1
)
*
gapBetween
;
totalWidth
+=
(
wordCount
-
1
)
*
gapBetween
;
// ★ If total width exceeds max, scale everything down
float
maxAllowedWidth
=
14f
;
float
maxAllowedWidth
=
14f
;
float
scaleFactor
=
1f
;
float
scaleFactor
=
1f
;
if
(
totalWidth
>
maxAllowedWidth
)
if
(
totalWidth
>
maxAllowedWidth
)
...
@@ -315,12 +306,12 @@ namespace com.al_arcade.cs
...
@@ -315,12 +306,12 @@ namespace com.al_arcade.cs
wordWidths
[
i
]
*=
scaleFactor
;
wordWidths
[
i
]
*=
scaleFactor
;
}
}
// Base position above bot
Vector3
basePos
=
bot
!=
null
Vector3
basePos
=
bot
!=
null
?
bot
.
transform
.
position
+
Vector3
.
up
*
3.5f
?
bot
.
transform
.
position
+
Vector3
.
up
*
3.5f
:
Vector3
.
up
*
4f
;
:
Vector3
.
up
*
4f
;
// ★ RTL layout: start from right edge
float
startX
=
totalWidth
/
2f
;
float
startX
=
totalWidth
/
2f
;
float
currentX
=
startX
;
float
currentX
=
startX
;
...
@@ -339,7 +330,7 @@ namespace com.al_arcade.cs
...
@@ -339,7 +330,7 @@ namespace com.al_arcade.cs
wb
.
Setup
(
word
.
word_text
,
word
.
is_wrong
,
i
,
wordWidths
[
i
],
scaleFactor
);
wb
.
Setup
(
word
.
word_text
,
word
.
is_wrong
,
i
,
wordWidths
[
i
],
scaleFactor
);
_wordButtons
.
Add
(
wb
);
_wordButtons
.
Add
(
wb
);
// Entrance animation
wordObj
.
transform
.
localScale
=
Vector3
.
zero
;
wordObj
.
transform
.
localScale
=
Vector3
.
zero
;
wordObj
.
transform
.
DOScale
(
Vector3
.
one
,
0.4f
)
wordObj
.
transform
.
DOScale
(
Vector3
.
one
,
0.4f
)
.
SetDelay
(
i
*
0.08f
)
.
SetDelay
(
i
*
0.08f
)
...
@@ -378,7 +369,6 @@ namespace com.al_arcade.cs
...
@@ -378,7 +369,6 @@ namespace com.al_arcade.cs
_wordClickLocked
=
false
;
_wordClickLocked
=
false
;
}
}
// ── Victory ──────────────────────────────────────────────────
private
IEnumerator
VictorySequence
()
private
IEnumerator
VictorySequence
()
{
{
...
...
My project/Assets/ScienceStreet/CS/Scripts/CsOptionDraggable.cs
View file @
c336f670
...
@@ -23,7 +23,7 @@ namespace com.al_arcade.cs
...
@@ -23,7 +23,7 @@ namespace com.al_arcade.cs
private
CsWordButton
_targetWord
;
private
CsWordButton
_targetWord
;
private
CanvasGroup
_canvasGroup
;
private
CanvasGroup
_canvasGroup
;
// ★ Drag offset: distance from pointer to rect center at grab time
private
Vector2
_dragOffset
;
private
Vector2
_dragOffset
;
private
bool
_originalPosCaptured
;
private
bool
_originalPosCaptured
;
private
Camera
_canvasCamera
;
private
Camera
_canvasCamera
;
...
@@ -38,20 +38,20 @@ namespace com.al_arcade.cs
...
@@ -38,20 +38,20 @@ namespace com.al_arcade.cs
_rect
=
GetComponent
<
RectTransform
>();
_rect
=
GetComponent
<
RectTransform
>();
if
(
_rect
==
null
)
_rect
=
gameObject
.
AddComponent
<
RectTransform
>();
if
(
_rect
==
null
)
_rect
=
gameObject
.
AddComponent
<
RectTransform
>();
// ★ CanvasGroup so we can make it not block raycasts while dragging
_canvasGroup
=
gameObject
.
AddComponent
<
CanvasGroup
>();
_canvasGroup
=
gameObject
.
AddComponent
<
CanvasGroup
>();
// Determine canvas camera (null for ScreenSpaceOverlay)
_canvasCamera
=
null
;
_canvasCamera
=
null
;
if
(
_canvas
!=
null
&&
_canvas
.
renderMode
!=
RenderMode
.
ScreenSpaceOverlay
)
if
(
_canvas
!=
null
&&
_canvas
.
renderMode
!=
RenderMode
.
ScreenSpaceOverlay
)
_canvasCamera
=
_canvas
.
worldCamera
;
_canvasCamera
=
_canvas
.
worldCamera
;
// Background
_bg
=
gameObject
.
AddComponent
<
Image
>();
_bg
=
gameObject
.
AddComponent
<
Image
>();
_bg
.
color
=
SSColorPalette
.
Card
;
_bg
.
color
=
SSColorPalette
.
Card
;
_bg
.
raycastTarget
=
true
;
_bg
.
raycastTarget
=
true
;
// Text
var
textObj
=
new
GameObject
(
"Text"
);
var
textObj
=
new
GameObject
(
"Text"
);
textObj
.
transform
.
SetParent
(
transform
,
false
);
textObj
.
transform
.
SetParent
(
transform
,
false
);
var
textRect
=
textObj
.
AddComponent
<
RectTransform
>();
var
textRect
=
textObj
.
AddComponent
<
RectTransform
>();
...
@@ -72,41 +72,37 @@ namespace com.al_arcade.cs
...
@@ -72,41 +72,37 @@ namespace com.al_arcade.cs
_text
.
fontSizeMax
=
22
;
_text
.
fontSizeMax
=
22
;
SSFontManager
.
Apply
(
_text
);
SSFontManager
.
Apply
(
_text
);
// Entrance animation
transform
.
localScale
=
Vector3
.
one
*
0.5f
;
transform
.
localScale
=
Vector3
.
one
*
0.5f
;
transform
.
DOScale
(
Vector3
.
one
,
0.3f
).
SetEase
(
Ease
.
OutBack
);
transform
.
DOScale
(
Vector3
.
one
,
0.3f
).
SetEase
(
Ease
.
OutBack
);
_originalPosCaptured
=
false
;
_originalPosCaptured
=
false
;
}
}
// ════════════════════════════════════════════════════════════
// DRAG HANDLERS — ★ Cursor-accurate positioning
// ════════════════════════════════════════════════════════════
public
void
OnBeginDrag
(
PointerEventData
eventData
)
public
void
OnBeginDrag
(
PointerEventData
eventData
)
{
{
// ★ Capture the original anchored position for return-to-origin
_originalAnchoredPos
=
_rect
.
anchoredPosition
;
_originalAnchoredPos
=
_rect
.
anchoredPosition
;
_originalPosCaptured
=
true
;
_originalPosCaptured
=
true
;
// ★ Calculate offset: where the pointer is relative to the rect's center
// so the card doesn't jump — it stays exactly where you grabbed it
Vector2
localPointerPos
;
Vector2
localPointerPos
;
RectTransformUtility
.
ScreenPointToLocalPointInRectangle
(
RectTransformUtility
.
ScreenPointToLocalPointInRectangle
(
_rect
.
parent
as
RectTransform
,
// parent rect
_rect
.
parent
as
RectTransform
,
eventData
.
position
,
// screen pointer
eventData
.
position
,
_canvasCamera
,
// camera (null for overlay)
_canvasCamera
,
out
localPointerPos
);
out
localPointerPos
);
_dragOffset
=
_rect
.
anchoredPosition
-
localPointerPos
;
_dragOffset
=
_rect
.
anchoredPosition
-
localPointerPos
;
// Visual feedback
_bg
.
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Primary
,
0.3f
);
_bg
.
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Primary
,
0.3f
);
DOTween
.
Kill
(
transform
,
"optScale"
);
DOTween
.
Kill
(
transform
,
"optScale"
);
transform
.
DOScale
(
Vector3
.
one
*
1.08f
,
0.12f
).
SetId
(
"optScale"
);
transform
.
DOScale
(
Vector3
.
one
*
1.08f
,
0.12f
).
SetId
(
"optScale"
);
transform
.
SetAsLastSibling
();
transform
.
SetAsLastSibling
();
// ★ Let raycasts pass through while dragging (optional, helps with drop detection)
_canvasGroup
.
blocksRaycasts
=
false
;
_canvasGroup
.
blocksRaycasts
=
false
;
var
audio
=
SSAudioManager
.
Instance
;
var
audio
=
SSAudioManager
.
Instance
;
...
@@ -117,7 +113,7 @@ namespace com.al_arcade.cs
...
@@ -117,7 +113,7 @@ namespace com.al_arcade.cs
{
{
if
(
_rect
==
null
||
_canvas
==
null
)
return
;
if
(
_rect
==
null
||
_canvas
==
null
)
return
;
// ★ Convert screen pointer to local position in parent
Vector2
localPointerPos
;
Vector2
localPointerPos
;
RectTransformUtility
.
ScreenPointToLocalPointInRectangle
(
RectTransformUtility
.
ScreenPointToLocalPointInRectangle
(
_rect
.
parent
as
RectTransform
,
_rect
.
parent
as
RectTransform
,
...
@@ -125,16 +121,16 @@ namespace com.al_arcade.cs
...
@@ -125,16 +121,16 @@ namespace com.al_arcade.cs
_canvasCamera
,
_canvasCamera
,
out
localPointerPos
);
out
localPointerPos
);
// ★ Apply with the initial offset so the card stays under the finger
_rect
.
anchoredPosition
=
localPointerPos
+
_dragOffset
;
_rect
.
anchoredPosition
=
localPointerPos
+
_dragOffset
;
}
}
public
void
OnEndDrag
(
PointerEventData
eventData
)
public
void
OnEndDrag
(
PointerEventData
eventData
)
{
{
// Re-enable raycasts
_canvasGroup
.
blocksRaycasts
=
true
;
_canvasGroup
.
blocksRaycasts
=
true
;
// ★ Check if dropped near the target word
bool
droppedOnTarget
=
false
;
bool
droppedOnTarget
=
false
;
if
(
_targetWord
!=
null
&&
Camera
.
main
!=
null
)
if
(
_targetWord
!=
null
&&
Camera
.
main
!=
null
)
{
{
...
@@ -151,7 +147,7 @@ namespace com.al_arcade.cs
...
@@ -151,7 +147,7 @@ namespace com.al_arcade.cs
if
(
IsCorrect
)
if
(
IsCorrect
)
{
{
// Snap to target and disappear
DOTween
.
Kill
(
transform
);
DOTween
.
Kill
(
transform
);
transform
.
DOScale
(
Vector3
.
zero
,
0.3f
)
transform
.
DOScale
(
Vector3
.
zero
,
0.3f
)
.
SetEase
(
Ease
.
InBack
)
.
SetEase
(
Ease
.
InBack
)
...
@@ -163,14 +159,14 @@ namespace com.al_arcade.cs
...
@@ -163,14 +159,14 @@ namespace com.al_arcade.cs
}
}
else
else
{
{
// Wrong — shake then return
DOTween
.
Kill
(
transform
,
"optShake"
);
DOTween
.
Kill
(
transform
,
"optShake"
);
transform
.
DOShakePosition
(
0.3f
,
10f
,
15
).
SetId
(
"optShake"
);
transform
.
DOShakePosition
(
0.3f
,
10f
,
15
).
SetId
(
"optShake"
);
}
}
}
}
}
}
// ★ Return to original position (always, unless correct + destroyed)
ReturnToOrigin
();
ReturnToOrigin
();
}
}
...
@@ -188,9 +184,6 @@ namespace com.al_arcade.cs
...
@@ -188,9 +184,6 @@ namespace com.al_arcade.cs
}
}
}
}
// ════════════════════════════════════════════════════════════
// HOVER
// ════════════════════════════════════════════════════════════
public
void
OnPointerEnter
(
PointerEventData
eventData
)
public
void
OnPointerEnter
(
PointerEventData
eventData
)
{
{
...
@@ -205,9 +198,6 @@ namespace com.al_arcade.cs
...
@@ -205,9 +198,6 @@ namespace com.al_arcade.cs
_bg
.
DOColor
(
SSColorPalette
.
Card
,
0.15f
).
SetId
(
"optHover"
);
_bg
.
DOColor
(
SSColorPalette
.
Card
,
0.15f
).
SetId
(
"optHover"
);
}
}
// ════════════════════════════════════════════════════════════
// CLEANUP
// ════════════════════════════════════════════════════════════
private
void
OnDestroy
()
private
void
OnDestroy
()
{
{
...
@@ -216,4 +206,4 @@ namespace com.al_arcade.cs
...
@@ -216,4 +206,4 @@ namespace com.al_arcade.cs
if
(
_bg
!=
null
)
DOTween
.
Kill
(
_bg
);
if
(
_bg
!=
null
)
DOTween
.
Kill
(
_bg
);
}
}
}
}
}
}
\ No newline at end of file
My project/Assets/ScienceStreet/CS/Scripts/CsPrefabBuilder.cs
View file @
c336f670
This diff is collapsed.
Click to expand it.
My project/Assets/ScienceStreet/CS/Scripts/CsUIManager.cs
View file @
c336f670
...
@@ -28,9 +28,6 @@ namespace com.al_arcade.cs
...
@@ -28,9 +28,6 @@ namespace com.al_arcade.cs
[
Header
(
"Events"
)]
[
Header
(
"Events"
)]
public
UnityEvent
onRestartClicked
;
public
UnityEvent
onRestartClicked
;
// ════════════════════════════════════════════════════════════
// BUILD
// ════════════════════════════════════════════════════════════
public
void
BuildUI
()
public
void
BuildUI
()
{
{
...
@@ -61,14 +58,13 @@ namespace com.al_arcade.cs
...
@@ -61,14 +58,13 @@ namespace com.al_arcade.cs
_feedbackGroup
.
alpha
=
0
;
_feedbackGroup
.
alpha
=
0
;
}
}
// ── Game HUD ─────────────────────────────────────────────────
private
void
BuildGameHUD
(
Transform
parent
)
private
void
BuildGameHUD
(
Transform
parent
)
{
{
var
go
=
MkFull
(
parent
,
"GameUI"
);
var
go
=
MkFull
(
parent
,
"GameUI"
);
_gameUI
=
go
.
AddComponent
<
CanvasGroup
>();
_gameUI
=
go
.
AddComponent
<
CanvasGroup
>();
// Top bar
var
topBar
=
new
GameObject
(
"TopBar"
);
var
topBar
=
new
GameObject
(
"TopBar"
);
topBar
.
transform
.
SetParent
(
go
.
transform
,
false
);
topBar
.
transform
.
SetParent
(
go
.
transform
,
false
);
var
tbr
=
topBar
.
AddComponent
<
RectTransform
>();
var
tbr
=
topBar
.
AddComponent
<
RectTransform
>();
...
@@ -93,7 +89,7 @@ namespace com.al_arcade.cs
...
@@ -93,7 +89,7 @@ namespace com.al_arcade.cs
_streakText
.
color
=
SSColorPalette
.
Warning
;
_streakText
.
color
=
SSColorPalette
.
Warning
;
_streakText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_streakText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
// Progress bar
var
pbg
=
MkFull
(
go
.
transform
,
"ProgressBg"
);
var
pbg
=
MkFull
(
go
.
transform
,
"ProgressBg"
);
var
pr
=
pbg
.
GetComponent
<
RectTransform
>();
var
pr
=
pbg
.
GetComponent
<
RectTransform
>();
pr
.
anchorMin
=
new
Vector2
(
0.25f
,
1
);
pr
.
anchorMax
=
new
Vector2
(
0.75f
,
1
);
pr
.
anchorMin
=
new
Vector2
(
0.25f
,
1
);
pr
.
anchorMax
=
new
Vector2
(
0.75f
,
1
);
...
@@ -115,7 +111,7 @@ namespace com.al_arcade.cs
...
@@ -115,7 +111,7 @@ namespace com.al_arcade.cs
_progressText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_progressText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_progressText
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.5f
);
_progressText
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.5f
);
// Hint
_hintText
=
MkTxt
(
go
.
transform
,
"Hint"
,
""
,
18
,
_hintText
=
MkTxt
(
go
.
transform
,
"Hint"
,
""
,
18
,
new
Vector2
(
0.5f
,
0
),
new
Vector2
(
0
,
200
),
new
Vector2
(
600
,
40
));
new
Vector2
(
0.5f
,
0
),
new
Vector2
(
0
,
200
),
new
Vector2
(
600
,
40
));
_hintText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_hintText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
...
@@ -123,7 +119,6 @@ namespace com.al_arcade.cs
...
@@ -123,7 +119,6 @@ namespace com.al_arcade.cs
_hintText
.
fontStyle
=
TMPro
.
FontStyles
.
Italic
;
_hintText
.
fontStyle
=
TMPro
.
FontStyles
.
Italic
;
}
}
// ── Options Panel ────────────────────────────────────────────
private
void
BuildOptionsPanel
(
Transform
parent
)
private
void
BuildOptionsPanel
(
Transform
parent
)
{
{
...
@@ -155,7 +150,6 @@ namespace com.al_arcade.cs
...
@@ -155,7 +150,6 @@ namespace com.al_arcade.cs
.
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.6f
);
.
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.6f
);
}
}
// ── Feedback Overlay ─────────────────────────────────────────
private
void
BuildFeedbackOverlay
(
Transform
parent
)
private
void
BuildFeedbackOverlay
(
Transform
parent
)
{
{
...
@@ -185,7 +179,6 @@ namespace com.al_arcade.cs
...
@@ -185,7 +179,6 @@ namespace com.al_arcade.cs
_feedbackText
.
enableWordWrapping
=
true
;
_feedbackText
.
enableWordWrapping
=
true
;
}
}
// ── Loading ──────────────────────────────────────────────────
private
void
BuildLoadingPanel
(
Transform
parent
)
private
void
BuildLoadingPanel
(
Transform
parent
)
{
{
...
@@ -199,7 +192,6 @@ namespace com.al_arcade.cs
...
@@ -199,7 +192,6 @@ namespace com.al_arcade.cs
_loadingText
.
color
=
Color
.
white
;
_loadingText
.
color
=
Color
.
white
;
}
}
// ── Error ────────────────────────────────────────────────────
private
void
BuildErrorPanel
(
Transform
parent
)
private
void
BuildErrorPanel
(
Transform
parent
)
{
{
...
@@ -214,7 +206,6 @@ namespace com.al_arcade.cs
...
@@ -214,7 +206,6 @@ namespace com.al_arcade.cs
_errorText
.
enableWordWrapping
=
true
;
_errorText
.
enableWordWrapping
=
true
;
}
}
// ── Results ──────────────────────────────────────────────────
private
void
BuildResultsPanel
(
Transform
parent
)
private
void
BuildResultsPanel
(
Transform
parent
)
{
{
...
@@ -241,7 +232,7 @@ namespace com.al_arcade.cs
...
@@ -241,7 +232,7 @@ namespace com.al_arcade.cs
_resultStats
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.7f
);
_resultStats
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.7f
);
_resultStats
.
enableWordWrapping
=
true
;
_resultStats
.
enableWordWrapping
=
true
;
// Restart button
var
btn
=
new
GameObject
(
"RestartBtn"
);
var
btn
=
new
GameObject
(
"RestartBtn"
);
btn
.
transform
.
SetParent
(
go
.
transform
,
false
);
btn
.
transform
.
SetParent
(
go
.
transform
,
false
);
var
br
=
btn
.
AddComponent
<
RectTransform
>();
var
br
=
btn
.
AddComponent
<
RectTransform
>();
...
@@ -264,9 +255,6 @@ namespace com.al_arcade.cs
...
@@ -264,9 +255,6 @@ namespace com.al_arcade.cs
bt
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
bt
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
}
}
// ════════════════════════════════════════════════════════════
// PUBLIC METHODS
// ════════════════════════════════════════════════════════════
public
void
ShowGameUI
()
public
void
ShowGameUI
()
{
_gameUI
.
gameObject
.
SetActive
(
true
);
_gameUI
.
DOFade
(
1f
,
0.3f
);
}
{
_gameUI
.
gameObject
.
SetActive
(
true
);
_gameUI
.
DOFade
(
1f
,
0.3f
);
}
...
@@ -333,7 +321,6 @@ namespace com.al_arcade.cs
...
@@ -333,7 +321,6 @@ namespace com.al_arcade.cs
}
}
}
}
// ── Options ──────────────────────────────────────────────────
public
void
ShowOptions
(
CsOption
[]
options
,
CsWordButton
targetWord
)
public
void
ShowOptions
(
CsOption
[]
options
,
CsWordButton
targetWord
)
{
{
...
@@ -387,7 +374,6 @@ namespace com.al_arcade.cs
...
@@ -387,7 +374,6 @@ namespace com.al_arcade.cs
_activeOptions
.
Clear
();
_activeOptions
.
Clear
();
}
}
// ── Loading / Error / Results ────────────────────────────────
public
void
ShowLoading
(
string
msg
)
public
void
ShowLoading
(
string
msg
)
{
_loadingUI
.
gameObject
.
SetActive
(
true
);
if
(
_loadingText
!=
null
)
_loadingText
.
arabicText
=
msg
;
_loadingUI
.
DOFade
(
1f
,
0.3f
);
}
{
_loadingUI
.
gameObject
.
SetActive
(
true
);
if
(
_loadingText
!=
null
)
_loadingText
.
arabicText
=
msg
;
_loadingUI
.
DOFade
(
1f
,
0.3f
);
}
...
@@ -440,7 +426,6 @@ namespace com.al_arcade.cs
...
@@ -440,7 +426,6 @@ namespace com.al_arcade.cs
ClearOptions
();
ClearOptions
();
}
}
// ── Helpers ──────────────────────────────────────────────────
private
GameObject
MkFull
(
Transform
p
,
string
n
)
private
GameObject
MkFull
(
Transform
p
,
string
n
)
{
{
...
...
My project/Assets/ScienceStreet/CS/Scripts/CsWordButton.cs
View file @
c336f670
...
@@ -22,9 +22,7 @@ namespace com.al_arcade.cs
...
@@ -22,9 +22,7 @@ namespace com.al_arcade.cs
private
float
_cardWidth
;
private
float
_cardWidth
;
private
float
_cardHeight
=
0.8f
;
private
float
_cardHeight
=
0.8f
;
/// <summary>
/// Setup with explicit width and optional scale factor to prevent overlaps.
/// </summary>
public
void
Setup
(
string
text
,
bool
isWrong
,
int
index
,
public
void
Setup
(
string
text
,
bool
isWrong
,
int
index
,
float
cardWidth
=
-
1f
,
float
scaleFactor
=
1f
)
float
cardWidth
=
-
1f
,
float
scaleFactor
=
1f
)
{
{
...
@@ -32,7 +30,7 @@ namespace com.al_arcade.cs
...
@@ -32,7 +30,7 @@ namespace com.al_arcade.cs
IsWrong
=
isWrong
;
IsWrong
=
isWrong
;
Index
=
index
;
Index
=
index
;
// ★ If width not provided, calculate from text
if
(
cardWidth
<=
0
)
if
(
cardWidth
<=
0
)
_cardWidth
=
text
.
Length
*
0.32f
+
0.6f
;
_cardWidth
=
text
.
Length
*
0.32f
+
0.6f
;
else
else
...
@@ -49,7 +47,7 @@ namespace com.al_arcade.cs
...
@@ -49,7 +47,7 @@ namespace com.al_arcade.cs
var
shader
=
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
var
shader
=
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
// ── Background card ──────────────────────────────────────
_background
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_background
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_background
.
name
=
"WordBg"
;
_background
.
name
=
"WordBg"
;
_background
.
transform
.
SetParent
(
transform
);
_background
.
transform
.
SetParent
(
transform
);
...
@@ -60,11 +58,11 @@ namespace com.al_arcade.cs
...
@@ -60,11 +58,11 @@ namespace com.al_arcade.cs
_bgMaterial
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
NeutralWord
};
_bgMaterial
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
NeutralWord
};
_background
.
GetComponent
<
Renderer
>().
material
=
_bgMaterial
;
_background
.
GetComponent
<
Renderer
>().
material
=
_bgMaterial
;
// ── Text ─────────────────────────────────────────────────
var
textObj
=
new
GameObject
(
"WordText"
);
var
textObj
=
new
GameObject
(
"WordText"
);
textObj
.
transform
.
SetParent
(
transform
);
textObj
.
transform
.
SetParent
(
transform
);
textObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0
,
-
0.05f
);
textObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0
,
-
0.05f
);
// ★ Face camera (identity rotation — parent handles billboard in LateUpdate if needed)
textObj
.
transform
.
localRotation
=
Quaternion
.
identity
;
textObj
.
transform
.
localRotation
=
Quaternion
.
identity
;
_text
=
textObj
.
AddComponent
<
ArabicTextMeshPro
>();
_text
=
textObj
.
AddComponent
<
ArabicTextMeshPro
>();
...
@@ -81,11 +79,11 @@ namespace com.al_arcade.cs
...
@@ -81,11 +79,11 @@ namespace com.al_arcade.cs
_text
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Ellipsis
;
_text
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Ellipsis
;
SSFontManager
.
Apply
(
_text
);
SSFontManager
.
Apply
(
_text
);
// ── Collider (matches card exactly) ──────────────────────
_collider
=
GetComponent
<
BoxCollider
>();
_collider
=
GetComponent
<
BoxCollider
>();
_collider
.
size
=
new
Vector3
(
_cardWidth
,
_cardHeight
,
0.2f
);
_collider
.
size
=
new
Vector3
(
_cardWidth
,
_cardHeight
,
0.2f
);
// ── Shadow ───────────────────────────────────────────────
var
shadow
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
shadow
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
shadow
.
name
=
"Shadow"
;
shadow
.
name
=
"Shadow"
;
shadow
.
transform
.
SetParent
(
transform
);
shadow
.
transform
.
SetParent
(
transform
);
...
@@ -120,7 +118,7 @@ namespace com.al_arcade.cs
...
@@ -120,7 +118,7 @@ namespace com.al_arcade.cs
if
(
_bgMaterial
!=
null
)
DOTween
.
Kill
(
_bgMaterial
);
if
(
_bgMaterial
!=
null
)
DOTween
.
Kill
(
_bgMaterial
);
}
}
// ── Billboard towards camera ─────────────────────────────────
private
void
LateUpdate
()
private
void
LateUpdate
()
{
{
if
(
Camera
.
main
==
null
)
return
;
if
(
Camera
.
main
==
null
)
return
;
...
@@ -130,7 +128,6 @@ namespace com.al_arcade.cs
...
@@ -130,7 +128,6 @@ namespace com.al_arcade.cs
transform
.
rotation
=
Quaternion
.
LookRotation
(
awayFromCam
);
transform
.
rotation
=
Quaternion
.
LookRotation
(
awayFromCam
);
}
}
// ── Mouse Interaction ────────────────────────────────────────
private
void
OnMouseEnter
()
private
void
OnMouseEnter
()
{
{
...
@@ -158,7 +155,6 @@ namespace com.al_arcade.cs
...
@@ -158,7 +155,6 @@ namespace com.al_arcade.cs
CsGameManager
.
Instance
.
OnWordClicked
(
this
);
CsGameManager
.
Instance
.
OnWordClicked
(
this
);
}
}
// ── Public Methods ───────────────────────────────────────────
public
void
Highlight
(
bool
isWrongWord
)
public
void
Highlight
(
bool
isWrongWord
)
{
{
...
@@ -173,7 +169,7 @@ namespace com.al_arcade.cs
...
@@ -173,7 +169,7 @@ namespace com.al_arcade.cs
if
(
_text
!=
null
)
_text
.
color
=
Color
.
white
;
if
(
_text
!=
null
)
_text
.
color
=
Color
.
white
;
transform
.
DOPunchScale
(
Vector3
.
one
*
0.2f
,
0.4f
,
8
,
0.3f
);
transform
.
DOPunchScale
(
Vector3
.
one
*
0.2f
,
0.4f
,
8
,
0.3f
);
// Pulsing glow
DOTween
.
Sequence
()
DOTween
.
Sequence
()
.
Append
(
_bgMaterial
.
DOColor
(
Color
.
Lerp
(
targetColor
,
Color
.
white
,
0.3f
),
0.5f
))
.
Append
(
_bgMaterial
.
DOColor
(
Color
.
Lerp
(
targetColor
,
Color
.
white
,
0.3f
),
0.5f
))
.
Append
(
_bgMaterial
.
DOColor
(
targetColor
,
0.5f
))
.
Append
(
_bgMaterial
.
DOColor
(
targetColor
,
0.5f
))
...
...
My project/Assets/ScienceStreet/MCQ/Scripts/McqDemoBuilder.cs
View file @
c336f670
...
@@ -46,7 +46,7 @@ namespace com.al_arcade.mcq
...
@@ -46,7 +46,7 @@ namespace com.al_arcade.mcq
{
{
Debug
.
Log
(
"══════ MCQ Runner Demo Builder ══════"
);
Debug
.
Log
(
"══════ MCQ Runner Demo Builder ══════"
);
// ── EventSystem ──────────────────────────────────────────
if
(
FindObjectOfType
<
EventSystem
>()
==
null
)
if
(
FindObjectOfType
<
EventSystem
>()
==
null
)
{
{
var
es
=
new
GameObject
(
"EventSystem"
);
var
es
=
new
GameObject
(
"EventSystem"
);
...
@@ -54,7 +54,7 @@ namespace com.al_arcade.mcq
...
@@ -54,7 +54,7 @@ namespace com.al_arcade.mcq
es
.
AddComponent
<
StandaloneInputModule
>();
es
.
AddComponent
<
StandaloneInputModule
>();
}
}
// ── Managers ─────────────────────────────────────────────
SSApiManager
.
EnsureInstance
();
SSApiManager
.
EnsureInstance
();
SSAudioManager
.
EnsureInstance
();
SSAudioManager
.
EnsureInstance
();
SSParticleManager
.
EnsureInstance
();
SSParticleManager
.
EnsureInstance
();
...
@@ -66,31 +66,31 @@ namespace com.al_arcade.mcq
...
@@ -66,31 +66,31 @@ namespace com.al_arcade.mcq
session
.
classCode
=
classCode
;
session
.
classCode
=
classCode
;
yield
return
null
;
yield
return
null
;
// ── Scene ────────────────────────────────────────────────
BuildScene
();
BuildScene
();
yield
return
null
;
yield
return
null
;
// ── Player ───────────────────────────────────────────────
BuildPlayer
();
BuildPlayer
();
yield
return
null
;
yield
return
null
;
// ── Question Display ─────────────────────────────────────
BuildQuestionDisplay
();
BuildQuestionDisplay
();
yield
return
null
;
yield
return
null
;
// ── UI ───────────────────────────────────────────────────
BuildUI
();
BuildUI
();
yield
return
null
;
yield
return
null
;
// ── Game Manager ─────────────────────────────────────────
BuildGameManager
();
BuildGameManager
();
yield
return
null
;
yield
return
null
;
// ── Camera ───────────────────────────────────────────────
SetupCamera
();
SetupCamera
();
yield
return
null
;
yield
return
null
;
// ── Lighting ─────────────────────────────────────────────
SetupLighting
();
SetupLighting
();
yield
return
null
;
yield
return
null
;
...
@@ -98,16 +98,13 @@ namespace com.al_arcade.mcq
...
@@ -98,16 +98,13 @@ namespace com.al_arcade.mcq
yield
return
new
WaitForSeconds
(
0.3f
);
yield
return
new
WaitForSeconds
(
0.3f
);
// ── Start ────────────────────────────────────────────────
if
(
useOfflineTestData
)
if
(
useOfflineTestData
)
_gm
.
StartWithQuestions
(
GetTestQuestions
());
_gm
.
StartWithQuestions
(
GetTestQuestions
());
else
else
_gm
.
StartGame
();
_gm
.
StartGame
();
}
}
// ════════════════════════════════════════════════════════════
// BUILD METHODS
// ════════════════════════════════════════════════════════════
private
void
BuildScene
()
private
void
BuildScene
()
{
{
...
@@ -116,7 +113,7 @@ namespace com.al_arcade.mcq
...
@@ -116,7 +113,7 @@ namespace com.al_arcade.mcq
var
shader
=
GetLitShader
();
var
shader
=
GetLitShader
();
// Road (centered at x=0, extends along +Z)
var
road
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
road
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
road
.
name
=
"Road"
;
road
.
name
=
"Road"
;
road
.
transform
.
position
=
new
Vector3
(
0
,
-
0.05f
,
200
);
road
.
transform
.
position
=
new
Vector3
(
0
,
-
0.05f
,
200
);
...
@@ -124,7 +121,7 @@ namespace com.al_arcade.mcq
...
@@ -124,7 +121,7 @@ namespace com.al_arcade.mcq
road
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
road
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
new
Color32
(
60
,
60
,
80
,
255
)
};
{
color
=
new
Color32
(
60
,
60
,
80
,
255
)
};
// Lane dividers
for
(
int
i
=
-
1
;
i
<=
1
;
i
+=
2
)
for
(
int
i
=
-
1
;
i
<=
1
;
i
+=
2
)
{
{
var
line
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
line
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
...
@@ -136,7 +133,7 @@ namespace com.al_arcade.mcq
...
@@ -136,7 +133,7 @@ namespace com.al_arcade.mcq
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.4f
)
};
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.4f
)
};
}
}
// Center dashes
for
(
float
z
=
0
;
z
<
400
;
z
+=
4
)
for
(
float
z
=
0
;
z
<
400
;
z
+=
4
)
{
{
var
dash
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
dash
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
...
@@ -148,7 +145,7 @@ namespace com.al_arcade.mcq
...
@@ -148,7 +145,7 @@ namespace com.al_arcade.mcq
{
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.2f
)
};
{
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.2f
)
};
}
}
// Side decorations
for
(
int
side
=
-
1
;
side
<=
1
;
side
+=
2
)
for
(
int
side
=
-
1
;
side
<=
1
;
side
+=
2
)
{
{
for
(
float
z
=
0
;
z
<
400
;
z
+=
20
)
for
(
float
z
=
0
;
z
<
400
;
z
+=
20
)
...
@@ -167,7 +164,7 @@ namespace com.al_arcade.mcq
...
@@ -167,7 +164,7 @@ namespace com.al_arcade.mcq
}
}
}
}
// Horizon
var
horizon
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
horizon
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
horizon
.
name
=
"Horizon"
;
horizon
.
name
=
"Horizon"
;
horizon
.
transform
.
position
=
new
Vector3
(
0
,
2f
,
500
);
horizon
.
transform
.
position
=
new
Vector3
(
0
,
2f
,
500
);
...
@@ -207,7 +204,7 @@ namespace com.al_arcade.mcq
...
@@ -207,7 +204,7 @@ namespace com.al_arcade.mcq
_uiManager
=
obj
.
AddComponent
<
McqUIManager
>();
_uiManager
=
obj
.
AddComponent
<
McqUIManager
>();
_uiManager
.
BuildUI
();
_uiManager
.
BuildUI
();
// ★ FIX: Initialize the UnityEvent if null
if
(
_uiManager
.
onRestartClicked
==
null
)
if
(
_uiManager
.
onRestartClicked
==
null
)
_uiManager
.
onRestartClicked
=
new
UnityEvent
();
_uiManager
.
onRestartClicked
=
new
UnityEvent
();
}
}
...
@@ -221,7 +218,7 @@ namespace com.al_arcade.mcq
...
@@ -221,7 +218,7 @@ namespace com.al_arcade.mcq
_gm
.
uiManager
=
_uiManager
;
_gm
.
uiManager
=
_uiManager
;
_gm
.
gateParent
=
new
GameObject
(
"Gates"
).
transform
;
_gm
.
gateParent
=
new
GameObject
(
"Gates"
).
transform
;
// ★ FIX: Safe listener — all refs captured after they exist
_uiManager
.
onRestartClicked
.
AddListener
(
OnRestartClicked
);
_uiManager
.
onRestartClicked
.
AddListener
(
OnRestartClicked
);
}
}
...
@@ -272,9 +269,6 @@ namespace com.al_arcade.mcq
...
@@ -272,9 +269,6 @@ namespace com.al_arcade.mcq
RenderSettings
.
ambientMode
=
UnityEngine
.
Rendering
.
AmbientMode
.
Flat
;
RenderSettings
.
ambientMode
=
UnityEngine
.
Rendering
.
AmbientMode
.
Flat
;
}
}
// ════════════════════════════════════════════════════════════
// TEST DATA
// ════════════════════════════════════════════════════════════
private
McqQuestion
[]
GetTestQuestions
()
private
McqQuestion
[]
GetTestQuestions
()
{
{
...
@@ -306,9 +300,7 @@ namespace com.al_arcade.mcq
...
@@ -306,9 +300,7 @@ namespace com.al_arcade.mcq
}
}
}
}
// ════════════════════════════════════════════════════════════════
// Camera follow — 3rd-person runner (behind + above)
// ════════════════════════════════════════════════════════════════
public
class
McqCameraFollow
:
MonoBehaviour
public
class
McqCameraFollow
:
MonoBehaviour
{
{
public
Transform
target
;
public
Transform
target
;
...
@@ -328,4 +320,4 @@ namespace com.al_arcade.mcq
...
@@ -328,4 +320,4 @@ namespace com.al_arcade.mcq
Time
.
deltaTime
*
smoothSpeed
);
Time
.
deltaTime
*
smoothSpeed
);
}
}
}
}
}
}
\ No newline at end of file
My project/Assets/ScienceStreet/MCQ/Scripts/McqGameManager.cs
View file @
c336f670
...
@@ -62,7 +62,6 @@ namespace com.al_arcade.mcq
...
@@ -62,7 +62,6 @@ namespace com.al_arcade.mcq
Instance
=
this
;
Instance
=
this
;
}
}
// ── Public API ───────────────────────────────────────────────
public
void
StartGame
()
=>
StartCoroutine
(
StartGameRoutine
());
public
void
StartGame
()
=>
StartCoroutine
(
StartGameRoutine
());
...
@@ -90,7 +89,6 @@ namespace com.al_arcade.mcq
...
@@ -90,7 +89,6 @@ namespace com.al_arcade.mcq
if
(
questionDisplay
!=
null
)
questionDisplay
.
Hide
();
if
(
questionDisplay
!=
null
)
questionDisplay
.
Hide
();
}
}
// ── Game Flow ────────────────────────────────────────────────
private
IEnumerator
StartGameRoutine
()
private
IEnumerator
StartGameRoutine
()
{
{
...
@@ -202,7 +200,7 @@ namespace com.al_arcade.mcq
...
@@ -202,7 +200,7 @@ namespace com.al_arcade.mcq
_state
=
McqGameState
.
AnswerFeedback
;
_state
=
McqGameState
.
AnswerFeedback
;
yield
return
ProcessAnswer
(
answered
&&
wasCorrect
);
yield
return
ProcessAnswer
(
answered
&&
wasCorrect
);
// Cleanup gates
foreach
(
var
gate
in
_activeGates
)
foreach
(
var
gate
in
_activeGates
)
{
{
if
(
gate
!=
null
)
if
(
gate
!=
null
)
...
@@ -272,9 +270,6 @@ namespace com.al_arcade.mcq
...
@@ -272,9 +270,6 @@ namespace com.al_arcade.mcq
yield
return
new
WaitForSeconds
(
feedbackDisplayTime
);
yield
return
new
WaitForSeconds
(
feedbackDisplayTime
);
}
}
// ══════════════════════════════════════════════════════════
// GATE SPAWNING — always road-center X=0
// ══════════════════════════════════════════════════════════
private
void
SpawnGates
(
McqQuestion
question
)
private
void
SpawnGates
(
McqQuestion
question
)
{
{
...
@@ -284,7 +279,7 @@ namespace com.al_arcade.mcq
...
@@ -284,7 +279,7 @@ namespace com.al_arcade.mcq
float
playerZ
=
player
!=
null
?
player
.
transform
.
position
.
z
:
0f
;
float
playerZ
=
player
!=
null
?
player
.
transform
.
position
.
z
:
0f
;
// ★ Gates spawn relative to ROAD center (x=0), NOT player x
Vector3
basePos
=
new
Vector3
(
0f
,
0f
,
playerZ
+
gateSpawnDistance
);
Vector3
basePos
=
new
Vector3
(
0f
,
0f
,
playerZ
+
gateSpawnDistance
);
float
totalWidth
=
(
answers
.
Length
-
1
)
*
gateSpacing
;
float
totalWidth
=
(
answers
.
Length
-
1
)
*
gateSpacing
;
...
@@ -315,7 +310,6 @@ namespace com.al_arcade.mcq
...
@@ -315,7 +310,6 @@ namespace com.al_arcade.mcq
return
gate
;
return
gate
;
}
}
// ── Feedback ─────────────────────────────────────────────────
private
void
ShowCorrectFeedback
(
int
points
)
private
void
ShowCorrectFeedback
(
int
points
)
{
{
...
...
My project/Assets/ScienceStreet/MCQ/Scripts/McqGateController.cs
View file @
c336f670
...
@@ -42,11 +42,11 @@ namespace com.al_arcade.mcq
...
@@ -42,11 +42,11 @@ namespace com.al_arcade.mcq
{
{
var
shader
=
GetShader
();
var
shader
=
GetShader
();
// ── Pillars ──────────────────────────────────────────────
CreatePillar
(
Vector3
.
left
*
(
GateWidth
/
2f
),
"LeftPillar"
,
shader
);
CreatePillar
(
Vector3
.
left
*
(
GateWidth
/
2f
),
"LeftPillar"
,
shader
);
CreatePillar
(
Vector3
.
right
*
(
GateWidth
/
2f
),
"RightPillar"
,
shader
);
CreatePillar
(
Vector3
.
right
*
(
GateWidth
/
2f
),
"RightPillar"
,
shader
);
// ── Top bar ──────────────────────────────────────────────
var
topBar
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
topBar
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
topBar
.
name
=
"TopBar"
;
topBar
.
name
=
"TopBar"
;
topBar
.
transform
.
SetParent
(
transform
);
topBar
.
transform
.
SetParent
(
transform
);
...
@@ -56,7 +56,7 @@ namespace com.al_arcade.mcq
...
@@ -56,7 +56,7 @@ namespace com.al_arcade.mcq
var
topMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Primary
};
var
topMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Primary
};
topBar
.
GetComponent
<
Renderer
>().
material
=
topMat
;
topBar
.
GetComponent
<
Renderer
>().
material
=
topMat
;
// ── Answer panel — on the +Z side (back wall of gate archway) ──
_backPanel
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_backPanel
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_backPanel
.
name
=
"AnswerPanel"
;
_backPanel
.
name
=
"AnswerPanel"
;
_backPanel
.
transform
.
SetParent
(
transform
);
_backPanel
.
transform
.
SetParent
(
transform
);
...
@@ -66,12 +66,12 @@ namespace com.al_arcade.mcq
...
@@ -66,12 +66,12 @@ namespace com.al_arcade.mcq
_panelMaterial
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
GateDefault
};
_panelMaterial
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
GateDefault
};
_backPanel
.
GetComponent
<
Renderer
>().
material
=
_panelMaterial
;
_backPanel
.
GetComponent
<
Renderer
>().
material
=
_panelMaterial
;
// ── Text label — identity rotation, readable from -Z (camera side) ──
var
textObj
=
new
GameObject
(
"AnswerLabel"
);
var
textObj
=
new
GameObject
(
"AnswerLabel"
);
textObj
.
transform
.
SetParent
(
transform
);
textObj
.
transform
.
SetParent
(
transform
);
textObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
GateHeight
/
2f
,
GateDepth
/
2f
-
0.08f
);
textObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
GateHeight
/
2f
,
GateDepth
/
2f
-
0.08f
);
// ★ NO Euler(0,180,0) — TMP 3D text is readable from -Z by default,
// camera is behind player at -Z. Identity rotation = correct.
textObj
.
transform
.
localRotation
=
Quaternion
.
identity
;
textObj
.
transform
.
localRotation
=
Quaternion
.
identity
;
_label
=
textObj
.
AddComponent
<
ArabicTextMeshPro
>();
_label
=
textObj
.
AddComponent
<
ArabicTextMeshPro
>();
...
@@ -88,13 +88,13 @@ namespace com.al_arcade.mcq
...
@@ -88,13 +88,13 @@ namespace com.al_arcade.mcq
_label
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Ellipsis
;
_label
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Ellipsis
;
SSFontManager
.
Apply
(
_label
);
SSFontManager
.
Apply
(
_label
);
// ── Trigger collider ─────────────────────────────────────
_collider
=
gameObject
.
AddComponent
<
BoxCollider
>();
_collider
=
gameObject
.
AddComponent
<
BoxCollider
>();
_collider
.
isTrigger
=
true
;
_collider
.
isTrigger
=
true
;
_collider
.
center
=
new
Vector3
(
0
,
GateHeight
/
2f
,
0
);
_collider
.
center
=
new
Vector3
(
0
,
GateHeight
/
2f
,
0
);
_collider
.
size
=
new
Vector3
(
GateWidth
,
GateHeight
,
GateDepth
);
_collider
.
size
=
new
Vector3
(
GateWidth
,
GateHeight
,
GateDepth
);
// ── Floor highlight ──────────────────────────────────────
var
floor
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
floor
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
floor
.
name
=
"FloorHighlight"
;
floor
.
name
=
"FloorHighlight"
;
floor
.
transform
.
SetParent
(
transform
);
floor
.
transform
.
SetParent
(
transform
);
...
@@ -147,7 +147,6 @@ namespace com.al_arcade.mcq
...
@@ -147,7 +147,6 @@ namespace com.al_arcade.mcq
if
(
_label
!=
null
)
DOTween
.
Kill
(
_label
.
transform
);
if
(
_label
!=
null
)
DOTween
.
Kill
(
_label
.
transform
);
}
}
// ── Collision ────────────────────────────────────────────────
private
void
OnTriggerEnter
(
Collider
other
)
private
void
OnTriggerEnter
(
Collider
other
)
{
{
...
@@ -157,7 +156,6 @@ namespace com.al_arcade.mcq
...
@@ -157,7 +156,6 @@ namespace com.al_arcade.mcq
onPlayerEnter
?.
Invoke
(
GateIndex
);
onPlayerEnter
?.
Invoke
(
GateIndex
);
}
}
// ── Feedback Animations ──────────────────────────────────────
public
void
PlayCorrectAnimation
()
public
void
PlayCorrectAnimation
()
{
{
...
...
My project/Assets/ScienceStreet/MCQ/Scripts/McqPrefabBuilder.cs
View file @
c336f670
This diff is collapsed.
Click to expand it.
My project/Assets/ScienceStreet/MCQ/Scripts/McqQuestionDisplay.cs
View file @
c336f670
...
@@ -25,7 +25,7 @@ namespace com.al_arcade.mcq
...
@@ -25,7 +25,7 @@ namespace com.al_arcade.mcq
var
shader
=
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
??
var
shader
=
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
// Background panel (Cube)
_panel
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_panel
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_panel
.
name
=
"QuestionPanel"
;
_panel
.
name
=
"QuestionPanel"
;
_panel
.
transform
.
SetParent
(
transform
);
_panel
.
transform
.
SetParent
(
transform
);
...
@@ -36,7 +36,7 @@ namespace com.al_arcade.mcq
...
@@ -36,7 +36,7 @@ namespace com.al_arcade.mcq
{
color
=
new
Color
(
0.12f
,
0.12f
,
0.5f
,
0.95f
)
};
{
color
=
new
Color
(
0.12f
,
0.12f
,
0.5f
,
0.95f
)
};
_panel
.
GetComponent
<
Renderer
>().
material
=
panelMat
;
_panel
.
GetComponent
<
Renderer
>().
material
=
panelMat
;
// Accent bar
var
bar
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
bar
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
bar
.
name
=
"AccentBar"
;
bar
.
name
=
"AccentBar"
;
bar
.
transform
.
SetParent
(
_panel
.
transform
);
bar
.
transform
.
SetParent
(
_panel
.
transform
);
...
@@ -46,8 +46,7 @@ namespace com.al_arcade.mcq
...
@@ -46,8 +46,7 @@ namespace com.al_arcade.mcq
bar
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
bar
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Accent
};
{
color
=
SSColorPalette
.
Accent
};
// ★ Question text — identity local rotation
// Parent will billboard to face camera
var
textObj
=
new
GameObject
(
"QuestionText"
);
var
textObj
=
new
GameObject
(
"QuestionText"
);
textObj
.
transform
.
SetParent
(
transform
);
textObj
.
transform
.
SetParent
(
transform
);
textObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0.2f
,
-
0.06f
);
textObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0.2f
,
-
0.06f
);
...
@@ -65,7 +64,7 @@ namespace com.al_arcade.mcq
...
@@ -65,7 +64,7 @@ namespace com.al_arcade.mcq
_questionText
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Ellipsis
;
_questionText
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Ellipsis
;
SSFontManager
.
Apply
(
_questionText
);
SSFontManager
.
Apply
(
_questionText
);
// Source text
var
srcObj
=
new
GameObject
(
"SourceText"
);
var
srcObj
=
new
GameObject
(
"SourceText"
);
srcObj
.
transform
.
SetParent
(
transform
);
srcObj
.
transform
.
SetParent
(
transform
);
srcObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
-
0.85f
,
-
0.06f
);
srcObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
-
0.85f
,
-
0.06f
);
...
@@ -104,14 +103,14 @@ namespace com.al_arcade.mcq
...
@@ -104,14 +103,14 @@ namespace com.al_arcade.mcq
{
{
if
(
_playerTransform
==
null
)
return
;
if
(
_playerTransform
==
null
)
return
;
// ★ Follow player, stay between player and gates
Vector3
targetPos
=
_playerTransform
.
position
Vector3
targetPos
=
_playerTransform
.
position
+
Vector3
.
up
*
floatHeight
+
Vector3
.
up
*
floatHeight
+
Vector3
.
forward
*
forwardOffset
;
+
Vector3
.
forward
*
forwardOffset
;
transform
.
position
=
Vector3
.
Lerp
(
transform
.
position
,
targetPos
,
transform
.
position
=
Vector3
.
Lerp
(
transform
.
position
,
targetPos
,
Time
.
deltaTime
*
followSpeed
);
Time
.
deltaTime
*
followSpeed
);
// ★ Billboard: face away from camera so text (-Z face) faces camera
if
(
Camera
.
main
!=
null
)
if
(
Camera
.
main
!=
null
)
{
{
Vector3
awayFromCam
=
transform
.
position
-
Camera
.
main
.
transform
.
position
;
Vector3
awayFromCam
=
transform
.
position
-
Camera
.
main
.
transform
.
position
;
...
...
My project/Assets/ScienceStreet/MCQ/Scripts/McqUIManager.cs
View file @
c336f670
...
@@ -27,9 +27,6 @@ namespace com.al_arcade.mcq
...
@@ -27,9 +27,6 @@ namespace com.al_arcade.mcq
[
Header
(
"Events"
)]
[
Header
(
"Events"
)]
public
UnityEvent
onRestartClicked
;
public
UnityEvent
onRestartClicked
;
// ════════════════════════════════════════════════════════════
// BUILD
// ════════════════════════════════════════════════════════════
public
void
BuildUI
()
public
void
BuildUI
()
{
{
...
@@ -82,7 +79,7 @@ namespace com.al_arcade.mcq
...
@@ -82,7 +79,7 @@ namespace com.al_arcade.mcq
new
Vector2
(
200
,
-
15
),
24
,
TMPro
.
TextAlignmentOptions
.
TopLeft
);
new
Vector2
(
200
,
-
15
),
24
,
TMPro
.
TextAlignmentOptions
.
TopLeft
);
_streakText
.
color
=
SSColorPalette
.
Warning
;
_streakText
.
color
=
SSColorPalette
.
Warning
;
// Hearts
_heartIcons
=
new
Image
[
5
];
_heartIcons
=
new
Image
[
5
];
for
(
int
i
=
0
;
i
<
5
;
i
++)
for
(
int
i
=
0
;
i
<
5
;
i
++)
{
{
...
@@ -98,7 +95,7 @@ namespace com.al_arcade.mcq
...
@@ -98,7 +95,7 @@ namespace com.al_arcade.mcq
h
.
SetActive
(
false
);
h
.
SetActive
(
false
);
}
}
// Progress bar
var
progBg
=
MakeImg
(
go
.
transform
,
"ProgressBg"
,
var
progBg
=
MakeImg
(
go
.
transform
,
"ProgressBg"
,
new
Vector2
(
0
,
0
),
new
Vector2
(
1
,
0
),
new
Vector2
(
0
,
0
),
new
Vector2
(
1
,
0
),
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.1f
));
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.1f
));
...
@@ -208,7 +205,7 @@ namespace com.al_arcade.mcq
...
@@ -208,7 +205,7 @@ namespace com.al_arcade.mcq
new
Vector2
(
200
,
0
),
24
);
new
Vector2
(
200
,
0
),
24
);
_resultStreak
.
color
=
SSColorPalette
.
Accent
;
_resultStreak
.
color
=
SSColorPalette
.
Accent
;
// Restart button
var
btnObj
=
new
GameObject
(
"RestartBtn"
);
var
btnObj
=
new
GameObject
(
"RestartBtn"
);
btnObj
.
transform
.
SetParent
(
go
.
transform
,
false
);
btnObj
.
transform
.
SetParent
(
go
.
transform
,
false
);
var
br
=
btnObj
.
AddComponent
<
RectTransform
>();
var
br
=
btnObj
.
AddComponent
<
RectTransform
>();
...
@@ -229,9 +226,6 @@ namespace com.al_arcade.mcq
...
@@ -229,9 +226,6 @@ namespace com.al_arcade.mcq
btnTxt
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
btnTxt
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
}
}
// ══════════════════════════════════════════════════════════
// PUBLIC
// ══════════════════════════════════════════════════════════
public
void
ShowGameUI
()
public
void
ShowGameUI
()
{
{
...
@@ -377,7 +371,6 @@ namespace com.al_arcade.mcq
...
@@ -377,7 +371,6 @@ namespace com.al_arcade.mcq
_feedbackUI
.
alpha
=
0
;
_feedbackUI
.
alpha
=
0
;
}
}
// ── Helpers ──────────────────────────────────────────────────
private
GameObject
MakePanel
(
Transform
p
,
string
n
,
Vector2
amin
,
Vector2
amax
)
private
GameObject
MakePanel
(
Transform
p
,
string
n
,
Vector2
amin
,
Vector2
amax
)
{
{
...
...
My project/Assets/ScienceStreet/Shared/Scripts/SSApiManager.cs
View file @
c336f670
// ============================================================================
// Science Street — API Manager (Singleton)
// Handles all communication with the PHP backend
// ============================================================================
using
System
;
using
System
;
using
System.Collections
;
using
System.Collections
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
...
@@ -21,7 +19,7 @@ namespace com.al_arcade.shared
...
@@ -21,7 +19,7 @@ namespace com.al_arcade.shared
[
SerializeField
]
private
int
timeoutSeconds
=
15
;
[
SerializeField
]
private
int
timeoutSeconds
=
15
;
// ── Singleton Setup ──────────────────────────────────────────
private
void
Awake
()
private
void
Awake
()
{
{
if
(
Instance
!=
null
&&
Instance
!=
this
)
if
(
Instance
!=
null
&&
Instance
!=
this
)
...
@@ -33,7 +31,7 @@ namespace com.al_arcade.shared
...
@@ -33,7 +31,7 @@ namespace com.al_arcade.shared
DontDestroyOnLoad
(
gameObject
);
DontDestroyOnLoad
(
gameObject
);
}
}
// ── Ensure Instance Exists ───────────────────────────────────
public
static
SSApiManager
EnsureInstance
()
public
static
SSApiManager
EnsureInstance
()
{
{
if
(
Instance
!=
null
)
return
Instance
;
if
(
Instance
!=
null
)
return
Instance
;
...
@@ -43,9 +41,6 @@ namespace com.al_arcade.shared
...
@@ -43,9 +41,6 @@ namespace com.al_arcade.shared
return
Instance
;
return
Instance
;
}
}
// ════════════════════════════════════════════════════════════
// GENERIC REQUEST
// ════════════════════════════════════════════════════════════
public
IEnumerator
GetRequest
(
string
action
,
public
IEnumerator
GetRequest
(
string
action
,
Dictionary
<
string
,
string
>
parameters
,
Dictionary
<
string
,
string
>
parameters
,
...
@@ -79,9 +74,6 @@ namespace com.al_arcade.shared
...
@@ -79,9 +74,6 @@ namespace com.al_arcade.shared
onSuccess
?.
Invoke
(
json
);
onSuccess
?.
Invoke
(
json
);
}
}
// ════════════════════════════════════════════════════════════
// PING
// ════════════════════════════════════════════════════════════
public
IEnumerator
Ping
(
Action
<
bool
>
onResult
)
public
IEnumerator
Ping
(
Action
<
bool
>
onResult
)
{
{
...
@@ -90,9 +82,6 @@ namespace com.al_arcade.shared
...
@@ -90,9 +82,6 @@ namespace com.al_arcade.shared
err
=>
onResult
?.
Invoke
(
false
));
err
=>
onResult
?.
Invoke
(
false
));
}
}
// ════════════════════════════════════════════════════════════
// VALIDATE CLASS CODE
// ════════════════════════════════════════════════════════════
public
IEnumerator
ValidateClassCode
(
string
code
,
public
IEnumerator
ValidateClassCode
(
string
code
,
Action
<
ClassInfo
>
onSuccess
,
Action
<
ClassInfo
>
onSuccess
,
...
@@ -120,9 +109,6 @@ namespace com.al_arcade.shared
...
@@ -120,9 +109,6 @@ namespace com.al_arcade.shared
onError
);
onError
);
}
}
// ════════════════════════════════════════════════════════════
// GET GRADES
// ════════════════════════════════════════════════════════════
public
IEnumerator
GetGrades
(
Action
<
GradeInfo
[
]>
onSuccess
,
public
IEnumerator
GetGrades
(
Action
<
GradeInfo
[
]>
onSuccess
,
Action
<
string
>
onError
)
Action
<
string
>
onError
)
...
@@ -146,9 +132,6 @@ namespace com.al_arcade.shared
...
@@ -146,9 +132,6 @@ namespace com.al_arcade.shared
onError
);
onError
);
}
}
// ════════════════════════════════════════════════════════════
// FETCH MCQ QUESTIONS
// ════════════════════════════════════════════════════════════
public
IEnumerator
FetchMcq
(
string
buildType
,
string
classCode
,
public
IEnumerator
FetchMcq
(
string
buildType
,
string
classCode
,
int
count
,
int
gradeId
,
int
count
,
int
gradeId
,
...
@@ -183,9 +166,6 @@ namespace com.al_arcade.shared
...
@@ -183,9 +166,6 @@ namespace com.al_arcade.shared
onError
);
onError
);
}
}
// ════════════════════════════════════════════════════════════
// FETCH T/F QUESTIONS
// ════════════════════════════════════════════════════════════
public
IEnumerator
FetchTf
(
string
buildType
,
string
classCode
,
public
IEnumerator
FetchTf
(
string
buildType
,
string
classCode
,
int
count
,
int
gradeId
,
int
count
,
int
gradeId
,
...
@@ -220,9 +200,6 @@ namespace com.al_arcade.shared
...
@@ -220,9 +200,6 @@ namespace com.al_arcade.shared
onError
);
onError
);
}
}
// ════════════════════════════════════════════════════════════
// FETCH CS QUESTIONS
// ════════════════════════════════════════════════════════════
public
IEnumerator
FetchCs
(
string
buildType
,
string
classCode
,
public
IEnumerator
FetchCs
(
string
buildType
,
string
classCode
,
int
count
,
int
gradeId
,
int
count
,
int
gradeId
,
...
...
My project/Assets/ScienceStreet/Shared/Scripts/SSAudioManager.cs
View file @
c336f670
// ============================================================================
// Science Street — Audio Manager
// Plays SFX with optional AudioClip references.
// Works silently if no clips are assigned.
// ============================================================================
using
UnityEngine
;
using
UnityEngine
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
...
@@ -77,7 +74,6 @@ namespace com.al_arcade.shared
...
@@ -77,7 +74,6 @@ namespace com.al_arcade.shared
return
src
;
return
src
;
}
}
// ── Play Methods ─────────────────────────────────────────────
public
void
Play
(
AudioClip
clip
,
float
volumeScale
=
1f
,
float
pitch
=
1f
)
public
void
Play
(
AudioClip
clip
,
float
volumeScale
=
1f
,
float
pitch
=
1f
)
{
{
...
@@ -104,10 +100,7 @@ namespace com.al_arcade.shared
...
@@ -104,10 +100,7 @@ namespace com.al_arcade.shared
public
void
PlayCheer
(
float
vol
=
1f
)
=>
Play
(
sfxCheer
,
vol
);
public
void
PlayCheer
(
float
vol
=
1f
)
=>
Play
(
sfxCheer
,
vol
);
public
void
PlayCountdown
(
float
vol
=
0.8f
)
=>
Play
(
sfxCountdown
,
vol
);
public
void
PlayCountdown
(
float
vol
=
0.8f
)
=>
Play
(
sfxCountdown
,
vol
);
/// <summary>
/// Plays a generated procedural beep (no AudioClip needed).
/// Useful for demo/prototype mode.
/// </summary>
public
void
PlayProceduralBeep
(
float
frequency
=
440f
,
float
duration
=
0.1f
,
public
void
PlayProceduralBeep
(
float
frequency
=
440f
,
float
duration
=
0.1f
,
float
volume
=
0.3f
)
float
volume
=
0.3f
)
{
{
...
@@ -119,7 +112,7 @@ namespace com.al_arcade.shared
...
@@ -119,7 +112,7 @@ namespace com.al_arcade.shared
for
(
int
i
=
0
;
i
<
sampleCount
;
i
++)
for
(
int
i
=
0
;
i
<
sampleCount
;
i
++)
{
{
float
t
=
(
float
)
i
/
sampleRate
;
float
t
=
(
float
)
i
/
sampleRate
;
float
envelope
=
1f
-
((
float
)
i
/
sampleCount
);
// fade out
float
envelope
=
1f
-
((
float
)
i
/
sampleCount
);
data
[
i
]
=
Mathf
.
Sin
(
2f
*
Mathf
.
PI
*
frequency
*
t
)
*
envelope
*
volume
;
data
[
i
]
=
Mathf
.
Sin
(
2f
*
Mathf
.
PI
*
frequency
*
t
)
*
envelope
*
volume
;
}
}
...
@@ -135,10 +128,10 @@ namespace com.al_arcade.shared
...
@@ -135,10 +128,10 @@ namespace com.al_arcade.shared
public
void
PlayClickBeep
()
=>
PlayProceduralBeep
(
660f
,
0.05f
,
0.15f
);
public
void
PlayClickBeep
()
=>
PlayProceduralBeep
(
660f
,
0.05f
,
0.15f
);
public
void
PlaySuccessJingle
()
public
void
PlaySuccessJingle
()
{
{
// Three ascending tones
PlayProceduralBeep
(
523f
,
0.12f
,
0.2f
);
// C5
PlayProceduralBeep
(
523f
,
0.12f
,
0.2f
);
StartCoroutine
(
DelayedBeep
(
660f
,
0.12f
,
0.1f
));
// E5
StartCoroutine
(
DelayedBeep
(
660f
,
0.12f
,
0.1f
));
StartCoroutine
(
DelayedBeep
(
784f
,
0.2f
,
0.2f
));
// G5
StartCoroutine
(
DelayedBeep
(
784f
,
0.2f
,
0.2f
));
}
}
public
void
PlayFailBuzz
()
public
void
PlayFailBuzz
()
...
...
My project/Assets/ScienceStreet/Shared/Scripts/SSColorPalette.cs
View file @
c336f670
// ============================================================================
// Science Street — Shared Color Palette
// AL-Arcade Game Dev Team
// ============================================================================
using
UnityEngine
;
using
UnityEngine
;
namespace
com.al_arcade.shared
namespace
com.al_arcade.shared
{
{
/// <summary>
/// Central color definitions matching the Science Street brand.
/// </summary>
public
static
class
SSColorPalette
public
static
class
SSColorPalette
{
{
// ── Brand Colors ─────────────────────────────────────────────
public
static
readonly
Color
Primary
=
new
Color32
(
48
,
48
,
208
,
255
);
// #3030D0
public
static
readonly
Color
Primary
=
new
Color32
(
48
,
48
,
208
,
255
);
public
static
readonly
Color
PrimaryDark
=
new
Color32
(
32
,
32
,
168
,
255
);
// #2020A8
public
static
readonly
Color
PrimaryDark
=
new
Color32
(
32
,
32
,
168
,
255
);
public
static
readonly
Color
PrimaryLight
=
new
Color32
(
80
,
80
,
220
,
255
);
// #5050DC
public
static
readonly
Color
PrimaryLight
=
new
Color32
(
80
,
80
,
220
,
255
);
public
static
readonly
Color
Accent
=
new
Color32
(
254
,
215
,
0
,
255
);
// #FED700
public
static
readonly
Color
Accent
=
new
Color32
(
254
,
215
,
0
,
255
);
public
static
readonly
Color
AccentDark
=
new
Color32
(
212
,
180
,
0
,
255
);
// #D4B400
public
static
readonly
Color
AccentDark
=
new
Color32
(
212
,
180
,
0
,
255
);
// ── Feedback Colors ──────────────────────────────────────────
public
static
readonly
Color
Success
=
new
Color32
(
16
,
185
,
129
,
255
);
// #10B981
public
static
readonly
Color
Success
=
new
Color32
(
16
,
185
,
129
,
255
);
public
static
readonly
Color
SuccessLight
=
new
Color32
(
209
,
250
,
229
,
255
);
// #D1FAE5
public
static
readonly
Color
SuccessLight
=
new
Color32
(
209
,
250
,
229
,
255
);
public
static
readonly
Color
Danger
=
new
Color32
(
239
,
68
,
68
,
255
);
// #EF4444
public
static
readonly
Color
Danger
=
new
Color32
(
239
,
68
,
68
,
255
);
public
static
readonly
Color
DangerLight
=
new
Color32
(
254
,
226
,
226
,
255
);
// #FEE2E2
public
static
readonly
Color
DangerLight
=
new
Color32
(
254
,
226
,
226
,
255
);
public
static
readonly
Color
Warning
=
new
Color32
(
245
,
158
,
11
,
255
);
// #F59E0B
public
static
readonly
Color
Warning
=
new
Color32
(
245
,
158
,
11
,
255
);
public
static
readonly
Color
Info
=
new
Color32
(
59
,
130
,
246
,
255
);
// #3B82F6
public
static
readonly
Color
Info
=
new
Color32
(
59
,
130
,
246
,
255
);
// ── UI Colors ────────────────────────────────────────────────
public
static
readonly
Color
Background
=
new
Color32
(
238
,
240
,
248
,
255
);
// #EEF0F8
public
static
readonly
Color
Background
=
new
Color32
(
238
,
240
,
248
,
255
);
public
static
readonly
Color
Card
=
Color
.
white
;
public
static
readonly
Color
Card
=
Color
.
white
;
public
static
readonly
Color
TextDark
=
new
Color32
(
26
,
26
,
46
,
255
);
// #1A1A2E
public
static
readonly
Color
TextDark
=
new
Color32
(
26
,
26
,
46
,
255
);
public
static
readonly
Color
TextMuted
=
new
Color32
(
107
,
114
,
128
,
255
);
// #6B7280
public
static
readonly
Color
TextMuted
=
new
Color32
(
107
,
114
,
128
,
255
);
public
static
readonly
Color
Border
=
new
Color32
(
229
,
231
,
235
,
255
);
// #E5E7EB
public
static
readonly
Color
Border
=
new
Color32
(
229
,
231
,
235
,
255
);
// ── Game-specific ────────────────────────────────────────────
public
static
readonly
Color
GateCorrect
=
new
Color32
(
16
,
185
,
129
,
255
);
public
static
readonly
Color
GateCorrect
=
new
Color32
(
16
,
185
,
129
,
255
);
public
static
readonly
Color
GateWrong
=
new
Color32
(
239
,
68
,
68
,
255
);
public
static
readonly
Color
GateWrong
=
new
Color32
(
239
,
68
,
68
,
255
);
public
static
readonly
Color
GateDefault
=
new
Color32
(
80
,
80
,
220
,
255
);
public
static
readonly
Color
GateDefault
=
new
Color32
(
80
,
80
,
220
,
255
);
public
static
readonly
Color
TrueGreen
=
new
Color32
(
34
,
197
,
94
,
255
);
// #22C55E
public
static
readonly
Color
TrueGreen
=
new
Color32
(
34
,
197
,
94
,
255
);
public
static
readonly
Color
FalseRed
=
new
Color32
(
239
,
68
,
68
,
255
);
// #EF4444
public
static
readonly
Color
FalseRed
=
new
Color32
(
239
,
68
,
68
,
255
);
public
static
readonly
Color
WrongWord
=
new
Color32
(
239
,
68
,
68
,
255
);
public
static
readonly
Color
WrongWord
=
new
Color32
(
239
,
68
,
68
,
255
);
public
static
readonly
Color
CorrectWord
=
new
Color32
(
16
,
185
,
129
,
255
);
public
static
readonly
Color
CorrectWord
=
new
Color32
(
16
,
185
,
129
,
255
);
public
static
readonly
Color
NeutralWord
=
new
Color32
(
248
,
249
,
252
,
255
);
public
static
readonly
Color
NeutralWord
=
new
Color32
(
248
,
249
,
252
,
255
);
// ── Helpers ──────────────────────────────────────────────────
public
static
Color
WithAlpha
(
Color
c
,
float
a
)
public
static
Color
WithAlpha
(
Color
c
,
float
a
)
{
{
return
new
Color
(
c
.
r
,
c
.
g
,
c
.
b
,
a
);
return
new
Color
(
c
.
r
,
c
.
g
,
c
.
b
,
a
);
...
...
My project/Assets/ScienceStreet/Shared/Scripts/SSDataModels.cs
View file @
c336f670
// ============================================================================
// Science Street — Shared Data Models
// JSON deserialization targets for API responses
// ============================================================================
using
System
;
using
System
;
using
UnityEngine
;
using
UnityEngine
;
using
Newtonsoft.Json
;
using
Newtonsoft.Json
;
namespace
com.al_arcade.shared
namespace
com.al_arcade.shared
{
{
// ── API Wrapper Responses ────────────────────────────────────────
[
Serializable
]
[
Serializable
]
public
class
ApiResponse
<
T
>
public
class
ApiResponse
<
T
>
...
@@ -37,7 +35,6 @@ namespace com.al_arcade.shared
...
@@ -37,7 +35,6 @@ namespace com.al_arcade.shared
public
ClassInfo
classInfo
;
public
ClassInfo
classInfo
;
}
}
// ── Core Data Types ──────────────────────────────────────────────
[
Serializable
]
[
Serializable
]
public
class
GradeInfo
public
class
GradeInfo
...
@@ -58,30 +55,26 @@ namespace com.al_arcade.shared
...
@@ -58,30 +55,26 @@ namespace com.al_arcade.shared
public
string
teacher_name
;
public
string
teacher_name
;
}
}
// ── MCQ ──────────────────────────────────────────────────────────
[
Serializable
]
[
Serializable
]
public
class
McqQuestion
public
class
McqQuestion
{
{
public
string
id
;
public
string
id
;
public
string
question_text
;
public
string
question_text
;
public
string
answer1
;
// always correct
public
string
answer1
;
public
string
answer2
;
public
string
answer2
;
public
string
answer3
;
public
string
answer3
;
public
string
answer4
;
public
string
answer4
;
public
string
source
;
public
string
source
;
public
string
grade_name
;
public
string
grade_name
;
/// <summary>
/// Returns all 4 answers shuffled. Sets correctIndex to the
/// position of the correct answer in the shuffled array.
/// </summary>
public
string
[]
GetShuffledAnswers
(
out
int
correctIndex
)
public
string
[]
GetShuffledAnswers
(
out
int
correctIndex
)
{
{
string
[]
arr
=
{
answer1
,
answer2
,
answer3
,
answer4
};
string
[]
arr
=
{
answer1
,
answer2
,
answer3
,
answer4
};
string
correct
=
answer1
;
string
correct
=
answer1
;
// Fisher-Yates shuffle
for
(
int
i
=
arr
.
Length
-
1
;
i
>
0
;
i
--)
for
(
int
i
=
arr
.
Length
-
1
;
i
>
0
;
i
--)
{
{
int
j
=
UnityEngine
.
Random
.
Range
(
0
,
i
+
1
);
int
j
=
UnityEngine
.
Random
.
Range
(
0
,
i
+
1
);
...
@@ -93,7 +86,6 @@ namespace com.al_arcade.shared
...
@@ -93,7 +86,6 @@ namespace com.al_arcade.shared
}
}
}
}
// ── True/False ───────────────────────────────────────────────────
[
Serializable
]
[
Serializable
]
public
class
TfQuestion
public
class
TfQuestion
...
@@ -105,7 +97,6 @@ namespace com.al_arcade.shared
...
@@ -105,7 +97,6 @@ namespace com.al_arcade.shared
public
string
grade_name
;
public
string
grade_name
;
}
}
// ── Correct Sentence ─────────────────────────────────────────────
[
Serializable
]
[
Serializable
]
public
class
CsQuestion
public
class
CsQuestion
...
...
My project/Assets/ScienceStreet/Shared/Scripts/SSFontManager.cs
View file @
c336f670
...
@@ -2,10 +2,8 @@ using UnityEngine;
...
@@ -2,10 +2,8 @@ using UnityEngine;
namespace
com.al_arcade.shared
namespace
com.al_arcade.shared
{
{
/// <summary>
/// Global Arabic font manager. Set the font once from any DemoBuilder,
/// then all text components pick it up via Apply().
/// </summary>
public
static
class
SSFontManager
public
static
class
SSFontManager
{
{
private
static
TMPro
.
TMP_FontAsset
_font
;
private
static
TMPro
.
TMP_FontAsset
_font
;
...
@@ -26,4 +24,4 @@ namespace com.al_arcade.shared
...
@@ -26,4 +24,4 @@ namespace com.al_arcade.shared
if
(
_font
!=
null
&&
tmp
!=
null
)
tmp
.
font
=
_font
;
if
(
_font
!=
null
&&
tmp
!=
null
)
tmp
.
font
=
_font
;
}
}
}
}
}
}
\ No newline at end of file
My project/Assets/ScienceStreet/Shared/Scripts/SSGameSession.cs
View file @
c336f670
// ============================================================================
// Science Street — Game Session Manager
// Holds current game session state (build type, class code, etc.)
// ============================================================================
using
System
;
using
System
;
using
System.Collections
;
using
System.Collections
;
using
UnityEngine
;
using
UnityEngine
;
...
@@ -23,14 +21,14 @@ namespace com.al_arcade.shared
...
@@ -23,14 +21,14 @@ namespace com.al_arcade.shared
[
Tooltip
(
"Number of questions to fetch"
)]
[
Tooltip
(
"Number of questions to fetch"
)]
public
int
questionCount
=
10
;
public
int
questionCount
=
10
;
// ── Runtime State (Teacher Build) ────────────────────────────
[
HideInInspector
]
public
string
classCode
=
""
;
[
HideInInspector
]
public
string
classCode
=
""
;
[
HideInInspector
]
public
string
className
=
""
;
[
HideInInspector
]
public
string
className
=
""
;
[
HideInInspector
]
public
string
teacherName
=
""
;
[
HideInInspector
]
public
string
teacherName
=
""
;
[
HideInInspector
]
public
string
gradeName
=
""
;
[
HideInInspector
]
public
string
gradeName
=
""
;
[
HideInInspector
]
public
bool
isClassValidated
=
false
;
[
HideInInspector
]
public
bool
isClassValidated
=
false
;
// ── Events ───────────────────────────────────────────────────
[
Header
(
"Events"
)]
[
Header
(
"Events"
)]
public
UnityEvent
onSessionReady
;
public
UnityEvent
onSessionReady
;
public
UnityEvent
<
string
>
onSessionError
;
public
UnityEvent
<
string
>
onSessionError
;
...
@@ -55,9 +53,7 @@ namespace com.al_arcade.shared
...
@@ -55,9 +53,7 @@ namespace com.al_arcade.shared
return
Instance
;
return
Instance
;
}
}
/// <summary>
/// Validates a teacher class code. On success, stores all class info.
/// </summary>
public
IEnumerator
ValidateAndStartTeacherSession
(
string
code
,
public
IEnumerator
ValidateAndStartTeacherSession
(
string
code
,
Action
onSuccess
,
Action
<
string
>
onError
)
Action
onSuccess
,
Action
<
string
>
onError
)
{
{
...
@@ -89,9 +85,7 @@ namespace com.al_arcade.shared
...
@@ -89,9 +85,7 @@ namespace com.al_arcade.shared
});
});
}
}
/// <summary>
/// Starts a Science Street (public) session.
/// </summary>
public
void
StartSciStreetSession
(
int
grade
=
0
)
public
void
StartSciStreetSession
(
int
grade
=
0
)
{
{
buildType
=
"scistreet"
;
buildType
=
"scistreet"
;
...
@@ -102,9 +96,7 @@ namespace com.al_arcade.shared
...
@@ -102,9 +96,7 @@ namespace com.al_arcade.shared
onSessionReady
?.
Invoke
();
onSessionReady
?.
Invoke
();
}
}
/// <summary>
/// Resets the session to defaults.
/// </summary>
public
void
ResetSession
()
public
void
ResetSession
()
{
{
buildType
=
"scistreet"
;
buildType
=
"scistreet"
;
...
...
My project/Assets/ScienceStreet/Shared/Scripts/SSParticleManager.cs
View file @
c336f670
// ============================================================================
// Science Street — Particle Effect Manager
// Creates particle effects programmatically. Works without any prefabs.
// ============================================================================
using
UnityEngine
;
using
UnityEngine
;
using
System.Collections
;
using
System.Collections
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
...
@@ -41,7 +39,6 @@ namespace com.al_arcade.shared
...
@@ -41,7 +39,6 @@ namespace com.al_arcade.shared
return
Instance
;
return
Instance
;
}
}
// ── Public Play Methods ──────────────────────────────────────
public
void
PlayCorrectBurst
(
Vector3
position
)
public
void
PlayCorrectBurst
(
Vector3
position
)
{
{
...
@@ -105,7 +102,6 @@ namespace com.al_arcade.shared
...
@@ -105,7 +102,6 @@ namespace com.al_arcade.shared
PlayConfetti
(
pos
);
PlayConfetti
(
pos
);
}
}
// ── Procedural Particle Creation ─────────────────────────────
private
void
PlayProceduralBurst
(
Vector3
pos
,
Color
startColor
,
private
void
PlayProceduralBurst
(
Vector3
pos
,
Color
startColor
,
Color
endColor
,
int
count
,
float
lifetime
)
Color
endColor
,
int
count
,
float
lifetime
)
...
@@ -141,7 +137,7 @@ namespace com.al_arcade.shared
...
@@ -141,7 +137,7 @@ namespace com.al_arcade.shared
new
Keyframe
(
0f
,
1f
),
new
Keyframe
(
0f
,
1f
),
new
Keyframe
(
1f
,
0f
)));
new
Keyframe
(
1f
,
0f
)));
// Use default material
var
renderer
=
go
.
GetComponent
<
ParticleSystemRenderer
>();
var
renderer
=
go
.
GetComponent
<
ParticleSystemRenderer
>();
renderer
.
material
=
GetParticleMaterial
();
renderer
.
material
=
GetParticleMaterial
();
...
@@ -169,7 +165,7 @@ namespace com.al_arcade.shared
...
@@ -169,7 +165,7 @@ namespace com.al_arcade.shared
main
.
loop
=
false
;
main
.
loop
=
false
;
main
.
duration
=
0.2f
;
main
.
duration
=
0.2f
;
// Random color from our palette
var
gradient
=
new
Gradient
();
var
gradient
=
new
Gradient
();
gradient
.
SetKeys
(
gradient
.
SetKeys
(
new
[]
{
new
[]
{
...
@@ -208,7 +204,6 @@ namespace com.al_arcade.shared
...
@@ -208,7 +204,6 @@ namespace com.al_arcade.shared
Destroy
(
go
,
5f
);
Destroy
(
go
,
5f
);
}
}
// ── Helpers ──────────────────────────────────────────────────
private
void
SpawnPrefab
(
ParticleSystem
prefab
,
Vector3
pos
)
private
void
SpawnPrefab
(
ParticleSystem
prefab
,
Vector3
pos
)
{
{
...
@@ -225,7 +220,7 @@ namespace com.al_arcade.shared
...
@@ -225,7 +220,7 @@ namespace com.al_arcade.shared
{
{
if
(
_cachedMat
!=
null
)
return
_cachedMat
;
if
(
_cachedMat
!=
null
)
return
_cachedMat
;
// Try to find the default particle shader
Shader
shader
=
Shader
.
Find
(
"Particles/Standard Unlit"
);
Shader
shader
=
Shader
.
Find
(
"Particles/Standard Unlit"
);
if
(
shader
==
null
)
shader
=
Shader
.
Find
(
"Universal Render Pipeline/Particles/Unlit"
);
if
(
shader
==
null
)
shader
=
Shader
.
Find
(
"Universal Render Pipeline/Particles/Unlit"
);
if
(
shader
==
null
)
shader
=
Shader
.
Find
(
"Mobile/Particles/Alpha Blended"
);
if
(
shader
==
null
)
shader
=
Shader
.
Find
(
"Mobile/Particles/Alpha Blended"
);
...
@@ -233,7 +228,7 @@ namespace com.al_arcade.shared
...
@@ -233,7 +228,7 @@ namespace com.al_arcade.shared
if
(
shader
==
null
)
shader
=
Shader
.
Find
(
"Unlit/Color"
);
if
(
shader
==
null
)
shader
=
Shader
.
Find
(
"Unlit/Color"
);
_cachedMat
=
new
Material
(
shader
);
_cachedMat
=
new
Material
(
shader
);
_cachedMat
.
SetFloat
(
"_Mode"
,
2
);
// Fade
_cachedMat
.
SetFloat
(
"_Mode"
,
2
);
return
_cachedMat
;
return
_cachedMat
;
}
}
}
}
...
...
My project/Assets/ScienceStreet/TF/Scripts/TfDemoBuilder.cs
View file @
c336f670
This diff is collapsed.
Click to expand it.
My project/Assets/ScienceStreet/TF/Scripts/TfHandController.cs
View file @
c336f670
...
@@ -43,13 +43,13 @@ namespace com.al_arcade.tf
...
@@ -43,13 +43,13 @@ namespace com.al_arcade.tf
float
side
=
isLeft
?
-
1f
:
1f
;
float
side
=
isLeft
?
-
1f
:
1f
;
var
shader
=
GetShader
();
var
shader
=
GetShader
();
// ── Hand root ────────────────────────────────────────────
hand
=
new
GameObject
(
isLeft
?
"LeftHand"
:
"RightHand"
);
hand
=
new
GameObject
(
isLeft
?
"LeftHand"
:
"RightHand"
);
hand
.
transform
.
SetParent
(
transform
);
hand
.
transform
.
SetParent
(
transform
);
hand
.
transform
.
localPosition
=
new
Vector3
(
side
*
0.35f
,
-
0.3f
,
0.55f
);
hand
.
transform
.
localPosition
=
new
Vector3
(
side
*
0.35f
,
-
0.3f
,
0.55f
);
hand
.
transform
.
localRotation
=
Quaternion
.
Euler
(
12f
,
-
side
*
8f
,
side
*
4f
);
hand
.
transform
.
localRotation
=
Quaternion
.
Euler
(
12f
,
-
side
*
8f
,
side
*
4f
);
// ── Arm (smaller, more proportional) ─────────────────────
var
arm
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Capsule
);
var
arm
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Capsule
);
arm
.
name
=
"Arm"
;
arm
.
name
=
"Arm"
;
arm
.
transform
.
SetParent
(
hand
.
transform
);
arm
.
transform
.
SetParent
(
hand
.
transform
);
...
@@ -59,7 +59,7 @@ namespace com.al_arcade.tf
...
@@ -59,7 +59,7 @@ namespace com.al_arcade.tf
arm
.
GetComponent
<
Renderer
>().
material
=
arm
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
new
Color32
(
255
,
220
,
180
,
255
)
};
new
Material
(
shader
)
{
color
=
new
Color32
(
255
,
220
,
180
,
255
)
};
// ── Button (sized for close-up FPS view) ─────────────────
btn
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
btn
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
btn
.
name
=
isLeft
?
"TrueButton"
:
"FalseButton"
;
btn
.
name
=
isLeft
?
"TrueButton"
:
"FalseButton"
;
btn
.
transform
.
SetParent
(
hand
.
transform
);
btn
.
transform
.
SetParent
(
hand
.
transform
);
...
@@ -73,17 +73,17 @@ namespace com.al_arcade.tf
...
@@ -73,17 +73,17 @@ namespace com.al_arcade.tf
};
};
btn
.
GetComponent
<
Renderer
>().
material
=
mat
;
btn
.
GetComponent
<
Renderer
>().
material
=
mat
;
// ── Label — ★ small font, tight rect, on top of button ───
var
labelObj
=
new
GameObject
(
"Label"
);
var
labelObj
=
new
GameObject
(
"Label"
);
labelObj
.
transform
.
SetParent
(
btn
.
transform
);
labelObj
.
transform
.
SetParent
(
btn
.
transform
);
labelObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0.8f
,
0
);
labelObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0.8f
,
0
);
labelObj
.
transform
.
localRotation
=
Quaternion
.
Euler
(
90
,
0
,
0
);
labelObj
.
transform
.
localRotation
=
Quaternion
.
Euler
(
90
,
0
,
0
);
// ★ Scale the label container down so the text is proportional
labelObj
.
transform
.
localScale
=
new
Vector3
(
0.6f
,
0.6f
,
0.6f
);
labelObj
.
transform
.
localScale
=
new
Vector3
(
0.6f
,
0.6f
,
0.6f
);
label
=
labelObj
.
AddComponent
<
ArabicTextMeshPro
>();
label
=
labelObj
.
AddComponent
<
ArabicTextMeshPro
>();
label
.
arabicText
=
isLeft
?
"صح ✓"
:
"خطأ ✗"
;
label
.
arabicText
=
isLeft
?
"صح ✓"
:
"خطأ ✗"
;
// ★ fontSize 2 in a small world-space rect = readable not giant
label
.
fontSize
=
2.2f
;
label
.
fontSize
=
2.2f
;
label
.
fontSizeMin
=
1.5f
;
label
.
fontSizeMin
=
1.5f
;
label
.
fontSizeMax
=
2.5f
;
label
.
fontSizeMax
=
2.5f
;
...
@@ -91,12 +91,12 @@ namespace com.al_arcade.tf
...
@@ -91,12 +91,12 @@ namespace com.al_arcade.tf
label
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
label
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
label
.
color
=
Color
.
white
;
label
.
color
=
Color
.
white
;
label
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
label
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
// ★ Tight rect so text doesn't overflow
label
.
rectTransform
.
sizeDelta
=
new
Vector2
(
1.2f
,
0.5f
);
label
.
rectTransform
.
sizeDelta
=
new
Vector2
(
1.2f
,
0.5f
);
label
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Overflow
;
label
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Overflow
;
SSFontManager
.
Apply
(
label
);
SSFontManager
.
Apply
(
label
);
// ── Glow ring ────────────────────────────────────────────
var
ring
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
var
ring
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
ring
.
name
=
"GlowRing"
;
ring
.
name
=
"GlowRing"
;
ring
.
transform
.
SetParent
(
btn
.
transform
);
ring
.
transform
.
SetParent
(
btn
.
transform
);
...
@@ -110,7 +110,6 @@ namespace com.al_arcade.tf
...
@@ -110,7 +110,6 @@ namespace com.al_arcade.tf
};
};
}
}
// ── Idle Animation ───────────────────────────────────────────
private
void
StartIdleAnimation
()
private
void
StartIdleAnimation
()
{
{
...
@@ -139,7 +138,6 @@ namespace com.al_arcade.tf
...
@@ -139,7 +138,6 @@ namespace com.al_arcade.tf
_idleSeq
=
null
;
_idleSeq
=
null
;
}
}
// ── Input ────────────────────────────────────────────────────
public
void
SetReady
(
bool
ready
)
=>
_isReady
=
ready
;
public
void
SetReady
(
bool
ready
)
=>
_isReady
=
ready
;
...
@@ -161,14 +159,14 @@ namespace com.al_arcade.tf
...
@@ -161,14 +159,14 @@ namespace com.al_arcade.tf
var
restPos
=
isTrue
?
_leftRestPos
:
_rightRestPos
;
var
restPos
=
isTrue
?
_leftRestPos
:
_rightRestPos
;
var
btnBaseScale
=
isTrue
?
_leftBtnBaseScale
:
_rightBtnBaseScale
;
var
btnBaseScale
=
isTrue
?
_leftBtnBaseScale
:
_rightBtnBaseScale
;
// ★ Kill ALL tweens, reset to known state
KillIdleTween
();
KillIdleTween
();
DOTween
.
Kill
(
hand
.
transform
);
DOTween
.
Kill
(
hand
.
transform
);
DOTween
.
Kill
(
btn
.
transform
);
DOTween
.
Kill
(
btn
.
transform
);
hand
.
transform
.
localPosition
=
restPos
;
hand
.
transform
.
localPosition
=
restPos
;
btn
.
transform
.
localScale
=
btnBaseScale
;
btn
.
transform
.
localScale
=
btnBaseScale
;
// ★ Press animation — always returns to restPos
var
pressSeq
=
DOTween
.
Sequence
();
var
pressSeq
=
DOTween
.
Sequence
();
pressSeq
.
Append
(
hand
.
transform
pressSeq
.
Append
(
hand
.
transform
.
DOLocalMoveY
(
restPos
.
y
+
0.06f
,
0.07f
)
.
DOLocalMoveY
(
restPos
.
y
+
0.06f
,
0.07f
)
...
@@ -181,7 +179,7 @@ namespace com.al_arcade.tf
...
@@ -181,7 +179,7 @@ namespace com.al_arcade.tf
.
SetEase
(
Ease
.
OutBounce
));
.
SetEase
(
Ease
.
OutBounce
));
pressSeq
.
OnComplete
(()
=>
StartIdleAnimation
());
pressSeq
.
OnComplete
(()
=>
StartIdleAnimation
());
// ★ Button squash (Y axis is thickness for cylinder)
btn
.
transform
.
DOScaleY
(
btnBaseScale
.
y
*
0.3f
,
0.05f
)
btn
.
transform
.
DOScaleY
(
btnBaseScale
.
y
*
0.3f
,
0.05f
)
.
SetEase
(
Ease
.
InQuad
)
.
SetEase
(
Ease
.
InQuad
)
.
OnComplete
(()
=>
.
OnComplete
(()
=>
...
@@ -195,7 +193,6 @@ namespace com.al_arcade.tf
...
@@ -195,7 +193,6 @@ namespace com.al_arcade.tf
TfGameManager
.
Instance
.
SubmitAnswer
(
isTrue
);
TfGameManager
.
Instance
.
SubmitAnswer
(
isTrue
);
}
}
// ── Feedback ─────────────────────────────────────────────────
public
void
PlayCorrectFeedback
(
bool
wasTrue
)
public
void
PlayCorrectFeedback
(
bool
wasTrue
)
{
{
...
@@ -270,4 +267,4 @@ namespace com.al_arcade.tf
...
@@ -270,4 +267,4 @@ namespace com.al_arcade.tf
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
}
}
}
}
\ No newline at end of file
My project/Assets/ScienceStreet/TF/Scripts/TfPrefabBuilder.cs
View file @
c336f670
...
@@ -12,9 +12,7 @@ namespace com.al_arcade.tf
...
@@ -12,9 +12,7 @@ namespace com.al_arcade.tf
[
AddComponentMenu
(
"Science Street/TF Prefab Builder"
)]
[
AddComponentMenu
(
"Science Street/TF Prefab Builder"
)]
public
class
TfPrefabBuilder
:
MonoBehaviour
public
class
TfPrefabBuilder
:
MonoBehaviour
{
{
// ════════════════════════════════════════════════════════════
// SCENE
// ════════════════════════════════════════════════════════════
[
Header
(
"Scene Environment"
)]
[
Header
(
"Scene Environment"
)]
[
Tooltip
(
"Your full factory environment prefab."
)]
[
Tooltip
(
"Your full factory environment prefab."
)]
...
@@ -26,18 +24,12 @@ namespace com.al_arcade.tf
...
@@ -26,18 +24,12 @@ namespace com.al_arcade.tf
[
SerializeField
]
private
float
cameraFOV
=
55f
;
[
SerializeField
]
private
float
cameraFOV
=
55f
;
[
SerializeField
]
private
Color
cameraBgColor
=
new
Color32
(
70
,
80
,
110
,
255
);
[
SerializeField
]
private
Color
cameraBgColor
=
new
Color32
(
70
,
80
,
110
,
255
);
// ════════════════════════════════════════════════════════════
// LIGHTING
// ════════════════════════════════════════════════════════════
[
Header
(
"Lighting"
)]
[
Header
(
"Lighting"
)]
[
SerializeField
]
private
GameObject
directionalLightPrefab
;
[
SerializeField
]
private
GameObject
directionalLightPrefab
;
[
SerializeField
]
private
GameObject
[]
extraLightPrefabs
;
[
SerializeField
]
private
GameObject
[]
extraLightPrefabs
;
[
SerializeField
]
private
Color
ambientColor
=
new
Color32
(
75
,
78
,
95
,
255
);
[
SerializeField
]
private
Color
ambientColor
=
new
Color32
(
75
,
78
,
95
,
255
);
// ════════════════════════════════════════════════════════════
// PRODUCTION LINE
// ════════════════════════════════════════════════════════════
[
Header
(
"Production Line"
)]
[
Header
(
"Production Line"
)]
[
Tooltip
(
"Your production line prefab. MUST have TfProductionLine.\n"
+
[
Tooltip
(
"Your production line prefab. MUST have TfProductionLine.\n"
+
...
@@ -45,9 +37,6 @@ namespace com.al_arcade.tf
...
@@ -45,9 +37,6 @@ namespace com.al_arcade.tf
[
SerializeField
]
private
GameObject
productionLinePrefab
;
[
SerializeField
]
private
GameObject
productionLinePrefab
;
[
SerializeField
]
private
Vector3
productionLinePosition
=
new
Vector3
(
0
,
0
,
2
);
[
SerializeField
]
private
Vector3
productionLinePosition
=
new
Vector3
(
0
,
0
,
2
);
// ════════════════════════════════════════════════════════════
// QUESTION SCREEN
// ════════════════════════════════════════════════════════════
[
Header
(
"Question Screen"
)]
[
Header
(
"Question Screen"
)]
[
Tooltip
(
"Your question screen prefab. MUST have TfQuestionScreen.\n"
+
[
Tooltip
(
"Your question screen prefab. MUST have TfQuestionScreen.\n"
+
...
@@ -55,27 +44,18 @@ namespace com.al_arcade.tf
...
@@ -55,27 +44,18 @@ namespace com.al_arcade.tf
[
SerializeField
]
private
GameObject
questionScreenPrefab
;
[
SerializeField
]
private
GameObject
questionScreenPrefab
;
[
SerializeField
]
private
Vector3
questionScreenPosition
=
new
Vector3
(
0
,
5f
,
12f
);
[
SerializeField
]
private
Vector3
questionScreenPosition
=
new
Vector3
(
0
,
5f
,
12f
);
// ════════════════════════════════════════════════════════════
// HANDS
// ════════════════════════════════════════════════════════════
[
Header
(
"Hands / Buttons"
)]
[
Header
(
"Hands / Buttons"
)]
[
Tooltip
(
"Your hands prefab. MUST have TfHandController.\n"
+
[
Tooltip
(
"Your hands prefab. MUST have TfHandController.\n"
+
"If null, procedural hands are created."
)]
"If null, procedural hands are created."
)]
[
SerializeField
]
private
GameObject
handsPrefab
;
[
SerializeField
]
private
GameObject
handsPrefab
;
// ════════════════════════════════════════════════════════════
// UI
// ════════════════════════════════════════════════════════════
[
Header
(
"UI Canvas"
)]
[
Header
(
"UI Canvas"
)]
[
Tooltip
(
"Your Canvas prefab. MUST have TfUIManager with all references wired.\n"
+
[
Tooltip
(
"Your Canvas prefab. MUST have TfUIManager with all references wired.\n"
+
"If null, procedural UI is created."
)]
"If null, procedural UI is created."
)]
[
SerializeField
]
private
GameObject
canvasPrefab
;
[
SerializeField
]
private
GameObject
canvasPrefab
;
// ════════════════════════════════════════════════════════════
// AUDIO
// ════════════════════════════════════════════════════════════
[
Header
(
"Audio — SFX Clips"
)]
[
Header
(
"Audio — SFX Clips"
)]
[
SerializeField
]
private
AudioClip
sfxCorrect
;
[
SerializeField
]
private
AudioClip
sfxCorrect
;
...
@@ -87,9 +67,6 @@ namespace com.al_arcade.tf
...
@@ -87,9 +67,6 @@ namespace com.al_arcade.tf
[
SerializeField
]
private
AudioClip
sfxPop
;
[
SerializeField
]
private
AudioClip
sfxPop
;
[
SerializeField
]
private
AudioClip
sfxSlam
;
[
SerializeField
]
private
AudioClip
sfxSlam
;
// ════════════════════════════════════════════════════════════
// PARTICLES
// ════════════════════════════════════════════════════════════
[
Header
(
"Particles"
)]
[
Header
(
"Particles"
)]
[
SerializeField
]
private
ParticleSystem
correctBurstParticle
;
[
SerializeField
]
private
ParticleSystem
correctBurstParticle
;
...
@@ -98,16 +75,10 @@ namespace com.al_arcade.tf
...
@@ -98,16 +75,10 @@ namespace com.al_arcade.tf
[
SerializeField
]
private
ParticleSystem
sparksParticle
;
[
SerializeField
]
private
ParticleSystem
sparksParticle
;
[
SerializeField
]
private
ParticleSystem
starBurstParticle
;
[
SerializeField
]
private
ParticleSystem
starBurstParticle
;
// ════════════════════════════════════════════════════════════
// FONT
// ════════════════════════════════════════════════════════════
[
Header
(
"Arabic Font"
)]
[
Header
(
"Arabic Font"
)]
[
SerializeField
]
private
TMP_FontAsset
arabicFont
;
[
SerializeField
]
private
TMP_FontAsset
arabicFont
;
// ════════════════════════════════════════════════════════════
// GAME SETTINGS
// ════════════════════════════════════════════════════════════
[
Header
(
"Game Settings"
)]
[
Header
(
"Game Settings"
)]
[
SerializeField
]
private
string
buildType
=
"scistreet"
;
[
SerializeField
]
private
string
buildType
=
"scistreet"
;
...
@@ -120,9 +91,6 @@ namespace com.al_arcade.tf
...
@@ -120,9 +91,6 @@ namespace com.al_arcade.tf
[
Header
(
"Debug"
)]
[
Header
(
"Debug"
)]
[
SerializeField
]
private
bool
useOfflineTestData
=
false
;
[
SerializeField
]
private
bool
useOfflineTestData
=
false
;
// ════════════════════════════════════════════════════════════
// RUNTIME
// ════════════════════════════════════════════════════════════
private
TfGameManager
_gm
;
private
TfGameManager
_gm
;
private
TfHandController
_handController
;
private
TfHandController
_handController
;
...
@@ -159,20 +127,20 @@ namespace com.al_arcade.tf
...
@@ -159,20 +127,20 @@ namespace com.al_arcade.tf
session
.
classCode
=
classCode
;
session
.
classCode
=
classCode
;
yield
return
null
;
yield
return
null
;
// ── Camera ───────────────────────────────────────────
SetupCamera
();
SetupCamera
();
yield
return
null
;
yield
return
null
;
// ── Environment ──────────────────────────────────────
if
(
environmentPrefab
!=
null
)
if
(
environmentPrefab
!=
null
)
Instantiate
(
environmentPrefab
,
Vector3
.
zero
,
Quaternion
.
identity
);
Instantiate
(
environmentPrefab
,
Vector3
.
zero
,
Quaternion
.
identity
);
yield
return
null
;
yield
return
null
;
// ── Lighting ─────────────────────────────────────────
SetupLighting
();
SetupLighting
();
yield
return
null
;
yield
return
null
;
// ── Production Line ──────────────────────────────────
if
(
productionLinePrefab
!=
null
)
if
(
productionLinePrefab
!=
null
)
{
{
var
lineObj
=
Instantiate
(
productionLinePrefab
,
var
lineObj
=
Instantiate
(
productionLinePrefab
,
...
@@ -194,7 +162,7 @@ namespace com.al_arcade.tf
...
@@ -194,7 +162,7 @@ namespace com.al_arcade.tf
}
}
yield
return
null
;
yield
return
null
;
// ── Question Screen ──────────────────────────────────
if
(
questionScreenPrefab
!=
null
)
if
(
questionScreenPrefab
!=
null
)
{
{
var
screenObj
=
Instantiate
(
questionScreenPrefab
,
var
screenObj
=
Instantiate
(
questionScreenPrefab
,
...
@@ -215,7 +183,7 @@ namespace com.al_arcade.tf
...
@@ -215,7 +183,7 @@ namespace com.al_arcade.tf
}
}
yield
return
null
;
yield
return
null
;
// ── Hands ────────────────────────────────────────────
if
(
handsPrefab
!=
null
)
if
(
handsPrefab
!=
null
)
{
{
var
handsObj
=
Instantiate
(
handsPrefab
);
var
handsObj
=
Instantiate
(
handsPrefab
);
...
@@ -235,7 +203,7 @@ namespace com.al_arcade.tf
...
@@ -235,7 +203,7 @@ namespace com.al_arcade.tf
}
}
yield
return
null
;
yield
return
null
;
// ── UI ───────────────────────────────────────────────
if
(
canvasPrefab
!=
null
)
if
(
canvasPrefab
!=
null
)
{
{
var
canvasObj
=
Instantiate
(
canvasPrefab
);
var
canvasObj
=
Instantiate
(
canvasPrefab
);
...
@@ -258,7 +226,7 @@ namespace com.al_arcade.tf
...
@@ -258,7 +226,7 @@ namespace com.al_arcade.tf
_uiManager
.
onRestartClicked
=
new
UnityEvent
();
_uiManager
.
onRestartClicked
=
new
UnityEvent
();
yield
return
null
;
yield
return
null
;
// ── Game Manager ─────────────────────────────────────
var
gmObj
=
new
GameObject
(
"TfGameManager"
);
var
gmObj
=
new
GameObject
(
"TfGameManager"
);
_gm
=
gmObj
.
AddComponent
<
TfGameManager
>();
_gm
=
gmObj
.
AddComponent
<
TfGameManager
>();
_gm
.
handController
=
_handController
;
_gm
.
handController
=
_handController
;
...
@@ -348,4 +316,4 @@ namespace com.al_arcade.tf
...
@@ -348,4 +316,4 @@ namespace com.al_arcade.tf
};
};
}
}
}
}
}
}
\ No newline at end of file
My project/Assets/ScienceStreet/TF/Scripts/TfProductionLine.cs
View file @
c336f670
...
@@ -21,7 +21,7 @@ namespace com.al_arcade.tf
...
@@ -21,7 +21,7 @@ namespace com.al_arcade.tf
float
totalLength
=
stepsToWin
*
stepDistance
+
10f
;
float
totalLength
=
stepsToWin
*
stepDistance
+
10f
;
var
shader
=
GetShader
();
var
shader
=
GetShader
();
// ── Belt surface ─────────────────────────────────────────
var
belt
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
belt
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
belt
.
name
=
"Belt"
;
belt
.
name
=
"Belt"
;
belt
.
transform
.
SetParent
(
transform
);
belt
.
transform
.
SetParent
(
transform
);
...
@@ -31,7 +31,7 @@ namespace com.al_arcade.tf
...
@@ -31,7 +31,7 @@ namespace com.al_arcade.tf
belt
.
GetComponent
<
Renderer
>().
material
=
belt
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
new
Color32
(
55
,
55
,
65
,
255
)
};
new
Material
(
shader
)
{
color
=
new
Color32
(
55
,
55
,
65
,
255
)
};
// ── Belt top highlight ───────────────────────────────────
var
beltTop
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
beltTop
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
beltTop
.
name
=
"BeltTop"
;
beltTop
.
name
=
"BeltTop"
;
beltTop
.
transform
.
SetParent
(
transform
);
beltTop
.
transform
.
SetParent
(
transform
);
...
@@ -41,7 +41,7 @@ namespace com.al_arcade.tf
...
@@ -41,7 +41,7 @@ namespace com.al_arcade.tf
beltTop
.
GetComponent
<
Renderer
>().
material
=
beltTop
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
new
Color32
(
70
,
70
,
80
,
255
)
};
new
Material
(
shader
)
{
color
=
new
Color32
(
70
,
70
,
80
,
255
)
};
// ── Rollers ──────────────────────────────────────────────
int
rc
=
Mathf
.
CeilToInt
(
totalLength
/
2f
);
int
rc
=
Mathf
.
CeilToInt
(
totalLength
/
2f
);
_rollers
=
new
GameObject
[
rc
];
_rollers
=
new
GameObject
[
rc
];
for
(
int
i
=
0
;
i
<
rc
;
i
++)
for
(
int
i
=
0
;
i
<
rc
;
i
++)
...
@@ -58,7 +58,7 @@ namespace com.al_arcade.tf
...
@@ -58,7 +58,7 @@ namespace com.al_arcade.tf
_rollers
[
i
]
=
r
;
_rollers
[
i
]
=
r
;
}
}
// ── Side rails ───────────────────────────────────────────
for
(
int
s
=
-
1
;
s
<=
1
;
s
+=
2
)
for
(
int
s
=
-
1
;
s
<=
1
;
s
+=
2
)
{
{
var
rail
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
rail
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
...
@@ -71,7 +71,7 @@ namespace com.al_arcade.tf
...
@@ -71,7 +71,7 @@ namespace com.al_arcade.tf
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Primary
};
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Primary
};
}
}
// ── Legs ─────────────────────────────────────────────────
for
(
float
z
=
1
;
z
<
totalLength
;
z
+=
4f
)
for
(
float
z
=
1
;
z
<
totalLength
;
z
+=
4f
)
{
{
for
(
int
s
=
-
1
;
s
<=
1
;
s
+=
2
)
for
(
int
s
=
-
1
;
s
<=
1
;
s
+=
2
)
...
@@ -87,12 +87,12 @@ namespace com.al_arcade.tf
...
@@ -87,12 +87,12 @@ namespace com.al_arcade.tf
}
}
}
}
// ── Progress markers ─────────────────────────────────────
for
(
int
i
=
0
;
i
<
stepsToWin
;
i
++)
for
(
int
i
=
0
;
i
<
stepsToWin
;
i
++)
{
{
float
mz
=
(
i
+
1
)
*
stepDistance
;
float
mz
=
(
i
+
1
)
*
stepDistance
;
// Line marker
var
marker
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
marker
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
marker
.
name
=
$"Marker_
{
i
}
"
;
marker
.
name
=
$"Marker_
{
i
}
"
;
marker
.
transform
.
SetParent
(
transform
);
marker
.
transform
.
SetParent
(
transform
);
...
@@ -105,13 +105,13 @@ namespace com.al_arcade.tf
...
@@ -105,13 +105,13 @@ namespace com.al_arcade.tf
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.5f
)
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.5f
)
};
};
// Step label — facing camera
var
labelObj
=
new
GameObject
(
"StepLabel"
);
var
labelObj
=
new
GameObject
(
"StepLabel"
);
labelObj
.
transform
.
SetParent
(
marker
.
transform
);
labelObj
.
transform
.
SetParent
(
marker
.
transform
);
labelObj
.
transform
.
position
=
labelObj
.
transform
.
position
=
marker
.
transform
.
position
+
new
Vector3
(
1.6f
,
0.5f
,
0
);
marker
.
transform
.
position
+
new
Vector3
(
1.6f
,
0.5f
,
0
);
// Billboard toward camera
Vector3
away
=
labelObj
.
transform
.
position
-
cameraPos
;
Vector3
away
=
labelObj
.
transform
.
position
-
cameraPos
;
away
.
y
=
0
;
away
.
y
=
0
;
if
(
away
.
sqrMagnitude
>
0.01f
)
if
(
away
.
sqrMagnitude
>
0.01f
)
...
@@ -119,7 +119,7 @@ namespace com.al_arcade.tf
...
@@ -119,7 +119,7 @@ namespace com.al_arcade.tf
var
lbl
=
labelObj
.
AddComponent
<
ArabicTextMeshPro
>();
var
lbl
=
labelObj
.
AddComponent
<
ArabicTextMeshPro
>();
lbl
.
arabicText
=
$"✦
{
i
+
1
}
"
;
lbl
.
arabicText
=
$"✦
{
i
+
1
}
"
;
// ★ Small readable size
lbl
.
fontSize
=
2f
;
lbl
.
fontSize
=
2f
;
lbl
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
lbl
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
lbl
.
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.7f
);
lbl
.
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.7f
);
...
@@ -127,7 +127,7 @@ namespace com.al_arcade.tf
...
@@ -127,7 +127,7 @@ namespace com.al_arcade.tf
SSFontManager
.
Apply
(
lbl
);
SSFontManager
.
Apply
(
lbl
);
}
}
// ── End zone ─────────────────────────────────────────────
float
endZ
=
stepsToWin
*
stepDistance
+
2f
;
float
endZ
=
stepsToWin
*
stepDistance
+
2f
;
var
ez
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
ez
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
ez
.
name
=
"EndZone"
;
ez
.
name
=
"EndZone"
;
...
@@ -138,7 +138,7 @@ namespace com.al_arcade.tf
...
@@ -138,7 +138,7 @@ namespace com.al_arcade.tf
ez
.
GetComponent
<
Renderer
>().
material
=
ez
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Success
,
0.35f
)
};
new
Material
(
shader
)
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Success
,
0.35f
)
};
// ── Product ──────────────────────────────────────────────
_product
=
new
GameObject
(
"Product"
);
_product
=
new
GameObject
(
"Product"
);
_product
.
transform
.
SetParent
(
transform
);
_product
.
transform
.
SetParent
(
transform
);
_product
.
transform
.
localPosition
=
new
Vector3
(
0
,
0.7f
,
0
);
_product
.
transform
.
localPosition
=
new
Vector3
(
0
,
0.7f
,
0
);
...
@@ -152,7 +152,7 @@ namespace com.al_arcade.tf
...
@@ -152,7 +152,7 @@ namespace com.al_arcade.tf
_productMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Accent
};
_productMat
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Accent
};
box
.
GetComponent
<
Renderer
>().
material
=
_productMat
;
box
.
GetComponent
<
Renderer
>().
material
=
_productMat
;
// Stripe on box
var
stripe
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
stripe
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
stripe
.
name
=
"Stripe"
;
stripe
.
name
=
"Stripe"
;
stripe
.
transform
.
SetParent
(
_product
.
transform
);
stripe
.
transform
.
SetParent
(
_product
.
transform
);
...
@@ -162,7 +162,7 @@ namespace com.al_arcade.tf
...
@@ -162,7 +162,7 @@ namespace com.al_arcade.tf
stripe
.
GetComponent
<
Renderer
>().
material
=
stripe
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Primary
};
new
Material
(
shader
)
{
color
=
SSColorPalette
.
Primary
};
// Star on top
var
star
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Sphere
);
var
star
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Sphere
);
star
.
name
=
"Star"
;
star
.
name
=
"Star"
;
star
.
transform
.
SetParent
(
_product
.
transform
);
star
.
transform
.
SetParent
(
_product
.
transform
);
...
@@ -175,7 +175,6 @@ namespace com.al_arcade.tf
...
@@ -175,7 +175,6 @@ namespace com.al_arcade.tf
_currentZ
=
0
;
_currentZ
=
0
;
}
}
// ── Movement ─────────────────────────────────────────────────
public
IEnumerator
MoveForward
(
float
dist
)
public
IEnumerator
MoveForward
(
float
dist
)
{
{
...
@@ -265,4 +264,4 @@ namespace com.al_arcade.tf
...
@@ -265,4 +264,4 @@ namespace com.al_arcade.tf
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
}
}
}
}
\ No newline at end of file
My project/Assets/ScienceStreet/TF/Scripts/TfQuestionScreen.cs
View file @
c336f670
...
@@ -15,15 +15,13 @@ namespace com.al_arcade.tf
...
@@ -15,15 +15,13 @@ namespace com.al_arcade.tf
private
Material
_feedbackMat
;
private
Material
_feedbackMat
;
private
GameObject
_feedbackPanel
;
private
GameObject
_feedbackPanel
;
/// <summary>
/// Build screen at position, rotated to face cameraPos.
/// </summary>
public
void
Build
(
Vector3
position
,
Vector3
cameraPos
)
public
void
Build
(
Vector3
position
,
Vector3
cameraPos
)
{
{
transform
.
position
=
position
;
transform
.
position
=
position
;
var
shader
=
GetShader
();
var
shader
=
GetShader
();
// ── Frame ────────────────────────────────────────────────
var
frame
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
frame
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
frame
.
name
=
"Frame"
;
frame
.
name
=
"Frame"
;
frame
.
transform
.
SetParent
(
transform
);
frame
.
transform
.
SetParent
(
transform
);
...
@@ -33,7 +31,7 @@ namespace com.al_arcade.tf
...
@@ -33,7 +31,7 @@ namespace com.al_arcade.tf
frame
.
GetComponent
<
Renderer
>().
material
=
frame
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
new
Color32
(
25
,
25
,
35
,
255
)
};
new
Material
(
shader
)
{
color
=
new
Color32
(
25
,
25
,
35
,
255
)
};
// ── Screen border highlight ──────────────────────────────
var
borderGlow
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
borderGlow
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
borderGlow
.
name
=
"BorderGlow"
;
borderGlow
.
name
=
"BorderGlow"
;
borderGlow
.
transform
.
SetParent
(
transform
);
borderGlow
.
transform
.
SetParent
(
transform
);
...
@@ -43,7 +41,7 @@ namespace com.al_arcade.tf
...
@@ -43,7 +41,7 @@ namespace com.al_arcade.tf
borderGlow
.
GetComponent
<
Renderer
>().
material
=
borderGlow
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Primary
,
0.3f
)
};
new
Material
(
shader
)
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Primary
,
0.3f
)
};
// ── Screen surface ───────────────────────────────────────
var
surface
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
surface
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
surface
.
name
=
"Surface"
;
surface
.
name
=
"Surface"
;
surface
.
transform
.
SetParent
(
transform
);
surface
.
transform
.
SetParent
(
transform
);
...
@@ -53,7 +51,7 @@ namespace com.al_arcade.tf
...
@@ -53,7 +51,7 @@ namespace com.al_arcade.tf
_screenMat
=
new
Material
(
shader
)
{
color
=
new
Color32
(
15
,
15
,
50
,
255
)
};
_screenMat
=
new
Material
(
shader
)
{
color
=
new
Color32
(
15
,
15
,
50
,
255
)
};
surface
.
GetComponent
<
Renderer
>().
material
=
_screenMat
;
surface
.
GetComponent
<
Renderer
>().
material
=
_screenMat
;
// ── Pole ─────────────────────────────────────────────────
var
pole
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
var
pole
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
pole
.
name
=
"Pole"
;
pole
.
name
=
"Pole"
;
pole
.
transform
.
SetParent
(
transform
);
pole
.
transform
.
SetParent
(
transform
);
...
@@ -63,7 +61,7 @@ namespace com.al_arcade.tf
...
@@ -63,7 +61,7 @@ namespace com.al_arcade.tf
pole
.
GetComponent
<
Renderer
>().
material
=
pole
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
new
Color32
(
70
,
70
,
85
,
255
)
};
new
Material
(
shader
)
{
color
=
new
Color32
(
70
,
70
,
85
,
255
)
};
// ── Pole base ────────────────────────────────────────────
var
poleBase
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
var
poleBase
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cylinder
);
poleBase
.
name
=
"PoleBase"
;
poleBase
.
name
=
"PoleBase"
;
poleBase
.
transform
.
SetParent
(
transform
);
poleBase
.
transform
.
SetParent
(
transform
);
...
@@ -73,7 +71,7 @@ namespace com.al_arcade.tf
...
@@ -73,7 +71,7 @@ namespace com.al_arcade.tf
poleBase
.
GetComponent
<
Renderer
>().
material
=
poleBase
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
new
Color32
(
60
,
60
,
75
,
255
)
};
new
Material
(
shader
)
{
color
=
new
Color32
(
60
,
60
,
75
,
255
)
};
// ── Question text ★ z = -0.25 (pushed out toward camera) ─
var
textObj
=
new
GameObject
(
"QuestionText"
);
var
textObj
=
new
GameObject
(
"QuestionText"
);
textObj
.
transform
.
SetParent
(
transform
);
textObj
.
transform
.
SetParent
(
transform
);
textObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0.25f
,
-
0.25f
);
textObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0.25f
,
-
0.25f
);
...
@@ -84,7 +82,7 @@ namespace com.al_arcade.tf
...
@@ -84,7 +82,7 @@ namespace com.al_arcade.tf
_questionText
.
color
=
Color
.
white
;
_questionText
.
color
=
Color
.
white
;
_questionText
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
_questionText
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
_questionText
.
enableAutoSizing
=
true
;
_questionText
.
enableAutoSizing
=
true
;
// ★ Sensible font range for a 7-unit-wide screen at ~12m distance
_questionText
.
fontSizeMin
=
1.8f
;
_questionText
.
fontSizeMin
=
1.8f
;
_questionText
.
fontSizeMax
=
3.8f
;
_questionText
.
fontSizeMax
=
3.8f
;
_questionText
.
rectTransform
.
sizeDelta
=
new
Vector2
(
6.2f
,
2.2f
);
_questionText
.
rectTransform
.
sizeDelta
=
new
Vector2
(
6.2f
,
2.2f
);
...
@@ -92,7 +90,7 @@ namespace com.al_arcade.tf
...
@@ -92,7 +90,7 @@ namespace com.al_arcade.tf
_questionText
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Ellipsis
;
_questionText
.
overflowMode
=
TMPro
.
TextOverflowModes
.
Ellipsis
;
SSFontManager
.
Apply
(
_questionText
);
SSFontManager
.
Apply
(
_questionText
);
// ── Source text ──────────────────────────────────────────
var
srcObj
=
new
GameObject
(
"SourceText"
);
var
srcObj
=
new
GameObject
(
"SourceText"
);
srcObj
.
transform
.
SetParent
(
transform
);
srcObj
.
transform
.
SetParent
(
transform
);
srcObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
-
1.15f
,
-
0.25f
);
srcObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
-
1.15f
,
-
0.25f
);
...
@@ -105,7 +103,7 @@ namespace com.al_arcade.tf
...
@@ -105,7 +103,7 @@ namespace com.al_arcade.tf
_sourceText
.
rectTransform
.
sizeDelta
=
new
Vector2
(
6f
,
0.5f
);
_sourceText
.
rectTransform
.
sizeDelta
=
new
Vector2
(
6f
,
0.5f
);
SSFontManager
.
Apply
(
_sourceText
);
SSFontManager
.
Apply
(
_sourceText
);
// ── Feedback panel (overlays question) ───────────────────
_feedbackPanel
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_feedbackPanel
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
_feedbackPanel
.
name
=
"FeedbackPanel"
;
_feedbackPanel
.
name
=
"FeedbackPanel"
;
_feedbackPanel
.
transform
.
SetParent
(
transform
);
_feedbackPanel
.
transform
.
SetParent
(
transform
);
...
@@ -122,14 +120,14 @@ namespace com.al_arcade.tf
...
@@ -122,14 +120,14 @@ namespace com.al_arcade.tf
fbObj
.
transform
.
SetParent
(
_feedbackPanel
.
transform
);
fbObj
.
transform
.
SetParent
(
_feedbackPanel
.
transform
);
fbObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0
,
-
0.15f
);
fbObj
.
transform
.
localPosition
=
new
Vector3
(
0
,
0
,
-
0.15f
);
fbObj
.
transform
.
localRotation
=
Quaternion
.
identity
;
fbObj
.
transform
.
localRotation
=
Quaternion
.
identity
;
// ★ Scale container so feedback text isn't giant
// FeedbackPanel is 6.6 wide but we want text around 3 units
fbObj
.
transform
.
localScale
=
new
Vector3
(
0.5f
,
0.5f
,
1f
);
fbObj
.
transform
.
localScale
=
new
Vector3
(
0.5f
,
0.5f
,
1f
);
_feedbackText
=
fbObj
.
AddComponent
<
ArabicTextMeshPro
>();
_feedbackText
=
fbObj
.
AddComponent
<
ArabicTextMeshPro
>();
_feedbackText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_feedbackText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_feedbackText
.
color
=
Color
.
white
;
_feedbackText
.
color
=
Color
.
white
;
// ★ Moderate feedback font size
_feedbackText
.
fontSize
=
4f
;
_feedbackText
.
fontSize
=
4f
;
_feedbackText
.
fontSizeMin
=
2.5f
;
_feedbackText
.
fontSizeMin
=
2.5f
;
_feedbackText
.
fontSizeMax
=
5f
;
_feedbackText
.
fontSizeMax
=
5f
;
...
@@ -140,7 +138,7 @@ namespace com.al_arcade.tf
...
@@ -140,7 +138,7 @@ namespace com.al_arcade.tf
_feedbackText
.
arabicText
=
""
;
_feedbackText
.
arabicText
=
""
;
SSFontManager
.
Apply
(
_feedbackText
);
SSFontManager
.
Apply
(
_feedbackText
);
// ── Accent strips (top + bottom) ─────────────────────────
var
topStrip
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
var
topStrip
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Cube
);
topStrip
.
name
=
"TopStrip"
;
topStrip
.
name
=
"TopStrip"
;
topStrip
.
transform
.
SetParent
(
transform
);
topStrip
.
transform
.
SetParent
(
transform
);
...
@@ -159,7 +157,7 @@ namespace com.al_arcade.tf
...
@@ -159,7 +157,7 @@ namespace com.al_arcade.tf
botStrip
.
GetComponent
<
Renderer
>().
material
=
botStrip
.
GetComponent
<
Renderer
>().
material
=
new
Material
(
shader
)
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.5f
)
};
new
Material
(
shader
)
{
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
Accent
,
0.5f
)
};
// ── Status indicator lights ──────────────────────────────
for
(
int
i
=
-
1
;
i
<=
1
;
i
+=
2
)
for
(
int
i
=
-
1
;
i
<=
1
;
i
+=
2
)
{
{
var
light
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Sphere
);
var
light
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Sphere
);
...
@@ -174,18 +172,17 @@ namespace com.al_arcade.tf
...
@@ -174,18 +172,17 @@ namespace com.al_arcade.tf
};
};
}
}
// ★ Rotate entire screen so -Z faces camera
Vector3
awayFromCamera
=
transform
.
position
-
cameraPos
;
Vector3
awayFromCamera
=
transform
.
position
-
cameraPos
;
awayFromCamera
.
y
=
0
;
awayFromCamera
.
y
=
0
;
if
(
awayFromCamera
.
sqrMagnitude
>
0.01f
)
if
(
awayFromCamera
.
sqrMagnitude
>
0.01f
)
transform
.
rotation
=
Quaternion
.
LookRotation
(
awayFromCamera
);
transform
.
rotation
=
Quaternion
.
LookRotation
(
awayFromCamera
);
}
}
// ── Show Question ────────────────────────────────────────────
public
void
ShowQuestion
(
string
text
,
string
source
=
""
)
public
void
ShowQuestion
(
string
text
,
string
source
=
""
)
{
{
// Hide feedback
if
(
_feedbackMat
!=
null
)
if
(
_feedbackMat
!=
null
)
{
{
DOTween
.
Kill
(
_feedbackMat
,
"fbMat"
);
DOTween
.
Kill
(
_feedbackMat
,
"fbMat"
);
...
@@ -207,7 +204,7 @@ namespace com.al_arcade.tf
...
@@ -207,7 +204,7 @@ namespace com.al_arcade.tf
if
(
_sourceText
!=
null
)
if
(
_sourceText
!=
null
)
_sourceText
.
arabicText
=
!
string
.
IsNullOrEmpty
(
source
)
?
$"📖
{
source
}
"
:
""
;
_sourceText
.
arabicText
=
!
string
.
IsNullOrEmpty
(
source
)
?
$"📖
{
source
}
"
:
""
;
// Screen flash effect
if
(
_screenMat
!=
null
)
if
(
_screenMat
!=
null
)
{
{
DOTween
.
Kill
(
_screenMat
,
"screenFlash"
);
DOTween
.
Kill
(
_screenMat
,
"screenFlash"
);
...
@@ -219,7 +216,6 @@ namespace com.al_arcade.tf
...
@@ -219,7 +216,6 @@ namespace com.al_arcade.tf
}
}
}
}
// ── Show Feedback ────────────────────────────────────────────
public
void
ShowFeedback
(
bool
correct
,
int
streak
)
public
void
ShowFeedback
(
bool
correct
,
int
streak
)
{
{
...
@@ -246,7 +242,6 @@ namespace com.al_arcade.tf
...
@@ -246,7 +242,6 @@ namespace com.al_arcade.tf
}
}
}
}
// ── Clear ────────────────────────────────────────────────────
public
void
Clear
()
public
void
Clear
()
{
{
...
@@ -264,4 +259,4 @@ namespace com.al_arcade.tf
...
@@ -264,4 +259,4 @@ namespace com.al_arcade.tf
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
Shader
.
Find
(
"Universal Render Pipeline/Lit"
)
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
??
Shader
.
Find
(
"Standard"
)
??
Shader
.
Find
(
"Unlit/Color"
);
}
}
}
}
\ No newline at end of file
My project/Assets/ScienceStreet/TF/Scripts/TfUIManager.cs
View file @
c336f670
...
@@ -21,9 +21,6 @@ namespace com.al_arcade.tf
...
@@ -21,9 +21,6 @@ namespace com.al_arcade.tf
[
Header
(
"Events"
)]
[
Header
(
"Events"
)]
public
UnityEvent
onRestartClicked
;
public
UnityEvent
onRestartClicked
;
// ════════════════════════════════════════════════════════════
// BUILD — all sizes tuned for 1920×1080 reference
// ════════════════════════════════════════════════════════════
public
void
BuildUI
()
public
void
BuildUI
()
{
{
...
@@ -50,14 +47,13 @@ namespace com.al_arcade.tf
...
@@ -50,14 +47,13 @@ namespace com.al_arcade.tf
_resultsUI
.
alpha
=
0
;
_resultsUI
.
gameObject
.
SetActive
(
false
);
_resultsUI
.
alpha
=
0
;
_resultsUI
.
gameObject
.
SetActive
(
false
);
}
}
// ── Game HUD ─────────────────────────────────────────────────
private
void
BuildGameHUD
(
Transform
parent
)
private
void
BuildGameHUD
(
Transform
parent
)
{
{
var
go
=
MkPanel
(
parent
,
"GameUI"
);
var
go
=
MkPanel
(
parent
,
"GameUI"
);
_gameUI
=
go
.
AddComponent
<
CanvasGroup
>();
_gameUI
=
go
.
AddComponent
<
CanvasGroup
>();
// ── Top bar ──────────────────────────────────────────────
var
topBarObj
=
new
GameObject
(
"TopBar"
);
var
topBarObj
=
new
GameObject
(
"TopBar"
);
topBarObj
.
transform
.
SetParent
(
go
.
transform
,
false
);
topBarObj
.
transform
.
SetParent
(
go
.
transform
,
false
);
var
tbr
=
topBarObj
.
AddComponent
<
RectTransform
>();
var
tbr
=
topBarObj
.
AddComponent
<
RectTransform
>();
...
@@ -69,26 +65,26 @@ namespace com.al_arcade.tf
...
@@ -69,26 +65,26 @@ namespace com.al_arcade.tf
topBarObj
.
AddComponent
<
Image
>().
color
=
topBarObj
.
AddComponent
<
Image
>().
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
PrimaryDark
,
0.82f
);
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
PrimaryDark
,
0.82f
);
// Score — top-left
_scoreText
=
MkTxt
(
topBarObj
.
transform
,
"Score"
,
"0"
,
_scoreText
=
MkTxt
(
topBarObj
.
transform
,
"Score"
,
"0"
,
32
,
new
Vector2
(
0
,
0.5f
),
new
Vector2
(
36
,
6
),
new
Vector2
(
180
,
44
));
32
,
new
Vector2
(
0
,
0.5f
),
new
Vector2
(
36
,
6
),
new
Vector2
(
180
,
44
));
_scoreText
.
color
=
SSColorPalette
.
Accent
;
_scoreText
.
color
=
SSColorPalette
.
Accent
;
_scoreText
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
_scoreText
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
_scoreText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
MidlineLeft
;
_scoreText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
MidlineLeft
;
// Score label
var
scoreLbl
=
MkTxt
(
topBarObj
.
transform
,
"ScoreLbl"
,
"النقاط"
,
var
scoreLbl
=
MkTxt
(
topBarObj
.
transform
,
"ScoreLbl"
,
"النقاط"
,
14
,
new
Vector2
(
0
,
0.5f
),
new
Vector2
(
36
,
-
20
),
new
Vector2
(
100
,
22
));
14
,
new
Vector2
(
0
,
0.5f
),
new
Vector2
(
36
,
-
20
),
new
Vector2
(
100
,
22
));
scoreLbl
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.5f
);
scoreLbl
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.5f
);
scoreLbl
.
alignment
=
TMPro
.
TextAlignmentOptions
.
MidlineLeft
;
scoreLbl
.
alignment
=
TMPro
.
TextAlignmentOptions
.
MidlineLeft
;
// Streak — center
_streakText
=
MkTxt
(
topBarObj
.
transform
,
"Streak"
,
""
,
_streakText
=
MkTxt
(
topBarObj
.
transform
,
"Streak"
,
""
,
26
,
new
Vector2
(
0.5f
,
0.5f
),
new
Vector2
(
0
,
0
),
new
Vector2
(
200
,
44
));
26
,
new
Vector2
(
0.5f
,
0.5f
),
new
Vector2
(
0
,
0
),
new
Vector2
(
200
,
44
));
_streakText
.
color
=
SSColorPalette
.
Warning
;
_streakText
.
color
=
SSColorPalette
.
Warning
;
_streakText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_streakText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
// ── Progress bar ─────────────────────────────────────────
var
progBg
=
new
GameObject
(
"ProgressBg"
);
var
progBg
=
new
GameObject
(
"ProgressBg"
);
progBg
.
transform
.
SetParent
(
go
.
transform
,
false
);
progBg
.
transform
.
SetParent
(
go
.
transform
,
false
);
var
pr
=
progBg
.
AddComponent
<
RectTransform
>();
var
pr
=
progBg
.
AddComponent
<
RectTransform
>();
...
@@ -111,13 +107,13 @@ namespace com.al_arcade.tf
...
@@ -111,13 +107,13 @@ namespace com.al_arcade.tf
_progressFill
=
fill
.
AddComponent
<
Image
>();
_progressFill
=
fill
.
AddComponent
<
Image
>();
_progressFill
.
color
=
SSColorPalette
.
Accent
;
_progressFill
.
color
=
SSColorPalette
.
Accent
;
// Progress label
_progressLabel
=
MkTxt
(
go
.
transform
,
"ProgLbl"
,
"0 / 5"
,
_progressLabel
=
MkTxt
(
go
.
transform
,
"ProgLbl"
,
"0 / 5"
,
16
,
new
Vector2
(
0.5f
,
1
),
new
Vector2
(
0
,
-
98
),
new
Vector2
(
200
,
22
));
16
,
new
Vector2
(
0.5f
,
1
),
new
Vector2
(
0
,
-
98
),
new
Vector2
(
200
,
22
));
_progressLabel
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_progressLabel
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_progressLabel
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.55f
);
_progressLabel
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.55f
);
// ── Bottom hint ──────────────────────────────────────────
var
hintObj
=
new
GameObject
(
"HintBg"
);
var
hintObj
=
new
GameObject
(
"HintBg"
);
hintObj
.
transform
.
SetParent
(
go
.
transform
,
false
);
hintObj
.
transform
.
SetParent
(
go
.
transform
,
false
);
var
hbr
=
hintObj
.
AddComponent
<
RectTransform
>();
var
hbr
=
hintObj
.
AddComponent
<
RectTransform
>();
...
@@ -136,7 +132,6 @@ namespace com.al_arcade.tf
...
@@ -136,7 +132,6 @@ namespace com.al_arcade.tf
hint
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.5f
);
hint
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.5f
);
}
}
// ── Loading ──────────────────────────────────────────────────
private
void
BuildLoadingPanel
(
Transform
parent
)
private
void
BuildLoadingPanel
(
Transform
parent
)
{
{
...
@@ -150,14 +145,13 @@ namespace com.al_arcade.tf
...
@@ -150,14 +145,13 @@ namespace com.al_arcade.tf
_loadingText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_loadingText
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_loadingText
.
color
=
Color
.
white
;
_loadingText
.
color
=
Color
.
white
;
// Spinner dots
var
dots
=
MkTxt
(
go
.
transform
,
"Dots"
,
"● ● ●"
,
var
dots
=
MkTxt
(
go
.
transform
,
"Dots"
,
"● ● ●"
,
18
,
new
Vector2
(
0.5f
,
0.5f
),
new
Vector2
(
0
,
-
36
),
new
Vector2
(
200
,
30
));
18
,
new
Vector2
(
0.5f
,
0.5f
),
new
Vector2
(
0
,
-
36
),
new
Vector2
(
200
,
30
));
dots
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
dots
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
dots
.
color
=
SSColorPalette
.
Accent
;
dots
.
color
=
SSColorPalette
.
Accent
;
}
}
// ── Error ────────────────────────────────────────────────────
private
void
BuildErrorPanel
(
Transform
parent
)
private
void
BuildErrorPanel
(
Transform
parent
)
{
{
...
@@ -173,18 +167,17 @@ namespace com.al_arcade.tf
...
@@ -173,18 +167,17 @@ namespace com.al_arcade.tf
_errorText
.
enableWordWrapping
=
true
;
_errorText
.
enableWordWrapping
=
true
;
}
}
// ── Results ──────────────────────────────────────────────────
private
void
BuildResultsPanel
(
Transform
parent
)
private
void
BuildResultsPanel
(
Transform
parent
)
{
{
var
go
=
MkPanel
(
parent
,
"ResultsUI"
);
var
go
=
MkPanel
(
parent
,
"ResultsUI"
);
_resultsUI
=
go
.
AddComponent
<
CanvasGroup
>();
_resultsUI
=
go
.
AddComponent
<
CanvasGroup
>();
// Semi-transparent background
var
bg
=
go
.
AddComponent
<
Image
>();
var
bg
=
go
.
AddComponent
<
Image
>();
bg
.
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
PrimaryDark
,
0.94f
);
bg
.
color
=
SSColorPalette
.
WithAlpha
(
SSColorPalette
.
PrimaryDark
,
0.94f
);
// Card panel (centered box)
var
card
=
new
GameObject
(
"Card"
);
var
card
=
new
GameObject
(
"Card"
);
card
.
transform
.
SetParent
(
go
.
transform
,
false
);
card
.
transform
.
SetParent
(
go
.
transform
,
false
);
var
cr
=
card
.
AddComponent
<
RectTransform
>();
var
cr
=
card
.
AddComponent
<
RectTransform
>();
...
@@ -194,33 +187,33 @@ namespace com.al_arcade.tf
...
@@ -194,33 +187,33 @@ namespace com.al_arcade.tf
var
cardImg
=
card
.
AddComponent
<
Image
>();
var
cardImg
=
card
.
AddComponent
<
Image
>();
cardImg
.
color
=
SSColorPalette
.
WithAlpha
(
new
Color32
(
30
,
30
,
55
,
255
),
0.95f
);
cardImg
.
color
=
SSColorPalette
.
WithAlpha
(
new
Color32
(
30
,
30
,
55
,
255
),
0.95f
);
// Title
_resultTitle
=
MkTxt
(
card
.
transform
,
"Title"
,
"تم التصنيع! 🎉"
,
_resultTitle
=
MkTxt
(
card
.
transform
,
"Title"
,
"تم التصنيع! 🎉"
,
42
,
new
Vector2
(
0.5f
,
1
),
new
Vector2
(
0
,
-
50
),
new
Vector2
(
500
,
55
));
42
,
new
Vector2
(
0.5f
,
1
),
new
Vector2
(
0
,
-
50
),
new
Vector2
(
500
,
55
));
_resultTitle
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_resultTitle
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_resultTitle
.
color
=
SSColorPalette
.
Accent
;
_resultTitle
.
color
=
SSColorPalette
.
Accent
;
_resultTitle
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
_resultTitle
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
// Score
_resultScore
=
MkTxt
(
card
.
transform
,
"Score"
,
"0"
,
_resultScore
=
MkTxt
(
card
.
transform
,
"Score"
,
"0"
,
56
,
new
Vector2
(
0.5f
,
1
),
new
Vector2
(
0
,
-
130
),
new
Vector2
(
300
,
70
));
56
,
new
Vector2
(
0.5f
,
1
),
new
Vector2
(
0
,
-
130
),
new
Vector2
(
300
,
70
));
_resultScore
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_resultScore
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_resultScore
.
color
=
Color
.
white
;
_resultScore
.
color
=
Color
.
white
;
_resultScore
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
_resultScore
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
// Score label
MkTxt
(
card
.
transform
,
"ScoreLbl"
,
"النقاط"
,
MkTxt
(
card
.
transform
,
"ScoreLbl"
,
"النقاط"
,
16
,
new
Vector2
(
0.5f
,
1
),
new
Vector2
(
0
,
-
185
),
new
Vector2
(
100
,
25
))
16
,
new
Vector2
(
0.5f
,
1
),
new
Vector2
(
0
,
-
185
),
new
Vector2
(
100
,
25
))
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.4f
);
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.4f
);
// Stats
_resultStats
=
MkTxt
(
card
.
transform
,
"Stats"
,
""
,
_resultStats
=
MkTxt
(
card
.
transform
,
"Stats"
,
""
,
20
,
new
Vector2
(
0.5f
,
0.5f
),
new
Vector2
(
0
,
10
),
new
Vector2
(
450
,
60
));
20
,
new
Vector2
(
0.5f
,
0.5f
),
new
Vector2
(
0
,
10
),
new
Vector2
(
450
,
60
));
_resultStats
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_resultStats
.
alignment
=
TMPro
.
TextAlignmentOptions
.
Center
;
_resultStats
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.65f
);
_resultStats
.
color
=
SSColorPalette
.
WithAlpha
(
Color
.
white
,
0.65f
);
_resultStats
.
enableWordWrapping
=
true
;
_resultStats
.
enableWordWrapping
=
true
;
// Restart button
var
btnObj
=
new
GameObject
(
"RestartBtn"
);
var
btnObj
=
new
GameObject
(
"RestartBtn"
);
btnObj
.
transform
.
SetParent
(
card
.
transform
,
false
);
btnObj
.
transform
.
SetParent
(
card
.
transform
,
false
);
var
br
=
btnObj
.
AddComponent
<
RectTransform
>();
var
br
=
btnObj
.
AddComponent
<
RectTransform
>();
...
@@ -251,9 +244,6 @@ namespace com.al_arcade.tf
...
@@ -251,9 +244,6 @@ namespace com.al_arcade.tf
btnTxt
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
btnTxt
.
fontStyle
=
TMPro
.
FontStyles
.
Bold
;
}
}
// ════════════════════════════════════════════════════════════
// PUBLIC METHODS
// ════════════════════════════════════════════════════════════
public
void
ShowGameUI
()
public
void
ShowGameUI
()
{
{
...
@@ -325,7 +315,7 @@ namespace com.al_arcade.tf
...
@@ -325,7 +315,7 @@ namespace com.al_arcade.tf
if
(
_resultStats
!=
null
)
if
(
_resultStats
!=
null
)
_resultStats
.
arabicText
=
$"✓ صحيح:
{
correct
}
| ✗ خطأ:
{
wrong
}
"
;
_resultStats
.
arabicText
=
$"✓ صحيح:
{
correct
}
| ✗ خطأ:
{
wrong
}
"
;
// Animated entrance
var
seq
=
DOTween
.
Sequence
();
var
seq
=
DOTween
.
Sequence
();
seq
.
Append
(
_resultsUI
.
DOFade
(
1
,
0.4f
));
seq
.
Append
(
_resultsUI
.
DOFade
(
1
,
0.4f
));
if
(
_resultTitle
!=
null
)
if
(
_resultTitle
!=
null
)
...
@@ -340,7 +330,7 @@ namespace com.al_arcade.tf
...
@@ -340,7 +330,7 @@ namespace com.al_arcade.tf
seq
.
Append
(
_resultScore
.
transform
seq
.
Append
(
_resultScore
.
transform
.
DOScale
(
1
,
0.35f
).
SetEase
(
Ease
.
OutBack
));
.
DOScale
(
1
,
0.35f
).
SetEase
(
Ease
.
OutBack
));
// Count-up
int
ds
=
0
;
int
ds
=
0
;
DOTween
.
To
(()
=>
ds
,
x
=>
DOTween
.
To
(()
=>
ds
,
x
=>
{
{
...
@@ -358,9 +348,6 @@ namespace com.al_arcade.tf
...
@@ -358,9 +348,6 @@ namespace com.al_arcade.tf
if
(
_resultsUI
!=
null
)
_resultsUI
.
gameObject
.
SetActive
(
false
);
if
(
_resultsUI
!=
null
)
_resultsUI
.
gameObject
.
SetActive
(
false
);
}
}
// ════════════════════════════════════════════════════════════
// HELPERS
// ════════════════════════════════════════════════════════════
private
GameObject
MkPanel
(
Transform
p
,
string
n
)
private
GameObject
MkPanel
(
Transform
p
,
string
n
)
{
{
...
@@ -391,4 +378,4 @@ namespace com.al_arcade.tf
...
@@ -391,4 +378,4 @@ namespace com.al_arcade.tf
return
t
;
return
t
;
}
}
}
}
}
}
\ No newline at end of file
My project/Assets/ScienceStreet/collectcodebase.sh
deleted
100644 → 0
View file @
9833ad6e
This diff is collapsed.
Click to expand it.
My project/Assets/ScienceStreet/c
ollectcodebase.sh
.meta
→
My project/Assets/ScienceStreet/c
s_comments_backup_20260222_185359
.meta
View file @
c336f670
fileFormatVersion: 2
fileFormatVersion: 2
guid: 5fe070f9e16c540beb7eae4411def4a3
guid: 172cb1724b3354adbba5be5427c4ab94
folderAsset: yes
DefaultImporter:
DefaultImporter:
externalObjects: {}
externalObjects: {}
userData:
userData:
...
...
My project/Assets/TextMesh Pro/Resources/Fonts & Materials/LiberationSans SDF - Fallback.asset
View file @
c336f670
This diff is collapsed.
Click to expand it.
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