HYNGNG | 알곡사료

2일차 : 헬기의 세부 조작 만들고 다듬기 본문

유니티/P1 : 유니티에서 헬리콥터 구현하기

2일차 : 헬기의 세부 조작 만들고 다듬기

hyngng 2022. 6. 24. 22:23
728x90
반응형

🙂블로그 이전했습니다!🙂

 

마우스를 이용해
헬기를 전후좌우로 조종하고 싶어졌다.

이에 간단한 인터넷의 도움을 받으니,
Input.GetAxis("Mouse X")의 형식을 사용하면
마우스의 좌우 움직임, 상하 움직임을 받아올 수 있다는 정보를 얻었다.

마우스의 움직임에 따라 헬기가 먼저 기울어졌으면 좋겠다는 마음이 생겨
헬기의 기울임에 대한 코드를 작성했다.

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

public class Heli_Movement : MonoBehaviour
{
    public float msX;
    public float msY;

    void FixedUpdate()
    {
        msX = Input.GetAxis("Mouse X") * 5;
        msY = Input.GetAxis("Mouse Y") * 5;
        
        transform.Rotate(new Vector3(msY, 0, msX) * Time.deltaTime * 60);
    }
}


실제 코드가 이런 모양새인 것은 아니고,
어느 상황에서든 이 코드를 그대로 복붙하면 사용할 수 있도록
핵심 부분만 추출해 정리한 것이다.

마우스의 상하 움직임에 관여하는 변수를 msX,
좌우 움직임에 관여하는 변수를 msY로 이름붙여 만들어
transform.Rotate에 벡터값으로 참조되도록 만들었다.

애를 먹은 부분이 하나 있었는데,
GetAxis("Mouse X")를 입력할 때
MouseX라 입력하면 안 되고,
Mouse X로 중간에 띄어쓰기를
무조건 해 주어야 한다.


잘 작동하긴 하는데,
W와 S를 누를 때 위아래로 움직이는 것이
오브젝트의 로컬 좌표가 아니라 오브젝트가 위치한 절대 공간의 위아래(Y축)에 대해 움직이는 문제가 있다.

로컬 좌표에 대해 움직이게 하기 위해 코드를
rigid.AddForce(new Vector3(0, WS, 0), ForceMode.Force)에서
transform.Translate(new Vector(0, WS, 0))으로 바꿔주었다.

여기에서도...Translate를 translate로 쓰는 바람에 계속 오류가 났고
이 하찮은 오류를 꽤나 시간을 들여 찾아내야 했다.


이어 앞뒤로도 움직이도록 만들어보자.
나는 헬기가 앞으로 기울어지면, 앞으로 기울어진 정도의 일부 만큼
헬기가 앞으로 이동하면 좋겠다.

그런데,


좌표계에서의 움직임을 표현할 때의 X, Y, Z와
회전을 표현할 때의 X, Y, Z는 다른 개념임임을 여기에서 발견했다.

헬기의 회전축 X값이 변했다고
그대로 헬기를 X축으로 이동시키면

앞으로 숙였을 때 오른쪽으로 질질 끌려가게 된다.
좌우 방향으로 숙이면 앞뒤로, 몸체를 좌우로돌리면 위아래로 끌리는 식.

좀 더 찾아보니 제대로 구현하기 위해선
절대좌표와 로컬좌표간 변환이 필요한 듯 하기에... 이 부분은 다음으로 미뤄둬야 할 것 같다.



헬기가 이동할 때 한도도 없이 너무 빠르게 움직이지 않았으면 하는 마음이 들었다.
이를 구현하기 위해 기초 속도 정보가 필요하게 되었는데, 다행히도 간단히 구할 수 있었다.

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

public class Heli_Movement : MonoBehaviour
{
    Rigidbody rigid;

    void Awake()
    {
        rigid = GetComponent<Rigidbody>();
    }
    
    void FixedUpdate()
    {
        Debug.Log(rigid.velocity.y);
    }
}


마찬가지로 핵심 부분만 간단히 정리해 두었다.

Rigidbody가 적용되어 있기 때문에
rigid.velocity를 사용하면 쉽게 속도(Vector3)값을 얻을 수 있다.

주의할 점은 Velocity가 아니라 velocity
대소문자를 구분하여 입력해야 한다.

더불어 벡터로 속도값에 접근할 때,
벡터.x || 벡터.y || 벡터.z
를 요구하면 해당 속도값을 X축, Y축, X축에 대하여 개별적으로 알 수 있다.

이렇게 코드를 작성해 적용하면,


요런 식으로
해당 스크립트가 적용된 오브젝트의 속도값을 콘솔창에 쏴준다.
나같은 경우는 Y축 속도값만을 원해 rigid.velocity.y로 입력했더니
정말 실수 하나만을 쏴주더라.

더불어, 이 내용을 찾다가 재미있는 기능을 하나 더 같이 찾았는데
Mathf.Clamp(변수, 최솟값, 최대값) 형식을 이용해
(실수형) 변수가 갈 수 있는 최대 범위를 제한시킬 수 있다는 것이었다.
헬기의 수직이동에 도움이 되는 내용이므로 바로 응용해보기로 했다.

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

public class Heli_Movement : MonoBehaviour
{
    Rigidbody rigid;
    private float VerticalSpeed;

    void Awake()
    {
        rigid = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
    	VerticalSpeed = Mathf.Clamp(rigid.velocity.y, -8, 8);
        rigid.velocity = new Vector3(0, VerticalSpeed, 0);
    }
}



FixedUpdate 함수 내의 마지막 밑줄에
rigid.velocity = new Vector3(0, VerticalSpeed, 0)를 추가하여 완성했다.


재미있게도 헬기의 수직 이동속도가 더이상 무한정 늘어나지 않고
쭉쭉 늘어나다가 내가 설정해둔 제한 속도 -8과 8에서 각각 멈추는 것을
콘솔창에서 확인할 수 있었다.



오늘의 요약 :
- 헬기의 여러 축 방향으로의 회전을 구현
- 기체가 상승과 하강할 때의 속도에 제한을 둠

 

728x90
반응형