말감로그

[Unity] 유니티 3D 모바일 조이스틱 플레이어 움직임 본문

Unity

[Unity] 유니티 3D 모바일 조이스틱 플레이어 움직임

habbn 2024. 4. 8. 22:47
728x90

 

조이스틱으로 플레이어를 이동하는 방법에 대해 알아보겠다.

 

우선 이 분의 티스토리를 보고 참고하였다.

https://red-tiger.tistory.com/58#google_vignette

 

유니티 3D모바일 조이스틱 조작 및 터치패널로 카메라 조작

우선 모바일환경에서 조이스틱 조작을 하기 위해선 당연히 조이스틱 에셋이 필요하다. 나는 아래 에셋을 사용하였다. 에셋스토어 링크 : https://assetstore.unity.com/packages/tools/input-management/joystick-pack

red-tiger.tistory.com


 

 

조이스틱 조작을 하기 위해서 조이스틱 에셋을 다운받아야 한다.

 

Joystick Pack | 입출력 관리 | Unity Asset Store

Get the Joystick Pack package from Fenerax Studios and speed up your game development process. Find this & other 입출력 관리 options on the Unity Asset Store.

assetstore.unity.com

 

 

PlayerController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public bool enableMobile = false;
    
    [SerializeField]
    private float smoothRotationTime;   //target 각도로 회전하는데 걸리는 시간
    [SerializeField]
    private float smoothMoveTime;   //target 속도로 바뀌는데 걸리는 시간
    [SerializeField]
    private float moveSpeed;
    private float rotationVelocity;
    private float speedVelocity;
    private float currentSpeed;
    private float targetSpeed;

    Transform cameraTransform;
    public VariableJoystick joystick;

    void Awake()
    {
        cameraTransform = Camera.main.transform;
    }

    void Update()
    {
        Vector2 input = Vector2.zero;

        if (enableMobile)
        {
            input = new Vector2(joystick.input.x, joystick.input.y);
        }
        else
        {
            input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
        }

        Vector2 inputDir = input.normalized;

        //움직임을 멈췄을 때 다시 처음 각도로 돌아가는 걸 막기 위함
        if (inputDir != Vector2.zero)
        {
            float rotation = Mathf.Atan2(inputDir.x, inputDir.y) * Mathf.Rad2Deg + cameraTransform.eulerAngles.y;
            transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, rotation, ref rotationVelocity, smoothRotationTime);
        }
        
        //입력 방향에 따른 목표 속도
        //inputDir.magnitude는 입력 벡터의 크기로 사용자가 입력한 방향의 크기에 해당
        targetSpeed = moveSpeed * inputDir.magnitude;
        
        //현재 속도를 목표 속도로 부드럽게 조절한다.
        //SmoothDamp 현재 속도를 목표 속도로 일정한 시간(smoothMoveTime)동안 부드럽게 변화
        //speedVelocity는 속도의 변화량을 추적하는데 사용되는 변수이며,
        //ref 키워드를 통해 이 값을 함수 내에서 직접 변경할 수 있다.
        currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedVelocity, smoothMoveTime);
        
        //현재 스피드에서 타겟 스피드까지 smoothMoveTime 동안 변한다.
        transform.Translate(transform.forward * currentSpeed * Time.deltaTime, Space.World);
        
    }
}

 

조이스틱을 이용해서 이동을 하게끔 구현을 하였고 테스트를 위해서 enableMobile bool형 변수를 만들어서 키보드 입력으로도 이동할 수 있게끔 하였다. (터치패드와 이동이 동시에 되는지 확인하기 위해 디버깅 용으로 만든 것이다.)

 

if (inputDir != Vector2.zero)
{
    float rotation = Mathf.Atan2(inputDir.x, inputDir.y) * Mathf.Rad2Deg 
    					+ cameraTransform.eulerAngles.y;
    transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, 
    						rotation, ref rotationVelocity, smoothRotationTime);
}

 

이 부분은 입력이 있는 경우 입력 방향으로 캐릭터를 회전시키는 역할을 하기 위해 각도를 구해주는 코드이다.

 

1 . Mathf.Atan2(inputDir.x, inputDir.y)는 입력 벡터의 x와 입력 벡터의 y 를 사용하여 각도를 계산한다.

2. Mathf.Rad2Deg 를 사용해서 라디안 값을 각도로 변환한다.

-> Mathf.Atan2는 라디안을 return하기에 다시 각도로 바꿔주는 Mathf.Rad2Deg를 곱해준다.

3. cameraTransform.eulerAngles.y 는 카메라의 현재 y축 회전 값을 가져온다.

4. 이렇게 계산된 회전값을 사용하여 Mathf.SmoothDampAngle 함수로 캐릭터를 부드럽게 회전시킨다.

-> Mathf.SmoothDampAngle 함수를 사용하면 플레이어가 딱딱하게 움직이지 않고 부드럽게 움직이게 된다.

-> Vector3.up은 y축을 의미한다. 

 

 

 

728x90

'Unity' 카테고리의 다른 글

[Unity] 싱글톤 패턴  (2) 2024.07.17
[Unity] 유니티 이벤트 함수의 실행 순서  (0) 2024.07.12
[Unity] Mathf.Sign() 부호 반환 함수  (2) 2024.06.27
Unity Cinemachine  (0) 2024.04.20
[Unity] 1. 로또번호 룰렛판 돌리기  (3) 2023.05.09