はじめに
今回のスクリプトは簡単です。
サウンドの再生についてはもっと早くに取り上げるべきでしたが、ついつい後回しになってしまいました(^^;
サウンドの再生についてはもっと早くに取り上げるべきでしたが、ついつい後回しになってしまいました(^^;
オブジェクトにちょっとした音を組み込むことは、簡単なわりに効果的です。
例えば照明のON/OFFをするときにスイッチ音を付けたり、アニメーションと一緒に効果音を付けたりするだけで、よりリアルで面白いものを実現することができます。
基本的にはスクリプトで実現できる音とは、効果音のことだと思ってください。
BGMのような長いサウンドを鳴らすことは容易ではありません。
というのも、SLにアップロード可能なサウンドは10秒以内に限られているためです。
例えば照明のON/OFFをするときにスイッチ音を付けたり、アニメーションと一緒に効果音を付けたりするだけで、よりリアルで面白いものを実現することができます。
基本的にはスクリプトで実現できる音とは、効果音のことだと思ってください。
BGMのような長いサウンドを鳴らすことは容易ではありません。
というのも、SLにアップロード可能なサウンドは10秒以内に限られているためです。
今回は簡単な例として、以前作ったドアのスクリプトに、開閉の音を組み込んでみたいと思います。
サウンドを扱う関数
llPlaySound(string sound, float volume) llTriggerSound(string sound, float volume)
引数は一緒です。
string型引数soundには、再生したいサウンドの名前かUUIDを指定します。
名前を指定した場合はそのサウンドがオブジェクトコンテンツの中になければいけません。
string型引数soundには、再生したいサウンドの名前かUUIDを指定します。
名前を指定した場合はそのサウンドがオブジェクトコンテンツの中になければいけません。
float型の引数volumeは、音量です。
指定できる数値は0.0~1.0になっています。
もともとのサウンドの音量で再生する場合は1.0(音量100%)、ミュートは0.0(音量0%)です(無音で再生することにどんな意味があるのか不明ですが(^^;)。
指定できる数値は0.0~1.0になっています。
もともとのサウンドの音量で再生する場合は1.0(音量100%)、ミュートは0.0(音量0%)です(無音で再生することにどんな意味があるのか不明ですが(^^;)。
llPlaySound()とllTriggerSound?()の違いは、音の発生源です。
llPlaySound()はオブジェクトから音を出します。
オブジェクトが移動すれば音も一緒に移動しますので、例えばスピーカーや楽器などはこちらを使います。
llTriggerSound?()は関数を実行した時点のオブジェクトの位置から音を出します。
オブジェクトが移動しても、音は移動しません。場所固定になります。
llPlaySound()はオブジェクトから音を出します。
オブジェクトが移動すれば音も一緒に移動しますので、例えばスピーカーや楽器などはこちらを使います。
llTriggerSound?()は関数を実行した時点のオブジェクトの位置から音を出します。
オブジェクトが移動しても、音は移動しません。場所固定になります。
またllPlaySound()をHUDで使った場合、音が聞こえるのはHUDの装着者のみです。
つまりボタン操作の音などを組み込んでも、周囲の人には聴こえません。
HUDから周囲の人にも聴こえるサウンドを鳴らすにはllTriggerSound?()のほうを使わなければなりません。
つまりボタン操作の音などを組み込んでも、周囲の人には聴こえません。
HUDから周囲の人にも聴こえるサウンドを鳴らすにはllTriggerSound?()のほうを使わなければなりません。
用途に応じて二つの関数を使い分けますが、今回のドアに関してはまあ、どちらでもいいでしょう。
llTriggerSound?()を使うことにします。
llTriggerSound?()を使うことにします。
音の出るドア
以前作ったドアのスクリプトに、llTriggerSound?()を組み込むだけで出来てしまいます。
rotation rot; key sound_open = "cb340647-9680-dd5e-49c0-86edfa01b3ac"; key sound_close = "e7ff1054-003d-d134-66be-207573f2b535"; default { state_entry() { rot = llGetRot(); state close; } } state open { state_entry() { llTriggerSound(sound_open, 1.0); llSetRot(rot * llEuler2Rot(<0.0, 0.0, 90.0> * DEG_TO_RAD)); llSetTimerEvent(30.0); } touch_start(integer total_number) { state close; } timer(){ llSetTimerEvent(0); state close; } } state close { state_entry() { llSetRot(rot); llTriggerSound(sound_close, 1.0); } touch_start(integer total_number) { state open; } }
出来ましたw
サウンドはSLにあらかじめ用意されている「きぃ~」「ばたん」を使いました。
最初に指定しているopenとcloseのUUIDがそれです。
このサウンドはもともとSLに用意されているので、ドアのコンテンツに入れなくても鳴らすことができます。
サウンドはSLにあらかじめ用意されている「きぃ~」「ばたん」を使いました。
最初に指定しているopenとcloseのUUIDがそれです。
このサウンドはもともとSLに用意されているので、ドアのコンテンツに入れなくても鳴らすことができます。
ループサウンド
えー・・・。
これだけで終わるのはさすがにアレなんで、もう少しサウンド系のお話を。
これだけで終わるのはさすがにアレなんで、もう少しサウンド系のお話を。
llPlaySound()とllTriggerSound?()はどちらも一度きりの再生ですが、時にはサウンドを繰り返し鳴らしたい場合があります。
例えば水音とか。
滝や川の近くに水音をループ再生するオブジェクトを置くと、なかなかに雰囲気が出ます。
例えば水音とか。
滝や川の近くに水音をループ再生するオブジェクトを置くと、なかなかに雰囲気が出ます。
サウンドのループ再生にはllLoopSound()を使います。
llLoopSound(string sound, float volume)
引数はllPlaySound()やllTriggerSound?()と同じです。
ループ再生したサウンドの停止にはllStopSound?()を使います。
この関数はllPlaySound()の停止にも使えます。
ですがllTriggerSound?()を止めることはできませんので注意して下さい。
この関数はllPlaySound()の停止にも使えます。
ですがllTriggerSound?()を止めることはできませんので注意して下さい。
環境音用のスクリプトを一応載せておきましょう。
オーナーのタッチでサウンドのON/OFFを切り替えられるようにしてあるものです。
オーナーのタッチでサウンドのON/OFFを切り替えられるようにしてあるものです。
integer play=FALSE; string sound="water_sound"; default { touch_start(integer detected){ if (llDetectedKey(0) == llGetOwner()){ play = !play; if (play) { llLoopSound(sound, 1.0); }else{ llStopSound(); } } } }
サウンドのON/OFF状態を管理するために、integer型の変数playを用意しました。
FALSEというのは「偽」という意味です。
具体的には0のことです。
FALSEというのは「偽」という意味です。
具体的には0のことです。
FALSEの反対はTRUEで、「真」のことです。
TRUEは1と等しい数値になっています。
TRUEは1と等しい数値になっています。
「ON/OFF」や「正しい/誤っている」など、対の関係にあるデータを管理する際にはTRUEとFALSEを使うのが便利です。
というのも、
というのも、
play = !play;
上記スクリプトにこのような記述がありますが、この式はTRUEとFALSEを引っくり返す計算になっています。
「!」は「否定」を意味します。
すなわち「!play」は「playの逆」なので、もしもplayの値がTRUEならばFALSEに、FALSEならばTRUEになります。
タッチするたびにON/OFFを切り替えるのですから、これは便利です。
「!」は「否定」を意味します。
すなわち「!play」は「playの逆」なので、もしもplayの値がTRUEならばFALSEに、FALSEならばTRUEになります。
タッチするたびにON/OFFを切り替えるのですから、これは便利です。
それからif文の条件のところに、ただ「play」としか書いていないのはどういうことでしょうか。
if (play) {}
実は今まで使ってきたif文の条件ですが、全てTRUEとFALSEの値を返すのです。
例えば、
例えば、
if (cmd == "red") {}
などというif文を今までに書いていました。
「cmd == "red"」というのは実は計算式になっており、「cmdが"red"だったらTRUE、違ったらFALSEを返す」のです。
「cmd == "red"」というのは実は計算式になっており、「cmdが"red"だったらTRUE、違ったらFALSEを返す」のです。
if文は()の中に書かれている値や計算式がTRUEかFALSEかを判断し、分岐処理を行います。
ですので、今回は単に
if (play) {}
としか書いていません。
この場合、playの値がTREUのときのみ{}の中が実行されます。
この場合、playの値がTREUのときのみ{}の中が実行されます。
このようにTREUとFALSEを管理する変数のことを、boolean型変数と言うことがあります。
実態はinteger型ですが、boolean型として使う場合にはTRUEとFALSEの値以外は通常使いません。
実態はinteger型ですが、boolean型として使う場合にはTRUEとFALSEの値以外は通常使いません。
「ゼロかイチか」
「黒でばければ白」
「黒でばければ白」
みたいな、極めてデジタルなデータ型です。
・・・・・・って、サウンドの関数があまりに簡単すぎるので、関係ないところを説明してみたりしました(^^;
今回のポイント
- サウンドの再生(1度のみ):
llPlaySound(string sound, float volume) llTriggerSound(string sound, float volume)
- サウンドの再生(ループ):
llLoopSound(string sound, float volume)
- サウンドの停止:
llStopSound()
- boolean型:
TRUE/真(実態は1) FALSE/偽(実態は0)
あんまりポイントのない回でした(^^;
とは言ってもサウンドを使えるようになると表現の幅は広がります。
今まで作ったスクリプトに組み込むだけで、面白いものが作れそうです。
座ったときに「ぶーー」と鳴るクッションとかw
ぜひぜひいろんなところで応用してみて下さい。
今まで作ったスクリプトに組み込むだけで、面白いものが作れそうです。
座ったときに「ぶーー」と鳴るクッションとかw
ぜひぜひいろんなところで応用してみて下さい。
ではまた。