본문 바로가기
카테고리 없음

미니자동차 마을을 달리다

이번 시간에는 지난 시간에 이어 

https://itadventure.tistory.com/692

 

바빌론JS - 때깔나는 미니자동차, 달려봐

지난 시간에는 미니자동차 외형을 구성하는 모델을 만들었는데요.https://itadventure.tistory.com/691 바빌론JS - 미니자동차어릴적 장난감 자동차를 붕붕 소리내어 가지고 놀아보신 적이 있나요?적어도

itadventure.tistory.com

미니자동차가 실제 움직이는 연출을 하겠습니다.

본 가이드는 공식 튜토리얼의 내용을 소화하여 크레이 입맛에 맞게 재구성하였습니다.


미니 자동차 저장

계속 공회전하는 자동자의 바퀴, 웬지 에너지가 아깝다는 생각이 들어
이제는 자동차가 앞으로 직진하는 장면을 연출해볼텐데요.

그 전에 자동차를 마을을 저장한 것처럼 gld 파일로 저장하면 코드가 훨씬 간결해 집니다.

아래 코드를 찾아

const car = buildCar(scene);

아래 코드를 추가하고

BABYLON.GLTF2Export.GLBAsync(scene, "./car.glb").then((glb) => {
    glb.downloadFiles();
});

웹페이지를 실행하면 파일을 다운받습니다.

만일 이런 화면이 나오면 그냥 '계속'을 눌러주세요. URL 이 https 가 아니라서 그렇습니다.

파일명을 car.glb 로 변경하여 main.js 와 같은 폴더에 저장하면 준비 끝!


자동차 소환!

이제 자동차를 생성하는 코드를 싹 지우고 불러오도록 바꿔봅시다.
이제 아래 코드를

// 시작
const car = buildCar(scene);
BABYLON.GLTF2Export.GLBAsync(scene, "./car.glb").then((glb) => {
    glb.downloadFiles();
});

이렇게 바꿔주세요.

BABYLON.SceneLoader.ImportMeshAsync("car", "./", "car.glb").then(() =>  {
    // 로딩 후 실행할 코드
});

그리고 아래 자동차 함수화 코드는 싹 지워주세요.
아까우면 따로 저장하거나 남기셔도 됩니다 :)

여전히 바퀴가 굴러가고 있는 자동차를 보실 수 있을텐데요.
.glb 장면파일에는 바퀴가 굴러가는 애니메이션도 저장되기 때문입니다.

만일 타이어를 멈추려면 // 로딩후 실행할 코드 영역에 아래 코드를 넣어주시면 됩니다.
타이어 모델을 찾아 애니메이션을 정지해주는 기능인데요

const wheelRB = scene.getMeshByName("wheelRB");
const wheelRF = scene.getMeshByName("wheelRF");
const wheelLB = scene.getMeshByName("wheelLB");
const wheelLF = scene.getMeshByName("wheelLF");

scene.stopAnimation(wheelRB);
scene.stopAnimation(wheelRF);
scene.stopAnimation(wheelLB);
scene.stopAnimation(wheelLF);

반대로 애니메이션을 다시 재생하는 코드는 아래와 같습니다.

const wheelRB = scene.getMeshByName("wheelRB");
const wheelRF = scene.getMeshByName("wheelRF");
const wheelLB = scene.getMeshByName("wheelLB");
const wheelLF = scene.getMeshByName("wheelLF");

scene.beginAnimation(wheelRB, 0, 30, true);
scene.beginAnimation(wheelRF, 0, 30, true);
scene.beginAnimation(wheelLB, 0, 30, true);
scene.beginAnimation(wheelLF, 0, 30, true);

우리는 그냥 그대로 쓸거니 넘어가도 됩니다 :)


씽씽~ 달려봐~

이제 자동차를 움직여 봅시다.
// 로딩후 실행할 코드 영역에 아래 코드를 넣어 주세요.

const car = scene.getMeshByName("car");

// 차의 X 좌표를 이동하는 애니메이션
const animCar = new BABYLON.Animation(
    "carAnimation",     // 애니메이션 이름
    "position.x",       // x좌표 이동
    30,                 // 30 fps
    BABYLON.Animation.ANIMATIONTYPE_FLOAT,  
    BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);

