DNF LOVE

[Unity기초-5] 사용자 입력에 따른 Player를 이동시켜보자 - ③ Object가 이동, 회전되는 여러가지 방법(Transform이용하기) 본문

Programming/Unity

[Unity기초-5] 사용자 입력에 따른 Player를 이동시켜보자 - ③ Object가 이동, 회전되는 여러가지 방법(Transform이용하기)

botho 2019. 7. 19. 19:44
반응형

[위치 이동]

사용자 입력을 받는 기능이 여러개이듯, Player를 이동시키는 데에도 여러가지 방법이 존재한다.

이제 그 방법을 알아보도록 하자.

각 객체의 인스팩터창의 Transform정보는 객체의 좌표이다.

Translate 컴포넌트가 있다. 이는 Object의 position, Rotation, Scale을 품고 있는 컴포넌트이다.

이것을 스크립트를 통해 변경할 수 있으며 이를 통해 Object가 이동이 될 수도 있고 방향이 바뀌거나 Scale이 변화될 수 있다.

1. Trasnform의 Position에 직접 접근하여 설정

tranform.position은 오브젝트의 현 위치와 무관하게 Global로 원하는 위치로 이동시키는 방법이다.

상대적 위치가 아닌 절대적 위치라는 뜻이다.

tranform.position과 Vector3를 사용하게 되는데 Vector3는 x, y, z를 활용한다. x, y, z의 데이터 타입은 float 이므로 데이터 유형에 유의하여 사용하길 바란다.

상대적이기 때문에 현재 오브젝트의 위치를 받아오는 것이 중요하게 작용될 수 있다.

** Vector3 방향

  • Vector3(0, 0, -1) or Vector3.back : 뒷쪽으로 이동
  • Vector3(0, -1, 0) or Vector3.down : 아래쪽으로 이동
  • Vector3(0, 0, 1) or Vector3.forward : 앞쪽으로 이동
  • Vector3(-1, 0, 0) or Vector3.left : 왼쪽으로 이동
  • Vector3(1, 1, 1) or Vector3.one : 세 축으로 이동
  • Vector3(1, 0, 0) or Vector3.Right : 오른쪽으로 이동
  • Vector3(0, 1, 0) or Vector3.up : 위쪽으로 이동
  • Vector3(0, 0, 0) or Vector3.zero : 원점으로 이동

** Vector3의 속성

  • magnitude : 벡터의 길이
  • normalized : 크기가 1인 벡터, 정규화 벡터 ( 중요 )
  • sqrMagnitude : 벡터의 길이의 제곱근

2. Transform.Translate 이용하여 이동하기

transform.Translate 명령은 상대좌표로 이동시키는 방법으로 오브젝트의 현재 위치에서 특정 거리만큼 이동시키는 방법이다. 즉, 현재 오브젝트의 위치와 방향으로 부터 명령에 따라 오브젝트가 이동하는 명렁어다.

(이는 보통 오브젝트 방향을 기준으로 하게 되는데 Gobal의 방향으로도 할 수 있다.)

transform.Translate를 사용할 경우 프레임 마다 이동시키기 때문에 time.deltatime을 사용하여 매 프레임을 추가해줘야 한다.

*** time.deltatime은 지난 프레임이 완료되는 데 까지 걸린 시간을 나타내며, 단위는 초를 사용한다.

사용자의 프레임 률(frame rate)을 독립적으로 적용하기 위해서 사용한다. 매 프레임마다 어떤 값을 더하거나 빼는 계산을 하는 경우에, Time.deltaTime과 곱해서 사용할 수 있다. 

이 time.deltatime을 쓰는 이유는 Object를 연속적으로 이동시키거나 회전시킬 때 Update() 혹은 FixedUpdate()에서 구현해야 한다.

FixedUpdate같은 경우 독립적으로 FixedUpdate()가 신뢰할 수있는 타이머에서 호출되기 때문에 Time.deltaTime을 쓰지 않아도 되지만 Update구문에서는 이를 사용해야 한다.

왜냐하면 매 프레임 마다 호출되는 Update() 특성 상 디바이스 성능에 따라 프레임 횟수가 다르기 때문에 문제가 발생되기 때문이다. (프레임 횟수가 다르면 움직이는 속도가 달라진다)

이는 Time.deltatime 이전 프레임이 완료되기까지 걸린 시간으로 성능이 느릴수록 값이 커지는 특성을 담고 있기 때문에 이를 통해 해결할 수 있다.

활용 방법은 float fTime = Time.deltaTime * speed; 이렇게 사용한다.

이렇게 기본적으로 두 가지 종류로 되며, 플레이 화면은 매 프레임 마다 1.5f 속도로 Object가 forward방향으로 이동한다.

** tranform.position += new Vector3(1, 0, 0); 이것과 transform.translate(new Vector3(1, 0, 0)); 이것은 동일한 효과를 낸다. transform.translate는 position에 직접 값을 더해주는 것과 같은 방식으로 동작되기 때문이다.

