261 lines
8.9 KiB
C#
261 lines
8.9 KiB
C#
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
|
|
public class PlayerController : MonoBehaviour
|
|
{
|
|
private PlayerStatus _status;
|
|
private Vector3 _destPos;
|
|
|
|
|
|
public enum PlayerState
|
|
{
|
|
Idle,
|
|
Move,
|
|
Die,
|
|
Skill,
|
|
}
|
|
|
|
[SerializeField]
|
|
PlayerState _playerState = PlayerState.Idle;
|
|
|
|
public PlayerState State
|
|
{
|
|
get
|
|
{
|
|
return _playerState;
|
|
}
|
|
set
|
|
{
|
|
_playerState = value;
|
|
Animator anim = GetComponent<Animator>();
|
|
switch (_playerState)
|
|
{
|
|
case PlayerState.Die:
|
|
anim.SetBool("attack", false);
|
|
break;
|
|
case PlayerState.Idle:
|
|
anim.SetFloat("speed", 0);
|
|
anim.SetBool("attack", false);
|
|
break;
|
|
case PlayerState.Move:
|
|
anim.SetFloat("speed", _status.MoveSpeed);
|
|
anim.SetBool("attack", false);
|
|
break;
|
|
case PlayerState.Skill:
|
|
anim.SetBool("attack", true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
|
|
_status = gameObject.GetComponent<PlayerStatus>();
|
|
|
|
Managers.Input.MouseAction -= OnMouseEvent;
|
|
Managers.Input.MouseAction += OnMouseEvent;
|
|
}
|
|
|
|
|
|
|
|
void UpdateIdle()
|
|
{
|
|
// 애니메이션 처리
|
|
// wait_run_ratio = Mathf.Lerp(wait_run_ratio, 0.0f, 8.0f * Time.deltaTime);
|
|
// Animator anim = GetComponent<Animator>();
|
|
// anim.SetFloat("speed", 0);
|
|
}
|
|
|
|
void UpdateMove()
|
|
{
|
|
// 몬스터가 내 사정거리보다 가까우면 공격
|
|
if(_lockTarget != null)
|
|
{
|
|
float dist = (_destPos- transform.position).magnitude;
|
|
if(dist <= 1.0f)
|
|
{
|
|
State = PlayerState.Skill;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 일반 이동
|
|
Vector3 dir = _destPos - transform.position;
|
|
|
|
// 이게 transform.position에 직접 넣을때는 정확도가 좀 높아서 0.001 도 가능했는데 지금은 Move로 간접적인 이동이라서 0.1 정도로 그 정확도를 좀 낮출 필요가 있다.
|
|
if (dir.magnitude < 0.1f)
|
|
{
|
|
State = PlayerState.Idle;
|
|
}
|
|
else
|
|
{
|
|
NavMeshAgent navMesh = gameObject.GetOrAddComponent<NavMeshAgent>();
|
|
|
|
float moveDist = Mathf.Clamp(_status.MoveSpeed * Time.deltaTime, 0, dir.magnitude);
|
|
|
|
// navMesh.CalculatePath()
|
|
navMesh.Move(dir.normalized * moveDist);
|
|
|
|
// 이게 앞을 막을 경우 계속 움직이는 모션이 아니라 그 앞에서 멈추게 하기 위해서
|
|
Debug.DrawRay(transform.position + Vector3.up * 0.5f, dir.normalized * 1.0f, Color.green, 1.0f);
|
|
// Debug.DrawRay(transform.position, ray.direction * 100.0f, Color.blue, 1.0f);
|
|
if(Physics.Raycast(transform.position + Vector3.up * 0.5f , dir, 1.0f, LayerMask.GetMask("Block")))
|
|
{
|
|
if(Input.GetMouseButton(0) == false)
|
|
State = PlayerState.Idle;
|
|
return;
|
|
}
|
|
|
|
// transform.position += dir.normalized * moveDist;
|
|
|
|
// 그래서 이렇게 부드럽게 회전
|
|
Vector3 targetDir = new Vector3(dir.x, 0, dir.z).normalized;
|
|
if (targetDir != Vector3.zero)
|
|
{
|
|
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetDir), 0.15f);
|
|
}
|
|
}
|
|
|
|
// 애니메이션 처리
|
|
// wait_run_ratio = Mathf.Lerp(wait_run_ratio, 1.0f, 8.0f * Time.deltaTime);
|
|
// Animator anim = GetComponent<Animator>();
|
|
// anim.SetFloat("speed", _status.MoveSpeed);
|
|
}
|
|
|
|
void UpdateSkill()
|
|
{
|
|
// Animator anim = GetComponent<Animator>();
|
|
// anim.SetBool("attack", true);
|
|
}
|
|
|
|
void OnHitEvent()
|
|
{
|
|
// Animator anim = GetComponent<Animator>();
|
|
// anim.SetBool("attack", false);
|
|
State = PlayerState.Idle;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
// UpdateMouseCursor();
|
|
switch (State)
|
|
{
|
|
case PlayerState.Die:
|
|
break;
|
|
case PlayerState.Idle:
|
|
UpdateIdle();
|
|
break;
|
|
case PlayerState.Move:
|
|
UpdateMove();
|
|
break;
|
|
case PlayerState.Skill:
|
|
UpdateSkill();
|
|
break;
|
|
}
|
|
}
|
|
|
|
// InputManager에서 하고 있긴 한데 마우스가 움직임에 따라 커서가 바뀔테니 이런건 여기서 하는게 좋을거 같아서
|
|
// void UpdateMouseCursor()
|
|
// {
|
|
// if(Input.GetMouseButton(0)) return;
|
|
//
|
|
// Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
// // Debug.DrawRay(Camera.main.transform.position, ray.direction * 100.0f, Color.blue, 1.0f);
|
|
//
|
|
// RaycastHit hit;
|
|
// if(Physics.Raycast(ray, out hit, 100.0f, _mask))
|
|
// {
|
|
// if(hit.collider.gameObject.layer == (int)Define.Layer.Monster)
|
|
// {
|
|
// // 몬스터 클릭시 공격 처리
|
|
//
|
|
// // 이 두번째 인자가 뭐냐면 보면 이게 16*16짜리 이미지에 커서를 그리면 이 커서 이미지 끝에 맞춰야 하는데 .zero로 하면 이미지의 끝이 아니라
|
|
// // 16*16 의 아이콘 레이어의 끝단에 맞게 된다. 그래서 커서 그림에 맞게 좀 옮겨 줘야 한다.
|
|
// // 세번째 인자는 오토에 맞게 맞춰주는건데 그냥 오토가 편하다. 수동으로 하는건 나중에 필요하면 따로 알아서 학습하는거로
|
|
// // Cursor.SetCursor(_cursorAttack, new Vector2(_cursorAttack.width / 5, 0), CursorMode.Auto);
|
|
//
|
|
// if(_cursorType != CursorType.Attack)
|
|
// {
|
|
// Cursor.SetCursor(_cursorAttack, new Vector2(_cursorAttack.width / 5, 0), CursorMode.Auto);
|
|
// _cursorType = CursorType.Attack;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// if (_cursorType != CursorType.Hand)
|
|
// {
|
|
// Cursor.SetCursor(_cursorHand, new Vector2(_cursorHand.width / 3, 0), CursorMode.Auto);
|
|
// _cursorType = CursorType.Hand;
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
int _mask = (1 << (int)Define.Layer.Ground) | (1 << (int)Define.Layer.Monster);
|
|
|
|
|
|
GameObject _lockTarget;
|
|
void OnMouseEvent(Define.MouseEvent evt)
|
|
{
|
|
// 클릭 뿐 아니라 마우스 누르고 있어도 이동이 가능하게 하기 위해서 일단 날리기
|
|
// if (evt != Define.MouseEvent.Click) return;
|
|
if(_playerState == PlayerState.Die) return;
|
|
|
|
RaycastHit hit;
|
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
// Debug.DrawRay(Camera.main.transform.position, ray.direction * 100.0f, Color.blue, 1.0f);
|
|
bool raycastHit = Physics.Raycast(ray, out hit, 100.0f, _mask);
|
|
|
|
switch (evt)
|
|
{
|
|
case Define.MouseEvent.PointerDown:
|
|
if (raycastHit)
|
|
{
|
|
_destPos = hit.point;
|
|
State = PlayerState.Move;
|
|
|
|
if (hit.collider.gameObject.layer == (int)Define.Layer.Monster)
|
|
_lockTarget = hit.collider.gameObject;
|
|
else
|
|
_lockTarget = null;
|
|
}
|
|
break;
|
|
case Define.MouseEvent.Press:
|
|
if (_lockTarget != null)
|
|
{
|
|
_destPos = _lockTarget.transform.position;
|
|
// _playerState = PlayerState.Move;
|
|
}
|
|
else if (raycastHit)
|
|
{
|
|
_destPos = hit.point;
|
|
// _playerState = PlayerState.Move;
|
|
}
|
|
break;
|
|
// case Define.MouseEvent.PointerUp:
|
|
// _lockTarget = null;
|
|
// break;
|
|
}
|
|
|
|
}
|
|
|
|
// void OnKeyboard()
|
|
// {
|
|
// if (Input.GetKey(KeyCode.W)) { Move(Vector3.forward); }
|
|
// else if (Input.GetKey(KeyCode.S)) { Move(Vector3.back); }
|
|
// else if (Input.GetKey(KeyCode.A)) { Move(Vector3.left); }
|
|
// else if (Input.GetKey(KeyCode.D)) { Move(Vector3.right); }
|
|
// _moveToDest = false;
|
|
// }
|
|
// void Move(Vector3 vector)
|
|
// {
|
|
// transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(vector), 0.15f);
|
|
// transform.position += vector * (Time.deltaTime * _speed);
|
|
// }
|
|
|
|
|
|
|
|
}
|