Files
AppleHillsProduction/Assets/Scripts/Minigames/DivingForPictures/Monster.cs

128 lines
3.5 KiB
C#

using UnityEngine;
using System;
using System.Collections;
namespace Minigames.DivingForPictures
{
public class Monster : MonoBehaviour
{
[Header("References")]
[SerializeField] private CircleCollider2D detectionCollider;
private bool pictureAlreadyTaken = false;
private Camera mainCamera;
// Events
public event Action<Monster> OnPictureTaken;
public event Action<Monster> OnMonsterSpawned;
public event Action<Monster> OnMonsterDespawned;
// Properties
public float PictureRadius => detectionCollider != null ? detectionCollider.radius : 0f;
private void Awake()
{
if (detectionCollider == null)
detectionCollider = GetComponent<CircleCollider2D>();
mainCamera = Camera.main;
// Start checking if monster is off-screen
StartCoroutine(CheckIfOffScreen());
}
private void OnEnable()
{
pictureAlreadyTaken = false;
OnMonsterSpawned?.Invoke(this);
}
private IEnumerator CheckIfOffScreen()
{
WaitForSeconds wait = new WaitForSeconds(0.5f);
while (true)
{
yield return wait;
if (!IsVisibleToCamera())
{
DespawnMonster();
yield break;
}
}
}
private bool IsVisibleToCamera()
{
if (mainCamera == null)
mainCamera = Camera.main;
if (mainCamera == null)
return false;
Vector3 viewportPoint = mainCamera.WorldToViewportPoint(transform.position);
float buffer = 0.2f; // Extra buffer outside the screen
return viewportPoint.x > -buffer &&
viewportPoint.x < 1 + buffer &&
viewportPoint.y > -buffer &&
viewportPoint.y < 1 + buffer;
}
private void OnTriggerEnter2D(Collider2D other)
{
// Check if it's the player
if (other.CompareTag("Player") && !pictureAlreadyTaken)
{
TakePicture();
}
}
// Called when a picture is taken of this monster
public void TakePicture()
{
if (pictureAlreadyTaken) return;
pictureAlreadyTaken = true;
OnPictureTaken?.Invoke(this);
DespawnMonster();
}
// Public method to despawn this monster
public void DespawnMonster()
{
if (gameObject.activeSelf)
{
OnMonsterDespawned?.Invoke(this);
gameObject.SetActive(false);
Destroy(gameObject);
}
}
// Visualization for the picture radius in editor
private void OnDrawGizmosSelected()
{
// Get the collider in edit mode
if (detectionCollider == null)
detectionCollider = GetComponent<CircleCollider2D>();
if (detectionCollider != null)
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, detectionCollider.radius / 2);
}
}
#if UNITY_EDITOR
// Update collider radius in editor
private void OnValidate()
{
if (detectionCollider == null)
detectionCollider = GetComponent<CircleCollider2D>();
}
#endif
}
}