디버그 기능 제거

This commit is contained in:
김민구
2026-07-08 05:13:08 +09:00
parent 5a453cc9aa
commit b70634ddca
8 changed files with 843 additions and 82 deletions
@@ -0,0 +1,163 @@
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에 배치한 공격 버튼
private string debugInputText = "불화살을 힘차게 쏜다!"; // OnGUI 디버그용 입력 기본값
private string statusText = "스킬을 입력하여 전투를 시작하세요.";
private bool isAttacking = false;
private void Start()
{
// 씬 내의 Player와 Enemy를 지정 안 했을 경우 자동으로 검색하여 매칭합니다.
if (player == null) player = FindObjectOfType<Player>();
if (enemy == null) enemy = FindObjectOfType<Enemy>();
// Canvas 버튼 클릭 이벤트 바인딩
if (attackButton != null)
{
attackButton.onClick.AddListener(OnAttackButtonClick);
}
}
// Canvas UI의 공격 버튼을 클릭했을 때 호출되는 함수
public void OnAttackButtonClick()
{
if (isAttacking) return;
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<SkillCreateResponse>(responseText);
statusText = $"[연성 완료] 스킬: {response.name} | 피해: {response.damage}";
Debug.Log($"[Battle] 스킬 연성 성공: {response.name} (대미지: {response.damage}) - {response.description}");
// 2. 플레이어 공격 애니메이션 및 적 타격 처리
if (player != null && player.hp > 0)
{
Animator pAnim = player.GetComponentInChildren<Animator>();
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;
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 33720e9c809ea4966a8848c5535d3f20
+97
View File
@@ -0,0 +1,97 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class Enemy : MonoBehaviour
{
[Header("적 스탯 설정")]
public string enemyName = "고블린 왕";
public int hp = 30;
public int maxHp = 30;
public int attackPower = 2; // 플레이어를 공격할 때의 기본 데미지 수치
[Header("UI 연결")]
public TextMeshProUGUI nameText; // 적 이름 표시 TMP
public Image hpImage; // 적 체력바 이미지
private Animator animator;
private void Start()
{
maxHp = hp;
// 자식 오브젝트의 애니메이터(SPUM 리소스 구조)를 획득합니다.
animator = GetComponentInChildren<Animator>();
// 적 캐릭터의 기본 방향을 플레이어를 바라보도록 좌측(스케일 양수)으로 정렬합니다.
Vector3 initialScale = transform.localScale;
initialScale.x = Mathf.Abs(initialScale.x);
transform.localScale = initialScale;
// 시작 시 적 이름을 UI 텍스트에 연동합니다.
if (nameText != null)
{
nameText.text = enemyName;
}
}
private void Update()
{
// 안전 조치: maxHp가 비정상(0 이하)이거나 현재 체력이 초과된 경우 자동 동기화
if (maxHp <= 0 || hp > maxHp)
{
maxHp = hp;
}
// 플레이어와 동일하게 Simple/Filled 이미지 방식 모두 가로가 정상 감축되도록 이중 연동합니다.
if (hpImage != null && maxHp > 0)
{
float fillRatio = Mathf.Clamp01((float)hp / maxHp);
hpImage.fillAmount = fillRatio;
hpImage.rectTransform.localScale = new Vector3(fillRatio, 1f, 1f);
}
}
// 플레이어의 공격을 받아 데미지를 입는 메서드
public void TakeDamage(int damage)
{
if (hp <= 0) return; // 이미 죽은 경우 무시
hp -= damage;
if (hp < 0) hp = 0;
Debug.Log($"[Enemy] 적 {enemyName}이(가) {damage} 피해를 입었습니다. 현재 체력: {hp}/{maxHp}");
if (animator != null)
{
if (hp <= 0)
{
// SPUM 리소스 기준 사망(4_Death) 트리거 작동
animator.SetTrigger("4_Death");
Debug.Log($"[Enemy] 적 {enemyName}이(가) 사망하였습니다.");
}
else
{
// SPUM 리소스 기준 피격(3_Damaged) 트리거 작동
animator.SetTrigger("3_Damaged");
}
}
}
// 플레이어를 반격 공격하는 메서드
public void Attack(Player player)
{
if (hp <= 0 || player == null) return;
Debug.Log($"[Enemy] 적 {enemyName}이(가) 플레이어를 공격합니다! (데미지: {attackPower})");
if (animator != null)
{
// SPUM 리소스 기준 공격(2_Attack) 트리거 작동
animator.SetTrigger("2_Attack");
}
// 플레이어 체력 차감 전송
player.TakeDamage(attackPower, enemyName);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0c1488b68fb3e4031a2f0e33d3b95cb5
@@ -39,4 +39,14 @@ public class GameManager : MonoBehaviour
Debug.Log($"[GameManager] 캐릭터 정보 보존 세이브 완료: {playerName} ({playerGeneration}대) | HP: {playerHp}/{playerMaxHp}");
}
}
// 플레이어 보존 세션을 리셋하는 메서드 (사망 시 호출)
public void ClearPlayerData()
{
playerName = "";
playerGeneration = 1;
playerHp = 5;
playerMaxHp = 5;
Debug.Log("[GameManager] 보존된 이전 플레이어 스탯 데이터를 비웠습니다. (신규 세대 생성 준비 완료)");
}
}
@@ -141,34 +141,5 @@ public class NPCDialogueManager : MonoBehaviour
typingCoroutine = null;
}
// 디버그용 임시 OnGUI 버튼
private void OnGUI()
{
GUI.backgroundColor = Color.yellow;
if (GUI.Button(new Rect(Screen.width - 240, 10, 220, 50), "Debug: Get NPC Dialogue"))
{
Player player = FindObjectOfType<Player>();
if (player != null)
{
RequestNPCDialogue(player.Generation);
}
else
{
RequestNPCDialogue(1);
}
}
if (dialoguePanel != null && dialoguePanel.activeSelf)
{
GUI.color = Color.white;
GUI.Box(new Rect(Screen.width - 450, 70, 430, 120), "늙은 문지기 '발두르'의 조언 (Debug)");
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);
}
}
}
+15 -51
View File
@@ -217,56 +217,7 @@ public class Player : MonoBehaviour
}
}
// 인스펙터 우클릭 메뉴에서 데미지를 테스트할 수 있는 기능 추가
[ContextMenu("Debug/Take 5 Damage")]
public void DebugTake5Damage()
{
TakeDamage(5, "인스펙터 디버그 공격");
}
[ContextMenu("Debug/Restore HP")]
public void DebugRestoreHP()
{
hp = maxHp;
if (animator != null)
{
animator.Rebind();
animator.Update(0f);
}
Debug.Log($"플레이어 체력이 {hp}로 회복되었습니다.");
// 체력 복구 시 다음 캐릭터 이름 및 세대 정보 갱신
StartCoroutine(GetNextGenerationFromServer());
}
// 임시 디버그용 화면 버튼 (게임 실행 시 화면 좌측 상단에 뜸)
private void OnGUI()
{
GUI.backgroundColor = Color.red;
if (GUI.Button(new Rect(10, 10, 180, 50), "Debug: Take 5 Damage (Trap)"))
{
TakeDamage(5, "테스트 함정");
}
GUI.backgroundColor = Color.blue;
// 기존 겹쳐있던 위치(10, 10)를 피해 y 좌표를 130으로 내렸습니다.
if (GUI.Button(new Rect(10, 130, 180, 50), "Debug: Take 3 Damage (Monster)"))
{
TakeDamage(3, "테스트 몬스터");
}
GUI.backgroundColor = Color.green;
if (GUI.Button(new Rect(10, 70, 180, 50), "Debug: Restore HP"))
{
DebugRestoreHP();
}
// 캐릭터 정보 UI 노출
GUI.color = Color.white;
GUI.skin.label.fontSize = 16;
GUI.Label(new Rect(10, 200, 400, 30), $"이름: {characterName}");
GUI.Label(new Rect(10, 230, 400, 30), $"세대: {generation}대손");
}
// 백엔드로부터 다음 세대 번호를 받아와 랜덤 이름과 매핑하는 코루틴
private System.Collections.IEnumerator GetNextGenerationFromServer()
@@ -343,9 +294,22 @@ public class Player : MonoBehaviour
else
{
Debug.Log("사망 기록 전송 성공: " + request.downloadHandler.text);
// 사망 전송 성공 즉시 다음 세대 정보 받아와 자동 갱신
StartCoroutine(GetNextGenerationFromServer());
}
// 1. 싱글톤 GameManager의 이전 캐릭터 정보 데이터 초기화 (신규 세대 생성 유도)
if (GameManager.Instance != null)
{
GameManager.Instance.ClearPlayerData();
}
// 2. 플레이어 사망 연출(2초 누워있기) 대기 후 로비 씬으로 씬 전환 실행
yield return new WaitForSeconds(2.0f);
Debug.Log("[Death Report] 로비 씬(Lobby)으로 되돌아갑니다.");
// 사망 연출이 종료되었으므로 플레이어 게임 오브젝트를 씬에서 완전히 파괴합니다.
Destroy(gameObject);
UnityEngine.SceneManagement.SceneManager.LoadScene("Lobby");
}
}
}