2008年08月31日
新しい関数 llGetAgentLanguage
Second Life で外人の方とのコミュニケーションは珍しくありませんよね。
ダンスクラブに来られた外人の方にダンスの開始方法を教えるのも、、、まぁ、英語ならなんとかチャットで教えてあげていました。
サーバー 1.24 でいくつかの新しい関数が追加されていますが、llGetAgentLanguage という関数は、その Avatar の Agent が使っているビューワーの言語のバージョンを取得する関数です。これを使うと、スクリプトのメモリが許せば、日本語、英語、がんばれば他の外国語のメッセージをスクリプト内に保存しておいて、Agent が利用しているビューワーの言語情報によって切り替えることが可能ですね。
MLDU(ダンス玉) でいうと DDManager みたいなダイアログの操作でストリング(文字列)とリストを多用していると、メモリの問題から1つのスクリプト内で処理するのはつらいのですが、個々のアバターのパーミッションを管理して、ダンスの開始、停止を行うスクリプトなどは、複数の言語メッセージを保管しておいて、llGetAgentLanguage の情報からメッセージを切り替えることが可能になりますね。
こんな感じです。
続きを読む
ダンスクラブに来られた外人の方にダンスの開始方法を教えるのも、、、まぁ、英語ならなんとかチャットで教えてあげていました。
サーバー 1.24 でいくつかの新しい関数が追加されていますが、llGetAgentLanguage という関数は、その Avatar の Agent が使っているビューワーの言語のバージョンを取得する関数です。これを使うと、スクリプトのメモリが許せば、日本語、英語、がんばれば他の外国語のメッセージをスクリプト内に保存しておいて、Agent が利用しているビューワーの言語情報によって切り替えることが可能ですね。
MLDU(ダンス玉) でいうと DDManager みたいなダイアログの操作でストリング(文字列)とリストを多用していると、メモリの問題から1つのスクリプト内で処理するのはつらいのですが、個々のアバターのパーミッションを管理して、ダンスの開始、停止を行うスクリプトなどは、複数の言語メッセージを保管しておいて、llGetAgentLanguage の情報からメッセージを切り替えることが可能になりますね。
こんな感じです。
続きを読む
2008年08月23日
Mono がやってきます
Linden の Official Blog に「Mono Launch」という記事がついに投稿されましたね。
Linden Official Blog - Mono Launch
20日から 1.24 サーバーの展開が始まって、その 1.24 サーバーには Mono が含まれている、ということらしいです。
サーバーが 1.24 になっただけでは Mono は使えず、スクリプト作成者はクライアントビューワーの 1.21 RC が必要になるということです。1.21 RC のビューワーではスクリプトエディタの下に [Mono] というチェックボックスが追加されるので、それをチェックして保存、コンパイルで Mono 対応に移行完了、ということらしいです。逆に [Mono] にチェックをいれなければ、従来のまま動くようです。
ちなみに サーバー 1.24 のリリースノートによれば、ビューワーの 1.21 RC は 8月25日の週にリリースする予定ですね。
Mono はスクリプトを動かすための新しいエンジンで、従来のものと並存して提供されるとのことです。すべてのスクリプトを変換する必要はなく、また、LSL の書き方が変わるわけではありません。ちょっと安心ですね。
この Mono ですが、この新しい実行環境はスクリプトの「実行スピード」と「メモリー管理」が現行のスクリプト エンジンよりも強化されている点が特徴です。
この 1ヶ月ほど、ダンス玉 (次の MLDU) に機能をどんどん追加していったらメモリーがかなり厳しくなって、スクリプトを分けないと 10人以上踊れない、、、という状況になっていてのこの記事だったので、早速ベータ グリッドにいって試してみました。メモリーに関していえば、これまで 1つのスクリプトは 16KB しかメモリーを使えませんでしたが、Mono では 64 KB まで拡張されていることは知っていました。
今の環境だと、一番メモリーがくるしい DDManager (Dance Slot と Dialog 管理スクリプト) は残りのメモリーが 1.1K しかありません。これ、リストの操作で空のリストを使う方法じゃないと、エラーでスクリプトが止まる状態だったりします、、、

