
今回はセンサースクリプトのお話です。
センサースクリプトとしては代表的な使い方のひとつで、
、持ってるいる人もいるかと思いますが、
HUD装着して他のアバターが何メートル先にいるかを教えてくれるスクリプトの紹介です。
ただ単に何メートル先かを知らせてくれるだけでは面白くないので、
後半では応用したものを載せておきます。
では、スクリプトから。
~スクリプト~
===================================================
1:float range=96.0; //Max96.0
2:float interval=2.0;
3:string str_av;
4:string str_name;
5:string str_dist;
6:default
7:{
8: state_entry()
9: {
10: llSensorRepeat("",NULL_KEY,AGENT,range,PI,interval);
11: }
12: sensor(integer num)
13: {
14: str_av="";
15: integer a;
16: for (a=0;a<num;a++)
17: {
18: vector my_pos=llGetPos();
19: vector dtc_pos=llDetectedPos(a);
20: //==============Avatar Name=====================
21: str_name=llDetectedName(a);
22: //==============================================
23: //===============Distance========================
24: str_dist=(string)llRound(llVecDist(dtc_pos,my_pos));
25: //===============================================
26: str_av=str_av+str_name+":"+str_dist+"m:\n";
27: }
28: llSetText(str_av,<1,1,1>,1);
29: }
30: no_sensor()
31: {
32: llSetText("",<1,1,1>,1);
33: }
34:}
===================================================
1行目や20行目にある「//」以降にある文字は注釈と言ってメモ書きみたいなものです。
スクリプトとしての機能はなく、覚書やメモを書いておくことができます。
メインとなるスクリプトは、
10行目、12行目、30行目の
llSensorRepeat("",NULL_KEY,AGENT,range,PI,interval);
sensor(integer num)
no_sensor()
です。
llSensorRepeatによってセンサーを起動することができます。
センサーを起動させてあと、
センサーに感知されたらsensor(integer num)以降のイベントが発生し、
何も感知されなかったらno_sensor()以降のイベントが発生します。
では、llSensorRepeatの中身ですが
llSensorRepeat(アバターやオブジェクトの名前,アバターやオブジェクトのID,感知する対象の種類,感知する範囲,感知する方向,感知する時間間隔);
となります。
アバターやオブジェクトの名前は、ここに名前を入れると、その名前だけに反応します。特定しない場合は””としておきます。
アバターやオブジェクトのIDは、UUIDをいれます。名前と同じく特定しない場合はNULL_IDとします。
感知する対象の種類は、4種類あって
・AGENT:アバター
・ACTIVE:移動しているオブジェクト
・PASSIVE:移動してないオブジェクト
・SCRIPTED:スクリプトが入っているオブジェクト
です。
感知する範囲は、何メートルまで感知するかを設定します(最大は96mです)。
感知する方向は、角度で表わします。感知する範囲が中心から何メートルと設定されますので、角度を最大にすると
ちょうど球形の感知エリアが生成されます。最大角度はラジアンで表わしPIとなります。
オブジェクトのX軸が角度の支軸になりますので、PI/2とすると、X軸を中心とした半球の形に感知エリアが形成されます。
感知する時間間隔は、何秒間隔にセンサーを起動するか設定します。
なので、
10行目の、llSensorRepeat("",NULL_KEY,AGENT,range,PI,interval)では
1行目~2行目に
float range=96.0;
float interval=2.0;
と宣言していますので、
2秒間隔で、96mの中に入ってきたアバターを感知します。
センサーに感知されたら、12行目以降に移ります。
sensor(integer num)のnumは何個感知したかが代入されます。
1個感知されるとnumは0となりますので、10個感知だとnumは9となります。
18: vector my_pos=llGetPos();
19: vector dtc_pos=llDetectedPos(a);
20: //==============Avatar Name=====================
21: str_name=llDetectedName(a);
22: //==============================================
23: //===============Distance========================
24: str_dist=(string)llRound(llVecDist(dtc_pos,my_pos));
25: //===============================================
26: str_av=str_av+str_name+":"+str_dist+"m:\n";
感知されたものの名前を調べるには、
llDetectedName(a)
感知されたものの位置を調べるのは、
llDetectedPos(a)
です
(a)はinteger numに影響され、num(正確にはnum-1)個感知されたうちのa番目という意味です。
これで、名前と位置はわかりました。
自分と相手の距離を調べるのは簡単で、
24行目のllVecDist(dtc_pos,my_pos)です。
18行目で自分の位置(llGetPos())も調べてありますので
llVecDistですぐ算出されます。ただこのままでは、小数まで出てきますので
小数点以下を四捨五入させてllRound(llVecDist(dtc_pos,my_pos))としています。
アバター名:●●mと表示させたいので、26行目でstr_av+str_name+":"+str_dist+"m:\n"と表記させています。
この行の最後に\nとありますが、これは改行の意味です。
llSetTextでこの改行を表示させたい文字の中に入れると、2行・3行と行を分けることができます。
このllSetTextですが、
オブジェクトの上に文字を表示させるスクリプトです。
中身はllSetText(表示させたい文字,文字色,透明度)となっており
R,G,B,透明度は0~1の数字を入れます。
ちなみに白は<1,1,1>、黒は<0,0,0>です。不透明は1、完全透明は0です。
一度llSetTextで文字をいれてしまうと、llSetTextの入ったスクリプトを消しても、オブジェクトの上の文字は消えません。
消したい場合は、llSetText("",<1,1,1>,1)のような空文字""をいれて消してくださいね。
~応用編~
基本的なセンサーの使い方の説明でしたが、これを応用して
相手がどっちの方向にいるか(自分から見て)のスクリプトを追加してみました。
アバター名:距離m:方向:上下
という風な表記にしています。
方向はForward,Back,Right,Leftの表記で8方向+同じXY軸上にいた時にCenter
上下はUp,Down+同じ高さにいた時にFlat
と表示させています。
===================================================
float range=96.0; //Max96.0
float interval=2.0;
string str_av;
string str_name;
string str_dist;
string str_dir;
string str_hi;
list list_dir=["Right","Forward/Right","Forward","Forward/Left","Left","Back/Left","Back","Back/Right","Right"];
default
{
state_entry()
{
llSensorRepeat("",NULL_KEY,AGENT,range,PI,interval);
}
sensor(integer num)
{
str_av="";
str_dir="";
str_hi="Flat";
integer a;
for (a=0;a<num;a++)
{
vector my_pos=llGetPos();
vector dtc_pos=llDetectedPos(a);
//==============Avatar Name=====================
str_name=llDetectedName(a);
//==============================================
//==============Height Level====================
float height=dtc_pos.z-my_pos.z;
if (height>=0.5)
{
str_hi="Up";
}
else
if (height<=-0.5)
{
str_hi="Down";
}
//===============================================
//===============Distance========================
str_dist=(string)llRound(llVecDist(dtc_pos,my_pos));
//===============================================
//===============Direction=======================
my_pos=;
dtc_pos=;
vector my_rot=llRot2Left(llGetRot());
vector dtc_rot=dtc_pos-my_pos;
float c=llAtan2(my_rot.x*dtc_rot.y-my_rot.y*dtc_rot.x,my_rot.x*dtc_rot.x+my_rot.y*dtc_rot.y);
str_dir=llList2String(list_dir,llRound(c/(PI/4))+4);
if (llVecDist(dtc_pos,my_pos)<1)
{
str_dir="Center";
}
//===============================================
str_av=str_av+str_name+":"+str_dist+"m:"+str_dir+":"+str_hi+"\n";
}
llSetText(str_av,<1,1,1>,1);
}
no_sensor()
{
llSetText("",<1,1,1>,1);
}
}
===================================================
追加した文は太文字で書いておきました。
このスクリプトの肝は、
float c=llAtan2(my_rot.x*dtc_rot.y-my_rot.y*dtc_rot.x,my_rot.x*dtc_rot.x+my_rot.y*dtc_rot.y);
です。
同一平面上の2ベクトル間の角度を求める式です。
自分の向いている方向をベクトル化し、自分と相手の位置をベクトル化させて、その間の角度を算出して、
相手が自分からみてどの方向にいるかを算出しています。
~さて次回は~
またまた、難しいことしてごめんなさい。。
もっと簡単なことできないかな~っとお持てるのですが
では、次回はグレア(光)をスクリプトで制御してみます^^
====訂正====
Zexさんから、スクリプトのエラーがでるとのご指摘があったので
修正させていただきます。
どうも半角の<が入ってるとhtmlタグと勘違いされて、そのあとの文がところどころ消えてしまうみたい。。
ー修正箇所ー
16行目(応用編も同じところ)の
for (a=0;a<num;a++)
は、あえて全角<にしてました。(ここだけは文字消去されてしまったの気づいたのですが)
全角<を半角<に修正してください。
投稿者:メルティングドッツ
この記事にコメントする
名前(ニックネーム可)とメールアドレスは必ず入力してください.
メールアドレスは管理者にのみ通知されます.
投稿に時間がかかる場合がございますが、投稿ボタンは2回押さないでください.
【プロフィール活用、してる?】
You: プロフィールのpickup機能は使ってる?>みんな あれおすすめですよ
C: 使ってないなぁ
N: 使ってる
K: つかってないなー
You: 自分がいつもいる場所やお気に入りの場所をいれておくことができる
D: 使ってない
N: オリエンいれてあるよ
L: それ使ってカードを送ってる
H: 今見たらWalker Island が入ってた
M: 知らなかった・・・w
D: 自分のプロフィール、いじってないな^^;
F: わしも、プロフのSS昔のだw
You: なんか書いてあるとみんな安心するよ>プロフィール
J: 知らなかった。
H: みんなのプロフは真っ先に見るよ
![]()
【日本語文字化けの理由】
You: プロフィール充実イベント とかやりたいね
C: プロフィールほったらかしだw
You: みんな集まってその日に超充実させるw
N: 中には一年以上やってるのに初心者ですって人もいるねw
J: プロフィール何も書いてない状態です
You: いるいるw
H: 中身書いてあると信用が増す^^
You: 1年に一回は更新しましょう、みたいな?
C: ずっと前に書いたので????になってるw
F: なってるねw
K: あ、日本語化けるね
F: 今、何気に更新してみたw
You: リンデンがクライアント変えるたびにばぐる
J: 文字ばけの原因はそれだったんですね
![]()
【自己主張の仕方。中よりも外に!】
A: 僕は、リアル誕生日の日にプロフに「誕生日でーす」って書いてみたけど、誰もみてくれないのか何にも反応無しでした^^;
F: 悲しいねw
You: どんまいw
N: あらら
K: そういうときは、フローティングテキストでめだつようにしなきゃ
F: 店のLM書くと、嫌がらせの人とか来るから、書きたくないしw
A: あっ、そーですね^^
![]()
You: よし、次回のチャット社長はそれでいきましょう「プロフィールの自己紹介に入れる内容」自己アピール時のフローティングテキスト等の共有 などなど
B: 今気づいたけどプロフィールの一番右って勝手にかけるんだ
K: うん。ここはメモ書ける
B: 右の私の記録ってとこ
A: あー、ほんとだ
H: 「私の記録」結構付けてるけど、、、日本語が全部化けて台無し;;
M: ^^;
A: ここの活用方法も何かあればいいですね
K: まえは、フレンド登録するたびいつどこで会ったかメモしてたけど面倒だからやめた
M: 私はMODEの予定とかしか書かない^^;
F: わしはモードの予定はカフェで見るw
B: 自分のプロフィールじゃなくて、相手のプロフィールにカキコできるんだよ
You: たしかそれは個人個人のメモ欄
K: で、内容は相手にはわからない
You: 自分だけがその文を見ることができる
You: もらった名刺にメモする感じ?
F: んだね、フレリスト見ても、いつフレしたかわからんくなるしw
You: SLはソーシャル機能がたりないよなー
H: むしろたまにしか会わない人の方がよく書くかな^^
B: 本人以外の人が見れるとおもしろいのに
![]()
You: 年賀状から思わぬ方向に話がw
F: んだねw何気にw
B: この人のうわさ みたいな
A: あはは^^;
You: それでは22:00を迎えましたのでイベントを終了したいと思います。
You: 来週は「プロフィール最適化計画」をお送りいたします。ではみなさん、良いセカンドライフを。
編集後記
よくテレビCMで、テレビ電話越しにおじいちゃんおばあちゃんと孫が顔を合わせて話すシーンなどがありますが、あのようなコミュニケーションが身近になったらな、といつも思っています。今回は、リアルで会えない相手同士、デジタルでどのように記念日などを祝ってあげられるか、を議論したく、このテーマとしました。セカンドライフ等のサービスが発展し、「同じ時間」「同じ体験」はネット越しでもおこなえるようになってきました。その部分は共通といえど、「デジタルで同じ場所」と「リアルで同じ場所」の差による影響がどれくらい大きくて、何ができて、何が変わるのか、少しヒントとなったような気がします。
投稿者:Asaeda Meltingdots
この記事にコメントする
名前(ニックネーム可)とメールアドレスは必ず入力してください.
メールアドレスは管理者にのみ通知されます.
投稿に時間がかかる場合がございますが、投稿ボタンは2回押さないでください.
イベントの集合までに準備が間に合わず焦りながらのスタート。。
いつも通り21時5分にメインランドに移動。
前回は大きい敷地にお邪魔したまま終了していたのでまた皆で訪問w

