Playvoi/Playvoi.Client/Assets/ShiroginSDK/Prefabs/IAP/UISections/README.md

226 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Haklısın: Gridde 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 `LayoutGroup` olan 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`
Bu kurulumda genişlik parenttan 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ş)
Gridi her çözünürlükte “tam **N sütun**” yapacak ufak bir yardımcı:
```csharp
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** `LayoutElement` kullan; dikey listede `Preferred Height` anlamlıdır. **Gridde hücre boyutunu Grid belirler**, `LayoutElement.Width` dikkate 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:
```csharp
Canvas.ForceUpdateCanvases();
LayoutRebuilder.ForceRebuildLayoutImmediate(contentRectTransform);
```
çağırmak layoutu 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)
* “23 sütunlu, alta doğru akan vitrin” → **Grid (StartAxis=Horizontal, FixedColumnCount=N)** + isteğe göre **GridAutoSizer** (Bölüm 34)
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. 23 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 (ItemsParenta genelde gerek yok). Grid/Vertical LG zaten Sectionın Preferred Heightını hesaplar.
Item prefab (UIStoreItem_*)
LayoutElement
Dikey listede: Preferred Height = (örn. 220)
Gridde: Cell Sizeı Grid belirler; Width/Heighti prefabla zorlamana gerek yok.