2014/05/21

リンクなしでも親子関係

宝箱の「箱」と「蓋」は別々のオブジェクトで、しかも親子関係になってます。
  • 「蓋」(子)オブジェクトは「箱」(親)の中に入っていて、親がRezされると自動で出てくる
  • 出たらすぐ、親との位置関係と回転を調整
  • その後も、親が動くと、子も同じ位置関係で追いかける
  • 追わせるために、親は動いたとき、子に自分の位置と回転を知らせる
メッセージの中に「pos:<x,y,z> rot:<x,y,z,s>」のような書式で項目名と値を書いて、通信するしかけです。

ややこしいですね~(^^;
なぜこんなことをするかというと、宝箱の蓋は、枠プリム(これが回転)と丸いカバーの2プリムでできていて、開くときには枠とカバーを一体で回したいからです。
もし蓋を箱にリンクすると、枠プリムもカバープリムも別々に箱のルートとリンクしてしまって、うまくいきません。
(千両箱と3億円ケースでは、蓋は1つのプリムだけなので、リンクしてもOKで簡単なんです)

親のメッセージデータから、子が項目の値を読むスクリプトはこんな感じ:
string getParam(string data,string name) { // データから値を得る
  integer i = llSubStringIndex(data,name); // 文字列中の項目名の先頭位置
  if (i < 0) return ""; // 項目名がないとき空文字を返す
  i += llStringLength(name); // 項目名の直後の位置
  return llGetSubString(data,i,-1); // 値の部分の文字列を返す
}
readParentPosRot(string msg) { // 親の位置と回転を読む
  string param = getParam(msg,"pos:");
  if (param) ParentPos = (vector)param; // 返答があれば値を設定
  param = getParam(msg,"rot:");
  if (param) ParentRot = (rotation)param;
}
こうして読んだ値から、子オブジェクトが位置と回転を調整する部分は:
resetPosRot() {
  Pos = ParentPos + Offset*ParentRot; // (Offset: 親に対する相対的な位置)
  Rot = RotLook * ParentRot; // (RotLook: 親に対する相対的な回転)
  llSetPos(Pos);
  llSetRot(Rot);
}