Wizard_Of_Wak/Assets/1_Script/Player/PlayerContoller.cs

150 lines
5.0 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 5f; // 이동 속도
public float dashDistance = 3f; // 대시 거리
public float dashCooldown = 1f; // 대시 쿨타임
public float maxSpeed = 8f; // 최대 속도 (2~3초 후 최대 속도 도달)
public float accelerationTime = 2f; // 2초 동안 가속
public float dashTime = 0.5f;
public float moveTime = 0f; // 이동한 시간
public enum PlayerState { Idle, Walking, Dash, Attack, Skill }
public PlayerState playerState;
private Vector2 moveDirection = Vector2.zero; // 현재 이동 방향
PlayerAttack playerAttack;
Animator animator;
public float idleState = 0f; // 0: 오른쪽, 0.333: 왼쪽, 0.666: 위, 1: 아래
void Start()
{
animator = GetComponentInChildren<Animator>();
playerAttack = GetComponent<PlayerAttack>();
// 키 이벤트와 스프라이트 및 회전 처리 연결
PlayManager.Instance.keySdown += () => SetMovement(Vector2.down, 1f / 3f); // 아래
PlayManager.Instance.keyWdown += () => SetMovement(Vector2.up, 2f / 3f); // 위
PlayManager.Instance.keyAdown += () => SetMovement(Vector2.left, 1f); // 왼쪽
PlayManager.Instance.keyDdown += () => SetMovement(Vector2.right, 1f); // 오른쪽
// 대시 기능
PlayManager.Instance.keySpace += Dash;
}
void Update()
{
HandleMovement(); // 이동 처리
}
// 이동 처리
void HandleMovement()
{
if (playerState == PlayerState.Dash || playerState == PlayerState.Attack || playerState == PlayerState.Skill) return;
moveDirection = Vector2.zero; // 매 프레임 초기화
if (Input.GetKey(KeyCode.A)) moveDirection += Vector2.left;
if (Input.GetKey(KeyCode.D)) moveDirection += Vector2.right;
if (Input.GetKey(KeyCode.W)) moveDirection += Vector2.up;
if (Input.GetKey(KeyCode.S)) moveDirection += Vector2.down;
// 이동 여부 판별
if (moveDirection != Vector2.zero)
{
animator.SetBool("isWalking", true);
playerState = PlayerState.Walking;
moveTime += Time.deltaTime;
// 2초 이상 이동하면 즉시 속도를 maxSpeed로 증가
float currentSpeed = HandleAcceleration();
transform.position += (Vector3)(moveDirection.normalized * currentSpeed * Time.deltaTime);
// A 또는 D가 눌린 상태라면 Side 애니메이션을 우선 적용
if (moveDirection.x != 0)
{
animator.SetFloat("PosX", 1);
animator.SetFloat("PosY", 0);
}
else
{
animator.SetFloat("PosX", 0);
animator.SetFloat("PosY", moveDirection.y);
}
// 회전 처리
if (Mathf.Abs(moveDirection.x) > 0)
{
PlayerRot(moveDirection);
}
}
else
{
// 이동하지 않으면 Idle 상태를 설정
moveTime = 0f;
animator.SetBool("isWalking", false);
animator.SetFloat("PosX", 0);
animator.SetFloat("PosY", 0);
animator.SetFloat("idleState", idleState);
}
}
private void PlayerRot(Vector2 direction)
{
if (direction.x < 0 && transform.GetChild(0).localEulerAngles.y != 180)
{
transform.GetChild(0).localEulerAngles = new Vector3(0, 180, 0);
}
else if (direction.x > 0 && transform.GetChild(0).localEulerAngles.y != 0)
{
transform.GetChild(0).localEulerAngles = new Vector3(0, 0, 0);
}
}
float HandleAcceleration()
{
if (playerState == PlayerState.Walking)
{
moveTime += Time.deltaTime;
if (moveTime >= accelerationTime)
{
return maxSpeed; // 2초 이상 이동 시 가속
}
}
return moveSpeed; // 기본 속도
}
// 대시 처리
void Dash()
{
if (playerState != PlayerState.Dash)
{
playerState = PlayerState.Dash;
animator.SetTrigger("DodgeTrigger");
playerAttack.AttackInitialized();
moveTime = 0f;
StartCoroutine(DashCoroutine()); // 대시 시작
}
}
IEnumerator DashCoroutine()
{
Vector3 startPosition = transform.position;
Vector3 targetPosition = startPosition + (Vector3)(moveDirection.normalized * dashDistance);
float elapsedTime = 0f;
while (elapsedTime < dashTime)
{
transform.position = Vector3.Lerp(startPosition, targetPosition, elapsedTime / dashTime);
elapsedTime += Time.deltaTime;
yield return null;
}
transform.position = targetPosition;
playerState = PlayerState.Idle;
}
// 이동 방향과 스프라이트, 회전 처리
void SetMovement(Vector2 direction, float idleStateValue)
{
moveDirection = direction;
idleState = idleStateValue;
}
}