본문 바로가기
자바스크립트와 캔버스

바빌론JS - 미니자동차의 마을 탐방

지난 시간에는 마을을 돌아다니는 NPC가 주인공이었지만,

https://itadventure.tistory.com/696

 

바빌론JS - 경로 우대? 경로 따라 걷는 NPC

지난 시간에는 한자리를 빙글 빙글 돌며 걷는 NPC를 만들었는데요.움직임이 좀 단순하지요?https://itadventure.tistory.com/695 바빌론JS - 이동하는 NPC지난 시간에는 마을을 달리는 미니 자동차에 대해

itadventure.tistory.com

미니자동차도 질세라 더 재미있는 것으로 인기를 찾겠다고 하네요.

어디 한번 구경해볼까요? :)


미니 자동차 다시 준비

 


미니 자동차도 직진만 하는 동작에 식상했는지 코스를 돌고 싶다고 합니다.
코스를 도는 시스템은 앞방향 이동이라는 동작이 필요한데요.
__root__ 라는 녀석을 불러와야 앞방향 이동 시스템이 제대로 동작합니다.
BABYLON.SceneLoader.ImportMeshAsync() 함수 코드를 싹 지우고 아래 코드로 변경해 주세요.

// 자동차 부르기
BABYLON.SceneLoader.ImportMeshAsync(
    "", 
    "./", 
    "car.glb").then((result) =>  {
    // 로딩 후 실행할 코드        
    var mesh = result.meshes[0];
    console.log("이름 : " + mesh.name);
});

브라우저에서 F12 키를 누르고 콘솔 탭을 선택하면,

이름 : __root__ 라고 표시되어 있을 겁니다.
result.meshes[0] 이 바로 __root__ 거든요.

이제 이걸 제어해야 코스를 바로 따라갑니다.
확인했으니 F12키를 눌러 창을 닫아 주세요.

미니 자동차가 땅속에 묻혀 있네요. 크기도 작고 하니 키워주고 꺼내주도록 합시다.

금방 이 코드 아래에

var mesh = result.meshes[0];

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

mesh.scaling = new BABYLON.Vector3(3, 3, 3);        
mesh.position.y = 0.5;

이제 좀 자유로와 진 것 같습니다.


코스 추가하기

이제 지난번처럼 경로를 정의해 봅시다.
금방 코드에 아래 코드를 추가하고,

 // 경로 정의
const track = [];

경로를 조사하는 코드를 주석처리했었으니 아래 코드의 주석을 풀어주세요.

// 마우스 클릭 3차원 벡터 추적
mousepick_traceVector3d();   <-- 앞의 // 를 삭제

이제 자동차가 다닐 코스를 만들어 봅시다.
지난번 캐릭터의 코스를 조사할 때처럼 코스 위치를 마우스 가운데 클릭하면서

이런식으로 코드를 추가하면 됩니다.

track.push(new BABYLON.Vector3( 5.66, 0.00, 7.97 ));
track.push(new BABYLON.Vector3( 1.91, 0.50, 0.84 ));
track.push(new BABYLON.Vector3( 2.05, 0.00, -9.08 ));
track.push(new BABYLON.Vector3( -7.90, 0.00, -7.66 ));
track.push(new BABYLON.Vector3( -9.11, 0.00, -1.84 ));
track.push(new BABYLON.Vector3( -8.83, -0.00, 7.41 ));
track.push(new BABYLON.Vector3( 8.54, 0.00, 8.37 ));
track.push(new BABYLON.Vector3( 7.90, 0.00, -8.97 ));
track.push(new BABYLON.Vector3( 3.94, 0.00, -9.15 ));
track.push(new BABYLON.Vector3( 2.64, 0.00, 0.69 ));
track.push(new BABYLON.Vector3( 6.43, -0.00, 6.89 ));

항상 마지막 줄에 처음 줄을 복사해서 붙여넣는 걸 잊지 마시구요 

그리고 코스를 표시하는 코드를 추가해주면 코스를 한 눈에 볼 수 있습니다.
코스와 차의 높이를 맞추는 코드도 한번에 추가하겠습니다.

// 차와 높이값을 맞춤
track.forEach((number, index)=>{
    track[index].y=mesh.position.y;
});

// 경로를 선으로 그림
const pathLine = BABYLON.MeshBuilder.CreateLines("carpath", {points: track});
pathLine.color = new BABYLON.Color3(0, 1, 0);

이제 코스도 준비되었으니 달릴 일만 남았군요.


코스를 따라 달려~

코스를 따라 가는건 캐릭터와 똑같습니다.
대신 속도를 좀 더 빠르게 해보죠. 아래 코드를 추가해 주세요.

let step = 0.03;
let p = 0;
// 시작 위치로
mesh.position = track[p];

