Adsense

2009年10月8日木曜日

[LSL] データを保存したい : llGet/SetObjectDesc

最近よく私が使う手です、、、(笑
スクリプトで、あるデータの保存をしたい場合、おおくは list にデータをいれて、のちのち使う、ということをしますよね。
ですが、list はスクリプトのリセットがかかってしまうと初期値にもどります。
そこで MLDU などでも使うのがユーザーさんが編集可能な「ノートカード」に使うべきデータ/情報を記述してもらい、スクリプトはそこからデータを読み込む、、、という方法をとってきました。
でも、、、ノートカード使うほどじゃない場合もあるわけで。
なれるとノートカード読み込みスクリプトはスラスラかけるのですが、それでもエラー処理をいれることになります。
また、ノートカードは明示的にノートを開き、ユーザーが編集して保存する、というステップを踏まなくてはならず、スクリプトからノートカードにデータを書き込みことができません。さらに編集後にノートカードを読み込む、もしくはスクリプトのリセットをかけなければなりません。
お友達の中には llHTTPRequest を使って、Web サーバーにデータを飛ばして、必要なときにとりにいくようなスクリプトを書く人もいますが、Web サーバーを用意するほどのものでもない、、、ってあるんです。
スクリプトのリセットがかかっても、データを保持できる場所で、スクリプトからの書き込みが可能、それも外部の Web サーバーを使わずに、、、となると、私の知る範囲だとプリム(オブジェクト)の「説明」の欄になります。(オブジェクトの名前も可能ですが、、、それはちょっとやりすぎ、、、、と思います)
ObjectDesc
この「説明」は llGetObjectDesc で現在のデータ(文字列)を取得し、llSetObjectDesc でこの「説明」の欄に新しい文字列をいれることができます。
もちろん、オブジェクトを「取る」でインベントリに戻しても、再度 Rez したときにその情報は残っているので再利用することが可能です。
注意点は以下です。
1. 日本語は使えません。英数字のみ使用することができます。日本語をいれてもエラーになりませんが、取り出すと ??????? となってしまいます。 (ただし、、、Base64 とかのエンコードを使って日本語の保持はできます。エンコードについてはこちらを参照してください。)

2. 127バイトまで利用可能です。それ以上いれてもエラーにはならず切り捨てられます。

3. changed イベントなどでの変更チェックはできません。
4. もちろん、、、関係ないユーザーを含めた全員が編集でここの値を見ることができます。
たとえば設置型オブジェクトのスクリプトでチャット・チャンネルをユーザーが自由に設定できるようにした場合など、この「説明」を使ったります。ユーザーさんがどんなチャンネルを指定するのかわかりませんし、ノートカードを使うほどの情報量でもなく、かつ、スクリプトのリセットを行っても情報を残したい場合などに重宝しています。
ちなみに、SIM のローリング・リスタートなどではスクリプトのリセットは行われません。なので、list に保持したものを引き続き使うことができます。どちらかといえば、ユーザーさんに好評なのは上記の例でいえば「自分がどんな値を設定したか一目瞭然」という意見が圧倒的に多かったです。
ご参考になればなによりです~
[追記 2009.10.9]
上記の方法のほかに、ノートカードを読み込まず、データ保存して再利用する方法があります。これは MLDU で使っている方法ですが、以下のような名前のノートカードを用意します。
00:dance1

スクリプトでは、llGetInventoryNumber(INVENTORY_NOTECARD) でプリムのフォルダにあるノートカードの数をチェックし、その数の分 for をまわして、ノートカードの名前をとり、先頭3文字が 00: だったら、それ以降の文字を取り込む、というものです。
ユーザーさんには「00: のあとに xxxxx をいれてね」と頼みます。ノートカードを開かず、ノートカードの名前の変更だけをお願いする方法です。
これでも、スクリプトからの書き込みはできません。スクリプトからの書き込みが OK なものは基本的に llSetXXXXX になるので、不揮発性のデータエリアとなるとやはりオブジェクトの名前か説明になってしまいます。