Documentatie Jason - j5x/PvB2025 GitHub Wiki
Allow the Match-3 grid to be manually positioned in the Unity Inspector using a gridOffset
field, without it being overwritten at runtime.
[SerializeField] private Vector3 gridOffset;
This lets you position the grid wherever you want in the scene from the Unity Inspector.
private void SpawnTile(int x, int y)
{
GameObject tilePrefab;
do
{
tilePrefab = GetRandomTilePrefab();
} while (WouldCreateMatch(x, y, tilePrefab));
Vector3 spawnPosition = new Vector3(x * tileSize, y * tileSize, 0) + gridOffset;
GameObject tile = Instantiate(tilePrefab, spawnPosition, Quaternion.identity, transform);
Tile tileComponent = tile.GetComponent<Tile>();
tileComponent.SetGridPosition(new Vector2Int(x, y));
_grid[x, y] = tile;
}
private IEnumerator MoveTile(Tile tile, Vector3 targetPos)
{
if (tile == null || tile.gameObject == null) yield break;
float duration = 0.2f;
float elapsedTime = 0f;
Vector3 startPos = tile.transform.position;
while (elapsedTime < duration)
{
if (tile == null || tile.gameObject == null) yield break;
tile.transform.position = Vector3.Lerp(startPos, targetPos + gridOffset, elapsedTime / duration);
elapsedTime += Time.deltaTime;
yield return null;
}
if (tile != null && tile.gameObject != null)
{
tile.transform.position = targetPos + gridOffset;
}
}
-
Background Scaling: Uses a
Canvas
withCanvasScaler
set toScale With Screen Size
to support phone resolutions. - Button Scaling: Buttons are inside the Canvas with anchoring and responsive layout (e.g., Vertical Layout Group, Content Size Fitter).
Loads the next scene when pressed: This is the start button
using UnityEngine;
using UnityEngine.SceneManagement;
public class StartButton : MonoBehaviour
{
public void StartGame()
{
SceneManager.LoadScene("LevelSelector"); // Replace with your level name
}
}
This is the credits button
- UI Text/Panel toggled by button:
using UnityEngine;
public class CreditsPopup : MonoBehaviour
{
[SerializeField] private GameObject creditsPanel;
public void ToggleCredits()
{
creditsPanel.SetActive(!creditsPanel.activeSelf);
}
}
- Button assigned to different scenes via a simple script:
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelButton : MonoBehaviour
{
public void LoadLevel(string levelName)
{
SceneManager.LoadScene(levelName);
}
}
- Character is selected via UI and remembered using a persistent GameManager:
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
public GameObject selectedPlayerPrefab;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
- In the scene:
void Start()
{
Instantiate(GameManager.Instance.selectedPlayerPrefab, spawnPosition, Quaternion.identity);
}
- Triggers
OnDeath
event when HP reaches 0.
- Subscribes to
OnDeath
and notifies spawner:
private void HandleDeath()
{
if (spawner != null)
{
spawner.SpawnEnemy();
}
Destroy(gameObject);
}
- Delay before spawn
- Max number of enemies that can spawn
using UnityEngine;
using System.Collections;
public class EnemySpawner : MonoBehaviour
{
[SerializeField] private GameObject enemyPrefab;
[SerializeField] private Transform spawnPoint;
[SerializeField] private float respawnDelay = 2f;
[SerializeField] private int maxSpawns = 5;
private int spawnCount = 0;
public void SpawnEnemy()
{
if (spawnCount >= maxSpawns) return;
StartCoroutine(SpawnEnemyWithDelay(respawnDelay));
}
private IEnumerator SpawnEnemyWithDelay(float delay)
{
yield return new WaitForSeconds(delay);
GameObject newEnemy = Instantiate(enemyPrefab, spawnPoint.position, Quaternion.identity);
Enemy enemyScript = newEnemy.GetComponent<Enemy>();
if (enemyScript != null)
{
enemyScript.spawner = this;
}
spawnCount++;
}
}
- Make sure all prefabs are assigned in the inspector.
- Use
DontDestroyOnLoad
only on necessary singletons like GameManager. - Consider object pooling for performance if many enemies are involved.