176 lines
5.6 KiB
C#
176 lines
5.6 KiB
C#
using Core;
|
|
using Minigames.TrashMaze.Core;
|
|
using UnityEngine;
|
|
|
|
namespace Minigames.TrashMaze.Objects
|
|
{
|
|
/// <summary>
|
|
/// Component for objects that need reveal memory (obstacles, booster packs, treasures).
|
|
/// Tracks if object has been revealed and updates material properties accordingly.
|
|
/// </summary>
|
|
[RequireComponent(typeof(SpriteRenderer))]
|
|
public class RevealableObject : MonoBehaviour
|
|
{
|
|
[Header("Textures")]
|
|
[SerializeField] private Sprite normalSprite;
|
|
[SerializeField] private Sprite outlineSprite;
|
|
|
|
[Header("Object Type")]
|
|
[SerializeField] private bool isBoosterPack = false;
|
|
[SerializeField] private bool isExit = false;
|
|
|
|
private SpriteRenderer _spriteRenderer;
|
|
private Material _instanceMaterial;
|
|
private bool _hasBeenRevealed = false;
|
|
private bool _isCollected = false;
|
|
|
|
// Material property IDs (cached for performance)
|
|
private static readonly int IsRevealedID = Shader.PropertyToID("_IsRevealed");
|
|
private static readonly int IsInVisionID = Shader.PropertyToID("_IsInVision");
|
|
|
|
private void Awake()
|
|
{
|
|
_spriteRenderer = GetComponent<SpriteRenderer>();
|
|
|
|
// Create instance material so each object has its own properties
|
|
if (_spriteRenderer.material != null)
|
|
{
|
|
_instanceMaterial = new Material(_spriteRenderer.material);
|
|
_spriteRenderer.material = _instanceMaterial;
|
|
}
|
|
else
|
|
{
|
|
Logging.Error($"[RevealableObject] No material assigned to {gameObject.name}");
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
// Initialize material properties
|
|
if (_instanceMaterial != null)
|
|
{
|
|
_instanceMaterial.SetFloat(IsRevealedID, 0f);
|
|
_instanceMaterial.SetFloat(IsInVisionID, 0f);
|
|
|
|
// Set textures if provided
|
|
if (normalSprite != null)
|
|
{
|
|
_instanceMaterial.SetTexture("_MainTex", normalSprite.texture);
|
|
}
|
|
if (outlineSprite != null)
|
|
{
|
|
_instanceMaterial.SetTexture("_OutlineTex", outlineSprite.texture);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (_isCollected || _instanceMaterial == null) return;
|
|
|
|
// Calculate distance to player
|
|
float distance = Vector2.Distance(transform.position, PulverController.PlayerPosition);
|
|
bool isInRadius = distance < PulverController.VisionRadius;
|
|
|
|
// Update real-time vision flag
|
|
_instanceMaterial.SetFloat(IsInVisionID, isInRadius ? 1f : 0f);
|
|
|
|
// Set revealed flag (once true, stays true)
|
|
if (isInRadius && !_hasBeenRevealed)
|
|
{
|
|
_hasBeenRevealed = true;
|
|
_instanceMaterial.SetFloat(IsRevealedID, 1f);
|
|
|
|
Logging.Debug($"[RevealableObject] {gameObject.name} revealed!");
|
|
}
|
|
}
|
|
|
|
private void OnTriggerEnter2D(Collider2D other)
|
|
{
|
|
// Check if player is interacting
|
|
if (other.CompareTag("Player") && _hasBeenRevealed && !_isCollected)
|
|
{
|
|
HandleInteraction();
|
|
}
|
|
}
|
|
|
|
private void HandleInteraction()
|
|
{
|
|
if (isBoosterPack)
|
|
{
|
|
CollectBoosterPack();
|
|
}
|
|
else if (isExit)
|
|
{
|
|
ActivateExit();
|
|
}
|
|
}
|
|
|
|
private void CollectBoosterPack()
|
|
{
|
|
_isCollected = true;
|
|
|
|
Logging.Debug($"[RevealableObject] Booster pack collected: {gameObject.name}");
|
|
|
|
// Notify controller
|
|
if (TrashMazeController.Instance != null)
|
|
{
|
|
TrashMazeController.Instance.OnBoosterPackCollected();
|
|
}
|
|
|
|
// Destroy object
|
|
Destroy(gameObject);
|
|
}
|
|
|
|
private void ActivateExit()
|
|
{
|
|
Logging.Debug($"[RevealableObject] Exit activated: {gameObject.name}");
|
|
|
|
// Notify controller
|
|
if (TrashMazeController.Instance != null)
|
|
{
|
|
TrashMazeController.Instance.OnExitReached();
|
|
}
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
// Clean up instance material
|
|
if (_instanceMaterial != null)
|
|
{
|
|
Destroy(_instanceMaterial);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if object is currently visible to player
|
|
/// </summary>
|
|
public bool IsVisible()
|
|
{
|
|
float distance = Vector2.Distance(transform.position, PulverController.PlayerPosition);
|
|
return distance < PulverController.VisionRadius;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if object has been revealed at any point
|
|
/// </summary>
|
|
public bool HasBeenRevealed()
|
|
{
|
|
return _hasBeenRevealed;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Force reveal the object (for debugging or special cases)
|
|
/// </summary>
|
|
public void ForceReveal()
|
|
{
|
|
_hasBeenRevealed = true;
|
|
if (_instanceMaterial != null)
|
|
{
|
|
_instanceMaterial.SetFloat(IsRevealedID, 1f);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|