心理的に道がひかれているところを歩く
今回の目標はスタート地点から南に7SIMくらいいったとこにしました。
アクセス制限などがあるため建物の床下などを見つけてはどんどん進む。

頭スレスレの高さ・・

意図的に創られた洞窟発見?!
偶然通れる場所を見つけて進んでいただけに洞窟を見つけて皆で驚くw
メインランドで歩くようになってから地下の道を見つける機会が大幅にアップした気がしますね。。
時間のある時は歩いて移動するのをオススメします!

地下を通らなくても抜け道があったようで出口で合流。。
洞窟を後にしてもっと南へ向かっているとSLExchangeで販売しているのを
みたことがあるアイテムを発見。
フリーで置いてるわけもなく雑談をして次の場所へ移動。

SCULPT S.P.E.E.D 3D

ちょっとした休憩エリア
イベント終了間際にスカイダイビングエリアを発見。
フリーフォールみたいになっていたのでとりあえず皆で座ってみる。
すると一気に上空4000mまで上昇してそこで下ろされるw

フリーのパラシュートを受け取る前に上昇・・・

強制落下・・・

個人的に持ってたパラシュートで助かるFrejaさんw
なんだかんだで楽しかったので次のメンバーがスカイダイビングで
飛び立ちイベントを終了としましたw

投稿者:Tsujikawa Meltingdots
この記事にコメントする
名前(ニックネーム可)とメールアドレスは必ず入力してください.
メールアドレスは管理者にのみ通知されます.
投稿に時間がかかる場合がございますが、投稿ボタンは2回押さないでください.