続きを読む
Linden Official Blog - Mono Launch
20日から 1.24 サーバーの展開が始まって、その 1.24 サーバーには Mono が含まれている、ということらしいです。
サーバーが 1.24 になっただけでは Mono は使えず、スクリプト作成者はクライアントビューワーの 1.21 RC が必要になるということです。1.21 RC のビューワーではスクリプトエディタの下に [Mono] というチェックボックスが追加されるので、それをチェックして保存、コンパイルで Mono 対応に移行完了、ということらしいです。逆に [Mono] にチェックをいれなければ、従来のまま動くようです。
ちなみに サーバー 1.24 のリリースノートによれば、ビューワーの 1.21 RC は 8月25日の週にリリースする予定ですね。
Mono はスクリプトを動かすための新しいエンジンで、従来のものと並存して提供されるとのことです。すべてのスクリプトを変換する必要はなく、また、LSL の書き方が変わるわけではありません。ちょっと安心ですね。
この Mono ですが、この新しい実行環境はスクリプトの「実行スピード」と「メモリー管理」が現行のスクリプト エンジンよりも強化されている点が特徴です。
この 1ヶ月ほど、ダンス玉 (次の MLDU) に機能をどんどん追加していったらメモリーがかなり厳しくなって、スクリプトを分けないと 10人以上踊れない、、、という状況になっていてのこの記事だったので、早速ベータ グリッドにいって試してみました。メモリーに関していえば、これまで 1つのスクリプトは 16KB しかメモリーを使えませんでしたが、Mono では 64 KB まで拡張されていることは知っていました。
今の環境だと、一番メモリーがくるしい DDManager (Dance Slot と Dialog 管理スクリプト) は残りのメモリーが 1.1K しかありません。これ、リストの操作で空のリストを使う方法じゃないと、エラーでスクリプトが止まる状態だったりします、、、

続きを読む
2008年08月17日
YazMania Videos Clip
NMR10~、遅ればせながら参加できました。

ファンの人からの「この曲が好き、なぜなら、、、」みたいなやり方って、ほんと楽しかったし。
それぞれが、それぞれの思いあるから、「へぇ~、そうなんだー」みたいなのがあって、新鮮でした。
Yaz Yaz で素人なりにビデオつくってきて良かったなぁ~、と思いました。それぞれの思いがある曲もみんな違うし、それぞれの考え方や印象もみんな違う。それって、いろいろな思いをいだかせることができる才能のある人がなせる業w
すごいなぁ、、、Yaz さんって、いろいろな人にいろいろな感情・体験を持たせているんだぁ、、、と改めて実感しました。
で。。。。
続きを読む

