using System.Collections; using UnityEngine; using UnityEngine.Networking; public class BattleManager : MonoBehaviour { [Header("전투 대상 오브젝트 연결")] public Player player; // 플레이어 캐릭터 public Enemy enemy; // 적(Enemy) 캐릭터 [Header("UI 연결 (선택 사항)")] public TMPro.TMP_InputField skillInputField; // Canvas에 배치한 텍스트 입력창 public UnityEngine.UI.Button attackButton; // Canvas에 배치한 공격 버튼 public TMPro.TextMeshProUGUI skillResultText; // 스킬 연성 결과 및 설명 출력용 텍스트 UI 추가 ⭐ private string debugInputText = "불화살을 힘차게 쏜다!"; // OnGUI 디버그용 입력 기본값 private string statusText = "스킬을 입력하여 전투를 시작하세요."; private bool isAttacking = false; private void Start() { // 씬 내의 Player와 Enemy를 지정 안 했을 경우 자동으로 검색하여 매칭합니다. if (player == null) player = FindObjectOfType(); if (enemy == null) enemy = FindObjectOfType(); // Canvas 버튼 클릭 이벤트 바인딩 if (attackButton != null) { attackButton.onClick.AddListener(OnAttackButtonClick); } } // Canvas UI의 공격 버튼을 클릭했을 때 호출되는 함수 public void OnAttackButtonClick() { if (isAttacking) return; // 버튼 클릭음 재생 if (SoundManager.Instance != null) { SoundManager.Instance.PlayButtonClick(); } string prompt = ""; if (skillInputField != null) { prompt = skillInputField.text; } if (string.IsNullOrEmpty(prompt)) { statusText = "스킬 묘사 텍스트를 입력해 주세요!"; return; } StartCoroutine(AttackFlowCoroutine(prompt)); } // AI 스킬 연성 및 턴제 상호작용(플레이어 공격 -> 피격 -> 적 반격)을 관리하는 코루틴 private IEnumerator AttackFlowCoroutine(string skillPrompt) { isAttacking = true; statusText = "AI가 스킬을 연성하는 중입니다..."; Debug.Log($"[Battle] 스킬 프롬프트 전송 시도: \"{skillPrompt}\""); // 1. FastAPI 서버의 generate-skill API 호출 (플레이어 레벨 파라미터에는 Generation 세대값 전달) string url = "http://127.0.0.1:8000/api/game/generate-skill"; int playerLevel = (player != null) ? player.Generation : 1; SkillCreateRequest requestData = new SkillCreateRequest { prompt = skillPrompt, player_level = playerLevel }; string jsonPayload = JsonUtility.ToJson(requestData); using (UnityWebRequest request = new UnityWebRequest(url, "POST")) { byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonPayload); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError) { Debug.LogError($"[Battle] 스킬 연성 실패: {request.error}"); statusText = "스킬 연성 실패 (서버 에러)"; isAttacking = false; yield break; } // 스킬 데이터 파싱 string responseText = request.downloadHandler.text; SkillCreateResponse response = JsonUtility.FromJson(responseText); statusText = $"[연성 완료] 스킬: {response.name} | 피해: {response.damage}"; Debug.Log($"[Battle] 스킬 연성 성공: {response.name} (대미지: {response.damage}) - {response.description}"); // AI가 연성한 최종 스킬 정보를 화면상 텍스트 UI에 실시간 갱신 출력합니다. if (skillResultText != null) { skillResultText.text = $"스킬 연성 성공: {response.name} (대미지: {response.damage})\n- {response.description}"; } // 2. 플레이어 공격 애니메이션 및 적 타격 처리 if (player != null && player.hp > 0) { // 플레이어 휘두르기 공격음 재생 if (SoundManager.Instance != null) { SoundManager.Instance.PlayAttackSwing(); } Animator pAnim = player.GetComponentInChildren(); if (pAnim != null) { pAnim.SetTrigger("2_Attack"); // 공격 모션 가동 } } yield return new WaitForSeconds(0.6f); // 공격 모션 타이밍 대기 if (enemy != null) { enemy.TakeDamage(response.damage); // 적에게 AI로 생성된 데미지 적용 } // 3. 적이 쓰러졌는지 확인 if (enemy != null && enemy.hp <= 0) { statusText = $"[승리] 적 {enemy.enemyName}을(를) 처치했습니다!"; isAttacking = false; yield break; } // 4. 적의 생존 시 반격 턴 개시 (1.5초 후 적이 플레이어를 공격) yield return new WaitForSeconds(1.5f); if (enemy != null && enemy.hp > 0 && player != null && player.hp > 0) { statusText = $"적 {enemy.enemyName}의 반격 차례!"; enemy.Attack(player); // 적의 플레이어 타격 실행 } yield return new WaitForSeconds(1.2f); // 피격 연출 대기 if (player != null && player.hp <= 0) { statusText = "[패배] 플레이어가 전사했습니다. 씬이 초기화됩니다."; } else { statusText = "전투 대기 중... 스킬을 입력하고 공격 버튼을 누르세요."; } isAttacking = false; } } } // ---------------------------------------------------- // JSON 연동용 API 페이로드 스키마 정의 클래스 // ---------------------------------------------------- [System.Serializable] public class SkillCreateRequest { public string prompt; public int player_level; } [System.Serializable] public class SkillCreateResponse { public string name; public int damage; public float speed; public string description; }