CorradeでSecondLife/OpenSimulatorのボット入門(その1)の続きです。前回はボットが棒立ちで終わってしまいましたが、今回はLSLを使って、実際にボットアバターを動かしてみます。Corradeサイトが結構癖のある造りとなっていますので、この記事で、どこに何があるのか、スクリプトを作成する際に見るべきポイントも紹介します。
概要
スクリプトを使ってボットアバターを動かす仕組みは、下の図のようになっています。
世間一般のボットは、ボットサーバーのようなものにRESTコマンドを発行するイメージが定着していますが、Corradeは少し異なります。
Corradeボットの実体は、機能を付加して軽量にした SecondLife クライアントです。デフォルトでは、サーバーとして動作しているわけではありません。ボットアバターへの命令は、仮想空間のオブジェクトからインスタントメッセージ(IM)を送信することで行います。
設定により、CorradeがHTTP(S)で直接命令を受け付けることもできます。今回の記事は、入門のため、詳細は割愛します。
では、ボットアバターからの返答や、状態が変わった時の通知はどうするのでしょう?逆方向、つまりボットアバターからオブジェクトへのIM送信はできません。このため、代わりに、LSLを使って簡易HTTPサーバーを立て、そこへボットアバターからPOSTしてもらうようにします。
スクリプトを書いてみる
それでは早速Corradeでボットに命令をしてみましょう。と思ってCorradeのサイトを見ても、どこに何が書いてあるか途方に暮れるかもしれません。私も途方に暮れました。実は、Corrade - Scripting Consideration が事実上のプログラミングガイドのようなものになっています。
そんなものはいいから、動くものを触りたい!という場合は、Second Life Marketplace の CORRADE ショップから0$で購入するという方法があります。ほぼ全てHUD(仮想空間には表示されず、画面インターフェースに表示されるオブジェクト)となっていますので、とりあえず装着してクリックしてみれば、何か動きます。HUDの中にあるスクリプトを開いて、本記事を参考に、処理の流れを追っていくと良いでしょう。
今回は、クリックしたらボットアバターがその場に座り、もう一度クリックしたら立ち上がる、というHUDを作ってみます。
HUD開発環境の準備
- オブジェクトが置ける場所にテレポートします。置ける場所が思い浮かばない方は、MeltingdotsのSandboxあたりをお薦めしておきます。
-
Ctrl+4
を押し、適当に地面をクリックして、オブジェクトを新規作成します。名前は適当で良いです。 - オブジェクトを
Take
または取る
します。 - インベントリを開き、拾ったオブジェクトを探します。「最新」というタブで探すと探しやすいです。
- オブジェクトを右クリック->
HUD装着先
->左下
を選択し、オブジェクトを画面に表示させます。 - 装着したオブジェクトを右クリック->
編集
で編集ダイアログを開き、中身
タブをクリックします。 -
新しいスクリプト
ボタンをクリックします。 -
新規スクリプト
をダブルクリックすると、エディタらしきものが開きます。 - この状態で、ボットのある場所までテレポートして戻ります。
枠を作る
クリックで状態を切り替える仕組みを作っておきます。開いているエディタの中のスクリプトを、以下のコードで上書きします。
default
{
touch_start(integer num_detected)
{
llOwnerSay("ボットアバターを座らせます");
//
// ここで[地面に座る]を命令
//
state on_the_ground;
}
}
state on_the_ground
{
touch_start(integer num_detected)
{
llOwnerSay("ボットアバターを立たせます");
//
// ここで[立ち上がる]を命令
//
state default;
}
}
保存した後、オブジェクトをクリックして、「座らせます」「立たせます」がチャットに交互に表示されていればOKです。
ここまで書いたスクリプトのGistはこちらです。
APIの入手
次に、やりたいことができるような関数を探してみましょう。
API一覧は、こちらにあります。
http://grimore.org/secondlife/scripted_agents/corrade/api/progressive
APIは、3つのカテゴリに分類されています。
- COMMANDS ... ボットに命令する関数
- CONFIGUFATION ... ボットの設定プロパティ
- NOTIFICATIONS ... ボットからのイベント通知のPOSTリクエスト仕様
今回出すべき命令は、「その場に座る(ground sit)」と「立ち上がる(stand)」の2つですので、COMMANDSの関数の中から、それっぽいものを探します。後者は比較的すぐ見つかると思いますが、前者は「ground sit site:grimore.org」のような感じでGoogle検索しないと見つからないかもしれません…
どうやら、以下の関数が、それっぽいことをするようです。
地面に座る(RELAX)
API仕様を確認します。リンク先の画面の中に、Example
というコーナーがあり、そこにスクリプトが書いてあります。これをそのまま、書きかけのスクリプトのここで[地面に座る]を命令
の位置に追加します。
llInstantMessage(CORRADE,
wasKeyValueEncode(
[
"command", "relax",
"group", wasURLEscape(GROUP),
"password", wasURLEscape(PASSWORD)
]
)
);
よく見ると、wasKeyValueEncode
やwasURLEscape
という関数が使われています。これは、Corradeの「ヘルパー関数」というものです。後で入手方法を説明します。
CORRADE
、GROUP
、PASSWORD
定数に設定すべき内容も、後で説明します。
立ち上がる(STAND)
同様に、API仕様を確認します。Example
のスクリプトをここで[立ち上がる]を命令
の場所に追加します。
llInstantMessage(CORRADE,
wasKeyValueEncode(
[
"command", "stand",
"group", wasURLEscape(GROUP),
"password", wasURLEscape(PASSWORD)
]
)
);
ここまで書いたスクリプトのGistはこちらです。
定数を追加
先に、CORRADE
、GROUP
、PASSWORD
を解決します。書きかけのスクリプトの先頭に、以下を追加します。XXXX
とかYYYY
とかはダミーです。
string CORRADE = "XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
string GROUP = "My Group";
string PASSWORD = "YYYYYYYY";
CORRADE
には、ボットアバターのUUIDが入ります。
CORRADE(ボットアバターのUUID)
オブジェクトの中に新しいスクリプトを作成して、以下で上書きして保存します。
default
{
touch_start(integer num_detected)
{
llSensor("", NULL_KEY, AGENT_BY_LEGACY_NAME, 5.0, PI);
}
sensor (integer num_detected)
{
integer i = 0;
while (i < num_detected)
{
llOwnerSay(llDetectedName(i) + ", " + (string)llDetectedKey(i));
i++;
}
llSensorRemove();
}
}
ボットアバターに近づいた状態でオブジェクトをクリックすると、「座らせます」「立たせます」以外に、名前とUUIDの組がチャットに表示されます。
確認し終わったら、新しく作成した方のスクリプトはオブジェクトから消しておきましょう。
GROUPとPASSWORD
その1で設定した内容をここで設定します。
GROUP
は、特に変更していない限りMy Group
です。
PASSWORD
は、Group Password
で設定した内容とします。
ここまで書いたスクリプトのGistはこちらです。
ヘルパー関数の入手
最後に、wasKeyValueEncode
やwasURLEscape
を解決します。
CorradeのLSLヘルパー関数は、ここにあります。URLやタイトルからは想像できませんが…
http://grimore.org/fuss/data_structures/key-value_pairs#index
1箇所で全て入手できるわけではなく、関数ごとにページが分かれています。主な関数のみ転載します。
関数名 | 説明 |
---|---|
wasKeyValueEncode() | listからkey-value文字列を生成 |
wasKeyValueURLEscape(), wasURLEscape() | RFC1738(URL)文字列へエスケープ |
wasKeyValueDecode() | key-value文字列からlistを生成 |
wasKeyValueURLUnescape(), wasURLUnescape() | RFC1738(URL)文字列のエスケープ解除 |
wasKeyValueGet() | 特定のプロパティのvalueを取得 |
wasKeyValueSet() | 特定のプロパティの値を変更したkey-value文字列の取得 |
wasKeyValueDelete() | 特定のプロパティを抜いたkey-value文字列を取得 |
wasKeyValueEncode
とwasURLEscape
のページを開いて、「LSL」セクションに書いてあるコードをコピーして、定数より下、default
の行より上に貼ります。関数ヘッダのGPLv3宣言も含めて貼りましょう。
これで保存すると、正常に保存が完了するはずです。
完成したスクリプトのGistはこちらです。
動かしてみる
オブジェクトをクリックします。うまくいけば、ボットアバターがその場で胡座をかいて座るはずです。
もう一度オブジェクトをクリックすると、立ち上がるはずです。
Corradeのコマンドプロンプトやログに、relax
やstand
の命令がされた旨が出力されます。
サンプルなど
ここまでで、一通り雰囲気はつかめたかと思います。興味があれば、もう少し複雑なサンプルを見てみましょう。Various Corrade Projectsが、事実上、サンプルの寄せ集めページになっています。
アドベントカレンダーでのCorrade入門記事は、この記事で最後です。今後、続編を書くことがあれば、Corradeタグで通常記事として書くつもりです。