오늘 배운 것
01. 스테이지 버튼 만들기
02. Scroll View 관련
01. 스테이지 버튼 만들기
하나 만들었을 때 가운데 정렬되는 현상
Grid Layoutgroup - child alignment
* 스테이지 셀을 프리팹으로 만들었을 때 안보이는 경우
- 스테이지 셀 프리팹의 크기를 체크, 현재는 Grid Layout Group에 의해 사이즈가 자동으로 조절되고 있기 때문에 Content 밑에서 보이는 상황일 수 있음.
Clear 상태일 때만 버튼 컴포넌트를 추가하거나,
코드로 Clear 상태일때만 OnClick 해도 동작되게 함.
Content의 RectTransform 값을 조정해서 , 마지막으로 클리어한 스테이지까지 한 번에 내려가게 하는 것이 과제
패딩은 각각 안에 들어있는 자식들 기준이 아닌, 부모 오브젝트에서 정하는 것.
using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(PopupPanelController))]
public class StagePopupPanelController : MonoBehaviour
{
[SerializeField] private GameObject stageCellPrefab;
[SerializeField] private Transform contentTransform;
[SerializeField] private ScrollRect scrollRect;
private void Start()
{
GetComponent<PopupPanelController>().SetTitleText("STAGE");
var lastStageIndex = 90; // UserInformations.LastStageIndex;
var maxStageCount = 100; // Constants.MAX_STAGE_COUNT;
RectTransform currentStageRect = null;
// Stage Cell 만들기
for (int i = 0; i < maxStageCount; i++)
{
GameObject stageCellObject = Instantiate(stageCellPrefab, contentTransform);
StageCellButton stageCellButton = stageCellObject.GetComponent<StageCellButton>();
if (i < lastStageIndex)
{
stageCellButton.SetStageCell(i, StageCellButton.StageCellType.Clear);
}
else if (i == lastStageIndex)
{
stageCellButton.SetStageCell(i, StageCellButton.StageCellType.Normal);
currentStageRect = stageCellObject.GetComponent<RectTransform>();
}
else
{
stageCellButton.SetStageCell(i, StageCellButton.StageCellType.Lock);
}
}
if (currentStageRect != null)
{
StartCoroutine(ScrollToStage(currentStageRect));
}
}
private IEnumerator ScrollToStage(RectTransform targetStage)
{
yield return new WaitForEndOfFrame(); // 레이아웃 업데이트 대기
RectTransform contentRect = contentTransform.GetComponent<RectTransform>();
float targetY = -targetStage.anchoredPosition.y; // 반대 방향으로 조정
float minY = 0f;
float maxY = contentRect.rect.height - scrollRect.viewport.rect.height;
targetY = Mathf.Clamp(targetY, minY, maxY);
contentRect.DOAnchorPosY(targetY, 1f).SetEase(Ease.OutQuad);
}
}
private IEnumerator ScrollToStage(RectTransform targetStage)
{
yield return new WaitForEndOfFrame(); // 레이아웃 업데이트 대기
RectTransform contentRect = contentTransform.GetComponent<RectTransform>();
float targetY = -targetStage.anchoredPosition.y; // 반대 방향으로 조정
float minY = 0f;
float maxY = contentRect.rect.height - scrollRect.viewport.rect.height;
targetY = Mathf.Clamp(targetY, minY, maxY);
contentRect.DOAnchorPosY(targetY, 1f).SetEase(Ease.OutQuad);
}
\
이렇게 셀을 만들면, 보여지지 않는데도 불구하고 준비해야하는문제가 있음
그래서 오브젝트 풀처럼 위 아래 몇 칸씩만 보이는 스크롤 뷰를 만들어보자.
02. Scroll View 만들기
거의 대부분의 게임에서 사용되는 UI, 에셋스토어에 팔기도 하지만 원리를 잘 이해해야 한다.
빈 게임 오브젝트 만들기
Scroll Rect 컴포넌트 추가.
VeiwPort (빈 오브젝트) 만들고 할당
이렇게 만드는 과정이 우리가 UI - Scroll view 하면 한 번에 되었던 것이다.
ScrollVeiw와 VeiwPort는 스트레치 ㅡ 스트레치가 맞으나, Content는 스크롤이 될 영역이기 때문에 너비만 맞으면 된다.
ViewPort 에 image와 Mask 추가
image는 백그라운드가 될 것이고, Mask는 마스킹을 할 것인지, Show mask Graphic은 일반적으로 언체크하나 지금은 일단...
Cell 추가 , 하나는 고유한 높이.
Cell 마다의 높이가 달라지기도 함, 기본적으로는 자기 자신만의 고유한 높이를 갖고 있음
그리고 셀을 하나 만듬
public struct Item
{
public string itemFlileName;
public string title;
public string subtitle;
}
아이템 데이터 같은 것은 struct로 선언하는 것이 좋다.
ScrollRect의 OnValueChanged는 0과 1값만 들어온다. 스크롤 방향에 따라 !
이 함수를 이용해야하는데 이건 '얼만큼 하는지'를 알려주지 않는다.
이건 완전 혼자 풀어봤다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(ScrollRect))]
[RequireComponent(typeof(RectTransform))]
public class ScrollVeiwController : MonoBehaviour
{
private ScrollRect _scrollRect;
private RectTransform _rectTransform;
//변하는 형태의 배열 ( 실행하면서 넣었다 뺄 수 잇므)
private List<Item> _items;
private void Awake()
{
_scrollRect = GetComponent<ScrollRect>();
_rectTransform = GetComponent<RectTransform>();
}
private void Start()
{
LoadData();
}
private void ReloadData()
{
//아이템 리스트가 수정되면 다시..
}
private void LoadData()
{
_items = new List<Item>
{
new Item { itemFlileName = "image1", title = "Title1", subtitle = "Subtitle1" },
new Item { itemFlileName = "image2", title = "Title2", subtitle = "Subtitle2" },
new Item { itemFlileName = "image3", title = "Title3", subtitle = "Subtitle3" },
new Item { itemFlileName = "image4", title = "Title4", subtitle = "Subtitle4" },
new Item { itemFlileName = "image5", title = "Title5", subtitle = "Subtitle5" },
new Item { itemFlileName = "image7", title = "Title7", subtitle = "Subtitle7" },
new Item { itemFlileName = "image8", title = "Title8", subtitle = "Subtitle8" },
new Item { itemFlileName = "image9", title = "Title9", subtitle = "Subtitle9" },
new Item { itemFlileName = "image10", title = "Title10", subtitle = "Subtitle10" },
};
ReloadData();
}
public void OnValueChanged(Vector2 value)
{
Debug.Log(value);
var x = _scrollRect.content.anchoredPosition.x;
var y = _scrollRect.content.anchoredPosition.y;
var w = _rectTransform.rect.width;
var h = _rectTransform.rect.height;
Debug.Log($"x:{x}, y:{y}, w:{w}, h:{h}");
}
}
이를 바탕으로 ObjectPool을 활용한 Scroll View를 만드는 것이 과제였다.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class Cell : MonoBehaviour
{[SerializeField] private Image image;
[SerializeField] private TMP_Text text;
[SerializeField] private TMP_Text subTitle;
public void SetItem(Item item)
{
image.sprite = Resources.Load<Sprite>(item.itemFlileName);
text.text = item.title;
subTitle.text = item.subtitle;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public struct Item
{
public string itemFlileName;
public string title;
public string subtitle;
}
일단 여기서 1차적으로 7개를 생성하고 나타내봤다.
private void Start()
{
LoadData();
for (int i = 0; i < 7; i++)
{
var cell = cellObjectPool.GetPool();
Debug.Log($"cell name: {cell.name}, is a prefab? {PrefabUtility.IsPartOfPrefabAsset(cell)}");
cell.GameObject().GetComponent<Cell>().SetItem(_items[i]);
cell.GameObject().transform.SetParent(_scrollRect.content, false);
}
}
진짜 하루 종일 했다. 자세한 내용은 따로 포스팅할 예정이다. (완)
https://febelo0524.tistory.com/150
Scroll View With ObjectPool
오늘의 목표오브젝트 풀을 활용한 스크롤 뷰 만들기 스테이지 등 스크롤뷰의 컨텐트 영역에 들어갈 무언가가 한정적이라면 만들지 않아도 괜찮겠지만,예를 들어 SNS라던가, 무한히 스크롤 되는
febelo0524.tistory.com
MVC 패턴 - model view Controller의 약자 - > 찾아보기
'TIL' 카테고리의 다른 글
[멋쟁이사자처럼 부트캠프 TIL회고] 02.27 : 보상형, 전면 광고 (0) | 2025.02.28 |
---|---|
[멋쟁이사자처럼 부트캠프 TIL 회고] 02 - 26 광고 관련 (0) | 2025.02.26 |
[멋쟁이 사자처럼 부트캠프 TIL회고] (0) | 2025.02.21 |
[멋쟁이사자처럼 부트캠프 TIL회고] (0) | 2025.02.20 |
[멋사 부트캠프 TIL 회고] 퀴즈게임 마무리단계(1) (0) | 2025.02.19 |