Car Movement in Unity
자동차 모델 이동하기
앞선 내용 참조 : http://micropilot.tistory.com/category/Unity3D%20Car/Model%20Import
사용된 자동차 모델 : http://tf3dm.com/download-page.php?url=lamborghini-diablo-33937
자동차 오브젝트를 장면(Scene)내에서 움직이는 효과를 내는 쉬운 방법은 WheelCollider.motorTorque=10 과 같은 방법을 사용하고,
정지하려면 WheelCollider.brakeTorque=100 을 사용하는 것이다.
아울러 자동차의 이동방향을 제어하기 위해서는 WheelCollider.steerAngle=40 과 같은 방법을 사용하면 된다
그러므로 차바퀴 4개에 적용했던 WheelCollider 오브젝트를 스크립트에서 참조해야 한다
현재 프로젝트를 확인해 보면 아래의 그림처럼 Hierarchy 뷰에서 Jeep 오브젝트 안에 4개의 바퀴 오브젝트가 포함되어 있고 그 중 한개의 바퀴 오브젝트를 Hierarchy 뷰에서 선택해보면 Inspector 뷰에서 포함된 WheelCollider 콤포넌트를 확인할 수 있다.
[자동차 바퀴 오브젝트에 포함된 WheelCollider 콤포넌트의 확인]
키보드의 방향키 입력을 받아서 스크립트에서 바퀴에 토크를 전달하는 내용은 다음과 같다
아래의 코드를 작성하여 Jeep 오브젝트에 스크립트 콤포넌트로 추가하면 된다
using UnityEngine;
using System.Collections;
public class Car : MonoBehaviour {
public WheelCollider colliderFR;
public WheelCollider colliderFL;
public WheelCollider colliderRR;
public WheelCollider colliderRL;
public int maxTorque;
// Use this for initialization
void Start () {
maxTorque = 30;
}
// Update is called once per frame
void FixedUpdate () {
colliderRR.motorTorque = maxTorque * Input.GetAxis("Vertical");
colliderRL.motorTorque = maxTorque * Input.GetAxis("Vertical");
colliderFR.steerAngle = 15 * Input.GetAxis("Horizontal");
colliderFL.steerAngle = 15 * Input.GetAxis("Horizontal");
}
}
위의 코드를 살펴보면 WheelCollider 형 변수 4개가 있는데 이는 바퀴에 추가된 WheelCollider 콤포넌트의 참조를 저장하기 위한 변수들이다.
그러므로 위의 WheelCollider 형 변수에 자동차 바퀴의 WheelCollider 콤포넌트의 참조가 전달되어야 키보드 방향키를 이용하여 자동차를 움직이게 할 수 있다.
다음과 같은 방법으로 스크립트에 선언된 public 변수에 Hierarchy 뷰에 등록된 오브젝트의 참조를 전달할 수 있다
- 위의 코드를 Assets / Scripts 폴더에 작성한다
- 작성된 코드를 마우스로 드래그하여 Hierarchy 뷰의 Jeep 오브젝트에 포함한다
- Hierarchy 뷰에서 Jeep 오브젝트를 클릭하면 Inspector 뷰에서 스크립트가 콤포넌트로 추가된 것을 확인할 수 있다
- Inspector 뷰에 나타난 4개의 public 변수에 Hierarchy 뷰의 바퀴 오브젝트 4개를 각각 드래그하여 할당한다
위에서 사용된 Jeep 자동차 모델의 중심이 실제 모델의 중심과 일치하지 않은 문제를 뒤늦게 알고 모델을 변경하여 테스트하였다
http://tf3dm.com/download-page.php?url=lamborghini-diablo-33937
인터넷을 통해 배포되는 많은 무료 모델들을 유니티로 임포트하여 테스트해보니 모델의 방향이나 모델의 중심 등이 일치하지 않아서 유니티에서 바로 사용하기가 어려웠고 어떤 모델은 WheelCollider 의 방향이 바퀴의 회전방향과 일치하지 않아서 사용할 수 없었다. 새로 변경한 모델도 방향키가 반대로 작동하는 현상이 있었기 때문에 아래처럼 스크립트에서 전후 방향키에 마이너스 사인(-)을 추가해 주어야 자동차의 이동방향이 일치하게 되었다
using UnityEngine;
using System.Collections;
public class Car : MonoBehaviour {
public WheelCollider colliderFR;
public WheelCollider colliderFL;
public WheelCollider colliderRR;
public WheelCollider colliderRL;
public int maxTorque;
// Use this for initialization
void Start () {
maxTorque = 30;
rigidbody.centerOfMass=new Vector3(0,-1,0); // 무게중심이 높으면 차가 쉽게 전복된다
}
// Update is called once per frame
void FixedUpdate () {
colliderRR.motorTorque = -maxTorque * Input.GetAxis("Vertical");
colliderRL.motorTorque = -maxTorque * Input.GetAxis("Vertical");
colliderFR.steerAngle = 15 * Input.GetAxis("Horizontal");
colliderFL.steerAngle = 15 * Input.GetAxis("Horizontal");
}
}
위와 같은 절차를 마치면 방향키(전후좌우)를 이용하여 기본적인 이동조작이 가능한 상태가 된다.
그러나 자동차가 이동할 때 바퀴를 관찰해보면 회전하지 않는 상태인데 자동차는 이동하고 있는 것을 볼 수 있다.
이 문제는 Hierarchy 뷰의 어떤 오브젝트가 바퀴에 연결되어 있는지 확인하여 해당 오브젝트를 코드상에서 회전하도록 하면 된다.
Hierarchy 뷰에서 자동차의 하위 오브젝트를 클릭해보면 어떤 오브젝트가 바퀴에 해당하는지 Scene 뷰에서 확인할 수 있으므로 작업을 쉽게 하려면 확인된 오브젝트의 이름을 보다 쉽고 직관적인 이름으로 변경하는 것이 좋겠다.
예를 들어, 타이어 4개는 각각 TireFL, TireFR, TireRL, TireRR 으로 오브젝트를 이름을 변경하고, 타이어와 휠 사이에 있는 오브젝트 인 크롬은 ChromeFL, ChromeFR, ChromeRL, ChromeRR 으로 하면 될 것이며, 바퀴의 가장 안쪽에 있는 휠은 각각 WheelFL, WheelFR, WheelRL, WheelRR 등으로 변경해주면 된다.
또 나중에 타이어와 그 안에 포함된 크롬, 휠 등은 이동방향 전환시 함께 움직여야 하므로 한개의 그룹으로 묶어 줄 필요가 있다.
여기서는 타이어 오브젝트 안에 크롬 오브젝트를 넣고, 크롬 오브젝트 안에 휠 오브젝트를 넣어서 이들 3가지 오브젝트를 제어할 때는 타이어 오브젝트를 제어하면 되도록 Hierarchy 뷰에서 다음 그림과 같이 설정하였다
타이어에는 WheelCollider 콤포넌트를 추가했으며 바퀴의 회전효과를 내기 위해 휠 오브젝트의 Transform을 코드에서 제어해야 하므로 위와 같이 드래그하여 할당하면 된다
스크립트에서는 휠의 Transform 을 이용하여 휠을 회전하도록 제어해야 하므로 아래와 같이 바퀴 회전기능을 추가하였다
using UnityEngine;
using System.Collections;
public class Car : MonoBehaviour {
public WheelCollider colliderFR;
public WheelCollider colliderFL;
public WheelCollider colliderRR;
public WheelCollider colliderRL;
// 바퀴 회전을 위한 Transform
public Transform wheelTransformFL;
public Transform wheelTransformFR;
public Transform wheelTransformRL;
public Transform wheelTransformRR;
public int maxTorque;
// Use this for initialization
void Start () {
maxTorque = 30;
rigidbody.centerOfMass=new Vector3(0,-1,0); // 무게중심이 높으면 차가 쉽게 전복된다
}
// Update is called once per frame
void FixedUpdate () {
//전진, 후진
colliderRR.motorTorque = -maxTorque * Input.GetAxis("Vertical");
colliderRL.motorTorque = -maxTorque * Input.GetAxis("Vertical");
//좌우 방향전환
colliderFR.steerAngle = 15 * Input.GetAxis("Horizontal");
colliderFL.steerAngle = 15 * Input.GetAxis("Horizontal");
// 바퀴회전효과
wheelTransformFL.Rotate (colliderFL.rpm/60*360 * Time.fixedDeltaTime, 0, 0);
wheelTransformFR.Rotate (colliderFR.rpm/60*360 * Time.fixedDeltaTime, 0, 0);
wheelTransformRL.Rotate (colliderRL.rpm/60*360 * Time.fixedDeltaTime, 0, 0);
wheelTransformRR.Rotate (colliderRR.rpm/60*360 * Time.fixedDeltaTime, 0, 0);
}
}
다음에 이어지는 내용은 자동차가 이동함에 따라 위치가 변경되므로 카메라도 차를 따라서 이동하여 항상 자동차가 시야에서 사라지지 않도록 하려고 한다