2014/09/13

階段を昇らずにジャンプ

SL内の階段やはしごには、歩いて昇るのが面倒な省エネタイプの人のために、簡単なジャンプをしかけておくと親切です。
このジャンプは「座る」位置を設定して、誰か座った人を目的の場所に立たせるようにします。
省エネの徹底には「メニューから選ぶ」のも省きたいので、「(左)クリックで座る」設定にします。

目的位置の設定も簡単にするため、所有者がそこに立ってタッチするとその位置を記録するようにします。
もしすでに設定済みの場合、普通のタッチ(左クリック)では座ってしまうので、右クリックでメニューを開いてタッチを選び、リセットで全部解除してから、もう一度目的位置に立ってタッチしなおします。

llSitTarget() で位置と向き(回転)を設定しますが、プリムから見た相対的(ローカル)な位置と回転にするため、タッチしたアバターの位置からプリムの位置を差し引き、プリムの回転で割ります。(回転は「引く」のでなく「割る」のだそうです)
default {
  state_entry() {
    llSitTarget(ZERO_VECTOR,ZERO_ROTATION); // 座る位置設定解除
    llSetClickAction(CLICK_ACTION_NONE); // 左クリックの動作設定解除
  }
  touch_start(integer num) {
    if (llDetectedKey(0)==llGetOwner()) { // 所有者だけが設定できる
      if (Target) llResetScript(); // 設定済みならリセット
      vector pos = llDetectedPos(0); // 位置
      rotation rot = llDetectedRot(0); // 回転(向き)
      pos = (pos-llGetPos())/llGetRot(); // ローカル座標に変換
      rot /= llGetRot();
      llSitTarget(pos,rot); // 座る位置と回転を設定
      llSetClickAction(CLICK_ACTION_SIT); // 左クリックの動作「座る」
      Target = TRUE; // 設定が済んだしるし
    }
  }
  changed(integer change) {
    if (change & CHANGED_LINK) { // 座るとリンクが変わる
      key id = llAvatarOnSitTarget();
      if (id) { // アバターが座ったら
        llSleep(0.7); // 落ち着くまで待って
        llUnSit(id); // 立たせる
      }
    }
  }
}