Unity3D_MMO - MouseEvent

k_hyun·2022년 10월 9일
0

Unity_MMO_Project

목록 보기
3/33

기존에 키보드로만 이동했던 부분을 마우스 클릭을 통해 이동을 구현하였다.

Define.cs

public class Define 
{
    public enum MouseEvent
    {
        Press,
        Click,
    }
    ...
}

추가적인 기능 구별을 위해 Define.cs를 생성하였다.

두 가지의 MouseEvent를 구현하기 위해 열거형 사용.

InpusManager.cs

public class InputManager 
{
	public Action<Define.MouseEvent> MouseAction = null;
    
    bool _pressed = false;

    public void OnUpdate()
    {               
        if (MouseAction != null)
        {
            // 마우스 왼쪽 버튼을 누르면
            if (Input.GetMouseButton(0))
            {
                MouseAction.Invoke(Define.MouseEvent.Press);
                _pressed = true;
            }
            else
            {
                if (_pressed)                
                    MouseAction.Invoke(Define.MouseEvent.Click);

                _pressed = false;                
            }
        }
    }
}    

MouseAction을 선언하였는데 이때 Action의 인자로 Define.MouseEvent를 넣었다.

즉 MouseEvent를 매개변수로 하는 함수에 한정하여 사용한다는 뜻이다.

PlayerController.cs

bool _moveToDest = false;
Vector3 _destPos;

현재 움직이고 있는 중인지 체크하기 위해 _moveToTest를 선언하였다.

_destPos는 이동할 목적지에 대한 위치이다.

void Start()
{
    // 구독 취소 후 신청 느낌
    Managers.Input.KeyAction -= OnKeyboard;
    Managers.Input.KeyAction += OnKeyboard;
    Managers.Input.MouseAction -= OnMouseClicked;
    Managers.Input.MouseAction += OnMouseClicked;
}
void OnMouseClicked(Define.MouseEvent evt)
   {
       if (evt != Define.MouseEvent.Click)
           return;

       Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
       Debug.DrawRay(Camera.main.transform.position, ray.direction * 100.0f, Color.red, 1.0f);

       RaycastHit hit;
       if (Physics.Raycast(ray, out hit, 100.0f, LayerMask.GetMask("Wall")))
       {
           _destPos = hit.point;
           _moveToDest = true;
       }
       
   }

마우스를 클릭하는 경우 클릭한 곳의 layer가 Wall일 때 해당 위치를 _desPos로, 이동중을 true로 바꾼다.

void Update()
    {
        if (_moveToDest)
        {
            Vector3 dir = _destPos - transform.position;
            if (dir.magnitude < 0.0001f)
                _moveToDest = false;
            else
            {
                float moveDist = Mathf.Clamp(_speed * Time.deltaTime, 0, dir.magnitude);
                transform.position += dir.normalized * moveDist;

                transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 10 * Time.deltaTime);                
            }
       }
    }

Update문 안에서 플레이어의 위치와 회전을 갱신해준다.

Mathf.Clamp를 통해 움직일 거리를 계속 갱신해서 버벅임을 방지하였다.

실행 결과

클릭한 지점으로 플레이어가 이동하고 회전함을 확인하였다.

0개의 댓글