121 lines
3.9 KiB
C#
121 lines
3.9 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
public class BallSpawner : MonoBehaviour
|
|
{
|
|
public GameObject basicBallPrefab;
|
|
|
|
public GameObject nuclearBallPrefab;
|
|
|
|
public GameObject glassBallPrefab;
|
|
|
|
public GameObject eyeBallPrefab;
|
|
|
|
public GameObject oozeBallPrefab;
|
|
|
|
public GameObject fruitBallPrefab;
|
|
|
|
public GameObject gameBoard;
|
|
|
|
private static WaitForSeconds _waitForSeconds0_5 = new WaitForSeconds(0.5f);
|
|
|
|
private Queue<System.Action> ballQueue = new Queue<System.Action>();
|
|
|
|
private Queue<GameObject> balls = new Queue<GameObject>();
|
|
|
|
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
|
void Start()
|
|
{
|
|
int currentLevel = PlayerPrefs.GetInt("CurrentLevel");
|
|
|
|
ballQueue.Enqueue(() => SpawnBall(basicBallPrefab));
|
|
ballQueue.Enqueue(() => SpawnBall(basicBallPrefab));
|
|
ballQueue.Enqueue(() => SpawnBall(basicBallPrefab));
|
|
ballQueue.Enqueue(() => SpawnBall(fruitBallPrefab));
|
|
ballQueue.Enqueue(() => SpawnBall(fruitBallPrefab));
|
|
ballQueue.Enqueue(() => SpawnBall(oozeBallPrefab));
|
|
|
|
StartCoroutine(SpawnBalls());
|
|
}
|
|
|
|
private void SpawnBall(GameObject ballPrefab)
|
|
{
|
|
if (ballPrefab == null || gameBoard == null)
|
|
{
|
|
Debug.LogWarning("BallSpawner: Missing ballPrefab or gameBoard reference.");
|
|
return;
|
|
}
|
|
|
|
Vector3 spawnPosition = GetRandomPositionInsideGameBoard();
|
|
var newBall = Instantiate(ballPrefab, spawnPosition, Quaternion.identity);
|
|
|
|
balls.Enqueue(newBall);
|
|
}
|
|
|
|
private Vector3 GetRandomPositionInsideGameBoard()
|
|
{
|
|
Bounds bounds;
|
|
|
|
Collider2D collider2D = gameBoard.GetComponent<Collider2D>();
|
|
if (collider2D != null)
|
|
{
|
|
bounds = collider2D.bounds;
|
|
}
|
|
else
|
|
{
|
|
Renderer boardRenderer = gameBoard.GetComponent<Renderer>();
|
|
if (boardRenderer == null)
|
|
{
|
|
Debug.LogWarning("BallSpawner: gameBoard needs a Collider2D or Renderer to read bounds.");
|
|
return gameBoard.transform.position;
|
|
}
|
|
|
|
bounds = boardRenderer.bounds;
|
|
}
|
|
|
|
const float edgeInset = 0.05f;
|
|
float randomX = Random.Range(bounds.min.x + edgeInset, bounds.max.x - edgeInset);
|
|
float randomY = Random.Range(bounds.min.y + edgeInset, bounds.max.y - edgeInset);
|
|
|
|
return new Vector3(randomX, randomY, gameBoard.transform.position.z);
|
|
}
|
|
|
|
private IEnumerator SpawnBalls()
|
|
{
|
|
while (ballQueue.Count > 0)
|
|
{
|
|
System.Action spawnAction = ballQueue.Dequeue();
|
|
spawnAction.Invoke();
|
|
yield return _waitForSeconds0_5;
|
|
}
|
|
|
|
// Disable collision between existing balls of certain types.
|
|
// Only basic balls and fruit balls will collide with each other, while ooze,
|
|
// nuclear, glass, and eye balls will not collide with any other balls.
|
|
// As an exception, glass balls will collide with other glass balls.
|
|
foreach (var ball in balls)
|
|
{
|
|
foreach (var otherBall in balls)
|
|
{
|
|
if (ball == otherBall) continue;
|
|
|
|
bool ballIsBasicOrFruit = ball.CompareTag("BasicBall") || ball.CompareTag("FruitBall");
|
|
bool otherIsBasicOrFruit = otherBall.CompareTag("BasicBall") || otherBall.CompareTag("FruitBall");
|
|
bool bothAreGlass = ball.CompareTag("GlassBall") && otherBall.CompareTag("GlassBall");
|
|
|
|
bool shouldCollide = (ballIsBasicOrFruit && otherIsBasicOrFruit) || bothAreGlass;
|
|
|
|
if (!shouldCollide)
|
|
{
|
|
Physics2D.IgnoreCollision(
|
|
ball.GetComponent<Collider2D>(),
|
|
otherBall.GetComponent<Collider2D>(),
|
|
true
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|