반응형
Notice
Recent Posts
Recent Comments
«   2024/04   »
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
Archives
Today
Total
관리 메뉴

Do Something IT

[Unity3D] GameObject 에 중력(Gravity)적용 방법에 관한 고찰과 Rigidbody, CharacterController(1) 본문

Unity3D

[Unity3D] GameObject 에 중력(Gravity)적용 방법에 관한 고찰과 Rigidbody, CharacterController(1)

아낙시만더 2011. 7. 29. 13:42
반응형
Unity3D를 처음 접하고 게임을 만들어 보면서 문득 궁굼증이 생겼다.
아직 내가 배우는 단계라서 그런지 선생님한테 배운 중력 적용 방법 Reference에서 가르치고 있는 중력 방법이
다 다른 것이였다.
이건 왜 이럴까 객체가 무엇인가에 따른 것일까, 아니면 왜 이렇게 다르게 해야되는 것인가, 내가 배우지 못한 차이점이 있는지라는 궁굼증이 나를 애워 싸서 떠나지 않았다. 
그래서 마음먹고 조사 해서 정리 해보기로 하였다.
(미리 말씀 드리지만 이 글은 주관적으로 적은 글이므로 정확 하지 않습니다.) 

일단 테스트를 위해 간단히 Scene을 준비해보자.
 


위처럼 FloorBox 하나와 BoxCube를 하나를 준비하고 우리는 BoxCube에 중력을 걸어 테스트를 해볼 것이다.
일단 제일 쉽게 중력을 적용 시킬수 있는 방법은 BoxCube에 RigidBody를 구성요소로 추가시켜 useGravity를 적용 시켜주면 적용된다.  Box를 클릭하고  Component -> Physics -> rigidbody를 클릭하자. 


이제 박스를 클릭하고 Inspecrtor 화면을 보면 RigidBody가 구성되어있는 것을 볼수있다. 
이 구성요소를 보면  


으로 되어있다 여기서 간단 소개  출처 : http://blog.daum.net/hopefullife/184 

----------------------------------------------------------------------------------------------------------------
rigidbody (강체) : 형태가 고정되어 외력이 가해져도 모양/크기가 변하지 않는 물체 
- 주요 레퍼런스 -
Mass (질량):  힘과 함께 중요한 요소로 질량에 의해 강체의 운동 형태가 많이 달라진다. 지구에서는 질량과 무게가 비례한다.
                    무게는 질량을 당기는 중력의 힘이라고 보면된다.
drag (항력) : 움직임에 대한 저항력. 반발력으로 마찰이나 저항등의 용도로 쓰인다. 물체의 이동에 영향을 주어,
                   나아가는 속도가 감소하는 효과가 있다.
angularDrag(회전항력) :  회전 저항력, 스피어를 일반 큐브로 만들어진 바닥으로 던질때 이 값이 0이면 회전 저항력이 없기때                                      문에 한없이 굴러간다.
useGravity(중력사용) : 중력 적용, 기본중력 방향은 Edit>Project Settings>Physics>Gravity 항목에 설정되어 있고,
                                스크립트에서는 physic.gravity(static)값으로 변경 가능하다.
iskinematic(운동학 적인가): 물리 적용여부, 체크하면 강체의 물리기능이 중지된다.
velocity : 특정 방향으로 속도.
centerOfMass : 무게 중심
inertiaTensor : 관성텐서
inertiaTensorRotation : 회전에 관한 관성 텐서
detectCollisions: 충돌을 검출 할지 여부 기본은 true
maxAngularVelocity: 회전을 줄수있는 힘의 최대치 

- 주요 메소드 -

AddForce(Vector3, ForceMode, Force);    : 특정 방향으로 힘을 가한다.
AddTorque(Vector3, ForceMode, Force);  : 특정 방향으로 회전을 가한다.


- 이벤트 -
충돌 관련 이벤트는 이녀석과 Collider 객체가 던진는데,
 
OnCollisionEnter(Collision);
            OnCollisionExit(Collision);
            OnCollisionStay(Collision);
가 rigidbody, collider에서 메시지를 전달하고,
OnTriggerEnter(Collision);
OnTriggerExit(Collision);
OnTriggerStay(Collision);
트리거 관련 이벤트는 collider 객체에서 전달한다.

- Physic Meterial-
  재질의 물리적인 특성을 부여 할수 잇다.
  rigidbody와 재질의 물리적인 특징이 함게 적용된다. 
---------------------------------------------------------------------------------------------------------------- 

