코딩의 신 57

김동관·2025년 12월 22일

오늘 한 일

Unity 튜토리얼 시스템 설계 & 대화 연동 정리

작업 목표

게임 시작 후 NPC와의 첫 대화가 끝나면 자연스럽게 튜토리얼로 이어지도록
이동 / 미니맵 조작을 단계적으로 안내하는 시스템을 구현했다.

단순히 텍스트로 설명하는 튜토리얼이 아니라,

  • 플레이어가 실제로 조작해야 다음 단계로 넘어가는 구조를 목표로 설계했다.
눈 뜸 연출
 → NPC와 대화
   → 대화 종료
     → 튜토리얼 시작
       1. 이동 (WASD / 방향키)
       2. 미니맵 열기 (M 키)
       3. 튜토리얼 종료 (자유 플레이)

튜토리얼 단계 관리 – enum 사용

튜토리얼의 현재 진행 상태를 명확하게 관리하기 위해
enum을 사용해 단계별 흐름을 정의했다.

public enum TutorialStep
{
    None,
    Move,
    OpenMap,
    End
}

사용 이유

숫자(int) 대신 의미가 보이는 이름으로 단계 관리

코드 가독성 및 유지보수성 향상

switch 문으로 단계별 입력 체크가 쉬워짐

TutorialManager 설계

튜토리얼 전체 흐름을 담당하는 TutorialManager를 별도로 생성했다.

핵심 역할

현재 튜토리얼 단계 관리

단계별 UI 문구 변경

플레이어 입력 감지

튜토리얼 종료 처리

public class TutorialManager : MonoBehaviour
{
    public static TutorialManager Instance;

    [SerializeField] private GameObject tutorialUI;
    [SerializeField] private TextMeshProUGUI tutorialText;

    private TutorialStep currentStep = TutorialStep.None;
    private bool tutorialStarted = false;

    private void Awake()
    {
        Instance = this;
    }

    public void StartTutorial()
    {
        if (tutorialStarted) return;

        tutorialStarted = true;
        tutorialUI.SetActive(true);
        SetStep(TutorialStep.Move);
    }

    private void Update()
    {
        switch (currentStep)
        {
            case TutorialStep.Move:
                if (Input.GetAxisRaw("Horizontal") != 0 ||
                    Input.GetAxisRaw("Vertical") != 0)
                {
                    SetStep(TutorialStep.OpenMap);
                }
                break;

            case TutorialStep.OpenMap:
                if (Input.GetKeyDown(KeyCode.M))
                {
                    SetStep(TutorialStep.End);
                }
                break;
        }
    }

    private void SetStep(TutorialStep step)
    {
        currentStep = step;

        switch (step)
        {
            case TutorialStep.Move:
                tutorialText.text = "W A S D 또는 방향키로 이동해 보세요";
                break;

            case TutorialStep.OpenMap:
                tutorialText.text = "M 키를 눌러 지도를 열어보세요";
                break;

            case TutorialStep.End:
                tutorialUI.SetActive(false);
                currentStep = TutorialStep.None;
                break;
        }
    }
}

대화 시스템과 튜토리얼 연결

이미 구현되어 있던 DialogueManager의
대화 종료 시점(EndDialogue)에 튜토리얼을 연결했다.

DialogueManager 일부 코드

private void EndDialogue()
{
    IsDialogueActive = false;

    dialogueText.text = "";
    dialogueText.gameObject.SetActive(false);
    dialogueCanvas.SetActive(false);

    if (playerMovement != null)
        playerMovement.enabled = true;

    if (dialogueCamera != null)
        dialogueCamera.EndDialogueCamera();

    if (npcFaceController != null)
        npcFaceController.StopLook();

    onDialogueEnd?.Invoke();
    onDialogueEnd = null;

    // 튜토리얼 시작
    if (TutorialManager.Instance != null)
        TutorialManager.Instance.StartTutorial();
}

이 위치가 좋은 이유

대사 UI가 완전히 종료된 상태

플레이어 조작이 다시 가능해진 시점

카메라, NPC 시선 연출 종료 후 자연스럽게 튜토리얼 진입 가능

profile
아이디어 뱅크

0개의 댓글