【Unity入門】打楽器を作成する|AR楽器アプリ作成②
UnityでVuforiaを使用したAR楽器アプリを作成します。
前回はVuforiaの初期設定について解説してきました。
今回は実際にタップすると音が鳴る打楽器を作成していきます。
Contents
アプリ概要
今回作成するAR楽器アプリはARマーカーを使用して、マーカー上にドラムを出現させます。
↓完成イメージ
出現したドラムをタップすることで音とエフェクトを出力するような仕様を実現していきます。
今回はドラムのアセットを含めて全て無料の素材を使用します。
作成の流れは、
- VuforiaでARマーカーとなる画像を登録する
- UnityでVuforiaを使用できる状態にする
- ドラムを作成する
- AR化する
- ドラムを拡大・縮小できるようにする(おまけ)
- iPhoneで実装する←本記事ではここまで
以上の流れで作成していきます。
前回の記事ではARマーカーをUnityで扱うところまで進めました。
ここまでの方法がわからない方は前回の記事をご参考ください。
↓前回までに以下の状態になっている
打楽器アセットをインポートする
今回使用する打楽器のアセットをダウンロード・インポートします。
アセットストアから「Drum Kit For Your Band」をダウンロード・インポートしてください。
インポートするとプロジェクトウィンドウにドラムのアセットが追加されます。
Drum_Kit_For_Your_Band→赤枠Prefabsを選択すると、ドラムのプレハブがあります。
今回はこの中でスネアドラムと呼ばれる打楽器をタップすると音が鳴る仕様にしていきます。
一つの実装方法を理解できれば、他の楽器も音の素材を変更するだけで実装できます。
オブジェクトをAR化する
ではスネアドラムをシーンビューに呼び出して、実際にARとして出力できる状態にしてみましょう。
先ほど開いたドラムアセットのフォルダから「DKFYB_SnareDKFYB_Snare_drum」をシーンビューにドラッグ&ドロップしてください。
↓アセットをシーンビューへドラッグ&ドロップ
シーンビューに呼び出したプレハブ化を解除します。
ヒエラルキーウィンドウのDKFYB_SnareDKFYB_Snare_drumを右クリックで選択してください。
選択したら、以下赤枠「UnpackPrefabCompletely」を選択してください。これでプレハブ化を解除できます。
スネアオブジェクトの座標を調節します。
ヒエラルキーウィンドウのDKFYB_SnareDKFYB_Snare_drumを選択してください。
インスペクターウィンドウのPositionの値を全て「0」に変更してください。
↓スネアオブジェクトのTransformの値
↓変更後の位置関係
呼び出したオブジェクトをAR化します。方法は非常に簡単です。
作成したスネアオブジェクトを前回の記事で作成したイメージターゲットオブジェクトの子オブジェクトにするだけで、AR化することができます。
↓スネアをイメージターゲットの子オブジェクトにする
すでにこの状態で実行してカメラで画像を認識するとスネアが出力されます。
PCにカメラが取り付けてあれば確認できますのでぜひ確認してみてください。
↓筆者のPCで撮影した画像(MacBook内蔵カメラではAR化されたスネアを確認できました)
タップして音が鳴るようにする
はじめに音声データをUnityに取り込みます。
音声データはネットなどからお好きなデータを取り込んでください。
ここでは以下のmp3形式の素材を使用します。
ダウンロードしてきた音声をUnityで使用する方法は非常に簡単です。
以下のように音声データをプロジェクトウィンドウにドラッグ&ドロップしてください。
↓音声データをドラッグ&ドロップ
取り込んだ音声データをスネアに取り付けます。
ヒエラルキーウィンドウでスネアオブジェクトを選択してください。
次に以下のようにインスペクターウィンドウのAddComponentから「AudioSource」コンポーネントを選択します。
↓AudioSourceコンポーネント取り付け
取り付けたAudioSourceコンポーネントで先ほど取得した音声データを取り付けます。
以下赤枠①AudioClipの左の丸を選択してSelectAudioClipウィンドウを表示します。次に赤枠②取り込んだ音声データを選択します。
最後に赤枠③PlayOnAwakeを選択してオブジェクト生成時に音声が出力されないように変更して設定完了です。
次にタップしたときに音が鳴るようなスクリプトを作成します。
ヒエラルキーウィンドウでスネアオブジェクトを選択してAddComponentから「NewScript」を選択してください。
スクリプトの名前は任意ですが、ここでは「SoundSnare」として作成します。
↓SoundSnareスクリプト作成
スクリプトを編集します。今回はタップされたときにAudioSourceで設定した音声が出力されるようなスクリプトを作成します。
スクリプトを以下のように変更してください。
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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SoundSnare : MonoBehaviour { //AudioSourceコンポーネント保存用変数 private AudioSource audioSource; //ARカメラ保存用変数 private Camera camera; // Start is called before the first frame update void Start() { //AudioSourceコンポーネントを取得し、変数に格納 audioSource = GetComponent<AudioSource>(); //ARカメラを取得し、変数に格納 camera = GameObject.Find("ARCamera").GetComponent<Camera>(); } // Update is called once per frame void Update() { //タップされたかどうか確認するメソッド「TouchCheck()」がTrueの場合 if (TouchCheck()) { //audioSourceのClipを再生する audioSource.PlayOneShot(audioSource.clip); } } //自分自身(取り付けオブジェクト自身)がタップされた場合Trueを返すメソッド bool TouchCheck() { //タッチ数を取得 int touchCount = Input.touchCount; //タッチ数が0より大きい場合 if (touchCount > 0) { //タッチの回数分ループ for (int i = 0; i < touchCount; i++) { //i回目のタッチ情報を取得 Touch touch = Input.GetTouch(i); //タップ位置からRayを取得 Ray ray = camera.ScreenPointToRay(touch.position); //ヒットしたオブジェクトの情報 RaycastHit hit = new RaycastHit(); //Rayを投げる if (Physics.Raycast(ray, out hit)) { //当たったオブジェクトが自分自身だった場合 if (hit.collider.gameObject == gameObject) { //Trueを返す return true; } } } } //自分自身に当たらなかった場合、falseを返す return false; } } |
これでオブジェクトがタップされたときに音声データが出力されるようになりました。
エフェクトを作成する
次にパーティクルシステムコンポーネントを使用してタップされたときに表示するエフェクトを作成します。
ヒエラルキーウィンドウでスネアオブジェクトを選択してください。
インスペクターウィンドウでAddComponentを選択して、Effects→ParticleSystemを選択してください。
パーティクルの設定を変更します。
基本値を以下のように変更してください。(画像赤線部が変更した部分です)
- Duration:0.30
- Looping:チェックを外す
- StartLifetime:0.1
- StartSpeed:3
- StartSize:0.1
- PlayOnAwake:チェックを外す
次にEmission値を変更します。
- RateOverTime:50
次にShapeの値を変更します。
- Angle:60
- Position:X=0、Y=0.6、Z=0
- Rotation:X=-90、Y=0、Z=0
- Scale:X=0.3、Y=0.3、Z=0.3
最後にRendererの値を変更します。
- 赤枠①Materialの右の丸を選択
- 赤枠②Default-Particleを選択
以上でパーティクルコンポーネントの設定は完了です。
今回はシンプルなエフェクトですが、パーティクルシステムでは色々な設定の変更を行うことができます。
もっとこだわったエフェクトを作成したいという方は以下の記事をご参考ください。
参考記事)パーティクルシステムについて
最後にタップされたときにこのエフェクトが出力されるようにスクリプトを改良します。
SoundSnareスクリプトを以下のように変更してください。(変更部分は黄色で強調)
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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SoundSnare : MonoBehaviour { //AudioSourceコンポーネント保存用変数 private AudioSource audioSource; //ARカメラ保存用変数 private Camera camera; //パーティクルシステム保存用変数 private ParticleSystem particle; // Start is called before the first frame update void Start() { //AudioSourceコンポーネントを取得し、変数に格納 audioSource = GetComponent<AudioSource>(); //ARカメラを取得し、変数に格納 camera = GameObject.Find("ARCamera").GetComponent<Camera>(); //パーティクルシステムを取得し、変数に格納 particle = GetComponent<ParticleSystem>(); } // Update is called once per frame void Update() { //タップされたかどうか確認するメソッド「TouchCheck()」がTrueの場合 if (TouchCheck()) { //パーティクルシステムを再生する particle.Play(); //audioSourceのClipを再生する audioSource.PlayOneShot(audioSource.clip); } } //自分自身(取り付けオブジェクト自身)がタップされた場合Trueを返すメソッド bool TouchCheck() { //タッチ数を取得 int touchCount = Input.touchCount; //タッチ数が0より大きい場合 if (touchCount > 0) { //タッチの回数分ループ for (int i = 0; i < touchCount; i++) { //i回目のタッチ情報を取得 Touch touch = Input.GetTouch(i); //タップ位置からRayを取得 Ray ray = camera.ScreenPointToRay(touch.position); //ヒットしたオブジェクトの情報 RaycastHit hit = new RaycastHit(); //Rayを投げる if (Physics.Raycast(ray, out hit)) { //当たったオブジェクトが自分自身だった場合 if (hit.collider.gameObject == gameObject) { //Trueを返す return true; } } } } //自分自身に当たらなかった場合、falseを返す return false; } } |
これでスネアがタップされたときに音声、エフェクトが出力されるようになりました。
以上の作業を繰り返し、複数の楽器を並べることでドラムを作成することが可能になります。
ARオブジェクトを拡大・縮小する
おまけとして作成したオブジェクトを拡大したり、縮小したりできるような仕様に変更します。
キューブを2つ作成してそれぞれをタップすると拡大・縮小する仕組みを作成していきます。
イメージターゲットオブジェクトの子オブジェクトにCubeオブジェクトを2つ追加してください。
ここでは名前をそれぞれ「Expantion(拡大)」、「Shrinking(縮小)」としています。
色や配置は任意ですのでお好きな色、位置に配置してください。楽器と位置が被ると操作しづらいのでご注意ください。
はじめに楽器を拡大するためのExpantionスクリプトを作成します。
ヒエラルキーウィンドウでExpantionオブジェクトを選択してAddComponentからExpantionスクリプトを作成してください。
作成したスクリプトを以下のように変更してください。
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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Expantion : MonoBehaviour { //拡大するオブジェクト保存用変数 private GameObject expantionObject; //ARカメラ保存用変数 private Camera camera; void Start() { //スネアオブジェクトを取得し、変数に保存 expantionObject = GameObject.Find("DKFYB_Snare_drum"); //ARカメラを取得し、変数に格納 camera = GameObject.Find("ARCamera").GetComponent<Camera>(); } void Update() { //タップされたオブジェクトが自分自身の場合 if(TouchCheck()){ //Scaleの値を1.01倍する expantionObject.transform.localScale *= 1.01f; } } bool TouchCheck() { //タッチ数を取得 int touchCount = Input.touchCount; //タッチ数が0より大きい場合 if (touchCount > 0) { //タッチの回数分ループ for (int i = 0; i < touchCount; i++) { //i回目のタッチ情報を取得 Touch touch = Input.GetTouch(i); //タップ位置からRayを取得 Ray ray = camera.ScreenPointToRay(touch.position); //ヒットしたオブジェクトの情報 RaycastHit hit = new RaycastHit(); //Rayを可視化(Debug用),DrawRayは始点と方向を指定して使用可能 Debug.DrawRay(ray.origin, ray.direction * 100); //Rayを投げる if (Physics.Raycast(ray, out hit)) { //当たったオブジェクトが自分自身だった場合 if (hit.collider.gameObject == gameObject) { return true; } } } } //自分自身に当たらなかった時false return false; } } |
タップの判定原理は先ほどのSoundSnareスクリプトと同じです。
次にヒエラルキーウィンドウでShrinkingオブジェクトを選択してAddComponentからShrinkingスクリプトを作成してください。
作成したスクリプトを以下のように変更してください。(Expantionオブジェクトとの変更点を黄色で強調してあります)
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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Shrinking : MonoBehaviour { //拡大するオブジェクト保存用変数 private GameObject expantionObject; //ARカメラ保存用変数 private Camera camera; void Start() { //スネアオブジェクトを取得し、変数に保存 expantionObject = GameObject.Find("DKFYB_Snare_drum"); //ARカメラを取得し、変数に格納 camera = GameObject.Find("ARCamera").GetComponent<Camera>(); } void Update() { //タップされたオブジェクトが自分自身の場合 if (TouchCheck()) { //Scaleの値を1.01倍する expantionObject.transform.localScale /= 1.01f; } } bool TouchCheck() { //タッチ数を取得 int touchCount = Input.touchCount; //タッチ数が0より大きい場合 if (touchCount > 0) { //タッチの回数分ループ for (int i = 0; i < touchCount; i++) { //i回目のタッチ情報を取得 Touch touch = Input.GetTouch(i); //タップ位置からRayを取得 Ray ray = camera.ScreenPointToRay(touch.position); //ヒットしたオブジェクトの情報 RaycastHit hit = new RaycastHit(); //Rayを可視化(Debug用),DrawRayは始点と方向を指定して使用可能 Debug.DrawRay(ray.origin, ray.direction * 100); //Rayを投げる if (Physics.Raycast(ray, out hit)) { //当たったオブジェクトが自分自身だった場合 if (hit.collider.gameObject == gameObject) { return true; } } } } //自分自身に当たらなかった時false return false; } } |
ExpantionスクリプトとShrinkingオブジェクトの違いは、Scaleの値を1.01倍するか割るかの違いのみです。
これで、それぞれのキューブがタップされたときにスネアオブジェクトが拡大縮小するような仕様に変更できました。
iPhoneでの実装
iPhoneでの実装方法は今回は省略しますが、やり方がわからない方は以下記事をご参考ください。
参考記事)iPhoneでの実装方法
また、スネア以外の楽器の作成も今回は省略しますが、やり方は全く同じですのでそれぞれの楽器に合う音声データを取得して実装してみてください。
まとめ
いかがでしたでしょうか。
今回はAR楽器アプリの楽器に音、エフェクトを取り付ける方法をご紹介してきました。
Unityを使用することで簡単にARのアプリを作成することができます。本記事をきっかけに色々なARのアプリを作成していただければ幸いです。
この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!