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

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

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


# できました

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

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">A-frameのアニメーションを、手で動かせるようにしてみました。ただ、右がうまく機能しなかった。。機械学習のやり直しかな。<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/Aframe?src=hash&amp;ref_src=twsrc%5Etfw">#Aframe</a> <a href="https://twitter.com/hashtag/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92?src=hash&amp;ref_src=twsrc%5Etfw">#機械学習</a>　<a href="https://twitter.com/hashtag/AI?src=hash&amp;ref_src=twsrc%5Etfw">#AI</a> <a href="https://t.co/EGLGB02SzH">pic.twitter.com/EGLGB02SzH</a></p>&mdash; 柳瀬浩之@人材開発×UX専門家 (@btap_hiro) <a href="https://twitter.com/btap_hiro/status/1306408718259683329?ref_src=twsrc%5Etfw">September 17, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


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

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


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

[こちら](https://jolly-brahmagupta-dec47b.netlify.app "こちら")

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


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


# 使った機能

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

# つくりかた

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

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

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


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

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

```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);
```

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


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

[こちら](https://developer.mozilla.org/ja/docs/Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_A-Frame "こちら")


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

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


![image11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664861/b270e7fa-7ecc-1619-69b8-54206ee37fa8.png)

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

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

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

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

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


```javascript

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のダウンロードページ](https://github.com/usablica/intro.js/releases"intro.js")


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

読み込み方

```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">
```

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

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

そして、最後にscript内に

```javascript
introJs().start();
```

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



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

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

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

など。

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


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