Files
badeend-go/Assets/CatchMinigameManager.cs

236 lines
6.8 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Serialization;
using Random = UnityEngine.Random;
public class CatchMinigameManager : MonoBehaviour
{
private int _score;
public int Score
{
get => _score;
set
{
_score = value;
scoreText.text = "Score: " + _score + " / " + minimalScore;
}
}
private int _netAttempts;
public int NetAttempts
{
get => _netAttempts;
set
{
_netAttempts = value;
netAttemptText.text = "Netten over: " + (maxNetAttempts - value) + " / " + maxNetAttempts;
}
}
public float minSpawnForce = 100;
public float maxSpawnForce = 400;
public Transform leftSpawnPoint;
public Transform rightSpawnPoint;
public Collider duckCaughtCollider;
public TMP_Text scoreText;
public TMP_Text netAttemptText;
[FormerlySerializedAs("MInigameInstruction")] public MinigameInstruction minigameInstruction;
public float netCooldown = 0.5f;
public float netVelocity = 10f;
public Vector3 netDisplacement = Vector3.up * 4;
public int maxNetAttempts = 5;
public int minimalScore = 20;
public GameObject net;
public ParticleSystem duckCollectEffect;
// When ducks leave the river bounds, they're disabled
public Bounds riverBounds;
public float avgSpawnsPerSecond = 5;
public Transform duckParent;
public Transform duckCollectEffectParent;
public FloatingDuckController floatingDuckPrefab;
public event EventHandler<MiniGameResult> MinigameFinished;
private List<FloatingDuckController> activeDucks = new List<FloatingDuckController>();
private Queue<FloatingDuckController> floatingDuckPool = new Queue<FloatingDuckController>();
private Queue<ParticleSystem> duckCollectEffectPool = new Queue<ParticleSystem>();
private bool _netMoving = false;
private static CatchMinigameManager _instance;
public static CatchMinigameManager Instance
{
get { return _instance; }
private set { _instance = value; }
}
public CatchMinigameManager()
{
Instance = this;
}
public void ResetMinigame()
{
Score = 0;
NetAttempts = 0;
for (var i = 0; i < activeDucks.Count; i++)
{
floatingDuckPool.Enqueue(activeDucks[i]);
activeDucks[i].gameObject.SetActive(false);
}
activeDucks.Clear();
minigameInstruction.Show();
}
void Update()
{
var spawnChance = Time.deltaTime * avgSpawnsPerSecond;
if (Random.value <= spawnChance)
{
var left = leftSpawnPoint.position;
var right = rightSpawnPoint.position;
var diff = left - right;
var pos = right + (diff * Random.value);
FloatingDuckController duck;
if (floatingDuckPool.Count > 0)
{
duck = floatingDuckPool.Dequeue();
var duckTransform = duck.transform;
duckTransform.position = pos;
duckTransform.rotation = Quaternion.identity;
duck.initialForce = Vector3.left * ((maxSpawnForce - minSpawnForce) * Random.value);
duck.gameObject.SetActive(true);
}
else
{
duck = Instantiate(floatingDuckPrefab, pos, Quaternion.identity, duckParent);
duck.initialForce = Vector3.left * ((maxSpawnForce - minSpawnForce) * Random.value);
duck.duckCaughtCollider = duckCaughtCollider;
duck.DuckCaught += (obj, args) =>
{
Score++;
DisableDuck(duck);
if (duckCollectEffect != null)
{
ParticleSystem effect;
if (duckCollectEffectPool.Count > 0)
{
effect = duckCollectEffectPool.Dequeue();
effect.gameObject.SetActive(true);
effect.transform.position = duck.transform.position;
}
else
{
effect = Instantiate(duckCollectEffect, duck.transform.position, duckCollectEffect.transform.rotation, duckCollectEffectParent);
}
effect.Play();
StartCoroutine(PoolEffectWhenFinished(effect));
}
};
}
activeDucks.Add(duck);
}
for (var i = 0; i < activeDucks.Count; i++)
{
var duck = activeDucks[i];
if (!riverBounds.Contains(duck.transform.position))
{
DisableDuck(i);
i--;
}
}
if (Input.GetMouseButtonDown(0) && !_netMoving)
{
// Activate the net
NetAttempts++;
StartCoroutine(MoveNet());
}
if (!_netMoving && NetAttempts >= maxNetAttempts)
{
// Minigame finished
if (MinigameFinished != null)
{
MinigameFinished.Invoke(this, Score >= minimalScore ? MiniGameResult.Success : MiniGameResult.Failed);
}
}
}
private IEnumerator PoolEffectWhenFinished(ParticleSystem effect)
{
while (effect.isPlaying)
{
yield return null;
}
effect.gameObject.SetActive(false);
duckCollectEffectPool.Enqueue(effect);
}
private void DisableDuck(FloatingDuckController duck)
{
DisableDuck(activeDucks.IndexOf(duck));
}
private void DisableDuck(int i)
{
var duck = activeDucks[i];
activeDucks.RemoveAt(i);
duck.gameObject.SetActive(false);
floatingDuckPool.Enqueue(duck);
}
private IEnumerator MoveNet()
{
_netMoving = true;
var totalTime = netDisplacement.magnitude / netVelocity;
var time = 0f;
var originalNetPosition = net.transform.position;
while (time < totalTime)
{
time += Time.deltaTime;
net.transform.position = originalNetPosition + (netDisplacement * (time / totalTime));
yield return null;
}
time = 0f;
while (time < netCooldown)
{
time += Time.deltaTime;
net.transform.position = originalNetPosition + netDisplacement - (netDisplacement * (time / netCooldown));
yield return null;
}
net.transform.position = originalNetPosition;
_netMoving = false;
}
}
public enum MiniGameResult
{
Success, Failed
}