251210 StringBuilder

2025. 12. 10. 12:19·📖TIL

StringBuilder

StringBuilder 는 문자열을 자주 이어 붙이거나 수정할 때 사용하는 특수한 클래스이다.

C# 에서 문자열 ( String ) 은 불변 ( Immutable ) 이라서 + 연산을 할 때마다 새로운 문자열 객체를 계속 생성한다.

그래서 반복문에서 문자열을 계속 더하면 성능이 매우 떨어지는 문제가 발생한다.

그 문제를 해결해주는게 StringBuilder 이다.

 

StringBuilder 핵심 개념

문자열을 변경해도 새로운 객체를 만들지 않는다

StringBuilder 는 내부 버퍼에서 문자열을 수정하기 때문에

+ 연산처럼 계속 새 객체를 만들 필요가 없다 → 빠르고 메모리 효율적이다

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerInteraction : MonoBehaviour
{
    TalkableBase talkTarget;
    // BallDialogue 같은 구체화 된 것을 들고 있는 것이 아닌 TalkableBase 추상 객체를 들고 있는다 SOLID

    public GameObject Fkey; // F키 상호작용. 안내 문구 껏다켰다 하려고 넣었음

    private void OnTriggerEnter(Collider other)
    {
        talkTarget = other.GetComponent<TalkableBase>(); // 플레이어가 만약 게임오브젝트에 충돌을 감지했는데 그 오브젝트에 이거 있으면?
        Fkey.SetActive(true); // F키 UI 띄워라
    }

    private void OnTriggerExit(Collider other)
    {
        if(talkTarget == other.GetComponent<TalkableBase>()) // 내가 대화중이었던 오브젝트가 맞으면?
        {
            talkTarget = null; // 대화 상대 정보 삭제
            Fkey.SetActive(false); // F키 UI 꺼라
        }
    }

    private void Update()
    {
        if(talkTarget != null && Keyboard.current.fKey.wasPressedThisFrame)
        {
            DialogueManager manager = FindFirstObjectByType<DialogueManager>(); // 업데이트마다 이거 하는건 비효율적인 코드. 예시라서 그냥 작성함
            // 매니저를 스타트와 동시에 찾는다
            // 매니저를 그냥 직렬화로 꽃아넣어둔다
            // 싱글톤으로 매니저를 활용한다

            talkTarget.Talk(manager);
        }
    }
}
using UnityEngine;

public class BallDialogue : TalkableBase
{
    private void Awake()
    {
        dialogueLines = new string[]
        {
            "공 : 나는 공이야. 할 말이 있어.",
            "공 : 근데 아마 TMP 한글 안구워놔서 내 말은 들리지 않을거야.",
            "Ball : Remember, use StringBuilder"
        };
    }

    // 사실 이런거 잘 리메이크하면, csv로부터 불러와서 대화집을 불러오는 방식으로 가능할 것
}
using UnityEngine;
using System.Text; // 문자열 최적화에 필요한 내용

// 모든 대화 가능한 대상들은 이걸 상속받게 한다
public abstract class TalkableBase : MonoBehaviour
{
    protected string[] dialogueLines; // 이건 상속받은 자식 객체에서 채울 예정 , 진짜 대사들이 들어갈 예정
    protected int currentLine;
    //protected string fullText = ""; // 누적된 문자열을 기억시킬 목적
    protected bool isTalking;
    protected StringBuilder sb = new StringBuilder(); // 문자열을 유연하게 해주는 객체


    // 모든 Talkable 은 Talk 메서드를 가진다
    public void Talk(DialogueManager manager)
    {
        if(!isTalking) // 대화중이지 않았다면?
        {
            isTalking = true; // 대화중으로 변경
            currentLine = 0; // 대화 현황 초기화
            sb.Clear(); // 스트링빌더에게 클리어 지시
            //fullText = ""; // 대화 문자열 초기화 (불변성 때문에 제외)
            //manager.ShowDialogue(fullText); // 매니저에게 풀 텍스트 던져주도 읽으라고 지시한다
            manager.ShowDialogue(sb.ToString());
            ShowNextLine(manager);
        }
        else // 대화 중이었다면
        {
            ShowNextLine(manager);
        }
    }

    protected virtual void ShowNextLine(DialogueManager manager)
    {
        if(currentLine < dialogueLines.Length) // 현재 보고 있는 줄이 전체 대화 내용보다 작다면?
        {
            //fullText += dialogueLines[currentLine] + "\n";
            sb.AppendLine(dialogueLines[currentLine]); // 차곡차곡 저 문자열들이 누적
            manager.ShowDialogue(sb.ToString()); // 갱신된 텍스트 띄울 목적 , 위 과정을 통해 누적된 최종 문자열을 합쳐서 한번에 출력
            currentLine++; // 현재 줄 증가
        }
        else // 대화를 다 출력했다면?
        {
            manager.HideDialogue();
            isTalking = false;
        }
    }
    


