-
[Unity][UI Toolkit] uss에서 gap 옵션(child 사이 spacing) 구현하기 [USS]앱 개발/Unity, C# 2024. 11. 29. 20:37
uss는 css처럼 유니티 UI Toolkit에서 스타일을 적용시킬 때 사용한다.
웹 형식과 비슷해 더욱 쉽게 디자인할 수 있다는 장점이 있지만,
아직 개발 단계라 css에서 제공하는 속성 중 적용되지 않는 것(line-height, gap 등)이 있다는 것이 단점이다.
특히, 웹을 할 때는 css에서 flex 속성과 함께 gap 속성을 주면 자식 요소를 간단하고 깔끔하게 정렬할 수 있었는데
유니티 uss에는 해당 속성이 없어서 자식의 margin을 하나씩 다 설정해줘야 한다. (아래의 css 코드처럼 말이다)
div > *:not(:last-child) { display: block; margin-bottom: 20px; }
그런데 문제는, uss가 not 선택자는 물론 last-child 선택자도 지원하지 않는다.
그래서 child의 margin을 자동으로 조정하여 css의 gap 효과를 구현할 수 있는 VisualElement 코드를 작성해보았다.
ChildAnnotator (first-child, last-child)
해당 코드에는 ChildAnnotator가 등장하는데, 이건 first-child와 last-child 클래스를 자동으로 추가해줌으로써
uss에서도 css의 first-child와 last-child 선택자를 비슷하게나마 사용할 수 있도록 하는 스크립트다.
자세한 내용은 아래의 포스팅 참고.
코드
GapContainer은 ChildAnnotator을 상속 받아, last-child를 제외하고 gap 값만큼 child의 margin-right 또는 margin-bottom 값을 자동으로 설정해도록 작성하였다.
더보기using UnityEngine.Scripting; using UnityEngine.UIElements; namespace UI.Common { public class GapContainer : ChildAnnotator { private int gapX { get; set; } private int gapY { get; set; } protected override void OnChildChange(ChildChangeEvent evt) { base.OnChildChange(evt); UpdateChildMargins(); } private void UpdateChildMargins() { for (var i = 0; i < childCount; i++) { var child = this[i]; child.style.marginRight = child == lastChild ? 0 : gapX; child.style.marginBottom = child == lastChild ? 0 : gapY; } } [Preserve] public new class UxmlFactory : UxmlFactory<GapContainer, UxmlTraits> { } [Preserve] public new class UxmlTraits : VisualElement.UxmlTraits { private readonly UxmlIntAttributeDescription checkInterval = new UxmlIntAttributeDescription { name = "check-interval", defaultValue = 0 }; private readonly UxmlIntAttributeDescription gapXAttribute = new UxmlIntAttributeDescription { name = "gap-x", defaultValue = 0 }; private readonly UxmlIntAttributeDescription gapYAttribute = new UxmlIntAttributeDescription { name = "gap-y", defaultValue = 0 }; public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc) { base.Init(ve, bag, cc); var item = (GapContainer) ve; item.childChanger.checkInterval = checkInterval.GetValueFromBag(bag, cc); item.gapX = gapXAttribute.GetValueFromBag(bag, cc); item.gapY = gapYAttribute.GetValueFromBag(bag, cc); } } } }
적용 결과
- Gap X: child 사이의 x축 방향 거리를 px 단위로 할당
- Gap Y: child 사이의 y축 방향 거리를 px 단위로 할당
후딱 간단하게 짠 거라 GapContainer 내에 있던 element가 밖으로 나간 경우 등의 상황은 고려되어 있지 않지만,
그래도 필요한 사람이 있을 것 같아 스리슬쩍 공유해봅니다..
child의 width(가로 정렬 시) 또는 height(세로 정렬 시)에 사용하기 적합하며, 그 이외의 경우에는 각 child마다의 크기가 달라질 수 있다는 것만 유의해주십셔
그리고 이 코드에서 더 나아가서 코드를 발전시키셨다면 어떻게 하셨는지 공유해주시면 큰 도움이 될 것 같습니다..!
아 참고로 전 유니티 2022.3.45f1 버전 사용 중입니다.
끗~
'앱 개발 > Unity, C#' 카테고리의 다른 글
[Unity][UI Toolkit] uss에서 first-child, last-child 구현하기 [USS] (0) 2024.11.29 [Unity] 커서 모양 바꾸기 + 커서 회전하기 [How to rotate custom cursor texture] (2) 2024.02.18 [Unity][UI Toolkit] 버튼 누르는 동안 동작 실행 (0) 2024.02.18 [Unity][ClickEvent] 버튼 클릭 이벤트를 처리하는 n가지 방법 (0) 2024.02.18 [Unity][UI Toolkit] UI Document를 생성하고 Visual Tree Asset(uxml 파일) 적용시키기 (0) 2022.09.06