유니티 3D 에서 Transform.LookAt() 함수를 이용한 특정 오브젝트 추적 예제
특정 오브젝트를 향하여 카메라를 정면으로 맞추거나 발사 방향을 목표가 있는 곳으로 향하도록 설정하기 위해서 사용되는 LookAt() 함수를 사용한다.
여기서는 비행기를 따라가는 카메라를 구현해보려고 한다. 비행기가 가는 곳으로 카메라의 방향을 맞추고 그 방향을 향하여 카메라가 따라가도록 할 것이다.
Transform.LookAt() 함수는 지정한 오브젝트를 향하여 전방벡터를 회전하여 마주 보는 자세를 만든다. 즉, 카메라에 적용하면 카메라가 대상 오브젝트를 향하여 초점을 맞추게 되므로 대상 오브젝트는 화면의 중간에 위치하게 될 것이다. 일반 오브젝트에 적용하면 대상 오브젝트를 향하여 정면으로 방향을 돌리는 동작을 취한다. 여기서는 FPC 카메라에 LookAt() 을 적용하여 헬기에 초점을 맞추고 헬기가 어디로 가든지 헬기는 항상 화면의 중앙에 위치하도록 할 것이다.
카메라가 아닌 다른 오브젝트에 LookAt() 함수를 적용한 예는 다음 페이지에서 다룬다
여기서 사용할 헬기 모델은 TF3DM 사이트에서 다운로드할 수 있다
http://tf3dm.com/download-page.php?url=uh-60-blackhawk-helicopter-93546
아래와 같이 헬기 모델을 Project 뷰로 임포트하고 Scene 뷰에 올린 상태에서 시작한다
위의 과정에서 헬기 모델을 Scene 뷰로 올렸을 때 유니티의 축방향과 모델의 축방향이 일치하지 않아서 모델이 뒤집어져 있거나 회전한 상태인 것을 확인할 수 있다. 이런 경우에는 모델링 툴에서 유니티에 맞추어 다시 축 방향을 조정할 수도 있겠지만 모델링 툴을 사용할 수 없는 환경이라면 유니티 내에서 해결해야 할 것이다. 헬기 모델을 유니티에서 회전하여 Scene 뷰에서 똑바로 보이도록 조정한 다음 빈 게임오브젝트를 생성하여 그 안에 두고 헬기의 이동과 회전이 필요한 경우에는 헬기 모델을 포함하고 있는 빈 게임오브젝트를 대상으로 회전 및 이동을 적용하면 된다.
여기서는 빈 게임오브젝트를 Heli 라는 이름을 사용하였다. 빈 게임오브젝트를 생성하려면 GameObject > Create Empty 를 선택하면 된다
간단한 지형을 생성하고 지형 위에 헬기와 First Person Controller 를 배치하여 헬기 뒤에서서 FPC의 카메라가 헬기를 볼 수 있도록 설정한다
헬기의 Main Rotor, Tail Rotor 가 회전하는 애니메이션은 아래의 스크립트를 작성하고 Hierarchy 뷰에서 헬기 모델의 하위 메시(main_rotor, rear_rotor)를 찾아서 마우스로 스크립트를 드래그하여 할당해주면 된다.
#pragma strict
function Start () {
}
function Update () {
transform.Rotate(Vector3(0,20,0));
}
아래와 같이 스크립트를 드래그하여 Hierarchy 뷰의 main_rotor, rear_rotor 에 할당하고 Play 모드로 테스트해보면 로터가 회전하는 것을 볼 수 있다
FPC 카메라가 헬기에 초점을 맞추고 헬기가 이동하는 곳으로 따라가게 하려면 공중으로도 이동할 수 있어야 하므로 FPC에는 중력의 효과를 제거해야 한다
FPC는 마우스 포인터의 위치에 초점을 맞추도록 설정되어 있는데, 여기서는 헬기에 초점을 맞추어야 하고, 또한 FPC는 WASD 키와 방향키로 이동하도록 디폴트로 설정되어 있는데, 여기서는 WASD 키와 방향키로 헬기를 이동하는데 사용할 것이므로 FPC 디폴트 제어 시스템을 무효화해야 한다
Hierarchy 뷰에서 FPC 를 선택하고 Inspector 뷰에서 확인되는 여러개의 콤포넌트 중에서 Character Controller, FPSInput Controller 를 제외하고 2개의 콤포넌트를 선택해제한다
Mouse Look, Character Motor 2개의 콤포넌트 선택해제
FPC 안에 있는 Main Camera 의 마우스 자동추적 기능(Mouse Look)도 해제하여야 여기서 헬기를 추적하도록 설정할 수 있다
위에서 해제한 FPC 마우스 추적 기능은 다음과 같이 스크립트 안에서도 해제할 수 있다
아래의 스크립트를 작성하고 헬기 모델을 포함하고 있는 빈 게임오브젝트(Heli)로 드래그하여 할당한다
이 스크립트는 Transform.LookAt() 함수를 테스트하는 것이 목적이므로 다른 기능은 관심을 두지 않는다
#pragma strict
internal var pitch:float;
internal var roll:float;
internal var yaw:float;
internal var forwardSpeed:float;
internal var sideSpeed:float;
internal var upSpeed:float;
internal var camDist:float = 0.4;
internal var fpcCamera:GameObject;
internal var fpc:GameObject;
function Start () {
fpc = GameObject.Find("First Person Controller");
/*
fpc.GetComponent(CharacterMotor).enabled = false;
fpc.GetComponent(MouseLook).enabled = false;
fpcCamera = GameObject.Find("First Person Controller/Main Camera");
fpcCamera.GetComponent(MouseLook).enabled = false;
*/
}
function Update () {
if(Input.GetKeyDown('w')){//상승
upSpeed += 0.0003;
}
if(Input.GetKeyDown('s')){//강하
upSpeed -= 0.0003;
}
if(Input.GetKeyDown('a')){//Left Yaw
yaw -= 0.02;
}
if(Input.GetKeyDown('d')){//Right Yaw
yaw += 0.02;
}
if(Input.GetKeyDown('up')){//forward pitch
pitch += 0.02;
}
if(Input.GetKeyDown('down')){//backward pitch
pitch -= 0.02;
}
if(Input.GetKeyDown('left')){//left roll
roll += 0.02;
}
if(Input.GetKeyDown('right')){//right roll
roll -= 0.02;
}
forwardSpeed = pitch;
sideSpeed = roll;
transform.Rotate(Vector3.forward*roll); //Roll
transform.Rotate(Vector3.right*pitch);//Pitch
transform.Rotate(Vector3.up*yaw);//Yaw
var pitchAng:float = transform.eulerAngles.x > 180 ? transform.eulerAngles.x-360 : transform.eulerAngles.x;
var rollAng:float = transform.eulerAngles.z > 180 ? transform.eulerAngles.z-360 : transform.eulerAngles.z;
transform.Translate(Vector3.forward*pitchAng*0.0001);
transform.Translate(Vector3.right*(-rollAng)*0.0001);
transform.Translate(Vector3.up*upSpeed);
fpc.transform.LookAt(transform.position);
var distance = Vector3.Distance(transform.position, fpc.transform.position);
if(distance>camDist) {
fpc.transform.Translate(Vector3.forward*((distance/camDist) * 0.003));
}
}
위의 스크립트는 Hierarchy 뷰의 Heli 빈 게임오브젝트에 할당할 것이므로 transform.position 이 가리키는 위치는 곧 헬기의 위치가 된다. 그러므로 FPC는 항상 헬기가 어디로 이동하든지 헬기를 추적하여 초점을 맞추게 되므로 화면의 중앙에는 헬기가 위치하게 된다
위와 같이 설정을 마치고 Play 모드로 테스트할 때 방향키로 헬기를 이동해보면 FPC의 카메라가 헬기에 초점을 유지하며 헬기가 가는 곳을 따라서 이동하는 것을 확인할 수 있다
헬기의 시작 위치, 헬기가 화면의 중앙에 위치하고 있다
아래 그림과 같이 헬기가 다른 위치로 이동한 경우에도 FPC 카메라가 헬기에 초점을 맞추고 따라서 이동한다