// 애니메이션 속성 정의
const carKeys = [];
carKeys.push({ frame:   0,   value: 8 });  // -4 위치에서
carKeys.push({ frame: 150,   value: -7 });  // 4 위치로 이동 ( 150프레임 )
carKeys.push({ frame: 210,   value: -7 });  // 4 위치에 머무름 ( 60프레임 )
animCar.setKeys(carKeys);

 // 차에 animCar 애니메이션 설정
 car.animations = [animCar];

 // 애니메이션 재생
 scene.beginAnimation(car, 0, 210, true);

그러면 자동차가 씽하니 달려가는 동작을 반복할 겁니다.

자세히 살펴보면 달려가다 어느 위치에서 잠깐 정지, 그리고 다시 처음 위치로 순간이동해서 다시 달리기를 할텐데요. 애니메이션 코드가 그렇게 정의되서 그렇습니다.
아래 부분이예요 :)

carKeys.push({ frame:   0,   value: 8 });
carKeys.push({ frame: 150,   value: -7 });
carKeys.push({ frame: 210,   value: -7 });  // 잠시 같은 자리에 머무름 ( 60프레임 )

마을을 달리다!

이제 마을을 불러와 자동차를 달리게 할 순간이 왔습니다.
자동차를 불러오는 코드를 찾아

BABYLON.SceneLoader.ImportMeshAsync("car", "./", "car.glb").then(() =>  {

그 위에 마을을 불러오는 코드를 추가해 주세요.

 // 마을 부르기
BABYLON.SceneLoader.ImportMeshAsync("", "./", "dwellings.glb").then(() =>  {
    // 기본 집 숨김        
    scene.getNodeByName("house1_base").setEnabled(false);
    scene.getNodeByName("house2_base").setEnabled(false);
    const crayground = scene.getMeshByName("crayground");
});

오! 마을이 보입니다!
그런데... 자세히 살펴보니 자동차가 땅 속으로 다니는 군요. 그리고 너무 작습니다.

자동차의 크기를 키우고 지면 위로 올려 봅시다.
아래 코드를 찾아

const car = scene.getMeshByName("car");

아래 코드를 추가해 주세요. 

car.scaling = new BABYLON.Vector3(2, 2, 2);
car.position.y = 0.4;

여러번 실험해 본 결과 크기는 2배, 높이는 0.4가 딱 적당하더라구요.
그런데 한가지 문제가 있습니다.
자동차가 막 집 벽을 뜷고 가는 것이 아니겠습니까? :)

위치를 조정해 봅시다.
마을의 뜷린 부분을 이 방향으로 달리게 해 보자구요.

이 경우 x좌표가 아닌 z좌표를 움직여주어야 합니다.
애니메이션 코드를 이렇게 수정하면 되는데요.

아래 코드에서

// 차의 X 좌표를 이동하는 애니메이션
const animCar = new BABYLON.Animation(
    "carAnimation",     // 애니메이션 이름
    "position.x",       // x좌표 이동
    30,                 // 30 fps
    BABYLON.Animation.ANIMATIONTYPE_FLOAT,  
    BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);

position.x 를 position.z 로 바꿔주세요.

그리고 이 코드 윗 부분에 아래 코드를 추가합니다.
애니메이션의 중심 좌표를 조정하는 겁니다 :)

car.position.x = -3;
car.position.z = 8;

그러면 자동차가 가긴 가는데 우스꽝스럽게도 옆으로 갈 겁니다 :)

그것은 자동차가 향하는 방향으로 몸통을 틀어주지 않아서 그런데요.

아래 코드를 추가하면 자동차가 해당 방향으로 회전합니다.

car.rotate(
    BABYLON.Axis.Z, 
    -Math.PI/2, 
    BABYLON.Space.LOCAL
);

이렇게 잘 주행하는 걸 볼 수 있지요.

실습이 어려우신 분은 아래 결과물 페이지를 참조해 주세요

http://dreamplan7.cafe24.com/babylon/ex11/


마무~리

마을을 주행하는 자동차를 드디어 보게 되었습니다.
다음에는 또 어떤 이야기가 기다리고 있을까요?

필요하신 분께 도움이 되셨나 모르겠습니다.
오늘도 방문해 주신 분들께 감사드립니다~


다음 게시글 : https://itadventure.tistory.com/695

 

바빌론JS - 이동하는 NPC

지난 시간에는 마을을 달리는 미니 자동차에 대해 다뤄보았습니다.https://itadventure.tistory.com/693 미니자동차 마을을 달리다이번 시간에는 지난 시간에 이어 https://itadventure.tistory.com/692 바빌론JS -

itadventure.tistory.com