유니티

조이스틱(Joystick)으로 캐릭터 움직임 조절

유니티세상 2025. 6. 17. 17:24

https://assetstore.unity.com/packages/tools/input-management/joystick-pack-107631

 

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

 

조이스틱으로 캐릭터 움직임 조절하기

rotation 막기

 

 

x 는 좌우 z 는 앞뒤

 


 

 

 

 

using UnityEngine;

public class JoystickPlayer : MonoBehaviour
{
    [SerializeField] private VariableJoystick variableJoystick;
    [SerializeField] private float speed = 5f;

    [SerializeField] private Rigidbody playerRigidbody;
    private  Vector3 moveVector;
    public void FixedUpdate()
    {
        //조이스틱의 입력값을 가져옴, x는 좌우, z는 앞뒤
        float x = variableJoystick.Horizontal;
        float z = variableJoystick.Vertical;

        //입력 방향을 기반으로 이동 벡터 생성,  Time.fixedDeltaTime으로 프레임 보정
        moveVector = new Vector3(x,0,z) * speed * Time.fixedDeltaTime;

        //이동 벡터만큼 자연스럽게 움직임
        playerRigidbody.MovePosition(playerRigidbody.position + moveVector);

        //캐릭터가 움직이고 있다면 회전
        //sqrMagnitude는 벡터의 크기를 제곱한 값, 0이 아니면 이동 중
        if (moveVector.sqrMagnitude != 0) 
        {
            Quaternion directionQuaternion = Quaternion.LookRotation(moveVector); //이동 방향을 바라보는 회전값
            Quaternion moveQuaternion = Quaternion.Slerp(playerRigidbody.rotation, directionQuaternion, 0.3f);//a에서 b로 회전하는 보간값, 0.3f는 회전 속도 조절 (보간)
            playerRigidbody.MoveRotation(moveQuaternion);
        }
    }
}

 


조이스틱 중요 변수

 

  • moveThreshold: Dynamic 조이스틱에서 조이스틱 베이스가 이동하기 시작하는 거리 기준
  • joystickType: 현재 조이스틱 타입 (Fixed, Floating, Dynamic)
  • fixedPosition: Fixed 모드에서 초기 배경 위치 저장용

 

Fixed 항상 지정된 위치에 고정, 보여짐
Floating 터치한 위치에 생성됨, 터치 끝나면 사라짐
Dynamic Floating처럼 나타나지만 일정 거리 이상 드래그하면 베이스도 이동함

 

 

Joystick.cs            → 기본 입력 로직 구현
└─ VariableJoystick.cs → 다양한 모드 확장(Fixed, Floating, Dynamic)
    └─ JoystickSetterExample.cs → UI로 모드 및 설정 실시간 조절
        └─ JoystickPlayerExample.cs → 실제 캐릭터 이동에 적용


✅ 1. MovePosition vs velocity 차이점

🔹 Rigidbody.velocity

rb.velocity = moveVector;
  • 속도 기반 이동
  • Rigidbody가 자연스럽게 가속되고, 중력의 영향을 받음
  • 이동 방향을 변경할 때 관성이 생기므로 제어가 덜 정확함
  • 여러 힘이 겹치면 복잡해져서 예측이 어려울 수 있음

🔹 Rigidbody.MovePosition

rb.MovePosition(rb.position + moveVector);
  • 직접 위치를 옮기지만, 충돌 감지는 그대로
  • 매 FixedUpdate마다 "이 위치로 옮겨줘"라고 명령
  • 중력, 가속도 영향을 받지 않음
  • 움직임이 정확하고 깔끔함
  • 애니메이션 기반 캐릭터 제어나 모바일 조이스틱 제어에 자주 사용됨

👉 결론: MovePosition은 프로그래머가 직접 캐릭터를 컨트롤하기에 더 안정적이고 정밀한 방식입니다.
velocity는 물리 기반 게임에서 더 자연스러운 "힘의 흐름"을 만들고 싶을 때 사용합니다.


✅ 2. moveVector.sqrMagnitude != 0 의미

if (moveVector.sqrMagnitude != 0)
  • sqrMagnitude는 벡터의 길이(크기)의 제곱입니다.
    • 예: new Vector3(3, 0, 4).sqrMagnitude == 3² + 4² = 25
  • magnitude보다 계산 비용이 훨씬 적습니다 (제곱근 연산 없음)
  • 이 조건은 캐릭터가 움직이고 있는지를 판단합니다.

👉 즉, 입력이 없으면 회전하지 않도록 막기 위한 조건입니다.


✅ 3. 회전 관련 두 줄 상세 해석

Quaternion directionQuaternion = Quaternion.LookRotation(moveVector);
  • moveVector가 가리키는 방향(예: 앞, 대각선 등)을 기준으로
    "이 방향을 향하도록 회전"하는 Quaternion 값을 만들어줍니다.
  • 즉, 이동 방향을 바라보는 회전값입니다.

 
Quaternion moveQuaternion = Quaternion.Slerp(playerRigidbody.rotation, directionQuaternion, 0.3f);
  • Quaternion.Slerp(a, b, t)는
    현재 회전값 a에서 → 목표 회전값 b까지
    부드럽게 보간(Slerp)해주는 함수입니다.
  • 0.3f는 회전 속도 (빠르게 회전하면 부자연스러움)

👉 이 줄은 캐릭터가 갑자기 방향을 확 틀지 않고, 부드럽게 방향을 전환하게 해줍니다.


✅ 한 줄 요약

playerRigidbody.MoveRotation(moveQuaternion);
  • 위에서 만든 부드러운 목표 회전값으로 캐릭터를 회전시킵니다.

✅ 최종 정리

코드 역할
sqrMagnitude != 0 캐릭터가 실제로 움직이고 있는지 확인
Quaternion.LookRotation() 이동 방향을 회전 값으로 변환
Quaternion.Slerp() 부드럽게 회전 변화 적용
MoveRotation() 회전 적용
MovePosition() 정확하고 안정적인 이동 처리