機械学習で、指でA-frameの3Dオブジェクトを動かすアプリをつくった


3Dの物体を指で動かしてみよう

A-frameを学び、animationの動きを見ていて、このanimationを指で動かせないかと思って、色々試してみました。動かせたら、ちょっとしたゲームができそうだなと。

できました

つくったものをまずご覧ください。

まだ機械学習の精度が低く、思ったようには動いてくれませんが、一応、手の動きに合わせて、アニメーションが変わるように設定できました。

また、使い方のチュートリアルが表示されるように、intro.jsも使ってみました。

WEBサイトも以下に公開しています。

こちら

※ただ、ローカルでファイルから開いた時は問題ないのですが、NetlifyでWEBサイトを公開すると、intro.jsのチュートリアルがうまく機能しません。原因がよくわかりません。

→(解決)単純に、動画が許可されてしまうと、すぐに画像認識のプログラムが動いてしまい、intro.jsのチュートリアルがストップしてしまうだけでした。

使った機能

・Javascript
・teachableMachine
・A-frame
・intro.js

つくりかた

ポイントだけ書いていきます。

まず対象物をA-frameで表示させる

ただA-frameのquickstartで書かれているやり方

<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>

これに後でanimationを追加する方法がわからなかったので、javascriptで対象物を作成してみました。

const scene = document.querySelector('a-scene');
let sphere = document.createElement('a-sphere');
sphere.setAttribute('color', '#FF9500');
sphere.setAttribute('radius', '0.5');
sphere.setAttribute('position', '0 0 -5');
scene.appendChild(sphere);

これで球体が表示されます。

以下の記事を参考にしました。

こちら

手の動きを機械学習で覚えさせる。

機械学習で使ったのが、teachableMachine。
手軽に学習できます。

使い方も簡単。
上、下、左、右、それぞれの手の形を写真で撮って覚えさせるだけです。

そうすると、URLが発行され、以下のコードをいれると簡単に使えるようになります。

const imageModelURL = 'TeachableMachineで取得したURL';

手の動きによって、球体にアニメーションを追加する

手の動きを解析した結果で、アニメーションを追加させるようにしました。


classifier.classify(onDetect);
    function onDetect(err, results) {
        console.log(results);
        if (results[0]) {
            console.log(results[0].label);
            if (results[0].label === '') {
                // [FIX] sound 関数実行
                moveUp();
            } else if (results[0].label === '') {
                moveDown();
            } else if (results[0].label === '') {
                moveRight();
            } else if (results[0].label === '') {
                moveLeft();
            } 
        }
        classifier.classify(onDetect);
    }
    // sphere.setAttribute('position', '0 0 -5');
    function moveUp() {
        sphere.setAttribute('animation', 'property: position; to: 0 5 -3; dur: 2000; easing: linear; loop: true');
    }
    function moveDown() {
        sphere.setAttribute('animation', 'property: position; to: 0 -5 -3; dur: 2000; easing: linear; loop: true');
    }
    function moveRight() {
        sphere.setAttribute('animation', 'property: position; to: 5 0 -3; dur: 2000; easing: linear; loop: true');
    }
    function moveLeft() {
        sphere.setAttribute('animation', 'property: position; to: -5 5 -3; dur: 2000; easing: linear; loop: true');
    }

チュートリアルを追加する

ちょっと前から気になっていたintro.jsを使ってみました。

サイトにも書いてある通り、簡単に使うことができました。

intro.jsのサイトから最新版をダウンロードして、

intro.jsのダウンロードページ

その内、intro.jsとintrojs.cssの2つのファイルを、index.htmlと同一ファイル内におさめ、index.htmlから読み込みます。

読み込み方

<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<script src="intro.js"></script>
<link rel="stylesheet" type="text/css" href="introjs.css">

チュートリアルの内容を作成します。

<div data-intro="" data-step="1">※3ステップを読んでから、動画の再生ボタンを押してください。</div>
<div data-intro="" data-step="2">1.カメラの使用を許可してください</div>
<div data-intro="" data-step="3">2.動画に向かって上下左右を指で指してください</div>
<div data-intro="" data-step="4">3.すると、球を指の方向へ動かせます</div>
<div data-intro="" data-step="5">では、「Done」を押して、ステップ1からはじめましょう。</div>

そして、最後にscript内に

introJs().start();

これを書けば、完成です。

この機能を使えば、ゲームがつくれそう

今回はゲームをつくるまでにはたどり着けなかったんですが、手で物体が動かせるということは、簡単なゲームが作れそうです。

・ボールを目的地まで動かす
・ちょっとした野球ゲーム

など。

自分の手で野球ゲームが作れたら面白そうだな、なんて思いました。

よかったら、LGTMお願いします!!