ファンの人からの「この曲が好き、なぜなら、、、」みたいなやり方って、ほんと楽しかったし。
それぞれが、それぞれの思いあるから、「へぇ~、そうなんだー」みたいなのがあって、新鮮でした。
Yaz Yaz で素人なりにビデオつくってきて良かったなぁ~、と思いました。それぞれの思いがある曲もみんな違うし、それぞれの考え方や印象もみんな違う。それって、いろいろな思いをいだかせることができる才能のある人がなせる業w
すごいなぁ、、、Yaz さんって、いろいろな人にいろいろな感情・体験を持たせているんだぁ、、、と改めて実感しました。
で。。。。
続きを読む
2008年08月12日
llDialog 再び
造形のセンスまったくなしなので、クールな HUD を作ってスクリプトを埋めこむ、、、なんてことができないので、どうしても llDialog を使うことになってしまいます。
llDialog で表示するダイアログには12個のボタンしか表示できない、ボタン内に表示できる文字数に制限がある、同じ場所から出てくるので「複数ダイアログ表示」できないことはないのですが、あまり使い勝手が良くないなど、制約が多いのですが、、、これを使うしかないわけで(笑
そこそこ多くのダイアログを作ってみて、気がついた点などを再度まとめてみようと思いました。
1) 複数の人がダイアログを押して、それを処理するような状況になるべくしないほうがいいかも
用途にもよりますが、複数の人がダイアログを押すような状況を仮定してスクリプトを組まないほうが懸命のようです。できないことはないのですが、if 文を駆使して、そのロジックをいろいろと悩むよりも、「前の人の処理が終わるまで待ってもらう」としたほうが当然のことながらスクリプトがシンプルになります。
[追記] ダンス玉(つまりアニメーション操作)など Permission を必要とするものなどは、touch されたら、アバターの Key を他のスクリプトに渡し、そちらで処理する方法があります。この場合は、複数の人が1つのプリムをタッチしても、個別に処理するスクリプトの数の最大に達するまで処理をさせることが可能になります。1つの Prim には複数のスクリプトを入れることが可能なので、touch を管理するスクリプトを親として、詳細の処理を子スクリプトに渡す、、、ということができます。
2) state を使ったほうがラクかも
これも人によりけりでしょうが、私の場合は、タッチされたら(もしくは、なんらかのイベントが発生してダイアログを呼ぶようなことになったら)、そのアバターの key を拾って state を変える方法を使うことが多くなりました。メリットは llListenRemove を使わなくても state が変わることによって listeners を溜めなくてすむこと(64 だったかな?、Remove せずにそのくらい溜まるとエラーになります)、他の人が touch したときの処理をシンプルにできること、だと思っています。また、state_entry, state_exit を使った初期化処理/終了処理が可能でスクリプトが見やすくなることもあげられます。デメリットは必ず llSetTimerEvent を使ってタイムアウトを検知させること。これをやらないでダイアログの [無視] ボタンを押されたら元の state に戻って来れません。
(以下は可読性を高めるためにグローバル変数をあまり使ってません)
key toucher = NULL_KEY;
list buttons = ["button1", "button2", "button3"];
default {
state_entry() {
toucher = NULL_KEY;
}
touch_start(integer detected_num) {
toucher = llDetectedKey(0); //一番最初にタッチいた Avatar の Key を取得
state dialog; //ダイアログ・ステートに移動
}
}
state dialog {
state_entry() {
integer hDialog = llListen(-5555, "", toucher, ""); //-5555チャンネルで、タッチした Avatar の声だけ聞く設定
llListenControl(hDialog, TRUE); //リスナーを追加(要は聞き始める、ということ)
llDialog(toucher, "好きなボタンを押してください。", buttons, -5555); //ダイアログを表示。返信は -5555 チャンネル
llSetTimerEvent(30.0); //30秒でタイムアウトにさせるため
}
touch_start(integer detected_num) { //ダイアログ処理中にタッチした Avatar への処理
integer i = 0;
for(; i<detected_num; i++) { //タッチした人分の処理をする for ループ
llInstantMessage(llDetectedKey(i), "ダイアログ使用中です。しばらくまってください。");
}
}
timer() {
llInstantMessage(toucher, "タイムアウトになりました。");
llSetTimerEvent(0.0);
state default;
}
listen(integer channel, string name, key id, string message) {
if (llListFindList(buttons, [message]) != -1) { //一応のチェック処理。この程度なら必要ないですが・・・
llSetTimerEvent(0.0);
if (message == "button1") {
xxxxxxxx;
} else if (message == "button2") {
yyyyyyyy;
} else if (message == "button3") {
zzzzzzzz;
}
state default;
}
}
state_exit() {
toucher = NULL_KEY;
llSetTimerEvent(0.0); //しつこいですが、、、過去に timer が戻らなかったことがあったので・・・
}
}
続きを読む
llDialog で表示するダイアログには12個のボタンしか表示できない、ボタン内に表示できる文字数に制限がある、同じ場所から出てくるので「複数ダイアログ表示」できないことはないのですが、あまり使い勝手が良くないなど、制約が多いのですが、、、これを使うしかないわけで(笑
そこそこ多くのダイアログを作ってみて、気がついた点などを再度まとめてみようと思いました。
1) 複数の人がダイアログを押して、それを処理するような状況になるべくしないほうがいいかも
用途にもよりますが、複数の人がダイアログを押すような状況を仮定してスクリプトを組まないほうが懸命のようです。できないことはないのですが、if 文を駆使して、そのロジックをいろいろと悩むよりも、「前の人の処理が終わるまで待ってもらう」としたほうが当然のことながらスクリプトがシンプルになります。
[追記] ダンス玉(つまりアニメーション操作)など Permission を必要とするものなどは、touch されたら、アバターの Key を他のスクリプトに渡し、そちらで処理する方法があります。この場合は、複数の人が1つのプリムをタッチしても、個別に処理するスクリプトの数の最大に達するまで処理をさせることが可能になります。1つの Prim には複数のスクリプトを入れることが可能なので、touch を管理するスクリプトを親として、詳細の処理を子スクリプトに渡す、、、ということができます。
2) state を使ったほうがラクかも
これも人によりけりでしょうが、私の場合は、タッチされたら(もしくは、なんらかのイベントが発生してダイアログを呼ぶようなことになったら)、そのアバターの key を拾って state を変える方法を使うことが多くなりました。メリットは llListenRemove を使わなくても state が変わることによって listeners を溜めなくてすむこと(64 だったかな?、Remove せずにそのくらい溜まるとエラーになります)、他の人が touch したときの処理をシンプルにできること、だと思っています。また、state_entry, state_exit を使った初期化処理/終了処理が可能でスクリプトが見やすくなることもあげられます。デメリットは必ず llSetTimerEvent を使ってタイムアウトを検知させること。これをやらないでダイアログの [無視] ボタンを押されたら元の state に戻って来れません。
(以下は可読性を高めるためにグローバル変数をあまり使ってません)
key toucher = NULL_KEY;
list buttons = ["button1", "button2", "button3"];
default {
state_entry() {
toucher = NULL_KEY;
}
touch_start(integer detected_num) {
toucher = llDetectedKey(0); //一番最初にタッチいた Avatar の Key を取得
state dialog; //ダイアログ・ステートに移動
}
}
state dialog {
state_entry() {
integer hDialog = llListen(-5555, "", toucher, ""); //-5555チャンネルで、タッチした Avatar の声だけ聞く設定
llListenControl(hDialog, TRUE); //リスナーを追加(要は聞き始める、ということ)
llDialog(toucher, "好きなボタンを押してください。", buttons, -5555); //ダイアログを表示。返信は -5555 チャンネル
llSetTimerEvent(30.0); //30秒でタイムアウトにさせるため
}
touch_start(integer detected_num) { //ダイアログ処理中にタッチした Avatar への処理
integer i = 0;
for(; i<detected_num; i++) { //タッチした人分の処理をする for ループ
llInstantMessage(llDetectedKey(i), "ダイアログ使用中です。しばらくまってください。");
}
}
timer() {
llInstantMessage(toucher, "タイムアウトになりました。");
llSetTimerEvent(0.0);
state default;
}
listen(integer channel, string name, key id, string message) {
if (llListFindList(buttons, [message]) != -1) { //一応のチェック処理。この程度なら必要ないですが・・・
llSetTimerEvent(0.0);
if (message == "button1") {
xxxxxxxx;
} else if (message == "button2") {
yyyyyyyy;
} else if (message == "button3") {
zzzzzzzz;
}
state default;
}
}
state_exit() {
toucher = NULL_KEY;
llSetTimerEvent(0.0); //しつこいですが、、、過去に timer が戻らなかったことがあったので・・・
}
}
続きを読む


