6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

A-FrameをつかってWebVRをためしてみた!

Last updated at Posted at 2020-06-03

概要

この記事はVue.jsで作ったサイトに3Dをいれてみたいというところで手軽にWebVRを実装できるというA-Frameをさわってみました

できたもの

色々足りず、ホラーなものができました。
2匹猫がいて、猫をクリクすると、猫が回ったり、雪が降ったりします。
猫はこちらからシャム猫3Dモデルとアメリカンショートヘアの3Dモデルをお借りしたのですが、なぜか表面がついてきませんでした。。。

環境

macOS Catalina 
Visual Studio Code 1.45.1
Node.js: v13.11.0
npm:6.14.5
Vue:@vue/cli 4.3.1

大まかな流れ

  1. Vue.jsとFirebaseでログイン認証付きのページをつくる
  • A-Frameをいれる
  • 3Dモデルに動きをつける
  • ドメインをとって公開

という流れです

1. Vue.js くみたてる

Vue.jsを勉強中のため、ちょっとむやみにセキュアなページにします。
こちらを参考に
Vue.jsでつくったサイトにfirebaseでユーザ認証してこっそり人の顔年齢を試して遊ぶ - Qiita
Firebaseでログイン処理をつくってVue.jsで3Pほどのページをつくります。

2. A-Frameをいれる

A-Frame – Make WebVR
スクリーンショット 2020-06-03 14.48.51.png

npmでいれたいのでaframe - npmこちらからインストールしていきましょう。
サンプルをベースに猫の3Dオブジェクトを2体配置します。
猫にたいしてクリックイベントをつけます。
A-Frameのパーティクルコンポーネントを使って雪をふらしましょう
Entity-Component-System – A-Frame
こちらもnpmでいれちゃいますaframe-particle-system-component - npm

3.3Dモデルに動きをつける

猫をクリックすると猫がグルングルン回るものと
猫をクリックしたら雪が降るというものをつくります


<template>
<a-text font="kelsonsans" value="Click Me!" width="6" position="1.5 1 -1.5" rotation="0 0 0"></a-text>
        <a-assets>
          <img id="sample_img" src="/static/cat.png" />
          <a-asset-item id="sample_obj" src="/static/cat-print.obj"></a-asset-item>
          <a-asset-item id="sample_mtl" src="/static/cat-print.mtl"></a-asset-item>
        </a-assets>
        <a-obj-model scale="0.3 0.3 0.3" position="2.5 0 -1.5" src="#sample_obj" mtl="#sample_mtl" animation__star_rotation="property: rotation; startEvents:click; from: 0 0 0; to: 0 360 0; loop:5;"></a-obj-model>

        <a-entity id="snow" visible="false">
        <a-entity particle-system="preset:snow;" position="0 0 -4"></a-entity>
      </a-entity>

        <a-assets>
          <img id="neko_img" src="static/CatTexture.png" />
          <a-asset-item id="neko_obj" src="/static/neko.obj"></a-asset-item>
          <a-asset-item id="neko_stl" src="/static/neko.stl"></a-asset-item>
        </a-assets>
        <a-obj-model scale="0.2 0.2 0.2" position="-4.5 -1 -1.5" src="#neko_obj" mtl="#neko_stl" @click="handlerMouseEnter"></a-obj-model>
</template>
<script>
import firebase from 'firebase'
import 'aframe'

export default {
  name: 'Vue3d',
  el: '#aframeApp',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      name: firebase.auth().currentUser.email,
      skyboxSrc: 'https://images.unsplash.com/photo-1505252772853-08ed4d526ceb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'
    }
  },
  methods: {
    handlerClick: function (event) {
      let boxid = event.target.id
      if (boxid === 'areabox2') {
        this.skyboxSrc = 'https://images.unsplash.com/photo-1557971370-e7298ee473fb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'
      }
    },
    handlerMouseEnter: function (event) {
      document.getElementById('snow').setAttribute('visible', 'true')
    }
  }
}
</script>

全体のコードはこちら

