반응형
특정 상황에서 ContentSizeFitter는 제대로 작동되지 않을 때가 있다.
UI끼리 겹치는 예가 딱 그렇다. (UI끼리 쓸데없이 멀어지기도 한다)
국내 해외 할 것없이 검색해보면 여러 방법들이 있었지만, 그 역시 제대로된 해결법이 아닌듯 했다.

좀 찾아보다가 제대로 작동하는 방법을 찾아서 이런저런 실험을 해보고 
몇가지 주의사항만 잘 참고해서 UI레이아웃 즉시 강제 재설정을 하면 해결된다.

텍스트UI와 이미지UI가 겹친다

우선 예시해결방법을 먼저 보고, 이러한 문제가 일어나는 특정상황에 대해서 설명하겠다.

예시

1. 예시를 위해 스크립트를 작성했다.

using UnityEngine;
using TMPro;
public class Test : MonoBehaviour
{
    [SerializeField] TextMeshProUGUI tText;

    //랜덤으로 가져 올 아이템 이름들
    string[] itemName = new string[] { "루비", "가짜보석", "빨갛게빛나는보석" };

    //텍스트를 변경하는 함수
    public void ChangeText()
    {
        //itemName 배열에 있는 string을 랜덤으로 하나 가져온다.
        int rand = Random.Range(0, itemName.Length);
        //랜덤으로 가져온 itemName과 함께 텍스트를 바꾼다
        tText.text = $"아이템 \'{itemName[rand]}\' 획득하였습니다!";
    }
}

2. 작성한 스크립트를 저장하고 스크립트를 오브젝트에 추가했다.

작성한 스크립트를 상위 Canvas에 추가했다.

 

그리고 Panel_Toast에 버튼을 만들어 주었고 

버튼을 눌러 ChangeText() 함수를 실행하면 itemName 배열에 담긴 아이템 이름 중 하나를 랜덤으로 뽑아 텍스트를 바꾼다.

예를 더 잘보여주기 위해 일부러 itemName은 글자 수가 다 다르게 지정했다.

 

각 오브젝트는 간단한 작업이지만 초보분들을 위해서 상세하게 설명하였다.

이글을 유심히 읽으시는 독자분이시라면 이미 하드하게 작업하다가 막혀서 오셨을테지만..

 

 

이제 실행을 해서 메시지를 눌러보면 바로 겹쳐버린다.

글자 길이가 가장 길게 나온 뒤 바로 다음 작은 글자수가 나오게되어도 마찬가지로 변화가 없다.

글자 수가 작은 것도 사이즈가 변경되지 않는걸로 보아 제대로 작동하지 않는다

해결법

자, 이문제를 해결할 함수는 ForceRebuildLayoutImmediate(UI레이아웃 즉시 강제 재설정) 이다.

using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    [SerializeField] TextMeshProUGUI tText;

    //랜덤으로 가져 올 아이템 이름들
    string[] itemName = new string[] { "루비", "가짜보석", "빨갛게빛나는보석" };

    //텍스트를 변경하는 함수
    public void ChangeText()
    {
        //itemName 배열에 있는 string을 랜덤으로 하나 가져온다.
        int rand = Random.Range(0, itemName.Length);
        //랜덤으로 가져온 itemName과 함께 텍스트를 바꾼다
        tText.text = $"아이템 \'{itemName[rand]}\' 획득하였습니다!";

        ///지금은 텍스트지만
        ///ContentSizeFitter가 적용되어 사이즈가 변경되는 UI의 RectTransform을 넣어주면 된.
        LayoutRebuilder.ForceRebuildLayoutImmediate(tText.rectTransform);
    }
}
 LayoutRebuilder.ForceRebuildLayoutImmediate( 타겟RectTransform );

저 한줄을 입력하고 실행해보면

잘 나온다.

 

이 외 검색을 해보면 다양한 방법들이 있는데, 

코루틴을 사용해서 리프레시를 한다던지,

LayoutGroup내 Control Child size 매개변수를 건드린다던가..(매개변수를 꺼주어도 안되는 상황이 있다.)

꼼수에 가깝거나 좀 지저분한 방법들이 많았다.

 

 

해당 문제가 일어나는 특정상황

우선 작동이 안되는 '특정상황'이란 이런 것이다.

