You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.4 KiB
C#
107 lines
3.4 KiB
C#
3 weeks ago
|
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;
|
||
|
}
|
||
|
}
|