ちら帳

喉元を過ぎると熱さを忘れる自分の為の、ちら裏メモ帳ブログです。

React VRでVrButtonに効果音をつける

今日も今日とてひっそりとReact VRをいじっております。ちらです。

今回は画面内にボタンを置いて、フォーカスが当たる・クリックされるといったイベントが発生したら効果音を鳴らすようにしてみます。

f:id:chira_pym:20170605031426p:plain

ボタンを表示する

ボタンの表示にはVrButtonコンポーネントを使います。 HTMLの<button>にとてもよく似ていますが、VrButtonはイベントをキャプチャするためのラッパーであり、外観を持たないようです。

実際にはTextやImageをラップして使います。

詳しくは例によってこちら。 facebook.github.io

VrButtonの入力に使えるボタンやキー

VrButtonでクリックイベントを検知できる入力については公式ドキュメントに以下の4つが挙げられています。

  • XboxゲームパッドのAボタン
  • キーボードのスペースキー
  • マウスの左クリック
  • スクリーンタッチ

XboxゲームパッドのAボタンが挙げられていますが、他のゲームパッドでも入力を検知することができます。 ただし、必ずAボタンが対応しているというわけではなく、Gamepad APIのGamepad#Buttons配列のインデックスが0のボタンが入力ボタンとなります。

ちなみに私はWindows 環境にOculus Touchを繋いで開発しているのですが、入力ボタンはスティックキーの押し込むところになっていました。

UnityだとOculus TouchのAボタンはjoystick button 0 が割り当てられているのですが、Gamepad APIだとキーマップが違うのでしょうか。

音を鳴らす

onClickイベントを検知して音源再生のAPIを叩く…のでもいいのですが、それをやってくれる専用のpropがVrButtonには用意されています。

  • onClickSound :ボタンにフォーカスが当たっている状態でクリックした時(厳密にはボタンなどを押して離した瞬間)に音源を再生します。
  • onLongClickSound :ボタンにフォーカスが当たっている状態で長めにクリックした時(厳密にはボタンなどを押して離した瞬間)に音源を再生します。
  • onEnterSound :ボタンにフォーカスが当たった瞬間に音源を再生します。
  • onExitSound :ボタンからフォーカスが外れた瞬間に音源を再生します。

なお、ボタンを押して離したタイミングではなく、ボタン押下時に音を鳴らしたい場合は、onButtonPressイベントを検知して、音源を再生する処理を書く必要がありそうです。

具体的にはあらかじめ再生したい音源をVrSoundEffects.loadでロードしておき、VrButttonのonButtonPressイベントが検知されたタイミングで、VrSoundEffects.playを使って音源を再生するといった流れになると思います。

サンプルプログラム

それでは前置きが長くなりましたが、VrButtonのonClick, onLongClick, onEnterSound, onExitSoundを使って効果音を鳴らすプログラムがこちらになります。

import React from 'react';
import { AppRegistry, asset, Pano, Text, View, VrButton} from 'react-vr';

export default class ButtonSample extends React.Component {

    constructor() {
        super();

        this.state = {
            sound:  {
                        wav: asset('click.wav'),
                        ogg: asset('click.ogg'),
                        mp3: asset('click.mp3')
                    }
        };
    }

    render() {
        const sound = this.state.sound;
        return (

            <View>
                <Pano source={asset('chess-world.jpg')}/>

                <View style={{
                    flex: 1,
                    flexDirection: 'row',
                    width: 5,
                    alignItems: 'stretch',
                    transform: [{translate: [-2.5, 0, -5]}],
                }}>

                <SampleButton text="Click" onClickSound={sound}/>

                <SampleButton text="LongClick" onLongClickSound={sound}/>

                <SampleButton text="Enter" onEnterSound={sound}/>

                <SampleButton text="Exit" onExitSound={sound}/>

            </View>
        </View>
        );
    }
}

export class SampleButton extends React.Component {

    static propTypes = {
        color: React.PropTypes.string,
        text: React.PropTypes.string,
        onClickSound: React.PropTypes.object,
        onLongClickSound: React.PropTypes.object,
        onEnterSound: React.PropTypes.object,
        onExitSound: React.PropTypes.object
    };


    static defaultProps = {
        color: 'coral',
        text: '',
        onClickSound: null,
        onLongClickSound: null,
        onEnterSound: null,
        onExitSound: null
    };

    constructor(props){
        super(props);
    }

    render(){
        return(

            <VrButton
                onLongClick={()=>{}}
                onClickSound={this.props.onClickSound}
                onLongClickSound={this.props.onLongClickSound}
                onEnterSound={this.props.onEnterSound}
                onExitSound={this.props.onExitSound}
                style={{flex: 1}}>
                    <Text style={{fontSize: 0.2, textAlign: 'center', margin: 0.1, height: 0.3, backgroundColor: this.props.color}}>{this.props.text}</Text>
            </VrButton>
        );
    }
}

AppRegistry.registerComponent('ButtonSample', () => ButtonSample);

onLongClickSoundの再生にはonLongClickの指定が必要

仕様なのか、バグなのか、onLongClickSoundのみ、音源を再生するには対応するイベントの定義が必要です。
onLongClickで何もしないで音だけ鳴らしたいということはほとんどないかもしれませんが、そうしたい場合は上のコードのようにonLongClick={()=>{}}を指定する必要があります。

VrButtonの詳しい実装についてはこちらのソースをお読みください。 github.com

ひとこと

cluster.でReact VRとかA-Frameとかの勉強会ってやってないのでしょうか。
おうちでのんびり聴講したいです。