유니티/유니티 C#

마우스 입력을 통한 캐릭터 이동

monstro 2024. 11. 10. 18:56
728x90
반응형

이번 포스트에서는 마우스 입력을 통한 캐릭터의 이동을 알아보겠습니다.

조금만 응용해도 모바일 환경에서의 터치에 대한 입력으로도 변형이 가능한 유용한 예제입니다.

 

1) 소스코드

public class PlayerController : MonoBehaviour
{
    bool moveToDest = false;
    Vector3 destPos;

    private void Update()
    {
        OnMouseDown();
        if (moveToDest)
        {
            MovePlayer();
        }
    }

    void OnMouseDown()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Debug.DrawRay(
                    Camera.main.transform.position,
                    ray.direction.normalized * 100.0f,
                    Color.blue,
                    1.0f
                );

            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 200.0f, LayerMask.GetMask("Ground")))
            {
                destPos = hit.point;
                moveToDest = true;
            }
        }
    }

    void MovePlayer()
    {
        Vector3 distance = destPos - gameObject.transform.position;
        if (distance.magnitude < 0.001f)
        {
            moveToDest = false;
        }
        else
        {
            float moveLength = Mathf.Clamp(100.0f * Time.deltaTime, 0, distance.magnitude);
            gameObject.transform.position += distance * moveLength;
        }
    }
}

 

위의 코드에서 moveToDest마우스를 클릭했는지를 판단하는 불리언 변수입니다.

어느때나 이동을 하는 것이 아닌 마우스를 입력하는 경우에만 이동해야 하므로 만들어 주겠습니다.

 

destPos 변수는 마우스를 클릭한 위치 즉, 플레이어가 이동할 목적지의 좌표입니다.

어디로 가야하는지를 알아야 하므로 역시 만들어 주었습니다.

 

코드는 총 2개의 함수로 구성되어 있는데,

하나씩 알아보겠습니다.

 

OnMouseDown함수는 Input.GetMouseButtonDown(0)을 통해 수행됩니다.

왼쪽 마우스를 클릭하게 되면 카메라에서 클릭 위치로 Ray를 발사하게 됩니다.

Ray의 세부 설정에 대한 설명은 생략하겠습니다.

 

Ray는 직선으로 쭉 날라가다 어딘가에 부딪히게 됩니다.

이때 부딪힌 모든 오브젝트를 판단하는 것이 아닌 오직 Layer가 Ground인 오브젝트만 판단합니다. 

부딪힌 오브젝트의 Layer가 Ground라면 

 

Ray가 부딪힌 좌표를 destPos로 설정하고, moveToDest를 참으로 바꿔

해당 위치로 이동하게 됩니다.

 

이제 MovePlayer함수로 넘어가보겠습니다.

distance목적지에서 현재 플레이어의 좌표까지의 거리를 의미합니다.

 

그 이전에 먼저 도착 여부를 판단하여 distance의 거리가 0.001보다 작다moveToDest를 거짓으로 바꿉니다.

이 경우에는 다시 클릭하기 전까지 플레이어는 움직이지 않게 됩니다.

 

moveLength는 Clamp 함수를 통해 값을 범위에서 사용하게 됩니다.

최소 0에서 최대 distance.magnitude의 값을 범위로 갖게 되는데

이때 범위 사이에서 절충하여 사용하는 값은 속도입니다. 

위의 과정을 거쳐 최종적으로 플레이어의 위치를 갱신하게 됩니다.

 

영상으로 한번 보겠습니다.

 

 

DebugRay가 잘 발생하고 실린더가 잘 이동하는 것을 확인할 수 있습니다.

그렇지만 위의 코드는 간단하게 코드로 만들어본 것이고

실제 영상에서도 문제가 보이는 것을 확인할 수 있습니다.

 

따라서 마우스를 입력하는 이벤트가 발생하는 경우에만 OnMouseDown 함수를 호출하거나

하드 코딩되어 있는 부분을 변수로 바꾸는 등의 상황에 맞는 수정이 꼭 필요합니다.

728x90
반응형

'유니티 > 유니티 C#' 카테고리의 다른 글

유니티 입력 처리 심화 - (2) 임베디드 방식  (0) 2024.12.10
유니티 입력 처리 심화 - (1) Direct 방식  (1) 2024.12.09
Collision과 Trigger  (0) 2024.11.11
오브젝트 풀  (0) 2024.09.28
Input Manager와 Input System  (0) 2024.07.13