This commit is contained in:
2026-04-22 00:29:09 +07:00
parent 8de65bb527
commit 1e2b7a0dd2
12 changed files with 2215 additions and 181 deletions

View File

@@ -6,7 +6,7 @@ namespace Hallucinate.GameSetup.Maze
{
/// <summary>
/// Responsible for the visual representation of the maze.
/// Handles spawning, pooling, and animations.
/// Handles spawning, pooling, and animations with safety checks.
/// </summary>
public class MazeRenderer : MonoBehaviour
{
@@ -32,7 +32,6 @@ namespace Hallucinate.GameSetup.Maze
public void Clear()
{
// IMPORTANT: Stop all running animations to prevent accessing destroyed objects
StopAllCoroutines();
foreach (var cell in _spawnedCells.Values)
@@ -51,7 +50,6 @@ namespace Hallucinate.GameSetup.Maze
{
Vector2Int pos = new Vector2Int(x, z);
// Remove old visual if exists
if (_spawnedCells.TryGetValue(pos, out GameObject oldObj))
{
Destroy(oldObj);
@@ -61,12 +59,15 @@ namespace Hallucinate.GameSetup.Maze
GameObject prefab = visualProfile.GetPrefab(type);
if (prefab == null) return;
Vector3 worldPos = new Vector3(x * visualProfile.scale, 0, z * visualProfile.scale);
// Ensure scale is always positive to avoid BoxCollider issues
float safeScale = Mathf.Max(0.001f, visualProfile.scale);
Vector3 worldPos = new Vector3(x * safeScale, 0, z * safeScale);
GameObject newObj = Instantiate(prefab, worldPos, Quaternion.identity, _container);
newObj.transform.localScale = Vector3.one * visualProfile.scale;
newObj.transform.localScale = Vector3.one * safeScale;
_spawnedCells[pos] = newObj;
if (animate)
if (animate && visualProfile.animationDuration > 0)
{
StartCoroutine(AnimateCell(newObj.transform));
}
@@ -76,20 +77,21 @@ namespace Hallucinate.GameSetup.Maze
{
if (target == null) yield break;
float duration = visualProfile.animationDuration;
float duration = Mathf.Max(0.01f, visualProfile.animationDuration);
float elapsed = 0;
Vector3 finalScale = target.localScale;
target.localScale = Vector3.zero;
target.localScale = Vector3.one * 0.001f; // Use tiny positive instead of zero
while (elapsed < duration)
{
// Extra safety check in case the object is destroyed mid-animation
if (target == null) yield break;
elapsed += Time.deltaTime;
float t = elapsed / duration;
float t = Mathf.Clamp01(elapsed / duration);
float s = Mathf.Sin(t * Mathf.PI * 0.5f);
target.localScale = finalScale * s;
// Ensure s is never negative
target.localScale = finalScale * Mathf.Max(0.001f, s);
yield return null;
}