This commit is contained in:
Ali Sharoz 2025-06-05 00:11:38 +05:00
parent fde0d8f908
commit 33aeb3b742
15 changed files with 7680 additions and 29 deletions

View File

@ -246,3 +246,33 @@ MonoBehaviour:
\u0627\u0644\u0648\u0627\u0636\u062D\u0629 \u064A\u0645\u0643\u0646 \u0623\u0646
\u062A\u0643\u0648\u0646 \u0639\u0644\u0627\u0645\u0629 \u0639\u0644\u0649
\u0645\u062D\u0627\u0648\u0644\u0629 \u062A\u0635\u064A\u062F \u0625\u0644\u0643\u062A\u0631\u0648\u0646\u064A.\r\n"
- key: mission_intro
english: 'Your mission: Analyze incoming emails for phishing threats'
arabic: "\u0645\u0647\u0645\u062A\u0643: \u062A\u062D\u0644\u064A\u0644 \u0631\u0633\u0627\u0626\u0644
\u0627\u0644\u0628\u0631\u064A\u062F \u0627\u0644\u0625\u0644\u0643\u062A\u0631\u0648\u0646\u064A
\u0627\u0644\u0648\u0627\u0631\u062F\u0629 \u0628\u062D\u062B\u064B\u0627 \u0639\u0646
\u0645\u062D\u0627\u0648\u0644\u0627\u062A \u062A\u0635\u064A\u062F"
- key: click_to_open
english: Click to open your inbox
arabic: "\u0627\u0636\u063A\u0637 \u0644\u0641\u062A\u062D \u0628\u0631\u064A\u062F\u0643"
- key: click_and_hold
english: Click and hold to scan the email
arabic: "\u0627\u0646\u0642\u0631 \u0645\u0639 \u0627\u0644\u0627\u0633\u062A\u0645\u0631\u0627\u0631
\u0644\u0645\u0633\u062D \u0627\u0644\u0628\u0631\u064A\u062F \u0627\u0644\u0625\u0644\u0643\u062A\u0631\u0648\u0646\u064A"
- key: review_email_content
english: Review the email content carefully
arabic: "\u0631\u0627\u062C\u0639 \u0645\u062D\u062A\u0648\u0649 \u0627\u0644\u0628\u0631\u064A\u062F
\u0628\u0639\u0646\u0627\u064A\u0629"
- key: correct_choice
english: Correct choice!
arabic: " \u0627\u062E\u062A\u064A\u0627\u0631 \u0635\u062D\u064A\u062D!"
- key: start
english: START
arabic: "\u0627\u0628\u062F\u0623"
- key: phishingawareness
english: PHISHING AWARENESS SIMULATION
arabic: "\u0645\u062D\u0627\u0643\u0627\u0629 \u0627\u0644\u062A\u0648\u0639\u064A\u0629
\u0628\u0627\u0644\u062A\u0635\u064A\u062F \u0627\u0644\u0627\u062D\u062A\u064A\u0627\u0644\u064A"
- key: poweredby
english: Powered by CyberCompanion
arabic: "\u0628\u062F\u0639\u0645 \u0645\u0646 CyberCompanion"

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,7 @@ public class CharacterMovement : MonoBehaviour
{
animator.SetTrigger("StartWalking");
isStarted = true;
InstructionManager.Instance?.ShowScreenInstruction("mission_intro");
}
void Update()
{
@ -163,6 +164,7 @@ public class CharacterMovement : MonoBehaviour
.OnComplete(() =>
{
state = MovementState.Finished;
InstructionManager.Instance?.ShowScreenInstruction("click_to_open");
});
}
}

View File

@ -1,4 +1,7 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class CursorManager : MonoBehaviour
{
@ -10,12 +13,33 @@ public class CursorManager : MonoBehaviour
[Header("Cursor Hotspot")]
public Vector2 hotspot = Vector2.zero;
public GraphicRaycaster raycaster;
public EventSystem eventSystem;
private void Awake()
{
Instance = this;
SetDefaultCursor();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
PointerEventData pointerData = new PointerEventData(eventSystem)
{
position = Input.mousePosition
};
List<RaycastResult> results = new List<RaycastResult>();
raycaster.Raycast(pointerData, results);
foreach (RaycastResult result in results)
{
Debug.Log("Clicked UI: " + result.gameObject.name,result.gameObject);
}
}
}
public void SetDefaultCursor()
{

View File

@ -50,6 +50,16 @@ public class EmailOpenPanel : MonoBehaviour
string summary = $"{action.ToUpper()} clicked on email from '{emailData.senderName}' with subject '{emailData.subject}'";
UserActionLogger.Instance?.Log(summary);
bool isCorrect =
(action == "report" && emailData.isPhishing) ||
(action == "ignore" && !emailData.isPhishing);
if (isCorrect)
{
// ✅ Correct choice → Show instruction
InstructionManager.Instance?.ShowScreenInstruction("correct_choice", 3f);
}
switch (action)
{
case "report":

View File

@ -0,0 +1,106 @@
using TMPro;
using UnityEngine;
using DG.Tweening;
public class InstructionManager : MonoBehaviour
{
public static InstructionManager Instance;
[Header("Screen Instruction (HUD)")]
public GameObject instructionBG; // The background image object
public TextMeshProUGUI instructionText; // The TMP text inside the background
[Header("Speech Bubble UI")]
public GameObject speechBubbleObj; // The bubble GameObject (inside its own canvas)
public TextMeshProUGUI speechText; // The TMP text inside the speech bubble
public Vector3 offset = new Vector3(0, 2f, 0); // Offset from followTarget
private Transform followTarget; // Target the speech bubble follows
private Camera mainCam;
[Header("Optional Settings")]
public float fadeDuration = 0.5f; // Not used unless you want to add tween effects later
void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
mainCam = Camera.main;
if (instructionBG != null)
instructionBG.SetActive(false);
if (speechBubbleObj != null)
speechBubbleObj.SetActive(false);
}
void LateUpdate()
{
// Reposition speech bubble to follow world target
if (speechBubbleObj != null && followTarget != null)
{
Vector3 screenPos = mainCam.WorldToScreenPoint(followTarget.position + offset);
speechBubbleObj.transform.position = screenPos;
}
}
// Show screen HUD instruction with localization key
public void ShowScreenInstruction(string key, float autoHideDelay = -1f)
{
if (LanguageManager.Instance == null || instructionText == null || instructionBG == null)
return;
string localized = LanguageManager.Instance.GetLocalizedText(key);
bool isArabic = LanguageManager.Instance.currentLanguage == "Arabic";
instructionText.text = isArabic
? ArabicFixerHelper.FixPreservingTags(localized)
: localized;
instructionText.font = LanguageManager.Instance.GetCurrentFont();
instructionBG.SetActive(true);
if (autoHideDelay > 0)
Invoke(nameof(HideScreenInstruction), autoHideDelay);
}
public void HideScreenInstruction()
{
if (instructionBG != null)
instructionBG.SetActive(false);
}
// Show speech bubble above a world target (e.g., teacher's head)
public void ShowSpeechBubble(string key, Transform target, float autoHideDelay = -1f)
{
if (LanguageManager.Instance == null || speechText == null || speechBubbleObj == null)
return;
string localized = LanguageManager.Instance.GetLocalizedText(key);
bool isArabic = LanguageManager.Instance.currentLanguage == "Arabic";
speechText.text = isArabic
? ArabicFixerHelper.FixPreservingTags(localized)
: localized;
speechText.font = LanguageManager.Instance.GetCurrentFont();
followTarget = target;
speechBubbleObj.SetActive(true);
if (autoHideDelay > 0)
Invoke(nameof(HideSpeechBubble), autoHideDelay);
}
public void HideSpeechBubble()
{
speechBubbleObj.SetActive(false);
followTarget = null;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 354e60420595cea4e80f051df74d201a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,6 @@
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class SceneOutcomeManager : MonoBehaviour
{
@ -67,7 +68,10 @@ public class SceneOutcomeManager : MonoBehaviour
Debug.Log("Ignored a safe email. No feedback triggered.");
}
}
public void Restarter()
{
SceneManager.LoadScene(0);
}
private IEnumerator MoveCameraToDebrief()
{
DebriefObj.SetActive(true);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 59bbd8cc5c5f37e4c8d25cd9eb892134
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,21 @@
fileFormatVersion: 2
guid: cfb623675ebe37b4abbb6fbcbf32166a
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- Noto Naskh Arabic
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 730 B

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
Build.zip

Binary file not shown.