128 lines
3.5 KiB
C#
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
|
|
}
|
|
}
|