忍者ブログ
This is an official blog of Orange Forest who is the aircraft developer in the Secondlife virtual world.

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

気まぐれスクリプト講座 Vol.1 - 物理なブランコ

こんにちわ。ミューズです。
今日のエントリは、先日オビワンさんが紹介して下さった ブランコ のスクリプトについて、たまたま題材にしやすそうだったので、ちょっと気まぐれで、LSL初心者+α位な方を想定して御紹介したいと思います。
これであなたも物理スクリプトデビュー?!

ブランコ
::: ブランコ :::

物理で動くブランコです。
設置位置について物言いがついていますwwww
置き場所はコチラ → Airship Caravan/32/83/255
ランディングポイントは飛行船ショップ店内なので、飛行船付属のエレベータで下に下りて頂くとすぐ行き着きます。

ブランコは複数名が好きな着座位置にsitでき、sit後に座席をタッチすると加速が掛かかってブラーンブランします。ブランコは2個のオブジェクトから構成されています。個々の構造については現物を御覧下さいネ

■物理なブランコスクリプトの説明

ここで説明するスクリプトの使用についてオレンジフォレストは一切の損害や、サポートに対する責任を負いません。あくまで自己責任で参照下さい。
スクリプトのCopyrightを保持した上で改変、再販は御自由に。



LSLの基本的な文法や使用方法についてはすぐれた解説書が出回っているのでここでは割愛します。

■ブランコスクリプトの構造

LSLはその言語仕様にステートの概念が入っているちょっと変わった言語ですよね。個人的にはあとはロボット用の動作記述言語でしか見たことが無いです。今回はそのステートを多用したので構造を説明するのに状態遷移図を使ってみます。
ブランコスクリプトは4つのステートから構成されています。

  • default : 初期状態
  • waiting : 誰も乗っていない待機状態
  • active : 誰かが乗ってくれた状態
  • accel : ブランコ加速中‥連続的な加速防止


::: 状態遷移図 :::

それでは、スクリプトです。
間違いとか、改善とかのツッコミは歓迎です。
日本語のコメントは後から書き足しました。普段はココまでやりません><

//================================================================================
// Physical Swing Seat
// All rights reserved, Copyright(C) 2008, Orange Forest
// $Id: seat.lsl 243 2008-09-09 15:04:22Z myuse $
//================================================================================

// グローバル変数 : 'g' は global を示す接頭語
// 変数を識別しやすくするためのローカルルール

integer gDefaultPrims; // 座席のプリム数
vector gDefaultPos; // 座席のホームポジション
rotation gDefaultRot; // 座席の据付時の角度

//---------------------------------------------------
// default state
// 座席のプリム数のカウントと、復帰座標の取得
// アバターが座ったかどうかをプリム数で判定するため
//---------------------------------------------------
default {
state_entry () {
gDefaultPrims = llGetNumberOfPrims();
gDefaultPos = llGetPos();
gDefaultRot = llGetRot();
state waiting;
}
}

//---------------------------------------------------
// waiting state
// 搭乗待ち状態
// SIM負荷軽減のため、人が乗らない場合は非物理
//---------------------------------------------------
state waiting {
state_entry () {
llOwnerSay("Enter waiting");

// 物理off
llSetStatus(STATUS_PHYSICS, FALSE);

// 初期位置に戻る - 後続のステートから戻った時用
llSetPos(gDefaultPos);
llSetRot(gDefaultRot);
}

// リンク状態の変化を検出
// 誰か乗ってくれたかどうかのチェック
changed (integer chgParam) {
if ((chgParam & CHANGED_LINK) && (llGetNumberOfPrims() > gDefaultPrims)) {
llOwnerSay("Enter active");
state active;
}
}

// 再rez 時はリセット
on_rez (integer rezParam) {
llResetScript();
}
}

//---------------------------------------------------
// active state
// 物理でぶらぶらしている状態
//---------------------------------------------------
state active {
state_entry () {
// 物理ON
llSetStatus(STATUS_PHYSICS, TRUE);
}

// リンク状態の変化を検出
// 全員降りちゃったかのチェック
changed (integer chgParam) {
if ((chgParam & CHANGED_LINK) && (llGetNumberOfPrims() == gDefaultPrims)) {
state waiting;
}
}

// 誰かがブランコをタッチして押した?
touch_start (integer numTouches) {
state accel;
}
}


//---------------------------------------------------
// accel state
// 加速状態 : 連続加速で暴走するのを防ぐため、
// 次回加速を受け付けるのは2秒後
//---------------------------------------------------
state accel {
state_entry () {
// 回転力を添加
llApplyRotationalImpulse(<0.0, 0.0, 100.0>, TRUE);
// 2秒毎にタイマーイベント
llSetTimerEvent(2.0);
}

// リンク状態の変化を検出
// 全員降りちゃったかのチェック
changed (integer chgParam) {
if ((chgParam & CHANGED_LINK) && (llGetNumberOfPrims() == gDefaultPrims)) {
state waiting;
}
}

timer () {
// タイマー停止
llSetTimerEvent(0.0);
state active;
}
}



いかがですか?
今回のスクリプトはアニメーション使うつもりが無かったので、着座位置を強制せず、誰かが座ったかどうかの判定をオブジェクトのプリム数で行っています。
そして物理のブランコは誰かが座ってオブジェクトにタッチしたら回転のモーメントを加えるだけです。非物理でブランコを作る場合は連続的な回転を演出しなければならないのでもっと大変ですよね。
また、タッチしたら回転‥というだけなので、応用が効くと思います。ミューズがパッと思いつくのは、鉄棒とか、ボール状のジャングルジムみたいなものかなぁ

それでは第1回スクリプト講座は終了です。
第2回があるかどうかはわっかりませーん
ではでは
PR