자 이제 플레이를 해보면 큐브가 중력을 받아 아래로 이동 하는것을 볼수 있다. 이는 기본 중력이 -y 방향으로 기본값이 주어져 있기 때문인데 Rigidbody에서 useGravity에 체크가 되어 있기 때문에 이 오브젝트에 중력이 적용 된것이다.  
박스는 중력의 영향으로 아래로 떨어져 밑에 floor 박스에 부딪혀 멈추게 되는데 이는 정확히 어떻게 일어 나는 것인가 하면 
floor 박스에는 Box Collider 라는것이 있다. floor 박스에서 BoxCollider라는 것을 removeComponent를 한후 다시 플레이를 해보자. 


그러면 BoxCube는 floorCube를 무시고 그냥 떨어저 버린다. 이는 왜 그런가 하면 Collider 라는 충돌체라는 구성 요소가 없어지기 때문이다. 두 물체가 충돌 하기 위해서는 두 오브젝이 충돌체여야 충돌을 발견 하고 반응을 할수 있다. 반대로 Boxcube에 collider를 빼고 floorcube에 collider가 있어도 둘은 충돌하지 않는다. collider에 또 충돌을 일으 킬수 있는 것이  CharacterController가 있는데 이는 난중에 소개 하도록 하겠다.

자 여기까지 Rigidbody를 이용하여 쉽게 중력 적용 방법을 알아보았다.

또 Boxcube에 중력을  줄 수 있는 방법은 무엇이 있을까?

내가 아는 한에서 중력이란 것은 객체의 어느 축이 중력 중심점으로 향하는 힘이라고 생각된다 즉 -y 쪽이 중력이라고 하면 그쪽을 향해 -되는 힘이 중력이라고 생각된다. 기본으로 -y축으로 중력이 작용 하니 -y쪽으로 감소하는 힘만 주면 이는 구현 되리라고 생각된다.   

일단 윗 Scene에서 Boxcube에서 Rigidbody를 제거 하고 실험을 해보자 자 이제부터는 스크립트를 통해 작업을 해서 -y에 감소되는 힘을 줄것이다.  

일단 스크립트를 작성해보자. 스크립트 생성은 project -> create -> c#script 로 생성한후  Edit를 클릭해서 연다. 

using UnityEngine;

using System.Collections;


public class InputSystem : MonoBehaviour {

int gravity=-5;

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {
                //transform.position.y = gravity * Time.deltaTime;  여기는 에러 

transform.Translate(new Vector3(0,gravity,0)*Time.deltaTime);

}

}

start는 빌드시 초기화 하는 부분이라고 보면 되고  Update 프레임당 한번씩 호출되는 함수이다. 즉 우리는 모든 행동을 여기사 기록 하면 된다.

이 스크립트를 작성 해서  Boxcube에 드래그해서 달아 주거나 box를 클릭하고 Component-> Script-> inputSystem을 적용 시키면된다. (inputSystem은 스크립명)

자 이제 중력을 적용 시키는 코드를 작성해보자. 이 스크립트는 boxcube에 구성요소로 되어있다 즉 boxcube에 상속되어 있다고보면 될거 같다. 이 스크립트에서 transform을 가지고 오면 해당 boxcube의 transform에 접근을 한다. transform은 객체의 position과 rotation, scale 및 아주 중요한 개념을 가지고 있는 녀석이다. 우리는 position을 -y 시키는 것이 목적이다.

일단 중력 수치로 쓰일 gravity를 하나 선언하고 나는 임의로 -5를 주었다. 적절한 숫치를 적용 시켜 주어라. 
일반적으로 
   //transform.position.y = gravity * Time.deltaTime;  여기는 에러  
작성하면 플레이가 될줄알았는데 에러가 발생했다. 이 수치는 변경될수 없는 값이 라고 한다. 
Assets/c#script/InputSystem.cs(15,27): error CS1612: Cannot modify a value type return value of `UnityEngine.Transform.position'. Consider storing the value in a temporary variable

[ Javascript에서는 에러가 발생하지 않는다.]

그래서 포지션 이동을 지원 해주는 것을 찾아보았다. 
      

 transform.Translate(new Vector3(0,gravity,0)*Time.deltaTime);


Translate는 거리와 방향(속도) 값으로 이동을 가능하게 해준다.  자 이제 플레이를 해보자.  


이게 왠일인가 collider, collider끼리 충돌이 일어 나지 않는다.  즉 여기서 중요한 개념이 나온다. Translate의 이동은 속도 값만큼의 이동이다. 즉 충돌에서 나오는 메서드가 없고 그냥 position값만 이동하는것이다. 우리는 이를 잘 확인하고 사용 해야될 것이다. 

이제 rigidbody가 아닌 또 다른 중력과 collider과의 충돌이 공존할 수 있는 CharacterController를 다음 시간에 정리 하겠다.

반응형
Comments