1. 조이스틱 동작
1.1. 플레이어 컨트롤러 연동
1.2. 자연스러운 방향 전환 추가
2. 베이스씬 작업
2.1. 게임 씬 추가
2.2. 조이스틱 UI 추가
Todo
1. 카메라를 캐릭터한테 붙이기
2. 다른 UI 작업도 추가하기
3. 몬스터 AI 작업도 할 수 있으면 해보기
264 lines
7.2 KiB
C#
264 lines
7.2 KiB
C#
using System;
|
|
using Animation;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
using UnityEngine.InputSystem;
|
|
|
|
public partial class PlayerController : MonoBehaviour
|
|
{
|
|
private AnimatorManager<AnimatorParam> _mAnimator;
|
|
private NavMeshAgent _agent;
|
|
|
|
private Status_Player _status;
|
|
private Vector2 _screenPos;
|
|
|
|
private Vector3 _currentVelocity;
|
|
private Vector3 _velocitySmoothDampRef;
|
|
|
|
[SerializeField] private float _rotationSpeed = 10f;
|
|
|
|
// --- Enum 정의 ---
|
|
enum AnimatorParam
|
|
{
|
|
speed,
|
|
atk_speed,
|
|
attack,
|
|
run,
|
|
}
|
|
|
|
enum PlayerBehavior
|
|
{
|
|
Idle,
|
|
Move,
|
|
Attack,
|
|
Die
|
|
}
|
|
|
|
private PlayerBehavior _behavior = PlayerBehavior.Idle;
|
|
private PlayerBehavior Behavior
|
|
{
|
|
get { return _behavior; }
|
|
set
|
|
{
|
|
_behavior = value;
|
|
switch (_behavior)
|
|
{
|
|
case PlayerBehavior.Die:
|
|
case PlayerBehavior.Idle:
|
|
_mAnimator.SetValue(AnimatorParam.speed, 0);
|
|
break;
|
|
case PlayerBehavior.Move:
|
|
_mAnimator.SetValue(AnimatorParam.attack, false);
|
|
break;
|
|
case PlayerBehavior.Attack:
|
|
_mAnimator.SetValue(AnimatorParam.attack, true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- 초기화 ---
|
|
private void Awake()
|
|
{
|
|
_mAnimator = new AnimatorManager<AnimatorParam>(GetComponent<Animator>());
|
|
_agent = gameObject.GetComponent<NavMeshAgent>();
|
|
_status = gameObject.GetComponent<Status_Player>();
|
|
_currentVelocity = Vector3.zero;
|
|
if(_agent != null) _agent.updateRotation = false;
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
|
|
Manager.Input.MoveAction -= OnMove;
|
|
Manager.Input.MoveAction += OnMove;
|
|
|
|
SetAnimator();
|
|
}
|
|
|
|
void SetAnimator()
|
|
{
|
|
if (_status != null)
|
|
{
|
|
_mAnimator.SetValue(AnimatorParam.atk_speed, _status.AtkSpeed);
|
|
}
|
|
}
|
|
|
|
// --- 매 프레임 실행 ---
|
|
void Update()
|
|
{
|
|
// if (_agent != null && _movement != null) _mAnimator.SetValue(AnimatorParam.speed, _movement.GetCurrentSpeed());
|
|
//
|
|
// if (_behavior == PlayerBehavior.Move)
|
|
// {
|
|
// if (!_movement.IsMoving()) Behavior = PlayerBehavior.Idle;
|
|
// else _mAnimator.SetValue(AnimatorParam.speed, _movement.GetCurrentSpeed());
|
|
// }
|
|
}
|
|
|
|
void OnInput(Define.InputEvent evt)
|
|
{
|
|
switch (evt)
|
|
{
|
|
case Define.InputEvent.Click:
|
|
break;
|
|
case Define.InputEvent.Down:
|
|
break;
|
|
case Define.InputEvent.Up:
|
|
break;
|
|
case Define.InputEvent.Press:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void OnMove(Vector2 direction)
|
|
{
|
|
float magnitude = direction.magnitude;
|
|
bool isRun = direction.magnitude > 0.6f ? true : false;
|
|
float speed = 0f; //isRun ? _status.MoveSpeed * 2.0f : _status.MoveSpeed;
|
|
|
|
// 입력이 거의 없을 때 (Deadzone 처리)
|
|
if (magnitude < 0.1f) speed = 0f;
|
|
// 걷기 구간일 때
|
|
else if (magnitude <= 0.6f) speed = Mathf.Lerp(0, _status.MoveSpeed, (magnitude/0.6f));
|
|
// 달리기 구간일 때
|
|
else
|
|
{
|
|
float runPercentage = (magnitude - 0.6f) / (1.0f - 0.6f);
|
|
speed = Mathf.Lerp(_status.MoveSpeed, _status.MoveSpeed*2.0f, runPercentage);
|
|
}
|
|
_agent.speed = speed;
|
|
|
|
_mAnimator.SetValue(AnimatorParam.run, isRun);
|
|
_mAnimator.SetValue(AnimatorParam.speed , speed);
|
|
if (direction == Vector2.zero)
|
|
{
|
|
if (_agent != null)
|
|
{
|
|
_agent.velocity = _currentVelocity;
|
|
_agent.isStopped = true;
|
|
}
|
|
return;
|
|
}
|
|
|
|
Vector3 camForward = Camera.main.transform.forward;
|
|
Vector3 camRight = Camera.main.transform.right;
|
|
|
|
camForward.y = 0;
|
|
camRight.y = 0;
|
|
camForward.Normalize();
|
|
camRight.Normalize();
|
|
Vector3 moveDir = (camForward * direction.y + camRight * direction.x).normalized;
|
|
// transform.rotation = Quaternion.LookRotation(moveDir);
|
|
if (moveDir != Vector3.zero)
|
|
{
|
|
Quaternion targetRotation = Quaternion.LookRotation(moveDir);
|
|
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, _rotationSpeed * Time.deltaTime);
|
|
}
|
|
|
|
if (_agent != null && _status != null)
|
|
{
|
|
_agent.isStopped = false;
|
|
|
|
// _agent.velocity = moveDir * speed;
|
|
_agent.velocity = transform.forward * direction.magnitude * speed;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private void OnDestroy()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
// void MoveCharacter(Define.InputEvent evt)
|
|
// {
|
|
// if(Behavior == PlayerBehavior.Die) return;
|
|
//
|
|
// Vector3 destination = MeasureDestination();
|
|
//
|
|
// switch (evt)
|
|
// {
|
|
// case Define.InputEvent.Click:
|
|
// case Define.InputEvent.Down:
|
|
// _movement.SetDestination(destination);
|
|
// Behavior = PlayerBehavior.Move;
|
|
// break;
|
|
// case Define.InputEvent.Press:
|
|
// if (Behavior == PlayerBehavior.Move) _movement.SetDestination(destination);
|
|
// break;
|
|
// }
|
|
// }
|
|
//
|
|
// Vector3 MeasureDestination()
|
|
// {
|
|
// RaycastHit hit;
|
|
// Ray ray = Camera.main.ScreenPointToRay(_screenPos);
|
|
//
|
|
// int layerMask = LayerMask.GetMask("Ground");
|
|
// if (!Physics.Raycast(ray, out hit, 100.0f, layerMask))
|
|
// return Vector3.zero;
|
|
//
|
|
// return hit.point;
|
|
// }
|
|
//
|
|
// void OnPoint(Vector2 point)
|
|
// {
|
|
// _screenPos = point;
|
|
// }
|
|
|
|
//
|
|
// void OnMouseClicked(Define.MouseEvent evt)
|
|
// {
|
|
// if (Behavior == PlayerBehavior.Die) return;
|
|
//
|
|
// RaycastHit hit;
|
|
// Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
|
|
//
|
|
// int layerMask = LayerMask.GetMask("Ground");
|
|
// if (!Physics.Raycast(ray, out hit, 100.0f, layerMask))
|
|
// return;
|
|
//
|
|
// _destPos = hit.point;
|
|
//
|
|
// switch (evt)
|
|
// {
|
|
// case Define.MouseEvent.Click:
|
|
// case Define.MouseEvent.Down:
|
|
// _movement.SetDestination(_destPos);
|
|
// Behavior = PlayerBehavior.Move;
|
|
// break;
|
|
// case Define.MouseEvent.Press:
|
|
// if (Behavior == PlayerBehavior.Move) _movement.SetDestination(_destPos);
|
|
// break;
|
|
// }
|
|
// }
|
|
//
|
|
// void OnKeyboardInput()
|
|
// {
|
|
// // 키보드 입력이 필요할 경우 여기에 로직 구현
|
|
// }
|
|
}
|
|
|
|
// 애니메이션의 이벤트 함수 확인 부분 - 후에 따로 뺄 것
|
|
public partial class PlayerController {
|
|
public void Hit()
|
|
{
|
|
_mAnimator.SetValue(AnimatorParam.attack, false);
|
|
Debug.Log("Knight Hit!");
|
|
}
|
|
|
|
public void FootR()
|
|
{
|
|
|
|
}
|
|
|
|
public void FootL()
|
|
{
|
|
|
|
}
|
|
|
|
}
|