[TASK] Added main "game manager" to switch between the minigame and the map + added simple UI to show that a sticker was collected
This commit is contained in:
231
Assets/CatchMinigameManager.cs
Normal file
231
Assets/CatchMinigameManager.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
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;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user