Unity Eğitim
Dersler
Forum Sınav Merkezi Premium 💎
Oyun Geliştirme

Unity Grid Sistem: Tasarım ve Yerleştirme Rehberi

Paylaşan: Unity Eğitim 31 December 2025 5 dakika okuma 233 görüntülenme

Oyun geliştirme dünyasında, özellikle strateji, simülasyon ve inşa türü oyunlarda düzen ve hassasiyet büyük önem taşır. Bu düzenin temelini oluşturan en kritik mekaniklerden biri de Grid Sistemler veya diğer adıyla Izgara Sistemlerdir. Unity motoruyla geliştirilen oyunlarda, oyuncuların nesneleri belirli bir düzene göre yerleştirmesini, hareket etmesini veya etkileşim kurmasını sağlayan bu sistemler, hem geliştiricilere hem de oyunculara büyük kolaylıklar sunar. Bu kapsamlı rehberde, Unity'de sıfırdan bir grid sistemin nasıl tasarlanacağını, temel bileşenlerini ve objeleri bu sisteme göre yerleştirme mekaniklerini adım adım inceleyeceğiz.

Bir grid sistemi, oyun dünyasını eşit boyutlu hücrelere bölen soyut bir yapıdır. Bu hücreler, oyun içi objelerin konumlandırılması, hareket yollarının belirlenmesi ve etkileşim alanlarının tanımlanması için bir referans noktası görevi görür. Doğru tasarlanmış bir grid sistemi, oyununuzun temel taşlarından biri olabilir.

Neden Grid Sistem Kullanmalıyız?

Grid sistemler, oyun dünyasına mantıksal bir yapı kazandırarak geliştirme sürecini kolaylaştırır ve oyuncu deneyimini zenginleştirir. İşte başlıca avantajları:

  • Düzen ve Estetik: Özellikle inşa ve strateji oyunlarında, oyuncuların binaları veya birimleri hizalı bir şekilde yerleştirmesi, estetik açıdan hoş ve işlevsel bir dünya yaratır. Bu, oyunun görsel kalitesini ve oynanabilirliğini artırır.
  • Kolay Yerleştirme ve Hareket: Grid, objelerin belirli noktalara "snap" etmesini (hizalanmasını) sağlayarak yerleştirme işlemini sezgisel hale getirir. Karakterlerin veya birimlerin grid üzerinde hareket etmesi, yol bulma algoritmaları için daha kolay ve optimize edilebilir bir zemin sunar.
  • Veri Yönetimi: Her bir grid hücresi, kendi içinde bilgi (örneğin, dolu/boş durumu, arazi tipi, maliyet) tutabilir. Bu, oyun durumunu yönetmeyi ve performanslı sorgular yapmayı kolaylaştırır.
  • Çakışma Kontrolü: Objelerin çakışmasını engellemek veya belirli alanların doluluğunu kontrol etmek, grid sistemi sayesinde çok daha basit hale gelir.

Oyun Türlerine Göre Grid Kullanımı

Grid sistemler, farklı oyun türlerinde çeşitli şekillerde karşımıza çıkar:

  • Strateji Oyunları (RTS, Sıra Tabanlı): StarCraft, Civilization gibi oyunlarda birimlerin hareketi ve bina yerleşimi grid tabanlıdır. Her hücre bir birimin veya binanın kapladığı alanı temsil edebilir.
  • İnşa ve Simülasyon Oyunları: Cities: Skylines, The Sims gibi oyunlarda binaların ve objelerin dünya üzerindeki konumları genellikle bir ızgara sistemine göre belirlenir. Bu, oyunculara detaylı ve düzenli şehirler kurma imkanı tanır.
  • Bulmaca Oyunları: Tetris, Sudoku gibi oyunlar doğrudan grid mantığı üzerine kuruludur. Her bir parça veya sayı, belirli bir grid hücresine yerleşir.
  • RPG ve Zindan Gezinme Oyunları: Eski tip zindan oyunlarında karakterler ve düşmanlar grid üzerinde hareket eder, bu da taktiksel savaşlara olanak tanır.

Unity'de Temel Grid Yapısı Oluşturma

Unity'de bir grid sistemi oluşturmak için genellikle bir C# scripti kullanılır. Bu script, oyun dünyasını belirli boyutlardaki hücrelere bölecek ve bu hücrelerin koordinatlarını yönetecek mantığı içerir.

İlk adım, bir GridManager veya benzeri bir sınıf oluşturmaktır. Bu sınıf, gridin boyutlarını (örneğin, genişlik ve yükseklik), her bir hücrenin boyutunu (cellSize) ve başlangıç noktasını tutacaktır. Genellikle bir Vector3 veya Vector2 dizisi veya listesi kullanarak her bir hücrenin dünya koordinatlarını depolayabiliriz.

public class GridManager : MonoBehaviour
{
    public Vector2Int gridSize = new Vector2Int(10, 10); // Grid'in hücre sayısı
    public float cellSize = 1f; // Her bir hücrenin dünya boyutu
    public Vector3 gridOrigin = Vector3.zero; // Grid'in dünya üzerindeki başlangıç noktası

