Files
Project-AI-Chronicle/unity-client/Assets/Scripts/PlayerMove.cs
T

228 lines
6.4 KiB
C#

using UnityEngine;
public struct Inputs
{
public Vector2 PlayerMove;
}
public class InputContoller
{
public static void UpdateInput(ref Inputs input)
{
input.PlayerMove.x = Input.GetAxisRaw("Horizontal");
input.PlayerMove.y = Input.GetAxisRaw("Vertical");
}
}
public class PlayerMove : MonoBehaviour
{
// 컴포넌트 프로퍼티
public Rigidbody2D rb { get; private set; }
// SPUM_Prefabs를 가져옵니다.
private SPUM_Prefabs spumPrefab;
private float maxSpeed;
private Inputs _inputs;
public Inputs Inputse => _inputs;
// 이동 관련 변수
[SerializeField] private float speed = 5f;
[SerializeField] public int hp = 5;
private int maxHp;
private bool isFacingRight = false;
private int currentAnimationState = -1;
private Animator animator;
void Awake()
{
// 1. Rigidbody2D 할당
rb = GetComponent<Rigidbody2D>();
// 2. 부모 오브젝트에 붙어 있는 SPUM_Prefabs를 가져옵니다.
spumPrefab = GetComponentInParent<SPUM_Prefabs>();
if (spumPrefab == null)
{
Debug.LogError($"{gameObject.name} 오브젝트에 SPUM_Prefabs 컴포넌트가 없습니다! 인스펙터를 확인하세요.");
}
// 캐릭터 방향 기본 오른쪽 설정
Vector3 initialScale = transform.localScale;
initialScale.x = Mathf.Abs(initialScale.x);
transform.localScale = initialScale;
animator = GetComponentInChildren<Animator>();
maxHp = hp;
}
private void Update()
{
if (hp <= 0)
{
if (animator != null)
{
animator.SetBool("1_Move", false);
}
return;
}
InputContoller.UpdateInput(ref _inputs);
// 좌우 방향 전환 (Flip)
if (_inputs.PlayerMove.x < 0f && isFacingRight)
{
Flip();
}
else if (_inputs.PlayerMove.x > 0f && !isFacingRight)
{
Flip();
}
// 애니메이션 업데이트 호출
if (_inputs.PlayerMove.x != 0f || _inputs.PlayerMove.y != 0f)
{
animator.SetBool("1_Move", true);
}
else
{
animator.SetBool("1_Move", false);
}
if (Input.GetKeyDown(KeyCode.Z))
{
animator.SetTrigger("2_Attack");
}
}
void FixedUpdate()
{
Move();
}
private void Move()
{
if (rb == null) return;
if (hp <= 0)
{
rb.linearVelocity = new Vector2(0f, rb.linearVelocity.y);
return;
}
rb.linearVelocity = new Vector2(_inputs.PlayerMove.x * speed, rb.linearVelocity.y);
}
private void Flip()
{
isFacingRight = !isFacingRight;
Vector3 scale = transform.localScale;
scale.x *= -1f;
transform.localScale = scale;
}
// 데미지를 입는 메서드
public void TakeDamage(int damage, string attackerName = "알 수 없는 위험")
{
if (hp <= 0) return; // 이미 사망한 경우 제외
hp -= damage;
if (hp < 0) hp = 0;
Debug.Log($"플레이어가 {attackerName}로부터 {damage} 데미지를 입었습니다. 현재 체력: {hp}");
if (animator != null)
{
if (hp <= 0)
{
animator.SetTrigger("4_Death");
Debug.Log($"플레이어가 {attackerName}에 의해 사망했습니다.");
StartCoroutine(SendDeathReport(attackerName));
}
else
{
animator.SetTrigger("3_Damaged");
}
}
}
// 인스펙터 우클릭 메뉴에서 데미지를 테스트할 수 있는 기능 추가
[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}로 회복되었습니다.");
}
// 임시 디버그용 화면 버튼 (게임 실행 시 화면 좌측 상단에 뜸)
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();
}
}
// 백엔드로 사망 원인을 전송하는 코루틴
private System.Collections.IEnumerator SendDeathReport(string cause)
{
string url = "http://127.0.0.1:8000/api/game/death";
DeathRecordRequest requestData = new DeathRecordRequest { cause_of_death = cause };
string json = JsonUtility.ToJson(requestData);
using (UnityEngine.Networking.UnityWebRequest request = new UnityEngine.Networking.UnityWebRequest(url, "POST"))
{
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(json);
request.uploadHandler = new UnityEngine.Networking.UploadHandlerRaw(bodyRaw);
request.downloadHandler = new UnityEngine.Networking.DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if (request.result == UnityEngine.Networking.UnityWebRequest.Result.ConnectionError ||
request.result == UnityEngine.Networking.UnityWebRequest.Result.ProtocolError)
{
Debug.LogError("사망 기록 전송 실패: " + request.error);
}
else
{
Debug.Log("사망 기록 전송 성공: " + request.downloadHandler.text);
}
}
}
}
// JSON 파싱용 요청 스키마 객체
[System.Serializable]
public class DeathRecordRequest
{
public string cause_of_death;
}