常用函数 :
string llList2String(list src, integer index)
从
List
里获取其中的一个元素
,
并转为
string. index begin from 0.
Example:
llList2String(foo, 0);
// returns the first element in the list
string llDumpList2String(list src, string separator)
通过第二个参数指定的字符把
List
里的所有
element
连成一个
string.
llParseString2List
是与该方法刚好相反
Example:
list foo = ["a", "b", 5, ZERO_VECTOR];
// outputs: "a + b + 5 + <0.000000, 0.000000, 0.000000>"
llSay(0, llDumpList2String(foo, " + "));
list llParseString2List(string src, list separators, list spacers)
把参数src根据参数separators and spacers来分成list.
其中参数separators和spacers都是拆分符,都是数组变量,他们之间的区别在于:
splitting at and
discarding
separators
, and splitting at and
keeping
spacers
见下面的例子
Example:
llParseString2List("one,two,three,'four','five,six' ",[","],[]);
返回结果是:
["one", "two", "three", "'four'", "'five", "six' "]
llParseString2List("one,two,three,'four','five,six' ",[",","'"],[]);
返回结果是:
["one", "two", "three", "four", "five", "six", " "]
llParseString2List("AllCowsEatGrass", ["A", "C", "E", "G"], []);
返回结果是:
["ll", "ows", "at", "rass"]
llParseString2List("AllCowsEatGrass", [], ["A", "C", "E", "G"]);
返回结果是:
["A", "ll", "C", "ows", "E", "at", "G", "rass"]
key llGetOwner()
返回该scripted object的拥有者(不是创造者, 因为object可以转让, 也不是touch该object的user)的key.
注意
:
由于
object
可以转让
,
这就会给你的
script
造成一个问题
:
例如你的
script
有调用
llListen
or
llRequestPermissions
方法
,
而且方法里用到
llGetOwner,
那么就可能会出问题
.
因为如果
object
转让给别人之后
, listen
的还是原来那个拥有者
,
而不是新的拥有者
.
解决方案是
:
在
on_rez
event
里调用方法
llResetScript
, or even
llListen
in
on_rez
.
还要记得通过调用
llListenRemove
来
remove old listens
.
integer llListen(integer channel, string name, key id, string msg)
很重要的一个方法
:
调用该方法会令
object
能够
listen
特定的
object/avatar
通过特定的
channel
发送的消息
.
注意不是监听
object
周围所有的
channel
所有的
object/avatar
的消息
.
当监听到消息时
,
会调用
listen()
event handler
.
参数
channel
就是指定监听的
channel.
比较特殊的值是
0,
表示
channel
是
public chat channel,
即只要在你平时用来聊天的
chat channel
里输入命令
,object
就会
listen
到
.
参数
name
和参数
id
是用来指定监听的
object/avatar,
如果设置
name
为
empty string and id
为
NULL_KEY
,
那么就会监听所有的
object/avatar
在
channel
上发送的消息
.
其中的参数
name
是指定
name
为该参数值的
object/avatar,
参数
id
是指定
key
为该参数值的
object/avatar
返回值是该
listener
的
handle,
用于将来通过调用
llListenControl
and
llListenRemove
方法来
deactivate or remove
该
listener.
强烈建议在不需要
listener
时要把它
remove
掉
,
这是因为即使
object
的
state
发生改变
, listener
不会自动的消失
.
The returned handles start at 1, so you can set your handle variable to 0 (zero) when you deactivate a channel and test for that elsewhere when you need to know if it's active or not.
过度的使用llListen方法会影响object的性能, 如果可以有其他方案(例如:
llMessageLinked)来代替使用llListen,那么就要尽量不要使用llListen
接收到的消息的长度问题
:
If a script with an
llListen
"hears" a string longer than the script's amount of available free memory, it will halt with a "stack/heap collision" error before your code in the
listen()
event handler has a chance to begin executing. As of SL v1.13, a single chat string on any channel can be up to 1023 bytes in length.
Examples:
Establishes a completely open filter for avatar chat
(
一个最大限度开放的
listener)
integer handle = llListen( 0, "", NULL_KEY, "" );
监听来自object owner在public chat发送来的消息
integer handle = llListen( 0, "", llGetOwner(), "" );
监听来自name为button的object在96号channel发送来的消息
integer handle = llListen( 96, "button", NULL_KEY, "" );
上面这个例子也有实际用途。例如:一个elevator object在不同的楼层都有button object,所有的button object都具有相同的name,但发送的消息里包含的floor number不同。
监听来自avatar的public chat channel的消息常会被见到,但来自object发送的消息是无法从public chat channel传送,那么就象上面最后一个例子那样,监听”值不为0”的channel。好!问题来了:object如何通过某个channel来发送消息?有三个方法可以调用来发送消息:
llWhisper(integer channel, string text)
llSay(integer channel, string text)
llShout(integer channel, string text)
example:
【Message listener】
integer handle = llListen( 96, "button", NULL_KEY, "" );
【Message sender: object named button】
llSay(96, “hello”);
另外llListen还有一个很实际的应用:就是用来接收avatar在llDialog窗口里选择的信息。例如script常常会popup a dialog window,然后avatar选择Yes or No。那么就通过listen event handle来receive avatar’s response。
Example:
key owner=llGetOwner();
listenID=llListen(85, "", owner, "");
llDialog(owner, "Do you like it?", ["Yes", "No"], 85)
。。。。
listen(integer channel, string name, key id, string msg){
if(channel == 85) //come from dialog
。。。。。。
}
}
一个object可以同时监听多个不同的channel(
注意:但不能同时监听不同的object/avatar使用同一个channel ――但好像目前版本支持)(最多监听64个),具体做法很简单,就是调用多个llListen方法,只是参数不同。但要记住,不管来自哪个channel,哪个object/avatar的消息,都会trigger listen() event handler。
llDialog(key id, string message, list buttons, integer chat_channel)
该方法会向参数
id
所对应的
avatar
弹出一个
dialog window
,该
dialog
会包含参数
message and buttons
的
info,
还会包含一个
ignore button
。当
avatar select
其中一个
button
时,就相当于
avatar
在参数
chat_channel
所指定的
channel
里发送了一条消息(消息内容是该
button
的
text
),从而会
trigger listen() event handler
。
如果参数
chat_channel
的值为
DEBUG_CHANNEL
,那么
avatar
选择
button
时发送的消息不是该
button
的
text
,而是该
button
的
name
l 参数message的值不能超过512个字符,也不可以为空。可以包含”/n” and “/t”等字符
参数buttons有以下要注意的:
l 必须是
a list of strings,其他类型不行
l buttons list包含的元素个数不能超过12个,但可以为0个。如果是0个的话,dialog会提供一个“OK” button
l buttons里的每个string的长度不能超过24个字符,否则会出错
如果user选择了dialog自身提供的“ignore” button,将不会trigger listen() event handler。
Example:
integer CHANNEL = 42; // dialog channel
list MENU_MAIN = ["Sit", "Stand", "Fly"]; // the main menu
default
{
state_entry() {
// listen for dialog answers (from multiple users)
llListen(CHANNEL,
""
, NULL_KEY,
""
);
}
touch_start(
integer
total_number)
{
//
llDetectedKey
函数返回的是激活了dialog的user的key
llDialog(
llDetectedKey(0
),
"What do you do?"
, MENU_MAIN, CHANNEL);
}
listen(
integer
channel,
string
name,
key
id,
string
message)
{
//
llListFindList
函数是检查
message
是否是
MENU_MAIN
的元素
if
(
llListFindList
(MENU_MAIN,
[
message
]
) != -1)
{
// output the avatar name and the selected button text
llSay(0, name +
" picked the option '"
+ message +
"'."
);
}
}
}
至于在
dialog
里各个
button
的摆放位置的问题,请详见 http://www.lslwiki.net/lslwiki/wakka.php?wakka=lldialog
还有就是强烈建议对
llDialog
设置
timeout
,用来防止
popup dialog
之后,
user
并没有选择任何
button
的情况!代码类似下面:
integer handle = -1;
integer CHANNEL = 42;
float TIMEOUT = 60.0;
list MENU = ["yes", "no"];
default
{
state_entry()
{
if ( handle != -1 )
{
llListenRemove( handle );
handle = -1;
}
}
touch_start( integer total_num )
{
handle = llListen( CHANNEL, "", llDetectedKey(0), "" );
llDialog( llDetectedKey(0), "Are you sure?", MENU, CHANNEL );
llSetTimerEvent( TIMEOUT );
}
listen( integer chan, string name, key id, string msg )
{
if (
llListFindList
( MENU, [msg] ) != -1 )
{
if ( msg == "yes" )
{
// Do your stuff...
}
else if ( msg == "no" )
{
// Don't do your stuff...
}
llListenRemove( handle );
handle = -1;
llSetTimerEvent(0.0);
}
}
timer()
{
if ( handle != -1 )
{
llListenRemove( handle );
handle = -1;
}
}
}
key llDetectedKey(integer number)
返回根据参数
number
指定的
detected object
的
key
。(如果
detect
到的
object
数为
0
,或者参数
number
的值无效,返回值为
NULL_KEY
)
所有以
llDetected
开头的
Detection
函数主要是用来获取被
sensors, touch, and collision events
detect
到的
objects and agents
的
info
所有的
Detection
函数都需要一个
integer
参数,该参数值指定的是
sensor, touch, or collision event
detect
到的所有
objects/avatars
中你想要的
object/avatar
的
index
(
该值从
0
到
detect
到的
object/avatar
total_number
- 1
)
If a detection function is called from a user-defined function, the function inherits the data from the event that called it.
l
非常要注意的知识点:
所有的
Detection
函数只能够在
collision
,
collision_start
,
collision_end
,
sensor
,
touch
,
touch_start
, or
touch_end
events
方法里
里调用,在其他地方调用是完全不起作用的!