티스토리 뷰

위의 이미지에서 키보드 a 와 d 자판은 Horizontal 이라는 이름의 버튼으로 할당 되어있다.

여기서 Input.GetAxis("Horizontal")를 사용하면 -1 에서 1 까지의 float 값을 반환 받을 수 있다.

이것에 관한 설정은 이하의 설정을 따르는데,

키가 입력되면 Sensitivity에 설정한 만큼 값이 서서히 -1이나 1에 도달한다.

그러다 입력이 중단되면 Gravity에 설정한 만큼 값이 서서히 0으로 되돌아간다.

그러다 Dead에 설정한 값에 도달하면 입력이 없는 것으로 한다.

 

사람들은 Input.GetAxis를 Horizontal이나 Vertical 과 같이 캐릭터의 조작에 사용한다.

 

 

transform.position += new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

위와 같은 코드 한 줄로 방향키 입력에 따라 x축과 z축을 이동할 수 있다.

이러한 방식으로 캐릭터가 이동해야할 방향을 구할 수 있는 것이다.

 

 

    float rotationSpeed = 1;

    private void Update()
    {
        Vector3 direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
        transform.position += direction;

        Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
    }

이렇게 구한 이동 방향을 사용하여 캐릭터가 자연스럽게 회전하게 만들 수 있다.  

 

 

 

float rotationSpeed = 1;

private void Update()
{
    Vector3 direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

    // 방향 벡터가 0이 아닐 때만 이동 및 회전을 수행합니다.
    if (direction != Vector3.zero)
    {
        transform.position += direction * Time.deltaTime;

        Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
    }
}

하지만 캐릭터가 항상 이동하는 것은 아니므로

direction 이 0,0,0 인 경우 예외 처리를 해주어야 한다.

 

그런데 아마 이동을 해보면 대각선 이동을 할 때 속도가 빠르다는 것을 느낄 수 있다.

 

 

float rotationSpeed = 1;
float moveSpeed = 5; // 이동 속도를 조절할 float 변수

private void Update()
{
    Vector3 direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

    // 방향 벡터를 정규화하여 대각선 이동 시 속도가 증가하지 않도록 합니다.
    if (direction != Vector3.zero)
    {
        direction.Normalize();
        transform.position += direction * moveSpeed * Time.deltaTime;

        Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
    }
}

normalize를 하여 방향 벡터값을 정규화하는 것으로

모든 방향에 대한 이동 속도를 같게 만들 수 있다.

 

그러나 정규화를 해버린 것 때문에

조작을 시작한 순간부터 빠른 속도로 이동하는 것을 볼 수 있다.

원래대로였다면 자연스럽게 속도가 올랐어야 한다.

 

 

float rotationSpeed = 1;
float moveSpeed = 5; // 이동 속도를 조절할 float 변수

private void Update()
{
    // 입력 값에 따라 방향 벡터를 생성합니다.
    Vector3 direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

    if (direction != Vector3.zero)
    {
        // 방향 벡터를 정규화합니다.
        direction.Normalize();

        // 정규화된 방향 벡터에 입력 값을 곱하여 이동 방향을 조정합니다.
        direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

        // 위치 업데이트
        transform.position += direction * moveSpeed * Time.deltaTime;

        // 목표 회전 계산
        Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
    }
}


이것은 정규화하여 구한 방향 벡터에

다시 Input.GetAxis 를 곱하여 점진적으로 높아지게 하여 해결할 수 있다.

 

 

중요한 것은 여기서부터이다.

 

Direction 값을 매 프레임마다 Update 문에서 조정하는데,

이것은 대각선 이동 중에 Horizontal 버튼과 Vertical 버튼을 동시에 떼지 않는 이상
한 프레임 차이로 인해 그 방향이 수직과 수평으로 고정되게 된다.

 

float rotationSpeed = 1;
float moveSpeed = 5; // 이동 속도를 조절할 float 변수
Vector3 dir = Vector3.zero; // 이동 방향을 저장할 변수

private void Update()
{
    // 키 입력이 있는 경우에만 방향을 업데이트합니다.
    if (Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
        Vector3 norDir = new Vector3(x, 0, z).normalized;
        dir = new Vector3(norDir.x * Mathf.Abs(x), 0, norDir.z * Mathf.Abs(z));
    }

    // 방향 벡터가 0이 아닐 때만 이동 및 회전을 수행합니다.
    if (dir != Vector3.zero)
    {
        transform.position += dir * moveSpeed * Time.deltaTime;

        Quaternion targetRotation = Quaternion.LookRotation(dir, Vector3.up);
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
    }
}

 

이것은 Direction 을 캐싱하고 키 입력이 하나도 없는 경우

Direction 을 새로 정의하지 않게 하는 것으로 해결할 수 있다.

 

 

float rotationSpeed = 1;
float moveSpeed = 5; // 이동 속도를 조절할 float 변수
float dead = 0.1f; // 감속 속도를 조절할 float 변수
Vector3 dir = Vector3.zero; // 이동 방향을 저장할 변수

private void Update()
{
    // 키 입력이 있는 경우에만 방향을 업데이트합니다.
    if (Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
        Vector3 norDir = new Vector3(x, 0, z).normalized;
        dir = new Vector3(norDir.x * Mathf.Abs(x), 0, norDir.z * Mathf.Abs(z));
    }
    else
    {
        // 키 입력이 없을 경우 direction 값을 서서히 0으로 줄어듭니다.
        dir = Vector3.Lerp(dir, Vector3.zero, dead * Time.deltaTime);
    }

    // 방향 벡터가 0이 아닐 때만 이동 및 회전을 수행합니다.
    if (dir != Vector3.zero)
    {
        transform.position += dir * moveSpeed * Time.deltaTime;

        Quaternion targetRotation = Quaternion.LookRotation(dir, Vector3.up);
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
    }
}

마지막으로 Mathf.lerp를 사용하여 아무런 입력이 없을 때

이동하는 방향은 유지한 채, 속도가 서서히 0으로 떨어지게 만들 수 있다.

 

 

 

수정한 코드

 

수정 전 코드

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함