はじめに
防災や観光など都市開発などをテーマとした場合の開発手法を色々と試しています。
様々な要件定義によっていろいろな開発手法が考えられますが、自身が受ける案件の中でよく挙げられる点は、
「VRやARなどに対応したい、高齢者や子供でも簡単に使えるようにしたい、開発の予算はない」
といったものです。
こうした要件の中で、最近、試しているのが、「ブラウザアプリ」による開発です。
アプリ開発の場合は、UnityやFlutterなどOSの違いを吸収してくれるSDKもありますが、
iOSの場合などはTestFlightの使い方などを習得する必要がある点や、仮に貸出用のスマートフォンなどを手配した場合、キッティングにかかる時間も多いため、ちょっとしたものをサクッと提供する場合には、ブラウザアプリの提供が欠かせません。
侮る事なかれブラウザゲームの現状
WebAssembly(通称Wasm)は、ブラウザゲームの開発に革命をもたらした技術の一つです。WebAssemblyは、ウェブブラウザで実行可能な低レベルのバイナリフォーマットです。これにより、C、C++、Rustなどの言語で書かれたコードをウェブブラウザで実行することが可能になります。WebAssemblyはJavaScriptよりも高速に実行できるため、ウェブアプリケーションやゲームにおいて、より複雑な計算や高度なグラフィックス処理が求められる場合に特に有用です。
ワークショップなどで活用することのできるブラウザSDK
0->1でのものづくりの際には、ゲームエンジンの活用が欠かせません。ゲームエンジンはグラフィックスのレンダリング、物理演算、音声、スクリプティング、アニメーション、人工知能、ネットワーキングなど、ゲーム開発に必要な多くの機能やコンポーネントを提供します。ゲームエンジンは、開発者がゼロから全てをコーディングする代わりに、これらの準備された機能を使用して、ゲームの独自の要素やロジックに集中できるように設計されています。
今回はブラウザをテーマとしているので、ブラウザ開発によく用いられるゲームエンジンをご紹介します。
Babylon.js(microsoft)、three.js、Cesium、Filament (google)
今回は、地図などを主体とした仕組みでの活用が想定されるCesiumと、
汎用的なMicrosoft社のBabylonの2つをテーマとして簡単な仕組みを提供する流れを作りたいと思います。
1.Hostingサーバーの準備
何をやるにも、まずはサーバーの準備が必要です。
自分のローカルマシンで立ち上げてlocalhostでアクセスする方法もありますが、
作ったものを誰かに見てもらうということが大事、ということで、今回はGlitchと呼ばれるホスティングサーバーをご紹介しいます。
Hostingサーバーの準備
Glichにアクセス
https://glitch.com/signin
右上のNew Projectを押下する
glitch-hello-websiteを押下する
左のファイルリストからindex.htmlを押下して、プログラミングをしよう
右上のShareを押下して、LivesiteのURLをコピーして、誰かに見てもらおう
2.Cesiumを使ってみよう
2-0.GlichのAssetsに下記の3Dモデルを読み込んでみてください。
読み込んだ後、CopyURLを押下してリンクをコピーしよう
2-1.Glichのindex.htmlに下記のコードをペーストしてみてください。
ソースコードをコピーする
コンテンツを追加したい場合は、表示したい地図の座標をGoogleMapで調べよう
簡単な内容
var target = viewer.entities.add({
name : 'かわまちてらす閖上',
// 緯度経度
position: Cesium.Cartesian3.fromDegrees(140.94808025489982,38.17948338366141),
point: {
pixelSize: 16,
color: Cesium.Color.YELLOW
},
label : {
text: 'かわまちてらす閖上',
font: 'bold 12pt Hiragino Maru Gothic ProN',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 10,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -16)
}
});
function createModel(lon,lat,h, url) {
var position = Cesium.Cartesian3.fromDegrees(lon,lat,h);
var heading = Cesium.Math.toRadians(150);
var pitch = Cesium.Math.toRadians(0);
var roll = Cesium.Math.toRadians(0);
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
);
var entity = viewer.entities.add({
name: url,
position: position,
orientation: orientation,
model: {
uri: url,
scale: 100,
},
});
}
createModel(140.94808025489982,38.17948338366141, 10, "./models/kaisendon.glb");
2-3.Sandcastleをみてみる
Cesium には、CesiumJS の機能を試すことができるインタラクティブな環境として、Cesium Sandcastle というものが用意されています。コードを書き換えるだけでサンプルに手を加えることが可能となっています。
3.Babylonを使ってみよう
2-0.GlichのAssetsに下記の3Dモデルを読み込んでみてください。
読み込んだ後、CopyURLを押下してリンクをコピーしよう
2-1.Glichのindex.htmlに下記のコードをペーストしてみてください。
3-e.完成イメージ
3-e.コード開設
シーンを作成して、重力と衝突を発生させる
var scene = new BABYLON.Scene(engine);
scene.enablePhysics();
scene.checkCollisions = true;
scene.collisionsEnabled = true;
scene.collisionEnabled = true;
scene.gravity = new BABYLON.Vector3(0, -9.81, 0);
ライトとカメラ、地面を作って準備
var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 2, -20), scene);
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);
camera.checkCollisions = true;
camera.applyGravity = true;
camera.ellipsoid = new BABYLON.Vector3(2, 2, 2);
camera.collisionRadius = new BABYLON.Vector3(0.5, 0.5, 0.5);
camera.attachControl(canvas, true);
camera.speed = 0.3;
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.8;
var ground = BABYLON.Mesh.CreateGround("ground1", 1000, 1000, 2, scene);
ground.receiveShadows = true;
ground.checkCollisions = true;
ground.physicsImpostor = new BABYLON.PhysicsImpostor(ground, BABYLON.PhysicsImpostor.BoxImpostor, {
mass: 0,
friction: 0.7,
restitution: 1.5,
}, scene);
海鮮丼を剛体にする
BABYLON.SceneLoader.ImportMeshAsync("", "./gltf/", "kaisendon.glb").then((result) => {
var box3 = BABYLON.Mesh.CreateBox("crate", 2, scene);
box3.position = new BABYLON.Vector3(0, 30, 0);
box3.checkCollisions = true;
box3.applyGravity = true;
box3.showBoundingBox = true;
box3.visibility = 0;
//質量や摩擦係
box3.physicsImpostor = new BABYLON.PhysicsImpostor(box3, BABYLON.PhysicsImpostor.BoxImpostor, {
mass: 2,
restitution: 0,
friction: 1,
}, scene);
result.meshes[0].scaling.x = 20;
result.meshes[0].scaling.y = 20;
result.meshes[0].scaling.z = 20;
result.meshes[0].position = new BABYLON.Vector3(0, 29, 0);
box3.addChild(result.meshes[0]);
});
ボタンを作ろう
let advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("myUI");
var button1 = BABYLON.GUI.Button.CreateSimpleButton("but1", "kaisendon");
button1.width = "150px"
button1.height = "40px";
button1.color = "white";
button1.cornerRadius = 20;
button1.background = "black";
button1.onPointerUpObservable.add(function () {
addObject();
});
advancedTexture.addControl(button1);
3Dデータを自分で作ってみよう
事前にscanierseやlumaaiなどで撮影したデータを.glbファイルに変換させて利用する準備をしよう。
撮影したデータをGLTFでダウンロード
または、こちらで用意したサンプルデータをダウンロードできます
ダウンロードした.glbファイルをビューアーを用いることで立体的にみることができます。
https://gltf-viewer.donmccurdy.com/
VRにも対応できる
VR対応
https://www.youtube.com/watch?v=OqA8Xr3Njaw
電車走行(3画面分割)
https://oggata.github.io/train-demo/
動物パズル
https://oggata.github.io/animalmashup/
マップを探索するサンプル
https://playground.babylonjs.com/#0VHCTL#32