유니티 3D 에서 게임 오브젝트와 기본적인 인터액션을 스크립트로 구현하는 예
유니티 3D의 모든 오브젝트는 transform 오브젝트를 내부에 가지고 있으며 transform 객체를 이용하여 오브젝트의 이동, 회전, 확대 변환이 가능하다.
유니티 3D를 실행하고 Scene 뷰에 Cube와 Directional Light 를 배치하고 Project 뷰의 Assets 폴더에 마우스 우측을 클릭하여 Javascript 항목을 선택하여 스크립트를 생성하고 생성된 스크립트 노드를 더블클릭하여 에디터가 열리면 다음과 같은 코드를 작성한다
#pragma strict
function Start () {
}
function Update () {
transform.Rotate(0, 0.5, 0); // 매 프레임당 오브젝트 Y축을 중심으로 0.5 도씩 회전함
}
작성된 스크립트를 저장하고 스크립트 노드를 드래그하여 Hierarchy 뷰의 Cube에 포함시키고 실행버튼을 눌러 보면 Cube 가 회전하는 것을 확인할 수 있다
Transform.Rotate() 함수에 대한 설명은 아래 문서 참조
https://docs.unity3d.com/Documentation/ScriptReference/Transform.Rotate.html
위의 설명에 의하면 아래의 코드는 모두 동일한 의미(오브젝트 Y축을 중심으로 회전)를 가지며 실제로 테스트해보면 그 효과가 모두 동일한 것을 확인할 수 있다.
transform.Rotate(0, 0.5, 0);
transform.Rotate(new Vector3(0, 0.5, 0));
transform.Rotate(Vector3.up * 0.5);
transform.Rotate(Vector3.up, 0.5);
다음과 같이 코드를 다시 작성하고 실행 테스트하면 실행 중이라도 Inspector 뷰에서 큐브의 회전속도를 조정할 수 있다
#pragma strict
var rotSpeed:float;
function Start () {
}
function Update () {
//transform.Rotate(0, 0.5, 0);
//transform.Rotate(new Vector3(0, 0.5, 0));
//transform.Rotate(Vector3.up * 0.5);
transform.Rotate(Vector3.up, rotSpeed);
}
회전속도를 일정하게 유지하려면 위의 코드를 약간 변경하여 아래처럼 단위시간당 회전수를 조정할 수 있다
#pragma strict
var rotSpeed:float;
function Start () {
}
function Update () {
//transform.Rotate(0, 0.5, 0);
//transform.Rotate(new Vector3(0, 0.5, 0));
//transform.Rotate(Vector3.up * 0.5);
transform.Rotate(Vector3.up, Time.deltaTime*rotSpeed);
}
Time.deltaTime 은 앞 프레임과 현재 프레임 사이의 경과시간을 초 단위(float)로 저장하고 있기 때문에 다음과 같은 표현이 가능하다.
Time.deltaTime * 50 --> 초당 50도 회전 ( 50도/초)
위와 같은 방법을 사용하면 CPU의 성능이나 시스템의 부하에 상관 없이 일정한 속도를 유지할 수 있다
마우스로 오브젝트를 클릭할 때마다 회전과 중지를 반복하는 예
#pragma strict
var rotate:boolean = true;
function Start () {
}
function Update () {
if(rotate) {
transform.Rotate(0, Time.deltaTime*70, 0);
}
}
/* MonoBehaivour 클래스의 OnMouseDown()을 오버라이드하면 오브젝트를 클릭했을 때 호출된다*/
function OnMouseDown() {
rotate = rotate ? false : true;
}
오브젝트의 이동
다음과 같은 코드를 사용하면 Z축을 따라 이동하게 된다. 이때 Z축은 오브젝트의 자체의 축을 말한다.
transform.Translate(Vector3.forward * Time.deltaTime*transSpeed);
transform.Translate(0, 0, Time.deltaTime*transSpeed);
회전과 이동을 동시에 하도록 설정하면?
#pragma strict
var rotSpeed:float;
var transSpeed:float;
function Start () {
}
function Update () {
// Y축을 중심으로 회전
//transform.Rotate(0, 0.5, 0);
//transform.Rotate(new Vector3(0, 0.5, 0));
//transform.Rotate(Vector3.up * 0.5);
transform.Rotate(Vector3.up, Time.deltaTime*rotSpeed);
// Z축을 따라 이동
//transform.Translate(Vector3.forward * Time.deltaTime*transSpeed);
//transform.position.z += Time.deltaTime*transSpeed;
transform.Translate(0, 0, Time.deltaTime*transSpeed);
}
위의 코드를 실행하면 이동과 회전을 번갈아 가면서 하게 되므로 짧은 시간 회전하면서 오브젝트의 축방향이 변경되므로 이후에 이동하는 방향은 처음 이동했던 방향과는 매번 달라지게 된다. 결국 위의 코드를 실행하면 오브젝트는 공전을 하면서 자전을 하는 애니메이션이 구현된다. 1회 공전하는 동안 1회 자전이 완료된다. 마치 태양계의 달과 같이 지구를 한바퀴 공전하는 동안 달은 1회 자전을 하는 것과 같은 운동을 한다.
아래의 그림은 위의 코드를 실행했을 때의 모습인데, 오브젝트의 방향 기즈모를 World 좌표 대신 Local 좌표를 표시하도록 설정하면 회전하는 오브젝트는 자체의 축이 계속 변경되기 때문에 이동하는 방향은 동일한 Z축방향이지만 결국 직선운동이 아니라 원운동으로 이동하는 것을 확인할 수 있다.
특정 위치에 오브젝트를 위치하게 하는 방법
#pragma strict
function Start () {
}
function Update () {
//transform.position.z += 0.1;
transform.Translate(0, 0, 0.1);
}
/* 마우스로 오브젝트를 클릭하면 오브젝트가 원점으로 되돌아온다
* MonoBehaivour 클래스의 OnMouseDown()을 오버라이드하면 오브젝트를 클릭했을 때 호출된다
*/
function OnMouseDown() {
transform.position = Vector3(0, 0, 0);
// 위의 코드는 아래와 같은 의미이다
// transform.position.x = 0;
// transform.position.y = 0;
// transform.position.z = 0;
}
오브젝트의 크기 조정
// 오브젝트의 X축방향으로 길이가 커진다
transform.localScale += Vector3(Time.deltaTime, 0,0);
참고'
인스턴스를 생성할 때 Javascript 문법에 따르면 new 키워드를 생략할 수도 있으므로 Vector3(x,x,x) 와 new Vector3(x,x,x) 는 동일한 의미이다