3. Rigidbody를 설정한 후 Velocity 값을 설정하기

앞서 1번과 2번은 Transform 값을 이용해 움직이는 방식이지만 Addforce를 사용하면 유니티의 물리 엔진인 Rigidbody를 사용하여 오브젝트의 위치를 변경시킬 수 있다.

Addforce는 물리엔진의 힘을 더한다는 것을 의미한다.

Transform과의 차이점을 정확히 이야기 하자면, translate를 이용하면 x좌표를 speed 만큼 이동시키는 것이고, Addforce를 이용하면 x좌표에 speed만큼의 '힘'을 가한다는 뜻이다.

Addforce를 이용한 오브젝트 이동은 Velocity(속도)를 직접 조절하는 방법과, 

물체에 힘을 가하는 Addforce 를 이용하는 두 가지 방법이 존재한다.

rd.velocity를 이용한 코드는 한번 실행 후 속도가 변화되기 전까지 transform.translate(new Vector3(speed, 0, 0)과 동일하다.

Rigidbody의 기본적인 기능중에 중력의 힘을 받는 것이 존재한다.

처음 중력의 영향을 받지 않을 경우 아래 움짤처럼 움직이고,

중력의 영향을 받았을 시 아래의 움짤처럼 움직인다.

이렇게 차이나는 이유는 중력을 작용하지 않으면 힘의 방향은 x축으로만 가하게 되기에 x축으로만 이동하게 되는 것이고,

중력이 작용되면 중력의 방향과, x축 방향의 합인 대각선 방향으로 힘이 가해지기 때문에 이동 모양이 차이가 나게 된다.

4. Character Controller 컴포넌트 이용하여 이동(3d사용)

캐릭터 컨트롤러는 RIgidbody물리를 활용하지 않고 3인 또는 1인 플레이어에 자주 사용된다. 충돌체를 가지고 있기 때문에 충돌체와 함꼐 사용할 수 없게 된다.

이는 다음에 fps게임을 만드는 프로젝트 시 사용해 보도록 하겠다.

 

다음은 회전과 크기를 수정하는 여러 방법이다.

스아실 위치에서 모든 힘을 다 써버렸기 때문에 코드만 간단 설명하고 끝내도록 하겠다.

 

[회전]

1. Quaternoion을 활용하기

쿼터니언의 값으로 지정한다. indentity는 기본적인 0, 0, 0 을 나타낸다.

쿼터니언은 회전을 표현하기 위해 사용한다. 이는 대부분 기존의 회전을 Tranform을 통해서 취하고, 새 회전을 생성하기 위해 사용한다.

자세한 사항은 아래 Doc를 참고하길 바란다(https://docs.unity3d.com/kr/530/ScriptReference/Quaternion.html)

// 쿼터니언의 값으로 지정한다. indentity는 기본적인 0, 0, 0 을 나타낸다
transform.rotation = Quaternion.identity;

 

2. 현재 회전값을 기준으로 회전

tranform.Rotate를 활용하여 회전한다.

// 현재 회전값을 기준으로 회전시킬 수 있다.
// 각 매개변수는 축, 각도, 기준좌표계이다.
transform.Rotate(Vector3.up, speed, Space.World);

 

3. LookAt과 RotateTowards

target을 지정하여 target의 tranform 정보를 기준으로 회전시킨다.

LookAt은 한번에 회전이 되지만 ROtateTowards는 천천히 회전된다.

// target의 Position 정보를 통해 타겟을 향하는 방향으로 회전시키고 싶을 떄 LookAt을 사용한다.
// LookAt은 한번에 회전이 된다.
transform.LookAt(target);

//LookAt과 같은 형식으로 되어있지만 천천히 사용자 입력 속력에 따라 회전하고 싶을 때 사용한다.
transform.rotation = Quaternion.RotateTowards(transform.rotation, target.position - transform.position, seed);

 

[크기]

1. 현재 크기를 기준으로 원하는 크기로 변화시키기

 // 현재 크기를 기준으로 원하는 방향(x)으로 늘리고자 할때
transform.localScale += new Vector3(1, 0, 0);

2. 절대적인 기준으로 크기 변화시키기

// 원하는 크기로 변경하고자 할 때
transform.localScale = new Vector3(1, 1.5f, 1);

 

(너무 힘들다 질찔찔)

여러 방식과 컴포넌트의 상호작용에 의해, Object의 tranform이 여러 형식으로 변화될 수 있다.

여러가지 조건을 추가하고 유니티 API를 참고하여 다양한 실험을 해 보는 것이 실력 향상에 도움이 될 것이다.

 

엉엉 너무 힘들었다. 이동시키는 것만 하려다가 Object의 transform을 다루다 보니 회전과 크기도 다뤄야 할 것 같아서

이것저것 추가하였다. 힘들었다.

다음은 정말로 사용자 입력을 받아서 오브젝트를 이동시키는 것을 꼭 하고야 말겠다.

반응형