Commit 860e02c1 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Update Fixeed Some Performance Shit

parent 7e7f8246
......@@ -55,6 +55,7 @@ namespace com.al_arcade.cs
private bool _isTicking;
private int _deltaChangeInSize;
private bool _showHint = true;
private Camera _cam;
CinemachineTargetGroup _targetGroup;
CinemachineGroupFraming _groupFraming;
......@@ -66,6 +67,7 @@ namespace com.al_arcade.cs
Instance = this;
base.Awake();
_cam = Camera.main;
_targetGroup = FindFirstObjectByType<CinemachineTargetGroup>();
_groupFraming = FindFirstObjectByType<CinemachineGroupFraming>();
}
......@@ -383,10 +385,10 @@ namespace com.al_arcade.cs
bot?.PlaySad();
if (Camera.main != null)
if (_cam != null)
{
DOTween.Kill(Camera.main.transform, "csShake");
Camera.main.transform.DOShakePosition(0.3f, 0.15f, 10).SetId("csShake");
DOTween.Kill(_cam.transform, "csShake");
_cam.transform.DOShakePosition(0.3f, 0.15f, 10).SetId("csShake");
}
uiManager?.TickPoints(_deltaChangeInSize);
......
......@@ -18,6 +18,8 @@ public class CsSentence : MonoBehaviour
private Camera _mainCamera;
private List<UniText> _wordTexts = new List<UniText>();
private List<RectTransform> _wordRects = new List<RectTransform>();
private List<Image> _wordImages = new List<Image>();
private float roundedCornerRadius = 16f;
private Vector2 eachWordPadding = new Vector2(8f, 4f);
......@@ -89,6 +91,8 @@ public class CsSentence : MonoBehaviour
var _uniText = Instantiate(CsPrefabBuilder.Instance.arabicTextPrefab, canvasObj.transform).GetComponent<UniText>();
_uniText.Text = text;
_wordTexts.Add(_uniText);
_wordRects.Add(rt);
_wordImages.Add(_backgroundImage);
return canvasObj;
}
......@@ -97,15 +101,15 @@ public class CsSentence : MonoBehaviour
{
float worldScale = 0.02f;
// 1. Calculate total height of the multi-line block
float totalHeight = 0f;
foreach (var line in _lines)
{
float maxLineHeight = 0f;
foreach (var t in line)
{
var rt = t.transform.parent.GetComponent<RectTransform>();
t.transform.parent.GetComponent<Image>().enabled = true;
int idx = _wordTexts.IndexOf(t);
var rt = _wordRects[idx];
_wordImages[idx].enabled = true;
float paddedHeight = (rt.rect.height + eachWordPadding.y) * worldScale;
if (paddedHeight > maxLineHeight) maxLineHeight = paddedHeight;
......@@ -114,56 +118,45 @@ public class CsSentence : MonoBehaviour
}
totalHeight += (_lines.Count - 1) * gap;
// 2. Start Y at top
float currentY = (totalHeight / 2f) + offsetY;
yield return null;
int wordIndex = 0;
// 3. Layout each line
for (int l = 0; l < _lines.Count; l++)
{
var line = _lines[l];
float maxLineHeight = 0f;
// Calculate width of this specific line to center it
float lineWidthWorld = 0f;
foreach (var t in line)
{
var rt = t.transform.parent.GetComponent<RectTransform>();
lineWidthWorld += (rt.rect.width + eachWordPadding.x) * worldScale;
int idx = _wordTexts.IndexOf(t);
lineWidthWorld += (_wordRects[idx].rect.width + eachWordPadding.x) * worldScale;
}
lineWidthWorld += (line.Count - 1) * gap;
// Start X at the right edge of the line for Arabic RTL flow
float currentX = lineWidthWorld / 2f;
for (int w = 0; w < line.Count; w++)
{
var t = line[w];
RectTransform rect = t.transform.parent.GetComponent<RectTransform>();
RectTransform rect = _wordRects[wordIndex];
Image image = _wordImages[wordIndex];
// Apply size
rect.sizeDelta += eachWordPadding;
float elementHeight = rect.rect.height * worldScale;
float elementWidth = rect.rect.width * worldScale;
if (elementHeight > maxLineHeight) maxLineHeight = elementHeight;
// Center point for this specific word
float targetY = currentY - (elementHeight / 2f);
float targetX = currentX - (elementWidth / 2f);
Vector3 targetPos = new Vector3(targetX, targetY, 0f);
// Move X cursor leftward for the next word
currentX -= (elementWidth + gap);
// --- Setup & Animation ---
if (!rect.gameObject.TryGetComponent<CsWordButton>(out var csWord))
{
csWord = rect.gameObject.AddComponent<CsWordButton>();
}
csWord.Setup(_question.words[wordIndex].word_text, _question.words[wordIndex].is_distractor, wordIndex, elementWidth, 1f);
rect.DOLocalMove(targetPos, 0.3f).SetEase(Ease.OutCubic).OnComplete(() =>
......@@ -171,7 +164,6 @@ public class CsSentence : MonoBehaviour
csWord.StartIdleAnimation();
});
var image = rect.GetComponent<Image>();
if (image != null)
{
image.pixelsPerUnitMultiplier = 5f;
......@@ -181,7 +173,6 @@ public class CsSentence : MonoBehaviour
wordIndex++;
}
// Move Y cursor down for the next line
currentY -= (maxLineHeight + gap);
}
......@@ -191,11 +182,9 @@ public class CsSentence : MonoBehaviour
private IEnumerator AnimateTextIn()
{
yield return null;
for (int i = 0; i < _wordTexts.Count; i++)
for (int i = 0; i < _wordRects.Count; i++)
{
RectTransform rect = _wordTexts[i].transform.parent.GetComponent<RectTransform>();
// Just pop the scale. Do NOT force X to 0, otherwise it breaks the line layout!
rect.localScale = Vector3.one * 0.02f;
_wordRects[i].localScale = Vector3.one * 0.02f;
}
yield return new WaitForSeconds(0.3f);
......@@ -206,19 +195,18 @@ public class CsSentence : MonoBehaviour
Canvas.willRenderCanvases -= SentenceCallbackAfterCanvasRender;
float worldScale = 0.02f;
float connectedGapPx = 2f; // Slight visual gap between words in the "sentence" phase
float connectedGapPx = 2f;
// --- LINE WRAPPING ALGORITHM ---
_lines.Clear();
List<UniText> currentLine = new List<UniText>();
float currentLinePxWidth = 0f;
float maxLinePxWidth = 0f;
// 1. Group words into lines
foreach (var uniText in _wordTexts)
for (int i = 0; i < _wordTexts.Count; i++)
{
var uniText = _wordTexts[i];
var rt = _wordRects[i];
Vector2 padding = new Vector2(8f, 4f);
var rt = uniText.transform.parent.GetComponent<RectTransform>();
rt.sizeDelta = new Vector2(uniText.preferredWidth + padding.x, uniText.preferredHeight + padding.y);
float wordPx = rt.sizeDelta.x;
......@@ -235,7 +223,6 @@ public class CsSentence : MonoBehaviour
currentLine.Add(uniText);
currentLinePxWidth += wordPx + connectedGapPx;
// Reset Anchors
var uniTextRect = uniText.GetComponent<RectTransform>();
uniTextRect.anchorMin = new Vector2(0, 0);
uniTextRect.anchorMax = new Vector2(1, 1);
......@@ -249,11 +236,15 @@ public class CsSentence : MonoBehaviour
if (currentLinePxWidth > maxLinePxWidth) maxLinePxWidth = currentLinePxWidth;
}
// 2. Position lines (Sentence compact state)
float totalHeightWorld = 0f;
foreach (var line in _lines)
{
float maxH = line.Max(w => w.transform.parent.GetComponent<RectTransform>().rect.height);
float maxH = 0f;
foreach (var w in line)
{
float h = _wordRects[_wordTexts.IndexOf(w)].rect.height;
if (h > maxH) maxH = h;
}
totalHeightWorld += maxH * worldScale;
}
float connectedGapWorld = connectedGapPx * worldScale;
......@@ -263,28 +254,36 @@ public class CsSentence : MonoBehaviour
foreach (var line in _lines)
{
float lineH = line.Max(w => w.transform.parent.GetComponent<RectTransform>().rect.height) * worldScale;
float targetY = currentY - (lineH * 0.5f);
// Total physical width of this specific line
float lineTotalWidthPx = line.Sum(w => w.transform.parent.GetComponent<RectTransform>().rect.width) + (line.Count - 1) * connectedGapPx;
float lineH = 0f;
float lineTotalWidthPx = 0f;
foreach (var w in line)
{
int idx = _wordTexts.IndexOf(w);
var rt = _wordRects[idx];
float h = rt.rect.height;
if (h > lineH) lineH = h;
lineTotalWidthPx += rt.rect.width;
}
lineH *= worldScale;
lineTotalWidthPx += (line.Count - 1) * connectedGapPx;
float lineTotalWidthWorld = lineTotalWidthPx * worldScale;
// Arabic Flow (RTL): Start layout cursor on the Right side
float targetY = currentY - (lineH * 0.5f);
float currentX = lineTotalWidthWorld * 0.5f;
foreach (var uniText in line)
{
var rt = uniText.transform.parent.GetComponent<RectTransform>();
int idx = _wordTexts.IndexOf(uniText);
var rt = _wordRects[idx];
var img = _wordImages[idx];
float wordWidthWorld = rt.rect.width * worldScale;
float targetX = currentX - (wordWidthWorld * 0.5f);
rt.localPosition = new Vector3(targetX, targetY - 0.08f, 0f);
rt.DOLocalMoveY(targetY, 0.3f).SetEase(Ease.OutCubic);
rt.GetComponent<Image>().DOFade(1f, 0.3f).SetEase(Ease.OutCubic).From(0f);
img.DOFade(1f, 0.3f).SetEase(Ease.OutCubic).From(0f);
// Move cursor left
currentX -= (wordWidthWorld + connectedGapWorld);
}
currentY -= (lineH + connectedGapWorld);
......@@ -328,9 +327,8 @@ public class CsSentence : MonoBehaviour
StartCoroutine(AnimateTextIn());
// 4. Update Camera Group (Target boundary objects instead of widest word)
var offsetFromCenter = Vector3.right * (maxLinePxWidth * worldScale * 0.5f);
float cameraTargetHeight = _wordTexts[0].transform.parent.GetComponent<RectTransform>().rect.height * 0.02f;
float cameraTargetHeight = _wordRects[0].rect.height * 0.02f;
var right = new GameObject("RightBoundary");
right.transform.SetParent(transform);
......
......@@ -377,7 +377,7 @@ namespace com.al_arcade.mcq
if (particles != null && player != null)
particles.PlayCorrectBurst(player.transform.position + Vector3.up * 2f);
Camera.main.DOColor(SSColorPalette.CorrectWord, 1).SetEase(Ease.Flash, 2);
_mainCamera.DOColor(SSColorPalette.CorrectWord, 1).SetEase(Ease.Flash, 2);
}
else
{
......@@ -401,7 +401,7 @@ namespace com.al_arcade.mcq
if (particles != null && player != null)
particles.PlayWrongBurst(player.transform.position + Vector3.up * 2f);
Camera.main.DOColor(SSColorPalette.WrongWord, 1).SetEase(Ease.Flash, 2);
_mainCamera.DOColor(SSColorPalette.WrongWord, 1).SetEase(Ease.Flash, 2);
}
if (uiManager != null)
......@@ -563,10 +563,10 @@ namespace com.al_arcade.mcq
}
}
if (Camera.main != null)
if (_mainCamera != null)
{
DOTween.Kill(Camera.main.transform, "camShake");
Camera.main.transform.DOShakePosition(0.4f, 0.3f, 15, 90f, false, true)
DOTween.Kill(_mainCamera.transform, "camShake");
_mainCamera.transform.DOShakePosition(0.4f, 0.3f, 15, 90f, false, true)
.SetEase(Ease.OutQuad).SetId("camShake");
}
}
......
......@@ -34,11 +34,7 @@ namespace ScienceStreet.Shared
}
StartFloating();
}
private void Update()
{
ApplyRotation();
StartRotation();
}
private void ApplyRandomization()
......@@ -81,9 +77,13 @@ namespace ScienceStreet.Shared
}
}
private void ApplyRotation()
private void StartRotation()
{
transform.Rotate(_actualRotationSpeed * Time.deltaTime, Space.Self);
Vector3 endRot = transform.localEulerAngles + _actualRotationSpeed * 360f;
float duration = 360f / Mathf.Max(_actualRotationSpeed.magnitude, 0.01f);
transform.DOLocalRotate(endRot, duration, RotateMode.FastBeyond360)
.SetEase(Ease.Linear)
.SetLoops(-1, LoopType.Incremental);
}
private void OnDestroy()
......
......@@ -95,10 +95,12 @@ new Color32(164, 255, 90, (byte)opacity),
float randomScale = Random.Range(minScale, maxScale);
instance.transform.localScale = Vector3.one * randomScale;
// Apply random color with balanced saturation
Color baseCol = colors[Random.Range(0, colors.Length)];
var renderer = instance.GetComponent<Renderer>();
renderer.material.color = baseCol;
var mpb = new MaterialPropertyBlock();
renderer.GetPropertyBlock(mpb);
mpb.SetColor("_BaseColor", baseCol);
renderer.SetPropertyBlock(mpb);
// if (renderer != null)
// {
......
......@@ -161,22 +161,30 @@ namespace com.al_arcade.shared
public void PlayShrink(float vol = 0.8f) => Play(sfxShrink, vol);
private Dictionary<string, AudioClip> _beepCache = new();
public void PlayProceduralBeep(float frequency = 440f, float duration = 0.1f,
float volume = 0.3f)
{
int sampleRate = AudioSettings.outputSampleRate;
int sampleCount = Mathf.CeilToInt(sampleRate * duration);
var clip = AudioClip.Create("beep", sampleCount, 1, sampleRate, false);
float[] data = new float[sampleCount];
for (int i = 0; i < sampleCount; i++)
string key = $"{frequency}_{duration}";
if (!_beepCache.TryGetValue(key, out var clip))
{
float t = (float)i / sampleRate;
float envelope = 1f - ((float)i / sampleCount);
data[i] = Mathf.Sin(2f * Mathf.PI * frequency * t) * envelope * volume;
int sampleRate = AudioSettings.outputSampleRate;
int sampleCount = Mathf.CeilToInt(sampleRate * duration);
clip = AudioClip.Create(key, sampleCount, 1, sampleRate, false);
float[] data = new float[sampleCount];
for (int i = 0; i < sampleCount; i++)
{
float t = (float)i / sampleRate;
float envelope = 1f - ((float)i / sampleCount);
data[i] = Mathf.Sin(2f * Mathf.PI * frequency * t) * envelope * volume;
}
clip.SetData(data, 0);
_beepCache[key] = clip;
}
clip.SetData(data, 0);
var src = GetSource();
src.pitch = 1f;
src.volume = masterVolume;
......
......@@ -18,6 +18,7 @@ namespace com.al_arcade.shared
public ParticleSystem starBurstPrefab;
private Dictionary<string, ParticleSystem> _cache = new();
private Camera _cam;
private void Awake()
{
......@@ -28,6 +29,7 @@ namespace com.al_arcade.shared
}
Instance = this;
DontDestroyOnLoad(gameObject);
_cam = Camera.main;
}
public static SSParticleManager EnsureInstance()
......@@ -95,9 +97,10 @@ namespace com.al_arcade.shared
public void PlayScreenConfetti()
{
if (Camera.main == null) return;
Vector3 pos = Camera.main.transform.position +
Camera.main.transform.forward * 5f +
if (_cam == null) _cam = Camera.main;
if (_cam == null) return;
Vector3 pos = _cam.transform.position +
_cam.transform.forward * 5f +
Vector3.up * 3f;
PlayConfetti(pos);
}
......
......@@ -30,6 +30,7 @@ namespace com.al_arcade.tf
private TfGameState _state = TfGameState.Idle;
private TfQuestion[] _questions;
private int _progress;
private Camera _cam;
private bool _waitingForAnswer;
private int _pendingAnswer = -1;
......@@ -45,6 +46,7 @@ namespace com.al_arcade.tf
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
Instance = this;
base.Awake();
_cam = Camera.main;
}
// ─── BaseGameManager implementation ──────────────────────────────────
......@@ -227,10 +229,10 @@ namespace com.al_arcade.tf
if (audio != null)
{ if (audio.sfxWrong != null) audio.PlayWrong(); else audio.PlayWrongBeep(); }
if (Camera.main != null)
if (_cam != null)
{
DOTween.Kill(Camera.main.transform, "camShake");
Camera.main.transform.DOShakePosition(0.4f, 0.3f, 15)
DOTween.Kill(_cam.transform, "camShake");
_cam.transform.DOShakePosition(0.4f, 0.3f, 15)
.SetEase(Ease.OutQuad).SetId("camShake");
}
......
......@@ -29,6 +29,7 @@ namespace com.al_arcade.tf
private float stepDistance;
private float _lastIntensity = -1f;
private bool _start = false;
private TfGameManager _gameManager;
public MachineVFXController machineVFXController;
......@@ -91,10 +92,11 @@ namespace com.al_arcade.tf
private void VFXUpdate()
{
if (machineVFXController == null || TfGameManager.Instance == null)
if (_gameManager == null) _gameManager = TfGameManager.Instance;
if (machineVFXController == null || _gameManager == null)
return;
float timeRatio = TfGameManager.Instance.GetCurrentTimeRatio();
float timeRatio = _gameManager.GetCurrentTimeRatio();
float intensity = 1f - Mathf.Clamp01(timeRatio);
if (Mathf.Abs(_lastIntensity - intensity) > 0.01f)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment