1인 개발 게임 (Unity)/UNITY

[UNITY6] 카카오톡 채팅 메세지 처럼 동적으로 텍스트 길이에 맞춰서 생성되는 대화창 만들기

Z46 2025. 12. 3. 13:16

스크립트 작성이 하나~도 필요없습니다!! 

유니티 설정만 조금 만져주면 되는데요 ^_^

먼저 채팅메세지가 될 프리팹의 구조는

빈게임오브젝트

  ㄴ대화창이미지

       ㄴ텍스트

 

요런 구조를 따른다고 보시면 됩니다!!

일단 빈게임 오브젝트에는 컴포넌트 중에 'vertical layout group'과 'content size fillter' 컴포넌트를 추가해줍니다.

설정은 요거처럼 하시면 됩니다.

왜 horizontal fit은 unconstrained냐면, 가로로 너무 길때 채팅방 화면을 넘어가지 않기 위함입니다!

반대로 너무 길면 밑으로 길어져야겠지요? 그래서 vertical fit은 preferred size로 해야합니다. 

vertical layout group 요소에 하나씩 설명을 해드리자면

1) padding은 말그대로 하위 자식 요소의 앞뒤공간을 얼만큼 남겨둘거냐는 얘기

2) spacing은 자식 요소끼리 얼마나 띄울 거냐의 얘기

3) child aligmnet는 어떻게 배열할거냐는 소리인데, 지금 설정은 '사용자'가 보내는 메세지 기준이라서 'upper Right'로 해줍니다.

4) revers arragement 는 자식 순서 뒤집을거냐? 인데 당연 채팅방이니까 아니구요

5) control child size는 하위자식요소의 사이즈를 너가 맘대로 조절할거야? 라는 건데 당연히 그래야겠지요? 그래야 저희가 content size fitter를 설정한 의미가 있겠지요. ^^ width 랑 height 둘 다 체크해줍니다.

6) use child saclae은 자식 스케일 사용할거야? 인데 이러면 세로로든 가로로든 무한정 확장되어 버리니 ㄴㄴ 해줍니다.

7) child force expand는 자식을 내 크기까지 강제로 키울거야? 인데 이러면 텍스트 크기에 따라 동적 조절이 아니라 고정이 되어 버리니까 이것도 ㄴㄴ 해줍니다.

 

자 다음! 채팅방 메시지의 말풍선이 될 이미지에 추가할 컴포넌트입니다. 바로 

vertical layout group 하나면 됩니다! 

 

설정은 요렇게 가져가주시면 됩니다! 내가 control child size를 할 수 있어야 고정시켜놓은 가로길이를 유지해놓을 수 있겠죠?

저 패딩정도주면 딱 보기좋게 말풍선 밑에 텍스트가 생긴답니다. 

텍스트 설정은 이렇게!

 

overflow 를 truncate로 바꿔줘야해요!

그럼 끝~~ ^_^ 

 protected virtual GameObject DisplayMessage(string sender, string content, bool animate = true)
    {
        GameObject prefab = sender == "user" ? userMessagePrefab : characterMessagePrefab;
        GameObject messageObj = Instantiate(prefab, messageContent);

        TextMeshProUGUI messageText = messageObj.GetComponentInChildren<TextMeshProUGUI>();
        if (messageText != null)
        {
            messageText.text = content;
        }

        messageObjects.Add(messageObj);

//  [핵심] 레이아웃 즉시 갱신 (말풍선 크기 재계산)
        // 텍스트가 바뀐 직후 ContentSizeFitter가 작동하도록 강제함
        LayoutRebuilder.ForceRebuildLayoutImmediate(messageObj.GetComponent<RectTransform>());
        
        // 부모인 Content의 레이아웃도 갱신
        if (messageContent != null)
        {
            LayoutRebuilder.ForceRebuildLayoutImmediate(messageContent);
        }

        //  스크롤 처리
        if (animate)
        {
            // 한 프레임 대기 후 스크롤을 내리면 더 자연스럽지만, 즉시 내리려면 아래 코드 사용
            Canvas.ForceUpdateCanvases();
            ScrollToBottom();
            
            // 만약 ScrollToBottom이 씹힌다면 코루틴으로 한 프레임 뒤에 호출하는 방법 권장
            StartCoroutine(ScrollToBottomNextFrame());
        }

        return messageObj;

    }

// 스크롤을 확실하게 내리기 위한 코루틴
    protected System.Collections.IEnumerator ScrollToBottomNextFrame()
    {
        yield return null; // 1프레임 대기 (UI 레이아웃 계산 완료 대기)
        messageScrollRect.verticalNormalizedPosition = 0f;
    }
    
    protected void ScrollToBottom()
    {
        Canvas.ForceUpdateCanvases();
        messageScrollRect.verticalNormalizedPosition = 0f;
    }

 

아직 디자인은 안한 스켈레톤의 결과물은 요론 느낌!! 적정한 가로사이즈를 찾기 위해 여러번 수정해보느라 채팅방 최대 가로메세지의 길이가 다른 점 이해해주세용