// 랜더 프레임별 실행 코드
scene.onBeforeRenderObservable.add(() => {        
    mesh.movePOV(0, 0, -step);

    let distance = 
        Math.sqrt( Math.abs( mesh.position.x - track[p].x ) ) +
        Math.sqrt( Math.abs( mesh.position.z - track[p].z ) );

    if(distance < 0.4)
    {
        p++;
        if(p>=track.length)p = 0;
        mesh.lookAt(track[p]);
    }

});

음? 그런데 코스를 따라가긴 한데 자동차가 옆으로 갑니다.
이걸 원한건 아니잖아!


자동차 방향 바로잡기

문제 해결 방법은 비교적 간단한데요.
__root__ 는 car 메쉬의 부모입니다.
__root__ 는 그대로 두고 car 만 돌려주면 되거든요.

아래 코드를 찾아

mesh.position.y = 0.5;

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

// car 를 받아와 맞는 방향으로 회전시켜준다.
const car = scene.getMeshByName("car");
car.rotation = new BABYLON.Vector3(-Math.PI / 2, -Math.PI/2, 0);
car.position = new BABYLON.Vector3(-0.1, 0, 0);

그러자 차게 코스 방향에 맞게 쭉 따라갑니다.


나를 따르라!

여기서 끝난다면 캐릭터와 다를 바가 없다고 생각한 미니자동차는 새로운 기술의 도입을 건의했습니다.
바로 대상을 부드럽게 추적하는 팔로우 카메라 라는 기술인데요.
바빌론JS에서는 간단한 코드로 구현이 가능합니다.

아래 코드를 찾아 

var camera = new BABYLON.ArcRotateCamera(
    "camera", 
    BABYLON.Tools.ToRadians(90), 
    BABYLON.Tools.ToRadians(65), 
    2,  // 카메라 거리
    BABYLON.Vector3.Zero(), 
    scene
);

주석처리 하고

// var camera = new BABYLON.ArcRotateCamera(
//     "camera", 
//     BABYLON.Tools.ToRadians(90), 
//     BABYLON.Tools.ToRadians(65), 
//     2,  // 카메라 거리
//     BABYLON.Vector3.Zero(), 
//     scene
// );

그 아래에 새로운 팔로우 카메라 코드를 추가합니다.

// 팔로우 카메라
const camera = new BABYLON.FollowCamera(
    "FollowCam", 
    new BABYLON.Vector3(-6, 0, 0), 
    scene
);

// 대상과의 거리
camera.radius = -1;

// 카메라의 높이
camera.heightOffset = 0.5;

// The goal rotation of camera around local origin (centre) of target in x y plane
//camera.rotationOffset = 0;

// 카메라 가속도
camera.cameraAcceleration = 0.005

//최대 가속도
camera.maxCameraSpeed = 10

그리고 팔로우 카메라가 따라갈 대상이 있어야 합니다.
BABYLON.SceneLoader.ImportMeshAsync() 함수 안에서 아래 코드를 찾아

mesh.position.y = 0.5;

아래 코드를 추가합니다.

// 팔로우 카메라가 따라갈 대상
camera.lockedTarget = mesh;

그러자 와우~
자동차를 따라가는 카메라 연출을 구경할 수 있네요! 멋지지 않나요? :)


비를 내려줘!

내친 김에 날씨까지 조정하고 싶다고 하네요. 비를 뿌리고 싶다니 뿌려보죠.
비를 내리는 특수효과를 파티클이라고 합니다.

아래 코드를 찾아,

// 씬 리턴
return scene;

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

BABYLON.ParticleHelper.CreateAsync(
    "rain",
    scene, 
    false)
.then((set) => {
    console.log(set);
    set.systems[0].updateSpeed = 0.1;    // 빗방울 속도        
    set.systems[0].emitRate = 1000;     // 비의 양
    set.systems[1].emitRate = 200;     // 스플래시 양
    set.start();
});

빗길을 주행하는 미니자동차를 보실 겁니다 :)

이제 코스 가이드선은 없애 주셔도 됩니다.
아래 코드를 찾아

const pathLine = BABYLON.MeshBuilder.CreateLines("carpath", {points: track});
pathLine.color = new BABYLON.Color3(0, 1, 0);

주석처리해 주세요.

// const pathLine = BABYLON.MeshBuilder.CreateLines("carpath", {points: track});
// pathLine.color = new BABYLON.Color3(0, 1, 0);

그리고 아래 코드도 찾아서

mousepick_traceVector3d();

다시 주석 처리해주시면 됩니다.

//mousepick_traceVector3d();

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

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


마무~리

빗길을 주행하는 미니 자동차의 행보, 재미있게 보셨나요?
필요하신 분에게 도움이 되셨으면 하는 바램입니다.

오늘도 방문해 주신 모든 분들께 감사드립니다.


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

 

바빌론JS - NPC, 내 이름은 케이!

지난 시간 엄청난 기술들을 선보이며 1위 자리를 다시 탈환한 미니 자동차,https://itadventure.tistory.com/697 바빌론JS - 미니자동차의 마을 탐방지난 시간에는 마을을 돌아다니는 NPC가 주인공이었지만

itadventure.tistory.com