Unity 画像位置の変更② 位置の移動ができるようになったのでスクリプト
Hierarchyは
back1Cuは左の背景
これを見たら曲が鳴ります。
ima1Cuはその背景の前にある画像を貼り付けてあるCube。
座標は
左の背景が (-300,0,10)
左の画像が (-300,0,-15.5)
右の背景が (300,0,10)
右の画像が (300,0,-15.5)
Directional Lightが (-16,194,-327)
Main Cameraが(2,0,-79)
で、そのInspectorがこうです。
左の背景
using System.Collections;
using System.IO;
using UnityEngine;
using Tobii.Gaming; //ライブラリの追加
using NAudio.Wave; //← 見つからないとエラーが出たときは Import Settings を見直す
public class play : MonoBehaviour
{
//サイズと位置変更のため必要 この背景に乗っている画像の状態を知る
public GameObject ima1Cu;
image1 image1;
//サイズと位置変更のため必要
//隣を見たら音を止めるために必要 隣の背景の方の状態を知る
public GameObject back2Cu;
play2 pl2;
//隣を見たら音を止めるために必要
public AudioSource audioSource;
///////////////////////////////////////////
string otoPath = "C:/オリジナル視線アプリ/音はここ/1";
///////////////////////////////////////////
//注視情報
private GazeAware gazeAware;
//停止中か再生中かなど
public int ichiziteishi;
Vector3 screenPoint;
Vector3 offset;
//オブジェクトをドラッグする処理
void OnMouseDown()
{
//カメラの座標を画面座標系で取得
this.screenPoint = Camera.main.WorldToScreenPoint(transform.position);
//アタッチしたオブジェクトの座標と画面内のタッチ座標との差分を求める(2つの座標の間のベクトルを求める)
this.offset = transform.position
- Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
void OnMouseDrag()
{
//移動したマウスの座標を代入
var currentScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
//移動したマウス座標をワールド座標へ変換し,先ほど求めた offset を適用してアタッチしたオブジェクトの座標に直す
var currentPosition = Camera.main.ScreenToWorldPoint(currentScreenPoint) + this.offset;
//セットする
transform.position = currentPosition;
ima1Cu.GetComponent<image1>().Posihenkoimage1();
}
//位置を変えるため必要
public void Posihenkopl()
{
this.transform.position = image1.transform.position; // image1.csのpositionを自分のpositionにする。
}
private void Start()
{
//サイズ変更、位置変更のため必要
ima1Cu = GameObject.Find("ima1Cu");
image1 = ima1Cu.GetComponent<image1>();
//サイズ変更、位置変更のため必要
//隣を見たら音を止めるために必要
back2Cu = GameObject.Find("back2Cu");
pl2 = back2Cu.GetComponent<play2>();
//隣を見たら音を止めるために必要
//値を保持できるならスタート時に↓前の値を読むけど、保持できないから消しても良いか。。。
this.transform.localScale = new Vector3(image1.xScale + 150, image1.yScale + 150, 1.0f);
//注視情報の取得
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}");
}
}
//サイズ変更のため必要 image1のサイズを基準にしている。背景は画像より150大きい
public void ScaleUp()
{
this.transform.localScale = new Vector3(image1.xScale + 150, image1.yScale + 150, 1.0f);
}
public void ScaleDown()
{
this.transform.localScale = new Vector3(image1.xScale + 150, image1.yScale + 150, 1.0f);
}
//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)) マウスをクリックして鳴らしたくなったらこっちを使う
if (flg)
{
//注視していたら赤色に
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))
if (flg)
{
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();
}
}
左の画像
using UnityEngine;
using System.Collections;
using System.IO;
using System.Collections.Generic;
public class image1: MonoBehaviour
{
//サイズ変更のため ただし、back1Cuは位置変更にも使用
public GameObject ima2Cu; //////もう一個のimageオブジェクト
public GameObject back1Cu;
public GameObject back2Cu;
//サイズ変更のため ただし、back1Cuは位置変更にも使用
[PersistentAmongPlayMode] //記憶できるならこれがいる。位置やサイズは難しそうだけど・・・。
public float xScale; //この画像のx方向のサイズ。これを基準にみんな大きさを変える
[PersistentAmongPlayMode]
public float yScale;
string imagePath = "C:/オリジナル視線アプリ/画像はここ/1";
//位置を変えるために必要
play pl;
//位置を変えるために必要
Vector3 screenPoint;
Vector3 offset;
//オブジェクトをドラッグする処理
void OnMouseDown()
{
//カメラの座標を画面座標系で取得
this.screenPoint = Camera.main.WorldToScreenPoint(transform.position);
//アタッチしたオブジェクトの座標と画面内のタッチ座標との差分を求める(2つの座標の間のベクトルを求める)
this.offset = transform.position
- Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
void OnMouseDrag()
{
//移動したマウスの座標を代入
var currentScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
//移動したマウス座標をワールド座標へ変換し,先ほど求めた offset を適用してアタッチしたオブジェクトの座標に直す
var currentPosition = Camera.main.ScreenToWorldPoint(currentScreenPoint) + this.offset;
//セットする
transform.position = currentPosition;
back1Cu.GetComponent<play>().Posihenkopl();
}
private void Start()
{
ima2Cu = GameObject.Find("ima2Cu"); //////もう一個のオブジェクトはima2Cuという名前のものです。ここではima2Cuという名前で使います//////
back1Cu = GameObject.Find("back1Cu");
back2Cu = GameObject.Find("back2Cu");
//位置を変えるために必要
back1Cu = GameObject.Find("back1Cu");
pl = back1Cu.GetComponent<play>();
//位置を変えるために必要
StartCoroutine(gazouyomu1()); //IEnumerator gazouyomu1() をここで実行。だと思う。
}
//位置変更のため必要
public void Posihenkoimage1()
{
this.transform.position = pl.transform.position;
}
//位置変更のため必要
/*
public void ScaleUp()
{
this.transform.localScale = new Vector3(image1.xScale + 150, image1.yScale + 150, 1.0f);
}
*/
IEnumerator gazouyomu1() //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;
}
//サイズの変更。この画像を基準にするから、このcsにだけ必要なコード。
IEnumerator sizehenko()
{
this.transform.localScale = new Vector3(xScale, yScale, 1.0f);
if (Input.GetKey(KeyCode.RightArrow))
{
xScale += 5f;
this.transform.localScale = new Vector3(xScale, yScale, 1.0f); /////このオブジェクトのサイズをxScaleとyScaleにする。
ima2Cu.GetComponent<image2>().ScaleUp(); /////ima2Cuのimage2.csのScaleUpをここで実行。という意味?
back1Cu.GetComponent<play>().ScaleUp();
back2Cu.GetComponent<play2>().ScaleUp();
}
if (Input.GetKey(KeyCode.LeftArrow))
{
xScale -= 5f;
this.transform.localScale = new Vector3(xScale, yScale, 1.0f); //////このオブジェクトのサイズをxScaleとyScaleにする。
ima2Cu.GetComponent<image2>().ScaleUp(); /////ima2Cuのimage2.csのScaleUpをここで実行。という意味?
back1Cu.GetComponent<play>().ScaleUp();
back2Cu.GetComponent<play2>().ScaleUp();
}
if (Input.GetKey(KeyCode.UpArrow))
{
yScale += 5f;
this.transform.localScale = new Vector3(xScale, yScale, 1.0f); //////このオブジェクトのサイズをxScaleとyScaleにする。
ima2Cu.GetComponent<image2>().ScaleUp(); /////ima2Cuのimage2.csのScaleUpをここで実行。という意味?
back1Cu.GetComponent<play>().ScaleUp();
back2Cu.GetComponent<play2>().ScaleUp();
}
if (Input.GetKey(KeyCode.DownArrow))
{
yScale -= 5f;
this.transform.localScale = new Vector3(xScale, yScale, 1.0f); //////このオブジェクトのサイズをxScaleとyScaleにする。
ima2Cu.GetComponent<image2>().ScaleUp(); /////ima2Cuのimage2.csのScaleUpをここで実行。という意味?
back1Cu.GetComponent<play>().ScaleUp();
back2Cu.GetComponent<play2>().ScaleUp();
}
yield return null;
}
//いつ、矢印キーをおしてもサイズ変更が行われるようにするためのもの。
void Update()
{
StartCoroutine("sizehenko");
}
}
右の背景はほとんど左と同じなので割愛
画像は左の画像がサイズ変更の基準になっているので
コードが多い。
そういうのが無ければ以下で良い。
右の画像
using UnityEngine;
using System.Collections;
using System.IO;
using System.Collections.Generic;
public class image2: MonoBehaviour
{
//サイズ変更のため必要
GameObject ima1Cu;
image1 image1;
//サイズ変更のため必要
//位置変更のため必要
public GameObject back2Cu;
//位置変更のため必要
string imagePath = "C:/オリジナル視線アプリ/画像はここ/2";
//位置を変えるために必要
play2 pl2;
//位置を変えるために必要
Vector3 screenPoint;
Vector3 offset;
//オブジェクトをドラッグする処理
void OnMouseDown()
{
//カメラの座標を画面座標系で取得
this.screenPoint = Camera.main.WorldToScreenPoint(transform.position);
//アタッチしたオブジェクトの座標と画面内のタッチ座標との差分を求める(2つの座標の間のベクトルを求める)
this.offset = transform.position
- Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
void OnMouseDrag()
{
//移動したマウスの座標を代入
var currentScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
//移動したマウス座標をワールド座標へ変換し,先ほど求めた offset を適用してアタッチしたオブジェクトの座標に直す
var currentPosition = Camera.main.ScreenToWorldPoint(currentScreenPoint) + this.offset;
//セットする
transform.position = currentPosition;
back2Cu.GetComponent<play2>().Posihenkopl2();
}
//位置変更のため必要
public void Posihenkoimage2()
{
this.transform.position = pl2.transform.position;
}
//位置変更のため必要
private void Start()
{
//サイズ変更のため必要
ima1Cu = GameObject.Find("ima1Cu");
image1 = ima1Cu.GetComponent<image1>();
//サイズ変更のため必要
//位置変更のため必要
back2Cu = GameObject.Find("back2Cu");
pl2 = back2Cu.GetComponent<play2>();
//位置を変えるために必要
//位置変更のため必要
StartCoroutine(gazouyomu2());
this.transform.localScale = new Vector3(image1.xScale, image1.yScale, 1.0f);
}
//サイズ変更のため必要
public void ScaleUp()
{
this.transform.localScale = new Vector3(image1.xScale, image1.yScale, 1.0f);
}
public void ScaleDown()
{
this.transform.localScale = new Vector3(image1.xScale, image1.yScale, 1.0f);
}
//サイズ変更のため必要
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;
}
}