1. 부모 오브젝트에 ContentSizeFitter가 있고, 하위오브젝트에도 ContentSizeFitter가 중복으로 있을 때
2. 혹은 서로 연관된 UI오브젝트가 각자 ContentSizeFitter 컴포넌트를 가지고 있을때다.

즉, ContentSizeFitter가 공통된 레이아웃 안 여러 곳에 있을 경우 발생한다.

이럴 경우,

결국 ContentSizeFitter가 작동하는 순서가 얽혀서,

가장 마지막에 작동하는 ContentSizeFitter에 의해 겹치거나 멀어지는 결과를 가져온다

즉 UI그리는 과정에서 순서가 꼬여서 생긴 문제이다.

 

그래서 다음 프레임에 다시 재설정하게 하는 것도 어찌보면 방법인셈.

 

주의사항 -  안되는 경우

간단하게 설명할 수도 있었지만 이렇게 원리까지 디테일하게 설명한 이유가 여기에있다.

 

ForceRebuildLayoutImmediate 함수로 인해 문제가 해결이 안되는 것은 열에 아홉은

해당 오브젝트가 activeSelf 가 false인 상태에서 호출을 하고 이후 SetActive(true); 를 했을 경우다.

예를들어

//액티브가 꺼져있는 상태로 강제로 재설정을 한다한들 결국 다시 true가 되었을 때 UI를 다시 그린다
//즉 ForceRebuildLayoutImmediate를 기입한 이유가 없어진다.

tName.SetActive(false);//어떠한 이유로 오브젝트를 꺼놓았다

LayoutRebuilder.ForceRebuildLayoutImmediate(tName.rectTransform);//UI레이아웃 즉시 강제 재설정

tName.SetActive(true); //오브젝트를 다시 켠다.

위처럼 사이즈 조절에 문제가 있는 레이아웃에 연관된 오브젝트가 꺼져있는 상황에서 백날 강제로 레이아웃을 재설정해도 반응이 없다.

(재정렬하려는 오브젝트의 active가 true가 되었을때 다시 리셋되기때문인지, false일때 작동을 안하는 건지는 확실치 않지만..)

 

해당 부분만 잘 인지하고 사용하면 문제 없이 작동한다

반응형
반응형
유니티 작업 시, 레이아웃을 따라 UI를 잘 꾸며 놓았는데 간혹 특정 UI의 크기를 자동으로 조절을 해야할 때가 있다.
즉, 특정 UI의 사이즈가 자식의 크기에 따라 자동으로 정렬이 되었으면 할때 필요한 기능이다.

딱 이런 경우

이런 경우 자식 오브젝트들의 사이즈에 맞게 가변형으로 바뀌게 할 수 있는 방법이다.

 

1. 사용방법

우선 패널의 인스펙터 내용이다.

간단하게 예시 Image와 HorizontalLayout Group을 추가해줬다

 

아래에서 추가 설명하겠지만,

이 글에서 설명하려는 ContentSizeFitter 컴포넌트의 경우

Layout Group이 필수로 함께 있어야한다

(Vertical  Layout Group 또는 Horizontal Layout Group)

 

나는 Horizontal Layout Group을 추가했다. 

 

하위 자식 오브젝트들은 아무거나 넣어주었고 사이즈도 대충 집어 넣었다.

 

 

 

 

 

 

 

 

 

 

 

이렇게까지만 하면 아마 여전히 아래와 같을 것이다.

 

자 그럼 다시 부모오브젝트인 panel로 돌아가서 Add Componenet ->  Content Size Fitter 추가

그럼 아래 그림과 같은 컴포넌트가 추가된다.

여기서,

가로사이즈를 가변형으로 바꾸고 싶다 하면 Horizontal Fit

세로사이즈바꾸고 싶다하면 Vertical Fit을 조절하면된다.

 

눌러보면 세 개중 하나를 고르도록 되어있다.

Unconstrained의 경우는 원래 그대로의 상태다 (쉽게 말해, 기능 off)

Min Size 혹은 Preferred Size 중 하나를 선택하면 된다.

 

Min Size는 가장 최소화된 사이즈로 맞춰준다.

Preferred Size 적당히 선호되는 사이즈로 맞춰준다.

아래는 Preferred Size를 누른 결과이다

완성

꽤 직관적으로 되어 있어서 몇 번 사용해보면 어떻게 동작하는지 금방 알 수있다.

텍스트의 길이에 따라 사이즈를 조절한다든지도 이걸로 해결할 수 있다.(텍스트는 Preferred Size 만 된다.)

 

 

2. 주의사항 두 가지

1. 경고메시지

다만, 주의 할 점은 이렇게 Layout Group을 사용하고있지 않은 오브젝트는 경고 메시지가 뜨는걸 확인할 수 있다.

ContentSizeFitter는 하위 자식오브젝트들을 감지해야하므로 Layout Group이 필수로 있어야한다

(Vertical  Layout Group 또는 Horizontal Layout Group)

당연히 하위 자식오브젝트들이 어떤 기준으로 정렬이 되어있어야 그에 맞춰 사이즈를 조절할테니..

하지만 내 경우 텍스트의 경우 이를 무시하고 사용할때가 종종있다. 문제없이 됨

 

2. 간혹 안되는 경우

간혹가다 ContentSizeFitter가 특정 상황에서 먹히지 않는 경우가 있다.

해당 부분은 특정상황과 해결방법에 대해 따로 다뤄야할 듯해서 바로 다음 글에 게시하겠다

반응형
반응형

좋은 코드는 언어나 기술에 종속되지 않는다.

 

그렇지만 코딩을 하면서 매일 드는 생각은 '그래서 이게 잘 짠 코드인가?' 이다.

 

결론부터 말하자면, 내가 생각하는 잘 짠코드의 정의는 단 두가지로 함축될 것 같다.

1. 남들이 읽기 쉬운가? a.k.a 가독성
    이 '남'의 정의를 코드를 짠 이후의 미래의 '나'도 '남'에 포함해야한다고 본다.
    시간이 지나고 다시 들여다 보면 내가 쓴 게 아닌 것 같다...
    ...그래서 보통 주석을 달곤하지만, 과연 그 주석도 잘 읽히던가?


2. 재사용이 가능한가 +모듈화
    내가 짠 코드를 다른 프로젝트에서도 그대로 가져와 쓸 수 있는지,
    그리고 타인이 사용했을 때도 간단하게 사용할 수 있는지

    간단한 것 조차도 항상 확장성을 고려해서 짜야한다

 

위의 내용만 잘 지켜도 유지 보수가 쉽고 확장 가능한 프로그래밍이라 할 수 있을듯하다.
하지만, 그 디테일 함은 여전히 누구나 어려워한다. 그래서 나도 몇가지 규칙을 두고 코딩을 하려고 노력한다.

오늘은 그 규칙들 중 4가지 정도만 설명해보고자 한다.

 

 

 

1) 주석보다 코드내용에 집중하자

주석이 달린 코드는 이후 수정이 필요할때 수정하고 난 후 주석도 같이 수정해야하지만 생각보다 번거롭다.

특히나 협업의 경우 다른 팀원이 내 코드내용을 수정한 이후 주석도 같이 수정해주는 팀원은 희귀했다.

이런문제들로 쌓인 '잘못된 주석' 때문에 리딩을 다시 해야하는 경우도 종종 생긴다

 

2) 이름은 항상 중요

아래 3)항과 같은 내용이라고도 볼수 있을지 모르겠지만

변수명이 무엇을 담고있는 변수인지 구체적으로 명시하자.

string name; //(X)
string user_name; //(O)

 

마찬가지로 함수명도 어떠한 기능을 하는지에 대해 구체적이고 명확한게 좋다.

 

하지만, 이름을 짓는게 가장 고통스럽다

프로그래머가 가장 힘들어하는 일은? = 이름 짓기...공감... 출처:나무위키

 

3) 조건은 항상 짧게

예시를 들어보면 바로 알 수 있다.

if(level > 1 && job == EJob.Designer && isWhiteUser)
{
	//내용
}

조건을 변수로 빼주고나면, 해당 조건문이 무엇을 뜻하는지 명확하게 알 수 있다.

bool isManager = level > 1 && job == EJob.Designer && isWhiteUser;
if(isManager)
{
	//내용
}

 

4) 리턴의 활용

코드를 보면 무슨 얘기를 할지 바로 이해할듯하다.

1.

public int GetUserPermission()
{
    int permission;
    if (IsWhiteUser()) //화이트유저인지체크
    {
        if (job == EJob.none) //Job이 공란일 경우
        {
            permission = 0;
        }
        else //Job이 공란이 아닐때
        {
            permission = level; 
        }
    }
    else
    {
        permission = 0;
    }
    return permission; //권한값을 리턴
}

2.

public int GetUserPermission()
{
    if (IsWhiteUser() && job != EJob.none) return level;
    return 0;
}

위 2개의 함수는 같은 기능을 한다.

그러나 1번 함수는 쓸데없이 이중 조건을 걸고 있다. (읽는데 거부감이 있다)

그리고 return에 대한 의미를 정확히 이해를 하지 못해 사족이 많이 길다.

당연하겠지만 if문에 들어가서 return이 되면 그 함수는 종료가 된다.

그럼 else는 필요가 없다.

 

//더 줄이자면 이렇게 변태같이 줄일 수도 있겠지만 좋은 예시는 아니라고 생각이 든다
public int GetUserPermission()=> (IsWhiteUser() && job != EJob.none) ? level : 0;

 

본인은 병적으로 코드최적화에 집착한다.

줄 수를 줄이면 최적화가 된다고 생각하는 사람이 많은 것 같은데, 맞는 말 같기도 틀린말 같기도 하다.

줄 수에 집착하기 보다는 정확한 플로우를 이해하는게 중요한 것같다.

즉, '실행 시점'과 '조건'을 잘 생각한다면 많은 것이 해결되더라.

 

더불어 enum의 활용과 코딩컨벤션, 상수활용 등 많은 방법이 있지만 커먼한 방법들이라 판단이되어 따로 게제하지는 않았다.

추후에 시간이 된다면 해볼지도..

반응형
반응형

맥북에서

- 화면은 닫은채로 음악을 틀어 놓고 싶은데, 화면이 닫히거나

- 다운로드나 어떤 작업이 길어져서 닫아두고 이동하고 해야할때

등등 여러 이유로 맥북에서 화면을 덮어도 꺼지지 않게 할 수 있습니다

 

잠자기 방지

터미널에서 (Command + Space를 눌러 Spotlight 검색창에 '터미널.app' 혹은 'terminal' 검색)

 

sudo pmset -c disablesleep 1

 

패스워드 입력 후 엔터

 

 

이제 맥북 모니터 화면을 닫아도 꺼지지 않는 상태가 됩니다.

 

잠자기 방지 기능 해제

해당 기능을 끄고 싶으면

sudo pmset -c disablesleep 0

맨 뒤 숫자 1 을 0으로 변경해서 터미널에 입력하면 잠자기방지 기능끄게 됩니다.

반응형
반응형

갑자기 손톱에 이런 세로줄이 있어, 궁금증이 생겨 정리해보았습니다.

손톱의 변화는 우리 손톱의 건강을 알리는 중요한 신호입니다. 세로줄의 색상 변화, 불규칙한 모양, 두께 변화 등의 증상은우리가 놓치기 쉬운 피부와 손톱의 문제를 알려주는 신호일 수 있습니다.

주요 증상

세로줄의 색상 변화: 검은색갈색노란색 등의 이상한 색상 변화를 관찰할 수 있습니다.
세로줄의 불규칙성: 일그러지거나 불규칙한 모양의 세로줄이 나타날 수 있습니다.
세로줄의 두께 변화: 두꺼워지거나 얇아지는 세로줄을 확인할 수 있습니다.
세로줄의 갈라짐: 세로줄이 갈라지거나 심한 경우 손톱이 쪼개질 수 있습니다.
세로줄의 부유물: 세로줄 아래에 얼룩이나 부유물이 발생할 수 있습니다.

 

원인

1. 노화 나이가 들면서 손톱의 세로줄이 더 강조될 수 있습니다.
2. 고유색소 일부 사람들은 고유한 피부 색소에 의해 세로줄이 갈색 또는 검은색으로 보일 수 있습니다.
3. 외상 손가락에 외상이나 손톱에 압력이 가해지면 세로줄이 생길 수 있습니다.
4. 피부 질환 피부 질환인 포즈노이드 루피스, 비젼토 세균 감염 등이 세로줄의 발생을 일으킬 수 있습니다.
5. 일시적인 원인 건강한 상태에서도 스트레스, 영양 부족, 임신 등의 일시적인 상황에 따라 손톱 세로줄이 변할 수 있습니다.

