유니티 3D에서 프로그램 실행 중에 동적으로 다른 오브젝트의 자식 오브젝트로 설정하는 예
유니티 3D 는 어떤 오브젝트의 하위에 다른 오브젝트를 포함하도록 설정하면 포함된 오브젝트는 부모 오브젝트의 이동이나 회전시 상대적인 변환을 하게 된다. 실세계의 형태를 그대로 재현하기 위해서 꼭 필요한 기술이다. 예를 들어 자동차에 타고 있는 물건이나 사람은 움직이지 않아도 차가 가는 곳으로 이동하게 된다. 차를 타기 전에는 차와 무관한 이동이었지만 차를 타면 차에 상대적인 움직임으로 표현되므로, 이를 유니티에서 구현하려면 차를 타기 전에는 자동차 오브젝트와 무관한 움직임을 보이던 오브젝트가 자동차를 타면 자동차 오브젝트에 포함되어 자동차 오브젝트가 부모 오브젝트가 되도록 설정해 주어야 한다. 일단 어떤 오브젝트가 특정 오브젝트의 자식 오브젝트가 되면 부모 오브젝트가 이동하거나 회전하는 등의 변환을 하면 그 안에 포함된 자식 오브젝트도 그 영향을 그대로 받게 된다
유니티에서는 게임 작성시에 유니티 에디터에서 오브젝트 간의 부모 자식 관계를 설정할 수도 있을 뿐만 아니라 프로그램 실행 중에도 동적으로 그런 관계를 설정할 수 있다.
여기서는 1인칭 카메라(First Person Controller)가 헬기가 있는 곳으로 이동하여 헬기에 탑승하는 순간 FPC가 헬기의 자식 오브젝트가 되어 헬기가 이동하는 곳으로 그대로 실려가는 효과를 구현해 보려고 한다
여기서 사용된 헬기 모델은 TF3DM 사이트에서 다운로드할 수 있다.
아래와 같이 20 x 20 크기의 작은 지형을 생성하고 헬기 모델을 지형 위에 놓고 헬기의 우측에 약간 떨어진 곳에 First Person Controller 를 놓고 FPC의 카메라가 헬기의 우측면을 바라보도록 설정한다.
FPC가 이동하여 헬기의 조종석에서 멈추고 FPC의 카메라가 헬기의 전방을 주시하도록 90도 회전한다. 이 때 FPC 가 헬기 안으로 들어오면 FPC가 더 이상 이동하지 않도록 해야 하는데, 헬기에게 Box Collider를 설정하고 Is Trigger 항목을 선택하면 다른 오브젝트가 헬기와 충돌할 때 OnTriggerEnter() 함수가 호출되므로 여기서 FPC가 더 이상 이동을 하지 않도록 설정하면 된다
FPC가 헬기 안에 도착하면 FPC의 부모 오브젝트를 헬기로 설정하면 이후에는 헬기가 이동하는 곳으로 FPC가 그대로 실려 다니는 효과를 볼 수 있다
아래 그림에서 AH-1 이라는 헬기 오브젝트를 빈 GameObject 에 포함시켰는데 그 이유는 헬기 모델을 유니티로 임포트했을 때 모델의 축방향과 유니티의 월드축방향이 서로 불일치하여 헬기를 90도 회전하여 바로 잡아 놓은 상태에서는 헬기의 이동 제어가 쉽지 않기 때문에 헬기를 빈 게임오브젝트에 포함시키고 헬기를 제어할 필요가 있다면 GameObject를 제어하면 보다 쉽게 제어할 수 있다
아래의 스크립트를 위의 그림에 표시된 것처럼 헬기 모델을 포함하고 있는 GameObject 에 드래그하여 포함시킨다
#pragma strict
internal var fpc:GameObject;
internal var mainRotor:GameObject;
internal var tailRotor:GameObject;
internal var onBoard:boolean;
internal var readyForTakeoff:boolean;
function Start () {
fpc = GameObject.Find("First Person Controller");
var chMotor: CharacterMotor = fpc.GetComponent(CharacterMotor);
//헬기에서 아래로 빠지지 않고 탑재된 효과를 내기위해 FPC 의 중력을 0 으로 설정
//chMotor.movement.gravity = 0;
Destroy(fpc.GetComponent(FPSInputController));
Destroy(chMotor);
mainRotor = GameObject.Find("MainRotor");
tailRotor = GameObject.Find("TailRotor");
}
function Update () {
if(!onBoard){//FPC가 헬기 안으로 이동한다
fpc.transform.Translate(Vector3.left * Time.deltaTime*0.3, Space.World);
return;
}
if(!readyForTakeoff) return;
if(transform.position.y<2.5){
//상승
transform.Translate(Vector3.up * Time.deltaTime*0.4, Space.World);
//전전비행
transform.Translate(Vector3.forward * Time.deltaTime*0.5);
}else{
//상승
transform.Translate(Vector3.up * Time.deltaTime*0.2, Space.World);
//전전비행
transform.Translate(Vector3.forward * Time.deltaTime*1.2);
//조금씩 좌선회
transform.Rotate(Vector3.up * Time.deltaTime*(-2.5));
}
mainRotor.transform.Rotate(Vector3.up*(-100));
tailRotor.transform.Rotate(Vector3.right*100);
}
function OnTriggerEnter(fpcCollider:Collider) {
print('FPC into Heli');
onBoard = true;
//헬기가 가는 곳으로 실려 다니는 효과를 내기 위해 헬기를 부모 오브젝트로 설정
fpc.transform.parent = this.transform;
fpc.transform.Rotate(Vector3.up*90);//FPC 카메라 전방
fpc.transform.Rotate(Vector3.right*5);//FPC 카메라 5도 아래
fpcCollider.enabled = false;//FPC와 헬기가 더이상 충돌 이벤트가 발생하지 않도록 함
//탑승 2초후에 이륙
yield new WaitForSeconds(2);
readyForTakeoff = true;
}
FPC가 헬기의 우측으로 접근하여 헬기 안으로 이동한다
헬기안에 도착하면 FPC는 헬기 오브젝트를 부모 오브젝트로 설정하고 헬기의 전방으로 방향을 회전한다
탑승 2초 후에 헬기의 로터가 회전하면서 상승과 동시에 전방으로 비행을 시작한다. 헬기가 이동하는 곳으로 FPC가 그대로 실려 다니게 되므로 공중에서 지상의 경치를 감상할 수 있는 효과를 낼 수 있다