using System.Collections; using System.Collections.Generic; using UnityEngine; public class BubblesGenerator : MonoBehaviour { public bool drawGizmos = false; public Vector2 NumberOfBubbles; public GameObject BubblePrefab; public float BubbleSize; public Sprite[] BubbleSprites; public Sprite GetRandomBubbleSprite() { return BubbleSprites[Random.Range(0, BubbleSprites.Length)]; } public Dictionary bubbles; public GameObject GetBubble(Vector2 gridPosition) { GameObject output = bubbles[gridPosition]; float minDistance = float.MaxValue; GameObject closestBubble = null; if (output == null) { foreach (KeyValuePair bubble in bubbles) { float distance = Vector2.Distance(gridPosition, bubble.Key); if (distance < minDistance) { minDistance = distance; closestBubble = bubble.Value; } } } if (minDistance < BubbleSize / 4f) { output = closestBubble; } return output; } public void UpdateAllNeighbors() { foreach (KeyValuePair bubble in bubbles) { if(bubble.Value == null){ continue; } Bubble bub = bubble.Value.GetComponent(); HashSet checkedBubbles = new HashSet(); List bubblesToCheck = new List(); List allMatchingBubbles = new List(); bub.neighbors = new List(); bubblesToCheck.Add(bubble.Value); checkedBubbles.Add(bubble.Value); int lowestNeightbourY = 10; while (bubblesToCheck.Count > 0) { GameObject currentBubble = bubblesToCheck[0]; bubblesToCheck.RemoveAt(0); allMatchingBubbles.Add(currentBubble); List neighbors = GetNeighbors(currentBubble); foreach (GameObject neighbor in neighbors) { if (!checkedBubbles.Contains(neighbor)) { bubblesToCheck.Add(neighbor); checkedBubbles.Add(neighbor); } if (neighbor != null && neighbor.GetComponent() != null) { if (neighbor.GetComponent().gridPosition.y < lowestNeightbourY) { lowestNeightbourY = (int)neighbor.GetComponent().gridPosition.y; } bub.neighbors.Add(neighbor); } } } bub.processNeighbors(lowestNeightbourY); } } public List GetNeighbors(GameObject bubble, bool filter = false) { List neighbors = new List(); try { Collider2D[] colliders = Physics2D.OverlapCircleAll(bubble.transform.position, BubbleSize); foreach (Collider2D collider in colliders) { if (collider.gameObject == bubble) { continue; } if (collider.gameObject != bubble) { if (filter) { if (bubble.GetComponent().sprite == collider.gameObject.GetComponent().sprite) { neighbors.Add(collider.gameObject); } } else { neighbors.Add(collider.gameObject); } if (collider.gameObject.GetComponent() != null) { } } } } catch { } return neighbors; } void Start() { GenerateBubbles(); } void GenerateBubbles() { List positions = GetBubblePositions(); bubbles = new Dictionary(); foreach (Vector2 gridPosition in positions) { Vector2 position = GetBubblePosition(gridPosition); AddBubble(gridPosition); } } public GameObject AddBubble(Vector2 gridPosition, Sprite sprite = null) { Sprite _sprite; if (sprite == null) { _sprite = GetRandomBubbleSprite(); } else { _sprite = sprite; } Vector2 position = GetBubblePosition(gridPosition); if (bubbles.ContainsKey(gridPosition)) { // Try to find a free neighboring position Vector2[] possibleNeighbors = new Vector2[] { new Vector2(gridPosition.x + 1, gridPosition.y), new Vector2(gridPosition.x - 1, gridPosition.y), new Vector2(gridPosition.x, gridPosition.y + 1), new Vector2(gridPosition.x, gridPosition.y - 1), new Vector2(gridPosition.x + 1, gridPosition.y + 1), new Vector2(gridPosition.x - 1, gridPosition.y + 1) }; foreach (Vector2 neighborPos in possibleNeighbors) { if (!bubbles.ContainsKey(neighborPos)) { gridPosition = neighborPos; position = GetBubblePosition(gridPosition); break; } } } GameObject bubble = Instantiate(BubblePrefab, position, Quaternion.identity); bubble.GetComponent().sprite = _sprite; bubble.GetComponent().gridPosition = gridPosition; bubble.GetComponent().bubblesGenerator = this; bubbles.Add(gridPosition, bubble); return bubble; } public void RemoveBubble(GameObject _bubble) { foreach (KeyValuePair bubble in bubbles) { if (bubble.Value == _bubble) { bubbles.Remove(bubble.Key); Destroy(_bubble); break; } } } void OnDrawGizmos() { if (!drawGizmos) { return; } Gizmos.color = Color.red; foreach (Vector2 gridPosition in GetBubblePositions()) { Vector2 position = GetBubblePosition(gridPosition); Gizmos.DrawWireSphere(position, BubbleSize / 2); } } List GetBubblePositions() { List positions = new List(); for (int i = 0; i < NumberOfBubbles.x; i++) { for (int j = 0; j < NumberOfBubbles.y; j++) { positions.Add(new Vector2(i, j)); if (i > 0) { positions.Add(new Vector2(-i, j)); } } } return positions; } public Vector2 GetBubblePosition(Vector2 gridPosition) { int i = (int)gridPosition.x; int j = (int)gridPosition.y; float xOffset = (j % 2 == 0) ? 0 : BubbleSize / 2; float yMult = 0.9f; return (Vector2)transform.position + (new Vector2(i + xOffset, -j * yMult) * BubbleSize); } }