6. 고유색소 증가 (Racial melanonychia) 고유색소 증가는 세로줄이 주로 갈색이거나 검은색으로 표시되는 현상입니다. 이는 동양인과 아프리카인 등의 피부 색이 더 어두운 인종에서 자주 나타나는 특징입니다. 일반적으로 건강한 상태에서 발생하며 큰 문제가 되지 않습니다.

동양인의 손톱에서 메란지 밴드나 고유색소 증가가 관찰되는 경우, 대부분은 생리적인 변화로서 심각한 질환과 관련되는 것이 아닙니다. 하지만 만약 새로운 세로줄이 갑자기 나타나거나 세로줄에 변화가 급격하게 나타난다면, 피부과 전문의를 방문하여 원인을 확인하는 것이 중요합니다. 건강한 손톱과 손에 대한 꾸준한 관리와 주의가 필요합니다.

 

결핍

1. 영양 부족 비타민과 무기질 부족은 손톱의 건강에 영향을 미치고 부족을 초래할 수 있습니다.
2. 손톱 건조 손톱이 건조한 상태에서 균열이 발생하거나 부족이 형성될 수 있습니다.
3. 부정확한 손톱 관리 지나치게 깎거나 강하게 손톱을 사용할 경우 부족이 발생할 수 있습니다.
4. 피부 질환 습진, 아토피 피부염 등 피부 질환으로 인해 손톱 주변의 피부가 손상될 수 있습니다.
5. 환경적 요인 수영을 많이 하거나 항상 물에 손이 닿는 상태에서도 부족이 발생할 수 있습니다.

 

비슷한 증상들

손톱 박리증 역시 손톱과 손톱 사이에 공간이 생기거나 손톱이 벗겨지는 증상으로 나타납니다. 이러한 증상은 외상, 화학적 자극, 피부질환 등의 원인으로 발생할 수 있습니다.

치료 방법


손톱 세로줄의 변화나 손톱 박리증의 경우, 원인을 파악하고 적절한 치료를 받는 것이 중요합니다. 따라서 다음과 같은 접근 방법을 고려해볼 수 있습니다.

원인 파악 피부과 전문의를 찾아 세로줄 변화나 손톱 박리증의 원인을 확인합니다.
손톱 관리 정기적인 손톱 관리로 세로줄을 깨끗하게 다듬고, 치료제나 보호제를 사용하여 건강한 손톱을 유지합니다.
약물 치료 피부질환에 의한 경우 의사의 처방에 따라 항염증제나 항진균제 등의 약물을 사용할 수 있습니다.
수술적 치료 심한 손톱 박리증이나 세로줄 변화의 경우 수술적 개입이 필요할 수 있습니다.
손톱 세로줄에 관련된 증상이나 손톱 박리증이 발생하면, 가능한 빨리 피부과를 방문하여 정확한 원인을 찾고 적절한 치료를 받는 것이 중요합니다. 건강한 손톱을 유지하여 우리의 손과 손톱이 항상 아름답게 빛날 수 있도록 합시다.

반응형
반응형

UI Text에 float을 String으로 표현해야 할 때 원하는 소수점 자리까지만 표현을 하고 싶을경우가 있다.

 

단순히 ToString() 함수에 'F' 포맷을 넣어주면 된다.

float a = 1.234f;

a.ToString("F1"); // 1.2

a.ToString("F2"); // 1.23

a.ToString("F3"); // 1.234

 

또 마찬가지로 숫자를 1,000 단위로 콤마를 표현해 String으로 반환하고 싶을때가 있다.

float a = 10000.123f;

a.ToString("N1"); // 10,000.1

a.ToString("N2"); // 10,000.12

a.ToString("N3"); // 10,000.123

F대신에 N으로 바꾸어 주면 된다.(아마도 Numric 의 약자가 아닐까 싶다.)

이렇게 간단한 포맷으로 사용이 가능하다.

반응형

+ Recent posts