こんにちは、ナレコム前川です。
今回は、Amazon Sumerian の公式チュートリアルのPhysics Part 2を進めていきたいと思います。
ここで学ぶのは、
・Rigid Body component
・Collider component
・State Machine
・Scripting
の4つです。
それでは、進めていきましょう。
1. 2つの Bumper を追加
まずはじめに、Table の傾きを 0 に変更してください。
① Bumper1 を選択し、複製。 Bumper4, Bumper5 を追加。
② 以下のように Bumper を配置。
※ここは好きなように配置して良いです。
2. Slant の追加
① Create Entity から Box を 2つ 追加。
② 名前を 「LeftSlant」と「RightSlant」に変更。
③ Transform を以下のように設定。
④ それぞれ Collider コンポーネントを追加し、以下のように設定。
– Friction : 0
– Restitution : 0.5
設定が完了したら、キャンバス内では以下のように配置されていると思います。
3. Flipper の追加
Flipper Pivot
① Create Entity から Empty Entity を 2つ 追加。
② 名前を「LeftFlipperPivot」と「RightFlipperPivot」に変更。
③ Transform をそれぞれ以下のように設定。
④ それぞれ Rigit Body コンポーネントを追加して、Kinematic にチェックを入れる。
Flipper
① Create Entity から Box を 2 つ追加。
② 名前を「LeftFlipper」と「RightFlipper」に変更。
③ それぞれの Flipper を FlipperPivot の子要素にする。
④ それぞれの Flipper の Transform を以下のようにする
⑤ 両方に Collider コンポーネントを追加し、以下のように設定。
実行して、衝突判定がきちんと行われているか確認しましょう。
私の場合は、前回のバグが改善されていないので、すり抜けて行ってしまいました。
はじめからシーンを作り直した際には、うまくいきました。
4. Script の追加
① Table を選択して、Script コンポーネントを追加。
② + ボタンをクリックし、Customを選択。
③ 編集ボタンをクリックして、エディタを開く。
④ 以下のコードをコピーしてエディタ内のコードと置き換える。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
var setup = function(args, ctx, sumerian) { ctx.speed = 8; ctx.cw = new sumerian.Vector3(0, ctx.speed, 0); // clockwise rotation ctx.ccw = new sumerian.Vector3(0, -ctx.speed, 0); // counterclockwise rotation ctx.tempVec = new sumerian.Vector3(0,0,0); ctx.tempQuat = new sumerian.Quaternion(); ctx.roundit = function(v) { return Math.round(v * 100) / 100; }; function initFlipper(name, dir, vec) { var f = ctx.world.by.name(name).first(); f.on = false; f.lr = f.transformComponent.transform.rotation; // local rotation shortcut f.wr = f.transformComponent.worldTransform.rotation; // world rotation shortcut f.lr.toAngles(ctx.tempVec); f.start = ctx.roundit(ctx.tempVec.y); // flipper start rotation f.goal = ctx.roundit(ctx.tempVec.y + dir); // flipper end rotation f.wr.applyPost(vec); // tilt the cw or ccw rotation vector along the table slope return f; } ctx.LeftFlipper = initFlipper('LeftFlipperPivot', Math.PI * 0.25, ctx.cw); ctx.RightFlipper = initFlipper('RightFlipperPivot', -Math.PI * 0.25, ctx.ccw); ctx.ball = ctx.world.by.name('Ball').first(); function react(e, flag, dirLeft, dirRight) { switch(e.keyCode){ case sumerian.ScriptUtils._keys.Leftarrow: case sumerian.ScriptUtils._keys.A: if(flag === ctx.LeftFlipper.on){ ctx.LeftFlipper.on = !flag; ctx.LeftFlipper.rigidBodyComponent.setAngularVelocity(dirLeft); } break; case sumerian.ScriptUtils._keys.Rightarrow: case sumerian.ScriptUtils._keys.D: if(flag === ctx.RightFlipper.on){ ctx.RightFlipper.on = !flag; ctx.RightFlipper.rigidBodyComponent.setAngularVelocity(dirRight); } break; } } ctx.keydown = function(e) { react( e,false,ctx.cw,ctx.ccw); }; ctx.keyup = function(e) { react( e,true,ctx.ccw,ctx.cw); }; document.body.addEventListener('keydown', ctx.keydown, false); document.body.addEventListener('keyup', ctx.keyup, false); document.body.addEventListener('touchstart', ctx.keydown, false); document.body.addEventListener('touchend', ctx.keyup, false); ctx.checkTarget = function(flipper, target, speed, comparator) { var tc = flipper.transformComponent; flipper.lr.toAngles(ctx.tempVec); var rot = ctx.roundit(ctx.tempVec.y); if(rot !== flipper.goal){ var angle = ctx.tempVec.y + speed * ctx.world.tpf; if( (comparator === '>=' && angle >= target) || (comparator === '<=' && angle <= target)){ flipper.rigidBodyComponent.setAngularVelocity(sumerian.Vector3.ZERO); flipper.lr.fromAngles(0, target, 0); tc.updateTransform(); tc.updateWorldTransform(); ctx.tempQuat.fromRotationMatrix(tc.worldTransform.rotation); flipper.rigidBodyComponent.setQuaternion(ctx.tempQuat); } } } }; var cleanup = function(args, ctx, sumerian) { document.body.removeEventListener('keydown', ctx.keydown); document.body.removeEventListener('keyup', ctx.keyup); document.body.removeEventListener('touchstart', ctx.keydown); document.body.removeEventListener('touchend', ctx.keyup); }; var update = function(args, ctx, sumerian) { if(ctx.LeftFlipper.on){ ctx.checkTarget( ctx.LeftFlipper, ctx.LeftFlipper.goal, ctx.speed, '>='); } else { ctx.checkTarget( ctx.LeftFlipper, ctx.LeftFlipper.start, -ctx.speed, '<='); } if(ctx.RightFlipper.on){ ctx.checkTarget( ctx.RightFlipper, ctx.RightFlipper.goal, -ctx.speed, '<='); } else { ctx.checkTarget( ctx.RightFlipper, ctx.RightFlipper.start, ctx.speed, '>='); } }; |
保存して、エディタを閉じたら実行してみてください。
実行の様子は以下からご覧ください。
キーボードの ← → ボタンをクリックすると、追加したFlipperを動かすことができます。
これで、落ちてきたボールを跳ね返して遊ぶことができるようになっています。
今回のチュートリアルは以上です。
お疲れ様でした。