unity 好きな画像で視線入力⑨ 2枚の画像にそれぞれの音 全コード
全コードを書きます。
コード内のコメントは自分なりの
理解なので、
不正確なことも書いていると思います!
正確に知りたいときは
当サイト以外を是非、お調べください!!
Play.csです。
・・・・・・
using System.Collections;
using System.IO;
using UnityEngine;
using Tobii.Gaming; //ライブラリの追加
using NAudio.Wave; //← 見つからないとエラーが出たときは Import Settings を見直す
public class play : MonoBehaviour
{
private GameObject cu2Object;
play2 pl2;
public AudioSource audioSource;
///////////////////////////////////////////
string otoPath = "C:/オリジナル視線アプリ/音はここ/1";
///////////////////////////////////////////
//注視情報
private GazeAware gazeAware;
//停止中か再生中かなど
public int ichiziteishi;
private void Start()
{
//audioSource = this.GetComponent<AudioSource>();
//StartCoroutine(Connect());
//注視情報の取得
gazeAware = GetComponent<GazeAware>();
//一時停止が押されたかどうかを見るための変数。最初と再生中は1.一時停止中は2
ichiziteishi = 1;
///////////////////////////////////////////
//Stringの配列 Pathmei string otoPath = "C:/sound/1" 拡張子* を入れる
string Pathmei = System.IO.Directory.GetFiles(otoPath, "*", System.IO.SearchOption.AllDirectories);
string file = Pathmei[0]; //配列の一個目(0番)をfileに入れる。
//拡張子の出力
Debug.Log(Path.GetExtension(file)); //配列の一個目(0番)、つまりfile の拡張子をLogに書き出す。
//ファイル名の出力
Debug.Log(Path.GetFileNameWithoutExtension(file)); //ついでに配列の一個目(0番)、つまりfile のFile名をLogに書き出す。いらないけど、後でいるかも知れないから書いた。
if (Path.GetExtension(file).Contains("mp3")) //もし、配列の一個目(0番)、つまりfile の拡張子がmp3なら
{
otoPath = Pathmei[0]; //otoPathにもし、配列の一個目(0番)、つまりfileを入れる。
}
else if (Path.GetExtension(file).Contains("wav")) //もし、配列の一個目(0番)、つまりfile の拡張子がwavなら
{
var wavPath = Pathmei[0]; // 下の方の if (File.Exists(otoPath)) ・・・ により、Application.temporaryCachePath内にconverted.wavという名前で保存
StartCoroutine(PlayWav(wavPath)); // 下の方のIEnumerator PlayWav(string path) ・・・より、PlayWavは関数名。これをここでスタートする。
}
else
{
Debug.Log($"どっちもないよ:{0}"); //mp3もwavも無いときのLog
}
if (File.Exists(otoPath)) //Fileが存在しているか。もししているなら。
{
//wav 変換した一時ファイルを保存するパス
var wavPath = Application.temporaryCachePath + "/converted.wav"; // Application.temporaryCachePath内にconverted.wavという名前で保存
Mp3ToWAV(otoPath, wavPath);
StartCoroutine(PlayWav(wavPath));
}
else
{
Debug.Log($"File not found : {otoPath}");
}
}
//mp3 → wav 変換して、保存したパスを返す
public void Mp3ToWAV(string otoPath, string wavPath)
{
//ファイルを byte 配列で読み込み
var bytes = File.ReadAllBytes(otoPath); //File.ReadAllBytes:バイナリ ファイルを開き、ファイルの内容をバイト配列に読み取った後、ファイルを閉じます。
//wav を一時ファイルとして保存
using (var stream = new MemoryStream()) //MemoryStreamはFileには保存しないが、メモリにデータを読み書きするクラス
{
stream.Write(bytes, 0, bytes.Length); //stream.Write で書き込み。bytes.Lengthで、bytesの配列全体を書き込み。
stream.Position = 0; //ストリームの位置を先頭に。ここに10と入れたら10バイト目にセットすることになる。
using (var reader = new Mp3FileReader(stream)) //Mp3FileReader:mp3Fileから読み込む Mp3FileReader(stream) でstreamのmp3Fileを読む。だと思う。
{
WaveFileWriter.CreateWaveFile(wavPath, reader); //wav で書き出し(mp3なら「MediaFoundationEncoder」wavなら「WaveFileWriter」)
Debug.Log($"Convert to wav successfully : {wavPath}"); //うまく行ったらwav保存先のパスを表示
}
}
}
///////////////////////////////////////////
void Update()
{
// マウスの左ボタンを推した場合も再生
//オブジェクトを注視していたらTrue
bool flg = gazeAware.HasGazeFocus;
//注視していたり、マウスが左クリックされたら
if (flg || Input.GetMouseButtonDown(0))
{
cu2Object = GameObject.Find("2Cu");
pl2 = cu2Object.GetComponent<play2>();
//注視していたら赤色に
gameObject.GetComponent<Renderer>().material.color = Color.red;
if (!audioSource.isPlaying) //再生中で無いなら
{
//一時停止関数がもし2(一時停止中)なら
if (ichiziteishi == 2)
{
//再開してください(同時にichiziteisi変数は1になる)
UnPause();
}
//一時停止関数がもし1(一時停止中でない(起動したところだったり、停止中だったり))なら再生する。
else
{
audioSource.Play();
//++++playが再生されるときは、play2は一時停止する++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
pl2.audioSource2.Pause();
// Play(audioClip);
// Play(audioClip);
}
}
}
//注視して無かったり、マウス左クリックされてなかったりしたら
else
{
//注視していなければ青色に
gameObject.GetComponent<Renderer>().material.color = Color.blue;
//注視がそれただけでは一時停止にはしていない。視線がそれることはよくあると思うので。
//一時停止にしたいならPauseを入れたら可能。
//改訂として目をそらしたら止めるようにする
// Pause();
}
// 停止
if (audioSource.isPlaying) //再生中なら
{
//注視がそれているときのみ有効。テンキーの「2」を押して離したら停止
if (Input.GetKeyUp(KeyCode.Keypad2))
{
Stop();
}
}
// 注視がそれているときのみ有効。一時停止
if (audioSource.isPlaying) //再生中なら
{
//テンキーの「1」を押して離したら一時停止し、ichiziteishi変数を2に。
if (Input.GetKeyUp(KeyCode.Keypad1))
{
Pause();
}
}
// 再開
if (!audioSource.isPlaying) //停止中なら
{
//もう一回、注視したり左クリックしたりしたら再開し、ichiziteishi変数を1に。
if (flg || Input.GetMouseButtonDown(0))
{
UnPause();
}
}
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
}
//ストリーミング再生する
IEnumerator PlayWav(string path) //IEnumeratorはコルーチンを使うのに宣言するとき使う。PlayWavは関数名。
//コルーチンは好きな場所で処理を止めたり再開したりできる機能
{
using (var www = new WWW("file://" + path)) //www(url)でURLにアクセスする
{
while (!www.isDone) //while(条件式) 条件式が真である限りループする。www.isDoneはダウンロード終了したかどうかを読み取る。!がついているから「終了していない限り処理する」ということ。と思う。
yield return null; //1フレーム停止
if (string.IsNullOrEmpty(www.error)) //string.IsNullOrEmptyは指定の文字列が、nullもしくは空の文字列かを判断
//www.errorはダウンロード中にエラーが起きたときのメッセージ
{
var clip = www.GetAudioClip(false, true); //最初のはクリップを2Dにする(false)3Dは(true)だと思う。よく分かってない。後の真偽はtrueならダウンロード中も再生。falseならダウンロードしてから再生
audioSource.clip = clip;
//audioSource.Play();
Debug.Log($"Play wav : {path}");
}
else
{
Debug.Log(www.error);
}
}
}
//再生、一時停止、停止、再開、完全に停止について
/*
// 再生 Play と、入力したら一回だけ再生
private void Play(AudioClip audi)
{
audioSource.PlayOneShot(audi);
}
*/
// 一時停止 Pauseと、入力したらichiziteishi変数に2を入れて、一時停止
private void Pause()
{
ichiziteishi = 2;
audioSource.Pause();
}
// 停止 Stopと、入力したら停止
private void Stop()
{
audioSource.Stop();
}
// 再開 UnPause と、入力したらichiziteishi変数に1を入れて、再開
private void UnPause()
{
ichiziteishi = 1;
audioSource.UnPause();
//++++playが再生されるときは、play2は一時停止する++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
pl2.audioSource2.Pause();
}
}
・・・・・・
視線入力があれば音を鳴らすcsファイルは二つあります。
二つ目は、play2という名前にしました。
using System.Collections;
using System.IO;
using UnityEngine;
using Tobii.Gaming; //ライブラリの追加
using NAudio.Wave; //← 見つからないとエラーが出たときは Import Settings を見直す
public class play2 : MonoBehaviour
{
private GameObject cu1Object;
play pl;
public AudioSource audioSource2;
///////////////////////////////////////////
string mp3Path = "C:/オリジナル視線アプリ/音はここ/2";
//注視情報
private GazeAware gazeAware;
//停止中か再生中かなど
public int ichiziteishi2;
private void Start()
{
//audioSource = this.GetComponent<AudioSource>();
//StartCoroutine(Connect());
//注視情報の取得
gazeAware = GetComponent<GazeAware>();
//一時停止が押されたかどうかを見るための変数。最初と再生中は1.一時停止中は2
ichiziteishi2 = 1;
///////////////////////////////////////////
//Stringの配列 Pathmei string mp3Path = "C:/sound/1" 拡張子* を入れる
string Pathmei = System.IO.Directory.GetFiles(mp3Path, "*", System.IO.SearchOption.AllDirectories);
string file = Pathmei[0]; //配列の一個目(0番)をfileに入れる。
//拡張子の出力
Debug.Log(Path.GetExtension(file)); //配列の一個目(0番)、つまりfile の拡張子をLogに書き出す。
//ファイル名の出力
Debug.Log(Path.GetFileNameWithoutExtension(file)); //ついでに配列の一個目(0番)、つまりfile のFile名をLogに書き出す。いらないけど、後でいるかも知れないから書いた。
if (Path.GetExtension(file).Contains("mp3")) //もし、配列の一個目(0番)、つまりfile の拡張子がmp3なら
{
mp3Path = Pathmei[0]; //mp3Pathにもし、配列の一個目(0番)、つまりfileを入れる。
}
else if (Path.GetExtension(file).Contains("wav")) //もし、配列の一個目(0番)、つまりfile の拡張子がwavなら
{
var wavPath = Pathmei[0]; // 下の方の if (File.Exists(mp3Path)) ・・・ により、Application.temporaryCachePath内にconverted.wavという名前で保存
StartCoroutine(PlayWav(wavPath)); // 下の方のIEnumerator PlayWav(string path) ・・・より、PlayWavは関数名。これをここでスタートする。
}
else
{
Debug.Log($"どっちもないよ:{0}"); //mp3もwavも無いときのLog
}
if (File.Exists(mp3Path)) //Fileが存在しているか。もししているなら。
{
//wav 変換した一時ファイルを保存するパス
var wavPath = Application.temporaryCachePath + "/converted.wav"; // Application.temporaryCachePath内にconverted.wavという名前で保存
Mp3ToWAV(mp3Path, wavPath);
StartCoroutine(PlayWav(wavPath));
}
else
{
Debug.Log($"File not found : {mp3Path}");
}
}
//mp3 → wav 変換して、保存したパスを返す
public void Mp3ToWAV(string mp3Path, string wavPath)
{
//ファイルを byte 配列で読み込み
var bytes = File.ReadAllBytes(mp3Path); //File.ReadAllBytes:バイナリ ファイルを開き、ファイルの内容をバイト配列に読み取った後、ファイルを閉じます。
//wav を一時ファイルとして保存
using (var stream = new MemoryStream()) //MemoryStreamはFileには保存しないが、メモリにデータを読み書きするクラス
{
stream.Write(bytes, 0, bytes.Length); //stream.Write で書き込み。bytes.Lengthで、bytesの配列全体を書き込み。
stream.Position = 0; //ストリームの位置を先頭に。ここに10と入れたら10バイト目にセットすることになる。
using (var reader = new Mp3FileReader(stream)) //Mp3FileReader:mp3Fileから読み込む Mp3FileReader(stream) でstreamのmp3Fileを読む。だと思う。
{
WaveFileWriter.CreateWaveFile(wavPath, reader); //wav で書き出し(mp3なら「MediaFoundationEncoder」wavなら「WaveFileWriter」)
Debug.Log($"Convert to wav successfully : {wavPath}"); //うまく行ったらwav保存先のパスを表示
}
}
}
///////////////////////////////////////////
void Update()
{
// マウスの左ボタンを推した場合も再生
//オブジェクトを注視していたらTrue
bool flg = gazeAware.HasGazeFocus;
//注視していたり、マウスが左クリックされたら
if (flg || Input.GetMouseButtonDown(0))
{
cu1Object = GameObject.Find("1Cu");
pl = cu1Object.GetComponent<play>();
//注視していたら赤色に
gameObject.GetComponent<Renderer>().material.color = Color.red;
if (!audioSource2.isPlaying) //再生中で無いなら
{
//一時停止関数がもし2(一時停止中)なら
if (ichiziteishi2 == 2)
{
//再開してください(同時にichiziteisi変数は1になる)
UnPause();
}
//一時停止関数がもし1(一時停止中でない(起動したところだったり、停止中だったり))なら再生する。
else
{
audioSource2.Play();
//++++playが再生されるときは、play2は一時停止する++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
pl.audioSource.Pause();
// Play(audioClip);
// Play(audioClip);
}
}
}
//注視して無かったり、マウス左クリックされてなかったりしたら
else
{
//注視していなければ青色に
gameObject.GetComponent<Renderer>().material.color = Color.blue;
//注視がそれただけでは一時停止にはしていない。視線がそれることはよくあると思うので。
//一時停止にしたいならPauseを入れたら可能。
//改訂として目をそらしたら止めるようにする
// Pause();
}
// 停止
if (audioSource2.isPlaying) //再生中なら
{
//注視がそれているときのみ有効。テンキーの「2」を押して離したら停止
if (Input.GetKeyUp(KeyCode.Keypad2))
{
Stop();
}
}
// 注視がそれているときのみ有効。一時停止
if (audioSource2.isPlaying) //再生中なら
{
//テンキーの「1」を押して離したら一時停止し、ichiziteishi変数を2に。
if (Input.GetKeyUp(KeyCode.Keypad1))
{
Pause();
}
}
// 再開
if (!audioSource2.isPlaying) //停止中なら
{
//もう一回、注視したり左クリックしたりしたら再開し、ichiziteishi変数を1に。
if (flg || Input.GetMouseButtonDown(0))
{
UnPause();
}
}
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
}
//ストリーミング再生する
IEnumerator PlayWav(string path) //IEnumeratorはコルーチンを使うのに宣言するとき使う。PlayWavは関数名。
//コルーチンは好きな場所で処理を止めたり再開したりできる機能
{
using (var www = new WWW("file://" + path)) //www(url)でURLにアクセスする
{
while (!www.isDone) //while(条件式) 条件式が真である限りループする。www.isDoneはダウンロード終了したかどうかを読み取る。!がついているから「終了していない限り処理する」ということ。と思う。
yield return null; //1フレーム停止
if (string.IsNullOrEmpty(www.error)) //string.IsNullOrEmptyは指定の文字列が、nullもしくは空の文字列かを判断
//www.errorはダウンロード中にエラーが起きたときのメッセージ
{
var clip = www.GetAudioClip(false, true); //最初のはクリップを2Dにする(false)3Dは(true)だと思う。よく分かってない。後の真偽はtrueならダウンロード中も再生。falseならダウンロードしてから再生
audioSource2.clip = clip;
//audioSource.Play();
Debug.Log($"Play wav : {path}");
}
else
{
Debug.Log(www.error);
}
}
}
//再生、一時停止、停止、再開、完全に停止について
/*
// 再生 Play と、入力したら一回だけ再生
private void Play(AudioClip audi)
{
audioSource.PlayOneShot(audi);
}
*/
// 一時停止 Pauseと、入力したらichiziteishi変数に2を入れて、一時停止
private void Pause()
{
ichiziteishi2 = 2;
audioSource2.Pause();
}
// 停止 Stopと、入力したら停止
private void Stop()
{
audioSource2.Stop();
}
// 再開 UnPause と、入力したらichiziteishi変数に1を入れて、再開
private void UnPause()
{
ichiziteishi2 = 1;
audioSource2.UnPause();
//++++playが再生されるときは、play2は一時停止する++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
pl.audioSource.Pause();
}
}
・・・・・
↑本当は
string mp3Path = "C:/オリジナル視線アプリ/音はここ/2";
の部分の
mp3Path
ですが、
mp3限定じゃないからotoPath2という名前にしたかったのですが、
変更するのを忘れています。
これらは、
上記Hierarchyの1Cuと2CuのCubeにそれぞれくっつけてあります。
1Cuのinspectorは ↑これら を追加しています。
Audio Sourceの白枠だけ1Cuをくっつけています。
2Cuの方も同様に2Cuをくっつけています。
視線入力があって、音を再生した後、
視線が外れても音をループしておきたいときは
Loopにチェックを入れます。
二つチェックが入っていますが、
正直、よく分かっていません。
次に、画像です。
image1.cs
・・・・・・
using UnityEngine;
using System.Collections;
using System.IO;
public class image1 : MonoBehaviour
{
string imagePath = "C:/オリジナル視線アプリ/画像はここ/1";
private void Start()
{
StartCoroutine(gazouyomu());
}
IEnumerator gazouyomu() //IEnumeratorはコルーチンを使うのに宣言するとき使う。gazouyomuは関数名。
//コルーチンは好きな場所で処理を止めたり再開したりできる機能
{
string Pathmei = System.IO.Directory.GetFiles(imagePath, "*", System.IO.SearchOption.AllDirectories);
string file = Pathmei[0]; //配列の一個目(0番)をfileに入れる。
//拡張子の出力
Debug.Log(Path.GetExtension(file)); //配列の一個目(0番)、つまりfile の拡張子をLogに書き出す。
WWW www = new WWW(Pathmei[0]);
yield return www; //関数から抜けずに、一旦停止して値を返す。
Renderer rend = GetComponent<Renderer>();
rend.material.mainTexture = www.texture;
}
}
・・・・・・
image2.csです。
using UnityEngine;
using System.Collections;
using System.IO;
public class image2: MonoBehaviour
{
string imagePath = "C:/オリジナル視線アプリ/画像はここ/2";
private void Start()
{
StartCoroutine(gazouyomu2());
}
IEnumerator gazouyomu2() //IEnumeratorはコルーチンを使うのに宣言するとき使う。gazouyomu2は関数名。
//コルーチンは好きな場所で処理を止めたり再開したりできる機能
{
string Pathmei = System.IO.Directory.GetFiles(imagePath, "*", System.IO.SearchOption.AllDirectories);
string file = Pathmei[0]; //配列の一個目(0番)をfileに入れる。
//拡張子の出力
Debug.Log(Path.GetExtension(file)); //配列の一個目(0番)、つまりfile の拡張子をLogに書き出す。
WWW www = new WWW(Pathmei[0]);
yield return www; //関数から抜けずに、一旦停止して値を返す。
Renderer rend = GetComponent<Renderer>();
rend.material.mainTexture = www.texture;
}
}
imageのcsはHierarchyのima1Cuとima2Cuにくっつけています。
どっちもCubeです。
各imageのCubeにおいて、inspectorで大事なのが
これを忘れると背景が透明なpngファイルを表示しても透明にならないようです。
Assets内で右クリックしてMaterialを新しく作れば
このへんを変えられるようになります。
ima1Cuとima2Cuどっちも同じMaterialをくっつけてますが
問題なく動いています。
Cドライブ内に、
オリジナル視線アプリというフォルダを作って、
各フォルダ内に
音はここ と 画像はここ フォルダを作って、
さらに各フォルダ内に
1 と 2 という名前のフォルダを作っています。
音はmp3かwav
画像はpngかjpgファイルを
各フォルダに入れます。
1に入れたら左に2に入れたら右に反映されます。
↓ 左が1フォルダ 右が2フォルダ