    //void Test()
    //{
    //    string s = "Hello";
    //
    //    s += " World"; // 실제로는 "Hello" + " World" 를 새로 만들어서 s에 다시 대입
    //
    //    // String immutable, 불변 객체. 한번 만든 문자열은 절대 변하지 않는다.
    //
    //    s[1] = 'e'; // 이런거 에러난다. 문자열 하나 통으로 기억하기에, 개별변경 불가능
    //}
}
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 5f;

    private void Update()
    {
        // WASD / 방향키 자동 지원
        Vector2 input = Keyboard.current != null ? new Vector2
            (
                (Keyboard.current.dKey.isPressed ? 1 : 0) - (Keyboard.current.aKey.isPressed ? 1 : 0),
                (Keyboard.current.wKey.isPressed ? 1 : 0) - (Keyboard.current.sKey.isPressed ? 1 : 0)
            )
            : Vector2.zero;

        Vector3 dir = new Vector3(input.x, 0f, input.y);
        transform.Translate(dir * moveSpeed * Time.deltaTime);
    }
}
using UnityEngine;
using TMPro;

public class DialogueManager : MonoBehaviour
{
    public GameObject dialoguePanel; // 대화창 전체 패널. 껏다켰다 할거라서 기억시킴
    public TextMeshProUGUI dialogueText; // 대화 내용 표시할 Text 컴포넌트

    // 패널 키고 대화 표시하는 메서드
    
    public void ShowDialogue(string fullText)
    {
        dialoguePanel.SetActive(true); // 대화 시작할거니까 일단 패널 켜서 UI 보여준다
        dialogueText.text = fullText; // 인자값으로 넘어온 내용을 UI 텍스트에 뿌려준다
    }

    public void HideDialogue()
    {
        dialoguePanel.SetActive(false); // 사실 텍스트야 비울 핖요 없이 그냥 패널만 꺼도 무방하다
        dialogueText.text = ""; // 혹시 모를 예외 처리
    }
}

 

'📖TIL' 카테고리의 다른 글

251230  (0) 2025.12.30
251210 Loading  (0) 2025.12.10
251210 Github Issue & Github Projects  (0) 2025.12.10
251209 CSV 파싱  (0) 2025.12.09
251208 옵저버 패턴 복습  (0) 2025.12.08
'📖TIL' 카테고리의 다른 글
  • 251230
  • 251210 Loading
  • 251210 Github Issue & Github Projects
  • 251209 CSV 파싱
DevHoChan
DevHoChan
맨땅에서 시작하는 코딩 도전
  • DevHoChan
    Debugging Life
    DevHoChan
  • 전체
    오늘
    어제
    • 분류 전체보기 (374)
      • 🕹️Game Life (1)
      • 🖥️Computer Science (5)
      • 📖TIL (141)
        • 🔥Projects (16)
        • 💡DevTips (5)
        • 🤔발생한 문제와 해결 (5)
        • 🔮Unity Graphics (5)
        • 🎤Interview (3)
        • ✅CodingTest (9)
      • 🚀Game Release (4)
      • 🧊Unity Basic (58)
        • 📌용어 사전 (1)
        • 에디터&인터페이스 (3)
        • 디버그 (1)
        • 라이프사이클 (4)
        • 게임오브젝트 (4)
        • 프리팹 (1)
        • 오브젝트풀링 (4)
        • 애트리뷰트 (2)
        • 트랜스폼 (4)
        • 물리&충돌 (1)
        • 프레임&델타타임 (4)
        • 코루틴&이벤트 (7)
        • 수학&보정함수 (3)
        • 디자인패턴 (9)
        • UGUI (3)
        • 벡터 ( Vector ) (3)
        • 씬 ( Scene ) (2)
        • 데이터 관리 (2)
      • ⭐C Sharp (99)
        • 📌용어 사전 (1)
        • 📌문법 사전 (6)
        • 메모리 관리 (3)
        • 00. 문법 (17)
        • 01. 변수 (3)
        • 02. 자료형 (2)
        • 03. 연산자 (6)
        • 04. 조건문 (2)
        • 05. 반복문 (2)
        • 06. 배열 (3)
        • 07. 메서드(함수) (7)
        • 08. 열거형 (3)
        • 09. 구조체 (2)
        • 10. 참조 (2)
        • 11. 객체 지향 (11)
        • 12. 델리게이트 (3)
        • 13. 디자인 패턴 (7)
        • 14. LINQ (1)
        • 📂▼자료구조 (2)
        • 15-1. 제네릭 (3)
        • 15-2. 배열 (4)
        • 15-3. 리스트 (2)
        • 15-4. 스택과 큐 (2)
        • 15-5. 딕셔너리 해시테이블 (2)
        • 15-6. 트리와 그래프 (3)
      • 📊Algorithm (16)
        • BigO (2)
        • 정렬 (4)
        • 셔플 (2)
        • 탐색 (6)
        • 최적화 (1)
      • 📝Game Design (16)
      • 🤖​AI Tools (12)
        • AI 리뷰 분석 (6)
        • Player2 (0)
        • 3D 모델링 (1)
        • 2D 스프라이트 (0)
        • 이미지 (2)
        • 사운드 (1)
        • 동영상 (1)
        • 문서 (1)
      • 🌍Network (6)
      • 🌱Github (11)
        • 기본 개념 (7)
        • 명령어 (1)
        • 도구 활용 (1)
      • ⚙️Visual Studio (5)
        • 🔧설치 및 환경설정 (2)
        • ⌨️HotKey (1)
        • 🚨디버깅 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    메모리관리
    c#
    유니티
    게임디자인
    기획
    gamedesign
    객체지향
    OOP
    부트캠프
    자료구조
    자료형
    게임기획
    GitHub
    디자인패턴
    til
    문법
    CodingTest
    csharp
    unity
    algorithm
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
DevHoChan
251210 StringBuilder
상단으로

티스토리툴바