注:所有内容摘抄自 http://www.ibm.com/developerworks/cn/edu/r-dw-r-radsl.html
图元,或简称 Prims,定义了一个空间的几何区域,以及它包含的物质。您在 Second Life 中可以进行交互的每样东西都是由图元构成的。图元可以与其他图元链接在一起,并且结果的复合物体可以作为一个单位进行控制。每个图元总是有一个当前状态,而每个状态都有一组事件处理程序。
在 Object 选项卡中,选择 Physical,意味着向您的物体应用物理惯例,它将落到地面上,撞到东西,其最重要的是,您可以从事件处理程序中向它施加力。
llApplyImpulse (<2, 0, 0>, FALSE);
物体就好像受到沿 x 轴的大小为 1 的力打击一样,应该沿着 x 轴移动
所有的碰撞检测都是由物理引擎处理的,当物体与其他任何东西碰撞时,就会简单地触发碰撞事件,collision_start和collision_end。
例如:
default {
state_entry () {
llSetStatus (1, TRUE); // make sure that Physical is turned on
}
collision_start (integer total_number) {
if( llDetectedKey(0) == llGetOwner() ) {
llSay (0, "Collided with "+llDetectedName (0));
llApplyImpulse (<2, 0, 0>,> FALSE);
}
}
}
记住使用碰撞事件的结果是该事件可以用比触摸(要求玩家的有意识的动作)更少的控制来触发。一个游戏物体触碰到其他物体时就会出现碰撞,即使该游戏物体对您来说像个地板。如果不是真实的陆地,那么它就是一个游戏物体,并且会碰撞。如果像最近两个实例中一样,您不根据
llGetOwner
进行检查,那么您就会与地板不断碰撞,而您的球将会很快消失。在任何将整数total_number作为参数的事件中(如touch_start,collision_start),total_number指的是同时发生该事件的数量,或者当前事件的参与人的数量。各种llDetected*方法收集有关第索引号次发生当前事件时的信息。因此,在此实例中,llDetectedName(0)获得了与当前物体第一个碰撞的人的名称。如果有两个人同时撞击,将会忽略第二个,因为您只参考索引 0。
LSL 系统中的另一个关键组件是传感器。
将传感器认为是在计时器上一次或重复触发的声纳脉冲信号。每次传感器扫描完毕时,将触发一个sensor事件。因此,使用传感器的基本方法是定义初始的扫描参数,然后提供循环扫描一次中找到的所有物体的传感器事件处理方法。在传感器事件处理方法里又是一个示范如何循环一系列对llDetected*方法的调用的绝佳机会(见下列代码)
default {
state_entry () {
//每一秒对方圆10米范围对AGENTS扫描1次(同时会trigger sensor event method),
llSensorRepeat ("","", AGENT, 10.0, 3.1415926, 1.0);
}
sensor (integer total) {
integer i;
//循环调用llDetected*方法
for (i = 0; i < total; i ++) {
string name = llDetectedName (i);
llWhisper (0, name+" is within 10 meters");
}
}
}
上面的例子是进行重复的扫描操作,如果你只希望扫描1次,那么调用llSensor方法(见下列代码)
default {
touch(integer total_number) {
llSensor("","",AGENT,20, 3.1415926);
}
sensor(integer total_number) {
llWhisper(0, "I see "+llDetectedName(0));
}
}
注意:您不能在运行一个循环的传感器的同时,调用单独扫描的方法。您不得不通过调用
llSensorRemove
方法来来停止循环的传感器,然后在重新启动循环扫描之前扫描并处理它记住重复的传感器和单独的传感器都触发同样的事件:sensor。由于每个状态的每个事件都只有一个处理程序,所以一个事件处理程序将收到所有的传感器事件。生成的事件是相同的,但是通过自己设置标志,您的代码应该知道目前运行的是否是重复的传感器,或者它是否在处理您的单独的脉冲。虽然做到这些是可行的,但是这是笨拙的设计模式,因此我不会详细地介绍一个实例。较好的方法是在单独的状态中设计,以便您可以拥有单独的传感器事件处理程序,每个状态一个。
例:下面的代码就是repeat state负责处理循环扫描,而single state则负责处理单独扫描。
default {
state_entry() {
state single;
}
}
state repeat {
state_entry() {
llSensorRepeat("","",AGENT,20,3.1415926, 1.0);
}
sensor(integer total) {
llSay(0, "Repeating: I see "+(string)total+" agents.");
}
state_exit() {
// turn off the repeating sensor
llSensorRemove();
}
touch(integer total) {
state single;
}
}
state single {
state_entry() {
// fire a sensor once
llSensor("","",AGENT,20,3.1415926);
}
sensor(integer total) {
llSay(0, "Once: I see "+(string)total+" agents.");
}
state_exit() {
// clean up the single sensor
// even though it isn't repeating,
// we might leave this state before the sensor fires once
llSensorRemove();
}
touch(integer total) {
state repeat;
}
}
Object script与玩家化身(avatar)
Object script与avatar之间的交互有三种主要方式。
1. 玩家可以通过“坐”在物体上来链接物体。为物体给出定制此过程流的事件和控制,以便您可以让玩家化身坐在,例如复合的交通工具的正确位置上。
2. 玩家可以‘穿’物体。要完成这件事,物体必须附着于身体的许多绑定点上(要查看列表,右键单击您的储备中的物体,并选择 Attach。您将获得一个身体可绑定点的完整列表)。
3. 具有足够权限的物体可以请求玩家化身启动或停止运行着的某个指定动画例程。
坐在物体上,是由方法llSitTarget和 changed 事件处理的
例
default {
state_entry() {
//该方法是设置“当有人要坐到object上”时该坐在object的哪个位置
//而不是执行坐这个动作
llSitTarget(<0.0, 0.0, 0.1>, ZERO_ROTATION);
}
changed(integer change) {
//表示有人坐到object上
if (change & CHANGED_LINK) {
llWhisper(0, llKey2Name(llAvatarOnSitTarget())+" sat down.");
}
}
}
不论什么时候有人坐下,都会‘链接’到所坐的物体。该动作触发了带有包括CHANGED_LINK参数的 changed 事件,指示有人链接到该物体。在坐完成之前,请求坐的玩家化身被传递给llSitTarget的参数平移并旋转。在上面实例的情况下,它们被提升了 .1 米,没有旋转。llAvatarOnSitTarget返回现在坐着的玩家化身的key。记住您总是根据物体的局部轴坐下。因此,如果您坐在旋转的球上,您也将旋转,不管您传递给llSitTarget的旋转参数是什么。
附着(穿)Attach
将脚本化的物体附着到您的身体上是超级简单的事,并且需要非常少的代码。但它迫使我们引入一个新概念:权限(permissions)。
用llGetPermissions来核实,您是否已经拥有,如果没有,使用llRequestPermissions打开对话框,向用户请求权限。在llRequestPermissions从用户那里得到回答之后,用新的权限触发事件run_time_permissions。(注意:它不返回。这是无阻塞的调用)。只有在触发该事件,并且您已经复核您现在拥有适当的权限之后,就可以安全调用llAttachToAvatar
例
default {
touch_start(integer detected) {
llRequestPermissions(llDetectedKey(0), PERMISSION_ATTACH);
}
run_time_permissions(integer perm) {
if (perm & PERMISSION_ATTACH) {
llAttachToAvatar(ATTACH_RLARM);
}
}
}
控制Avatar (如让avatar跳舞、鼓掌)
为了让Avatar动起来,您必须拥有权限PERMISSION_TRIGGER_ANIMATION。像前面实例中一样进行,并请求权限,一旦您得到允许就启动动画。有一长列内嵌的游戏动画列表,您可以在参考部分中找到完整列表的链接。
例:当您触摸时,您就会鼓掌
default {
touch(integer total) {
key avatar = llDetectedKey(0);
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);
}
run_time_permissions(integer perm) {
if (perm & PERMISSION_TRIGGER_ANIMATION) {
llStartAnimation("clap");
}
}
}
“鼓掌”动画将持续运行,您可以调用
llStopAnimation("clap")
来中断。要查看您是否仍旧在运行此动画,调用llGetAnimationList
。