using System.Collections; using UnityEngine; using UnityEngine.Networking; public class NPCDialogueManager : MonoBehaviour { private string lastDialogueText = "대화 버튼을 눌러 조언을 얻으세요."; private string targetDialogueText = ""; // 목표 대사 텍스트 private Coroutine typingCoroutine; // 타이핑 코루틴 제어용 // NPC 대화를 요청하는 메서드 public void RequestNPCDialogue(int currentGeneration) { StartCoroutine(FetchNPCDialogue(currentGeneration)); } private IEnumerator FetchNPCDialogue(int currentGeneration) { // 1. 대기 연출: 요청 즉시 로딩중 텍스트를 띄워 렉처럼 보이지 않게 합니다. if (typingCoroutine != null) { StopCoroutine(typingCoroutine); } lastDialogueText = "늙은 문지기 발두르가 눈을 지그시 감고 네 선조들의 최후를 떠올리는 중입니다..."; // FastAPI의 NPC 대화 조회 엔드포인트 URL 구성 string url = $"http://127.0.0.1:8000/api/game/npc-dialogue?current_generation={currentGeneration}"; Debug.Log($"[Dialogue] NPC 대사 조회 요청 전송: {url}"); using (UnityWebRequest request = UnityWebRequest.Get(url)) { yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError) { Debug.LogError($"[Dialogue] NPC 대사 조회 실패: {request.error}"); lastDialogueText = "문지기 발두르가 침묵하고 있습니다. (서버 연결 실패)"; } else { try { string json = request.downloadHandler.text; DialogueResponse response = JsonUtility.FromJson(json); targetDialogueText = response.dialogue; Debug.Log($"[Dialogue] 문지기 대사 수신 성공:\n{targetDialogueText}"); // 2. 타자기 연출(Typewriter) 코루틴 시작 typingCoroutine = StartCoroutine(TypeTextEffect(targetDialogueText)); } catch (System.Exception ex) { Debug.LogError($"[Dialogue] JSON 파싱 에러: {ex.Message}"); lastDialogueText = "문지기의 말을 이해할 수 없습니다. (데이터 파싱 오류)"; } } } } // 한 글자씩 부드럽게 출력해주는 타자기 효과 코루틴 private IEnumerator TypeTextEffect(string fullText) { lastDialogueText = ""; // 문지기가 고민하면서 한 글자씩 읊조리는 속도 (0.04초 간격) float letterDelay = 0.04f; foreach (char letter in fullText.ToCharArray()) { lastDialogueText += letter; // 쉼표(,)나 마침표(.) 등 문장이 끊기는 지점에서는 살짝 더 더듬는 효과(딜레이 추가) 제공 if (letter == ',' || letter == '.') { yield return new WaitForSeconds(letterDelay * 4f); } else { yield return new WaitForSeconds(letterDelay); } } typingCoroutine = null; } // 디버그용 임시 GUI 버튼 및 대사 출력창 private void OnGUI() { GUI.backgroundColor = Color.yellow; // NPC 대화 요청 버튼 (화면 우측 상단 배치) if (GUI.Button(new Rect(Screen.width - 240, 10, 220, 50), "Debug: Get NPC Dialogue")) { // 플레이어 오브젝트를 찾아 현재 세대 값을 가져옵니다. Player player = FindObjectOfType(); if (player != null) { RequestNPCDialogue(player.Generation); } else { RequestNPCDialogue(1); } } // 대사 출력 박스 배경 및 텍스트 렌더링 GUI.color = Color.white; GUI.Box(new Rect(Screen.width - 450, 70, 430, 120), "늙은 문지기 '발두르'의 조언"); GUIStyle dialogueStyle = new GUIStyle(GUI.skin.label); dialogueStyle.wordWrap = true; dialogueStyle.fontSize = 14; GUI.Label(new Rect(Screen.width - 440, 95, 410, 90), lastDialogueText, dialogueStyle); } } // JSON 파싱용 Dialogue 응답 매핑 클래스 [System.Serializable] public class DialogueResponse { public string dialogue; }