7.3 KiB
Haklısın: Grid’de yatay/dikey akışı sadece Constraint değil, Start Axis belirler. Aşağıya “dikey liste”, “yatay tek sıra” ve “çok sütunlu grid” için tam parametre setlerini koyuyorum; hepsi tek bir dikey ScrollView içinde problemsiz çalışır.
0) Temel kurgu (bir kez)
Canvas
└─ ScrollView (dikey)
└─ Viewport
└─ Content ← (VerticalLayoutGroup + ContentSizeFitter[Vertical=PreferredSize])
-
Content / VerticalLayoutGroup- Child Alignment: Upper Center
- Spacing: 32 (örnek)
- Child Control Width/Height: true
- Child Force Expand Width: true, Height: false
-
Önemli: İç içe
LayoutGroupolan yerlerde ContentSizeFitter kullanma. Sadece ScrollView/Content’te dursun. Aksi halde “layout loop” uyarısı çıkar.
Her kategori bir Section prefab:
Section
├─ Header (başlık)
└─ ItemsParent ← (buradaki LayoutGroup tipi, dizilim tipini belirler)
Section kökünde VerticalLayoutGroup olsun. ItemsParent’ın kendi başına ContentSizeFitter’ı yok.
1) Dikey liste (alt alta kartlar)
ItemsParent → VerticalLayoutGroup
-
VerticalLayoutGroup
- Child Alignment: Upper Center
- Spacing: 20
- Child Control Width/Height: true
- Child Force Expand Width: true, Height: false
-
Item prefablarında LayoutElement
- Preferred Height: örn.
220 - Flexible Height:
0
- Preferred Height: örn.
Bu kurulumda genişlik parent’tan gelir, yükseklik LayoutElement ile tutarlı olur.
2) Yatay tek sıra (sağa doğru uzayan sıra — istersen yatay scroll yaparsın)
Bunu iki şekilde kurarsın:
2A) Grid ile tek satır
ItemsParent → GridLayoutGroup
- Start Corner: Upper Left
- Start Axis: Vertical ⬅️ (tek satır için kritik)
- Constraint: Fixed Row Count
- Constraint Count: 1
- Cell Size: (kart boyutu, örn. 420×280)
- Spacing: X=24, Y=24
- Child Alignment: Upper Left
“Start Axis = Vertical” + “Fixed Row Count = 1” ⇒ önce satırı doldurur, sonra yeni kolona geçer. Yani tek bir sıra halinde sağa doğru uzar. Yatay ScrollView kullanacaksan bu kalıp idealdir.
2B) HorizontalLayoutGroup ile tek satır
ItemsParent → HorizontalLayoutGroup
- Spacing: 24
- Child Control Height: true
- Child Control Width: false (genişliği kart belirlesin)
- Child Force Expand: false/false
Basit yatay sıra istiyorsan bu daha hafif. Yatay ScrollView ile iyi çalışır. Grid gerekmiyorsa tercih edilir.
3) Çok sütunlu grid (ör. 2 sütun, alta doğru yeni satırlar)
ItemsParent → GridLayoutGroup
- Start Corner: Upper Left
- Start Axis: Horizontal ⬅️ (satırı soldan sağa doldurur)
- Constraint: Fixed Column Count
- Constraint Count: 2 (2 sütun/row)
- Cell Size: (kart boyutu, örn. 480×320)
- Spacing: X=24, Y=24
- Child Alignment: Upper Center
“Start Axis = Horizontal” + “Fixed Column Count = 2” ⇒ satır önce 2 kolonla dolar, sonra alt satıra geçer. Mağaza ekranlarındaki “chest/gem/ticket packs” dizilimleri için tipik ve temiz çözüm.
4) Ekran genişliğine göre hücreyi otomatik hesaplat (profesyonel dokunuş)
Grid’i her çözünürlükte “tam N sütun” yapacak ufak bir yardımcı:
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(GridLayoutGroup), typeof(RectTransform))]
public class GridAutoSizer : MonoBehaviour
{
[Min(1)] public int columns = 2; // satır başına kaç sütun
public float aspect = 0.66f; // hücre yüksekliği = width * aspect (örn. 0.66 => 3:2)
public Vector2 spacing = new Vector2(24, 24);
public RectOffset padding = new RectOffset(24, 24, 24, 24);
GridLayoutGroup grid;
RectTransform rt;
void Awake() { grid = GetComponent<GridLayoutGroup>(); rt = GetComponent<RectTransform>(); Apply(); }
void OnRectTransformDimensionsChange() { if (isActiveAndEnabled) Apply(); }
void Apply()
{
var totalW = rt.rect.width - padding.left - padding.right - spacing.x * (columns - 1);
var cellW = Mathf.Floor(totalW / columns);
var cellH = Mathf.Round(cellW * aspect);
grid.cellSize = new Vector2(cellW, cellH);
grid.spacing = spacing;
grid.padding = padding;
grid.startCorner = GridLayoutGroup.Corner.UpperLeft;
grid.startAxis = GridLayoutGroup.Axis.Horizontal; // çok sütunlu grid için
grid.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
grid.constraintCount = columns;
grid.childAlignment = TextAnchor.UpperCenter;
}
}
- Bunu çok sütunlu
ItemsParent’larına ekle. - Sadece tek satırlık yatay sıra istiyorsan (bölüm 2A), gridi o profile göre kur (StartAxis=Vertical, FixedRowCount=1) ve hücre genişliğini manuel ver veya yine yukarıdaki kodu “columns = çok büyük bir sayı” yerine “FixedRowCount=1” düzeni için uyarlayabilirsin.
5) İnce ayar ve sık düşülen tuzaklar
-
ContentSizeFitter’ı yalnızca ScrollView/Content’te kullan. Grid/Vertical/Horizontal Layout olan ara düğümlerde kullanırsan layout loop uyarısı alırsın.
-
Item prefablarında
LayoutElementkullan; dikey listedePreferred Heightanlamlıdır. Grid’de hücre boyutunu Grid belirler,LayoutElement.Widthdikkate alınmaz. -
Canvas Scaler:
Scale With Screen Size (Ref: 1080×1920, Match=0.5)→ her cihazda tutarlı görünür. -
Çok sayıda item Instantiate ediyorsan, sonunda:
Canvas.ForceUpdateCanvases(); LayoutRebuilder.ForceRebuildLayoutImmediate(contentRectTransform);çağırmak layout’u anında toparlar.
Hangi kombinasyonu ne zaman?
- “Alt alta büyük kartlar” → VerticalLayoutGroup (Bölüm 1)
- “Sağa doğru giden tek sıra” → Grid (StartAxis=Vertical, FixedRowCount=1) ya da HorizontalLayoutGroup (Bölüm 2)
- “2–3 sütunlu, alta doğru akan vitrin” → Grid (StartAxis=Horizontal, FixedColumnCount=N) + isteğe göre GridAutoSizer (Bölüm 3–4)
Sonraki adım olarak, chest/gem/ticket bölümlerinde kaç sütun istediğini belirleyip GridAutoSizer’ı ilgili ItemsParent’lara ekleyerek her çözünürlükte milimetrik hizayı koruyan bir mağaza elde edebilirsin.
Final hali ItemsParent (ürünlerin olduğu kısım)
Dikey liste (kartlar alt alta):
VerticalLayoutGroup
Spacing: 20
Child Control Size: Width=ON, Height=ON
Child Force Expand: Width=ON, Height=OFF
Yatay tek sıra (sağa doğru uzayan):
GridLayoutGroup
Start Corner: Upper Left
Start Axis: Vertical
Constraint: Fixed Row Count
Constraint Count: 1 → tek satır
Cell Size: (kart boyutu)
Spacing: (örn. 24, 24)
Çok sütunlu grid (ör. 2–3 sütun, alta doğru):
GridLayoutGroup
Start Corner: Upper Left
Start Axis: Horizontal
Constraint: Fixed Column Count
Constraint Count: 2 veya 3
Cell Size: (kart boyutu)
Spacing: (örn. 24, 24)
ContentSizeFitter ekleme (ItemsParent’a genelde gerek yok). Grid/Vertical LG zaten Section’ın Preferred Height’ını hesaplar.
Item prefab (UIStoreItem_*)
LayoutElement
Dikey listede: Preferred Height = (örn. 220)
Grid’de: Cell Size’ı Grid belirler; Width/Height’i prefabla zorlamana gerek yok.