<template>
  <div class="hello">
    <div class="inf">
      <h2>猫を探してください</h2>
      <p>ここには猫が2匹います。<br>真ん中にある<span class="maru"></span>を動かして、猫を探してクリックしてあげてください
      </p>
    </div>
      <a-scene>
        <a-entity id="aframeApps">
          <!-- 背景設定 -->
          <a-sky ref="skybox" v-bind:src="skyboxSrc" rotation="0 -130 0"></a-sky>
          <a-box id="areabox2" position="2.5 0 1.5" rotation="45 45 45" @click="handlerClick"></a-box>
        </a-entity>
        <!-- ぐるぐる回る猫 -->
        <a-text font="kelsonsans" value="Click Me!" width="6" position="1.5 1 -1.5" rotation="0 0 0"></a-text>
        <a-assets>
          <img id="sample_img" src="/static/cat.png" />
          <a-asset-item id="sample_obj" src="/static/cat-print.obj"></a-asset-item>
          <a-asset-item id="sample_mtl" src="/static/cat-print.mtl"></a-asset-item>
        </a-assets>
        <a-obj-model scale="0.3 0.3 0.3" position="2.5 0 -1.5" src="#sample_obj" mtl="#sample_mtl" animation__star_rotation="property: rotation; startEvents:click; from: 0 0 0; to: 0 360 0; loop:5;"></a-obj-model>
        <!-- 雪を最初非表示 -->
        <a-entity id="snow" visible="false">
          <a-entity particle-system="preset:snow;" position="0 0 -4"></a-entity>
        </a-entity>
        <!-- 雪を降らす猫 -->
        <a-assets>
          <img id="neko_img" src="static/CatTexture.png" />
          <a-asset-item id="neko_obj" src="/static/neko.obj"></a-asset-item>
          <a-asset-item id="neko_stl" src="/static/neko.stl"></a-asset-item>
        </a-assets>
        <a-obj-model scale="0.2 0.2 0.2" position="-4.5 -1 -1.5" src="#neko_obj" mtl="#neko_stl" @click="handlerMouseEnter"></a-obj-model>

        <a-entity>
          <a-camera>
            <a-cursor></a-cursor>
          </a-camera>
        </a-entity>
      </a-scene>

</div>
</template>

<script>
import firebase from 'firebase'
import 'aframe'

export default {
  name: 'Vue3d',
  el: '#aframeApp',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      name: firebase.auth().currentUser.email,
      skyboxSrc: 'https://images.unsplash.com/photo-1505252772853-08ed4d526ceb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'
    }
  },
  methods: {
    handlerClick: function (event) {
      console.log('handlerClick')
      console.log(event.target.id)
      let boxid = event.target.id
      if (boxid === 'areabox2') {
        this.skyboxSrc = 'https://images.unsplash.com/photo-1557971370-e7298ee473fb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1600&q=80'
      }
    },
    handlerMouseEnter: function (event) {
      console.log('handlerMouseEnter')
      console.log(event)
      document.getElementById('snow').setAttribute('visible', 'true')
    }
  }
}
</script>
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
.inf{
    position: absolute;
    left: calc(50% - 16rem);
    top: 20%;
    z-index: 99999;
    color: #fff;
    font-size: 1rem;
    padding: 0.5rem;
    background: hsla(0,0%,100%,.18);
    width: 32rem;
}
.maru{
  font-size:80%;
  color:#000;
  font-weight:bold;
}
</style>

ドメインを取るNetlifyにDeploy

こちらを参考にfreenomでドメインをとってNetlifyにDeployします
Vue.jsでつくったサイトにfirebaseでユーザ認証してこっそり人の顔年齢を試して遊ぶ - Qiita

できなかったところ

最初のロード時にA-Frameのデフォルト?の水色とか出てきちゃうのをとめたかった。。。あれはなんだろう。
猫の表面が読み込めず、石膏像になってしまった。
Singin画面に画像を置いたのですがうまく反映されず。publicにおいたのに。。。


<img v-bind:src="img">
 ---略---
data: function () {
    return {
      img: '/public/img/nko3d.png'
    }
  }

参考サイト

AframeをVue.jsで使うよ! : 新人SEの気まぐれ日記
新しいWebVRフレームワークA-Frame入門 - Qiita
A-Frame v1.0 で クリスマスアニメーション - Qiita

感想

簡単に3Dが実装できた!でもちょっとやり込もうとするとやはり難しかった・・・。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?