    // Grid hücrelerinin dünya koordinatlarını tutacak bir yapı
    private Vector3[,] gridCells;

    void Awake()
    {
        GenerateGrid();
    }

    void GenerateGrid()
    {
        gridCells = new Vector3[gridSize.x, gridSize.y];
        for (int x = 0; x < gridSize.x; x++)
        {
            for (int y = 0; y < gridSize.y; y++)
            {
                // Her hücrenin merkez noktasını hesapla
                float worldX = gridOrigin.x + x * cellSize + cellSize / 2f;
                float worldY = gridOrigin.y + y * cellSize + cellSize / 2f;
                gridCells[x, y] = new Vector3(worldX, worldY, gridOrigin.z);
            }
        }
    }

    // Dünya koordinatını grid koordinatına dönüştürme
    public Vector2Int WorldToGridPosition(Vector3 worldPosition)
    {
        int x = Mathf.FloorToInt((worldPosition.x - gridOrigin.x) / cellSize);
        int y = Mathf.FloorToInt((worldPosition.y - gridOrigin.y) / cellSize);
        return new Vector2Int(x, y);
    }

    // Grid koordinatını dünya koordinatına dönüştürme (hücre merkezi)
    public Vector3 GridToWorldPosition(Vector2Int gridPosition)
    {
        float worldX = gridOrigin.x + gridPosition.x * cellSize + cellSize / 2f;
        float worldY = gridOrigin.y + gridPosition.y * cellSize + cellSize / 2f;
        return new Vector3(worldX, worldY, gridOrigin.z);
    }

    // Debug için gridi çizme (Editörde görünür)
    void OnDrawGizmos()
    {
        if (gridSize.x <= 0 || gridSize.y <= 0 || cellSize <= 0) return;

        Gizmos.color = Color.grey;
        for (int x = 0; x < gridSize.x; x++)
        {
            for (int y = 0; y < gridSize.y; y++)
            {
                Vector3 cellCenter = GridToWorldPosition(new Vector2Int(x, y));
                Gizmos.DrawWireCube(cellCenter, new Vector3(cellSize, cellSize, 0.1f));
            }
        }
    }
}

Grid Boyutları ve Izgara Hücreleri

Yukarıdaki örnekte gridSize, kaç hücreye sahip olacağımızı (x ve y ekseninde) belirlerken, cellSize her bir hücrenin dünya birimindeki genişliğini ve yüksekliğini tanımlar. gridOrigin ise gridin dünya üzerindeki başlangıç (genellikle sol alt) noktasıdır. WorldToGridPosition ve GridToWorldPosition metotları, dünya koordinatları ile grid koordinatları arasında dönüşüm yapmamızı sağlar; bu, objeleri doğru hücrelere yerleştirmek için hayati öneme sahiptir.

Yerleştirme Mekaniği Tasarımı

Bir grid sistemi oluşturduktan sonra, objeleri bu sisteme göre yerleştirme mekaniğini geliştirmek gerekir. Bu genellikle oyuncunun fare tıklamasıyla veya sürükle-bırak yöntemiyle objeleri seçip grid üzerine konumlandırmasını içerir.

Temel bir yerleştirme mekaniği genellikle şu adımları içerir:

  1. Oyuncunun fare girişini algılama.
  2. Fare konumundan oyun dünyasına bir ışın (Ray) gönderme (Raycasting).
  3. Işının çarptığı noktayı (genellikle bir zemin veya arsa) belirleme.
  4. Bu dünya koordinatını grid koordinatına dönüştürme.
  5. Dönüştürülen grid koordinatına objeyi hizalama (snap etme).

Objeleri Gride Hizalama (Snapping)

Oyuncunun fareyle seçtiği bir objeyi gridin en yakın hücresine hizalamak (snapping), yerleştirme mekaniğinin temelidir. Yukarıdaki GridToWorldPosition metodu tam da bu iş için kullanılabilir. Fare ışınının çarptığı dünya koordinatını önce grid koordinatına çevirir, sonra bu grid koordinatını tekrar dünya koordinatına çevirerek objeyi hücrenin merkezine yerleştiririz.

public class PlacementManager : MonoBehaviour
{
    public GridManager gridManager; // GridManager referansı
    public GameObject objectToPlacePrefab; // Yerleştirilecek obje prefab'ı
    private GameObject currentObjectPreview; // Mevcut önizleme objesi

    void Update()
    {
        HandlePlacementInput();
    }

