Documentatie Jason - j5x/PvB2025 GitHub Wiki

Unity Game Mechanic Documentation

๐Ÿงฉ Grid Offset Documentation for Match-3 Game

๐ŸŽฏ Goal

Allow the Match-3 grid to be manually positioned in the Unity Inspector using a gridOffset field, without it being overwritten at runtime.


โœ… Final Setup

Grid Offset Variable

[SerializeField] private Vector3 gridOffset;

This lets you position the grid wherever you want in the scene from the Unity Inspector.


๐Ÿ“ฆ Updated Functions

SpawnTile

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;
}

MoveTile

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;
    }
}



๐Ÿ“ฑ UI Scaling (Main Menu)

  • Background Scaling: Uses a Canvas with CanvasScaler set to Scale 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).

๐ŸŽฎ Main Menu

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);
    }
}

๐Ÿ”ข Level Selector

  • 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 Selector

  • 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);
}

๐Ÿ‘พ Enemy Respawn System

HealthComponent.cs

  • Triggers OnDeath event when HP reaches 0.

Enemy.cs

  • Subscribes to OnDeath and notifies spawner:
private void HandleDeath()
{
    if (spawner != null)
    {
        spawner.SpawnEnemy();
    }
    Destroy(gameObject);
}

๐Ÿง  Enemy Spawner

Features:

  • 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++;
    }
}

๐Ÿงช Notes

  • 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.
โš ๏ธ **GitHub.com Fallback** โš ๏ธ