Decentraland SDK version5.0 を用いてsceneを作ります。
ステージとか丸い物体のパーツは素材としてもともと存在していて、その素材を特定の位置に配置させたり丸い物体(以降、車輪と呼びます)をぐるぐる回転させたりするのをコーディングで作成します。
※decentralandのチュートリアルの日本語訳です。公式を読みたい場合はこちらから
空のsceneを作成する
まずはDecentraland SDK をインストール
npm install -g decentraland
空のフォルダを作成し、そのディレクトリに移動し、以下のコマンドを実行する
dcl init
game.ts
を開いて、ファイル内のコードを全て削除する。
scene内で使用するアセットをこのリンクからダウンロードし、/materials
と/models
を該当ディレクトリのルートディレクトリに配置する。
EntityとComponentを追加する
ステージEntityの作成
game.ts
に以下のコードを追加する
let stage = new Entity()
stage.addComponent(new GLTFShape("models/Theatre.gltf"))
stage.addComponent(new Transform({
position: new Vector3(8, 0, 8),
rotation: Quaternion.Euler(0, 90, 0)
}))
engine.addEntity(stage)
上記のコードでは、stage
という名前のEntityを作成している。
で、Entityに各Componentを追加していく。
GLTFShape
コンポーネントは.gltf 3Dモデルをロードしてくれる。
この3Dモデルには、このsceneにある全ての固定物(車輪以外)が含まれている
Transform
コンポーネントは、Entityの位置や回転、スケールを定義する。
最後に、engineにstageを追加する。
車輪Entityの作成
通り抜けができないような設定をしていく。
let CylinderWCollisions = new CylinderShape()
CylinderWCollisions.withCollisions = true
CylinderShape
コンポーネントは人が通り抜けできないようにcolliderとして振舞う。
次に、車輪Entityの作成
// Create the first wheel entity
let wheel1 = new Entity()
wheel1.addComponent(CylinderWCollisions)
wheel1.addComponent(new Transform({
position: new Vector3(6, 2, 11.9),
rotation: Quaternion.Euler(90, 0, 0),
scale: new Vector3(1, 0.05, 1)
}))
engine.addEntity(wheel1)
// Create a second wheel entity
let wheel2 = new Entity()
wheel2.addComponent(CylinderWCollisions)
wheel2.addComponent(new Transform({
position: new Vector3(10, 2, 11.9),
rotation: Quaternion.Euler(90, 0, 0),
scale: new Vector3(1, 0.05, 1)
}))
engine.addEntity(wheel2)
Quaternionの概念は難しいが、Elulerという関数を使うことで通常の0-360の角度を使えるようになるっぽい
ルードディレクトリで以下を実行するとsceneのプレビューが見れます
dcl start
Material
車輪にTextureを与える
// Create texture
const spiralTexture = new Texture("materials/hypno-wheel.png")
// Create material
let spiralMaterial = new Material()
spiralMaterial.albedoTexture = spiralTexture
// Add material to wheels
wheel1.addComponent(spiralMaterial)
wheel2.addComponent(spiralMaterial)
コンポーネントのカスタマイズ
@Component('wheelSpin')
export class WheelSpin {
active: boolean = false
speed: number = 30
direction: Vector3 = Vector3.Up()
}
- 車輪が回転しているかどうかを確認するためのbool値
- 回転速度を表す数値
- スピンの方向を表すベクトル
一度カスタムコンポーネントを定義するとscene内のどこでも使えます。
wheel1.addComponent(new WheelSpin())
wheel2.addComponent(new WheelSpin())
コンポーネントグループ
コンポーネントグループとは、特定の条件に一致するscene内の全てのEntityを追跡する配列。
const wheels = engine.getComponentGroup(WheelSpin)
WheelSpinコンポーネントを持つ全てのEntityを配列で表してくれます。
wheelsは後ほど使います。
クリックで特定の動きをさせる
車輪をクリックすると、ぐるぐる回り出すという動きを付ける
wheel1.addComponent(
new OnPointerDown(e => {
let spin = wheel1.getComponent(WheelSpin)
if (!spin.active){
spin.active = true
} else {
spin.speed += 20
}
//log("speed: ", spin.speed)
})
)
wheel2.addComponent(
new OnPointerDown(e => {
let spin = wheel2.getComponent(WheelSpin)
if (!spin.active){
spin.active = true
} else {
spin.speed += 30
}
//log("speed: ", spin.speed)
})
)
export class RotatorSystem implements ISystem {
update(dt: number) {
for (let wheel of wheels.entities) {
let spin = wheel.getComponent(WheelSpin)
let transform = wheel.getComponent(Transform)
if (spin.active){
transform.rotate(spin.direction, spin.speed * dt)
}
}
}
}
これで車輪がぐるぐる回るようになりました。
次は、車輪の動きを変えたり、トリガーボタンを設置する実装を付け加えたい。