    void HandlePlacementInput()
    {
        // Fare konumunu al
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        // Belirli bir layer'daki zemine çarptığında
        if (Physics.Raycast(ray, out hit, 100f, LayerMask.GetMask("Ground")))
        {
            Vector3 worldPosition = hit.point;
            Vector2Int gridPosition = gridManager.WorldToGridPosition(worldPosition);
            Vector3 snappedWorldPosition = gridManager.GridToWorldPosition(gridPosition);

            // Önizleme objesini oluştur veya güncelle
            if (currentObjectPreview == null)
            {
                currentObjectPreview = Instantiate(objectToPlacePrefab);
                currentObjectPreview.GetComponent<Collider>().enabled = false; // Çakışma kontrolü için kapat
            }
            currentObjectPreview.transform.position = snappedWorldPosition;

            // Sol tık ile yerleştirme
            if (Input.GetMouseButtonDown(0))
            {
                // Kontrolleri geçtikten sonra objeyi kalıcı olarak yerleştir
                PlaceObject(gridPosition, snappedWorldPosition);
            }
        }
        else
        {
            // Fare grid üzerinde değilse önizlemeyi kaldır
            if (currentObjectPreview != null)
            {
                Destroy(currentObjectPreview);
                currentObjectPreview = null;
            }
        }
    }

    void PlaceObject(Vector2Int gridPosition, Vector3 worldPosition)
    {
        // Burada çakışma kontrolü ve geçerlilik testleri yapılmalı
        if (CanPlaceObject(gridPosition))
        {
            Instantiate(objectToPlacePrefab, worldPosition, Quaternion.identity);
            // GridManager'a bu hücrenin dolu olduğunu bildir
            gridManager.OccupyCell(gridPosition);
            Destroy(currentObjectPreview); // Önizlemeyi yok et
            currentObjectPreview = null;
        }
        else
        {
            Debug.Log("Bu alana obje yerleştirilemez!");
        }
    }

    bool CanPlaceObject(Vector2Int gridPosition)
    {
        // Bu metotta gridManager üzerinden hücrenin dolu olup olmadığı kontrol edilebilir.
        // Veya yerleştirilecek objenin boyutuna göre birden fazla hücrenin uygunluğu kontrol edilebilir.
        return !gridManager.IsCellOccupied(gridPosition);
    }
}

Çakışma Kontrolü ve Geçerlilik

Objelerin doğru şekilde yerleştirilmesi için çakışma kontrolü ve geçerlilik testleri vazgeçilmezdir. Bir hücrenin zaten dolu olup olmadığını veya yerleştirilmek istenen objenin birden fazla hücre kaplaması durumunda bu hücrelerin de boş olup olmadığını kontrol etmek gerekir. Bu genellikle GridManager sınıfında bir bool[,] occupiedCells; dizisi tutarak veya her hücreye özel bir obje referansı atayarak yapılır.

Geçerlilik kontrolü sırasında, önizleme objesinin rengini değiştirerek (örneğin, geçerliyse yeşil, geçersizse kırmızı) oyuncuya anında geri bildirim sağlamak kullanıcı deneyimini artırır. Bu, currentObjectPreview'in materyalini veya rengini dinamik olarak değiştirmekle mümkündür.

Gelişmiş Grid Sistem Özellikleri

Temel bir grid sistemi oluşturduktan sonra, oyununuzun ihtiyaçlarına göre çeşitli gelişmiş özellikler ekleyebilirsiniz:

  • Yol Bulma (Pathfinding): A* gibi algoritmalar, grid sistemini kullanarak karakterlerin en kısa ve en verimli yolu bulmasını sağlar. Her bir hücre bir düğüm (node) olarak kabul edilir ve hücreler arası geçiş maliyetleri tanımlanabilir.
  • Görüş Alanı (Fog of War): Grid hücrelerini kullanarak oyuncunun görüş alanı dışında kalan bölgeleri gizleyebilirsiniz.
  • Çok Katmanlı Gridler: Dikey olarak birden fazla seviyeye sahip oyunlar için (örneğin, binaların farklı katları) çok katmanlı grid sistemleri tasarlanabilir.
  • Performans Optimizasyonu: Büyük gridler için, sadece aktif olan veya kamera görüş alanındaki hücreleri işlemek gibi optimizasyon teknikleri kullanılabilir.
  • Grid Tabanlı Etkileşimler: Objelerin grid üzerindeki konumlarına göre birbirleriyle etkileşim kurmasını sağlamak (örneğin, bitişik binaların bonus vermesi).

Unity'de bir grid sistemi tasarlamak ve yerleştirme mekaniği oluşturmak, oyun geliştirme projeleriniz için sağlam bir temel sunar. Bu rehberde ele alınan temel prensipleri ve kod örneklerini kullanarak kendi özgün grid sistemlerinizi geliştirebilir, oyunlarınıza daha fazla derinlik ve kontrol katabilirsiniz. Unutmayın, iyi tasarlanmış bir grid, oyuncu deneyimini doğrudan etkileyen önemli bir faktördür.

🧠 Ders Sonu Değerlendirme Testi

Dersi tamamladıktan sonra bilgilerinizi test edin ve ekstra puanlar kazanın.

🔥 +50 XP Ödül
🔒

Sınava Katılmak İçin Giriş Yapın

Bu ders sonu testini çözebilmek, bilginizi test edip **+50 XP** kazanmak ve **Sınav Şampiyonu** rozetinin kilidini açmak için üye girişi yapmalısınız.

Yorumlar (0)

Yorum yazabilmek ve derslere katkıda bulunabilmek için giriş yapmalısınız.

İlk yorumu siz yapın!