미니 RPG
📜Define
public enum MouseEvent
{
Press,
PointerDown, // 마우스 뗀 상태에서 처음 눌렀을 때
PointerUp, // 마우스 누르고 있던 상태에서 처음 뗏을 때
Click,
}
Press : 누르는 동안
PointerDown : 안 누르고 있던 상태에서 처음으로 눌렀을 때
PointerUp : 0.2초 이상 꾹 누르고 있던 상태에서 처음으로 뗏을 때 (꽤 누르고 있다가 뗐을 때)
Click : 0.2초 이하로 누르고 있던 상태에서 처음으로 뗏을 때 (말 그대로 클릭 수준. 찰나만 누르고 뗐을 떄)
📜InputManager
public class InputManager
{
public Action KeyAction = null;
public Action<Define.MouseEvent> MouseAction = null;
bool _pressed = false;
float _pressedTime = 0;
public void OnUpdate()
{
if (EventSystem.current.IsPointerOverGameObject())
return;
if (Input.anyKey && KeyAction != null)
KeyAction.Invoke();
if (MouseAction != null)
{
if (Input.GetMouseButton(0)) // PointerDown -> Press
{
if (!_pressed) // 한번도 눌렀던적이 없었는데 클릭 들어온거면
{
MouseAction.Invoke(Define.MouseEvent.PointerDown);
_pressedTime = Time.time; // start 이후 경과 시간 (구분만 할 수 있으면 됨)
}
MouseAction.Invoke(Define.MouseEvent.Press); // 비효율적일 수 있음(이벤트 발생)
_pressed = true;
}
else // Click(금방 뗏을 때) -> PointerUp(좀 오래 눌려있다가 뗏을 때)
{
if (_pressed) // 클릭 이벤트는 안들어왔는데 눌린 상태였었다면
{
if (Time.time < _pressedTime + 0.2f) // 0.2초 내에 뗐을때
MouseAction.Invoke(Define.MouseEvent.Click);
MouseAction.Invoke(Define.MouseEvent.PointerUp);
}
_pressed = false;
_pressedTime = 0;
}
}
}
MouseAction : Define.MouseEvent 을 인수로 받는 함수만 등록 가능한 액션. 📜PlayerController에서 이 인수가 무엇인지에 따라 다르게 동작하도록 설정한다.
_pressedTime : Click 과 PointerUp 을 구분하기 위해 누르는 시간을 샐 것이다. 0.2 초 이하로 누르면 Click, 0.2 초 이상으로 누르면 PointerUp 로 인식되게 설정한다.
마우스 클릭 발생 ⭕ if (Input.GetMouseButton(0))
1. if (!_pressed) 👉 한번도 눌렀던적이 없었는데 클릭 들어온거면 PointerDown
- 이제부터 누르는 동안의 시간인 _pressedTime 타이밍을 시작해야 한다. Time.time은 Start() 함수 시작 후 실행 시간이다. 현재 플레이한 초 단위의 시간이라고 생각하면 될 것 같다. Time.time < _pressedTime + 0.2f 로 0.2초 이상 눌렀는지 아닌지를 비교하는데 쓸거라 Time.time 이용한 것이다.
마우스 클릭 발생 ❌
1. if (_pressed) 👉 방금까지 누르고 있더 상태였다면
- 누른지 0.2초 이내 Click
- 누른지 0.2초 이상 PointerUp
- _pressed와 _pressedTime 리셋
누르는 동안엔 MouseAction.Invoke(Define.MouseEvent.Press); 로 인해 매 프레임마다 이벤트를 발생시킬 수 있으니 성능상 비효율적일 수도 있다. Update문에서 Input.GetMouseButton
📜PlayerController
void UpdateMoving()
{
// ...
if (Physics.Raycast(transform.position + Vector3.up * 0.5f, dir, 1.0f, LayerMask.GetMask("Block")))
{
if (Input.GetMouseButton(0) == false) //
State = PlayerState.Idle;
return;
}
}
}
마우스를 꾹 누르고 있는 상태면 (그러니까 Input.GetMouseButton(0)가 true 이면) 커서가 “Block”에 있더라도 달리는 상태를 유지하도록 한다.
int _mask = (1 << (int)Define.Layer.Ground) | (1 << (int)Define.Layer.Monster);
GameObject _lockTarget;
void OnMouseEvent(Define.MouseEvent evt)
{
switch (State)
{
case PlayerState.Idle:
OnMouseEvent_IdleRun(evt);
break;
case PlayerState.Moving:
OnMouseEvent_IdleRun(evt);
break;
case PlayerState.Skill:
{
if (evt == Define.MouseEvent.PointerUp)
_stopSkill = true;
}
break;
}
}
void OnMouseEvent_IdleRun(Define.MouseEvent evt)
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
bool raycastHit = Physics.Raycast(ray, out hit, 100.0f, _mask);
switch (evt)
{
case Define.MouseEvent.PointerDown: // 처음으로 누른 순간
{
if (raycastHit)
{
// 몬스터 클릭했든 아니든 클릭한 곳으로 이동은 해야.
_destPos = hit.point;
State = PlayerState.Moving;
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; // 누르는 동안에도 몬스터를 따라가야
else if (raycastHit)
_destPos = hit.point; // 누르는 쪽으로!
}
break;
}
}
PointerDown일 때 (처음 누른 순간)
if (raycastHit) 몬스터 혹은 땅에 화면클릭 Raycast 가 충돌했을 때 클릭한 곳으로 이동해야 한다. (_destPos, State 업데이트)
1. 몬스터를 클릭했을 때
- _lockTarget에 몬스터 오브젝트 저장
2. 땅 클릭했을 때
- _lockTarget null
Press일 때 (누르는 동안)
1. 몬스터 타겟인 상태라면 if (_lockTarget != null)
누르고 있는 동안에도 몬스터를 향해 가야한다. (위 gif 참고)
2.땅 타겟인 상태라면
누르고 있는 동안이더라도 커서가 향하는 곳으로 가야 한다.
'공부 > 인프런 - Rookiss' 카테고리의 다른 글
Part 3-13-5. 미니 RPG : 체력 게이지 (0) | 2023.08.31 |
---|---|
Part 3-13-4. 미니 RPG : 공격 (0) | 2023.08.31 |
Part 3-13-2. 미니 RPG : 스탯 설정, 마우스 커서 변경 (0) | 2023.08.30 |
Part 3-13-1. 미니 RPG : 환경 설정, 이동 (0) | 2023.08.30 |
Part 3-12-1. Data : Json을 이용한 Data Manager (0) | 2023.08.29 |