2014年3月7日金曜日

キャストレイのお話

・キャストレイとはなんぞや?
 速い 軽い 使えると楽しい めんどくさい

・使うことによるメリット、デメリット

-メリット
 rez出来なくても当たり判定や距離が計測出来る
 物理弾と比較して命中判定がほぼ即時といっていい
 法線ベクトルを検出できるので着弾エフェクト等が精密に出せる

-デメリット?
 ちょっと凝った事しようとすると座標演算が面倒
 確実性を上げようとするとループ処理が要る
 ものすげー重いSIMだとコケる可能性が高い
 銃系だと互換性の関係で結局rezしないとなんも出来ん

・センサーやコリジョンとの違い
 仕様上Detected系が全く機能しないため
 (何にぶつかったか)を単独では検出できない

・キャストレイの”弾速”は?
 理論上は一応無限大ですが
 SIMサイズからくる制約的には
 大体秒速200キロって辺り
 動作確実性をほぼ完全にするなら第二宇宙速度くらい

・物理弾と比較してのメリットは?
 結局Rez要るからぶっちゃけほとんど無い(笑)
 とまーそんなこと書いてもブログ的には意味ねーので

 -なにしろ弾速が速い rezから着弾のラグほぼゼロ 移動とrezのラグはある
 -なにしろ大きさが無い 1cmでも隙間があれば軽々とすり抜ける
 -着弾エフェクトが精密に出せる 壁に弾痕沢山とか素敵やん?
 -ゼロ距離CQBが出来る ナイフで懐に入れば無敵なんてのが幻想になる
 -近接戦闘で刃の軌跡で当たり判定が取れる
 -キルボックス式の爆発物で遮蔽物の概念が出来る
 -近接専用弾みたいな”射程距離”の概念が精密に作れる



この辺まで前置き

実際にキャストレイ使う場合のお話

maxhitをn,法線アリにした場合
UUID1,座標1,法線1,UUID2,座標2,法線2,・・・,UUIDn,座標n,法線n,検出合計(n)
こんなかんじのデータが戻ってきます
RootKey指定した場合はUUIDがRootPrimのものになります

なんも検出されなかった場合(検出コケた場合も含む)
長さ1で0以下のintegerが入ったリストになります

んでリストの末尾は常に検出数が出ますので
 if(llList2Integer(list raycast,-1)>0){}
これで検出したかどうかがわかります

0未満は全てエラーコード扱いとなっており
基本0未満の数値が出ることはほぼありません
(検出コケて0になることは割とよくある)

検出がコケる例
・やたら長いベクトルを指定
・やたら短いベクトルを指定
・開始地点が何かにめり込んでる場合
・地面に向けた場合(NULL_KEYが戻ってきますがたまーにコケる)
・なんも無い空間指定してその先がSIM外だった場合

なおアウトSIM置いててファントム検出しようとすると多分エラー出まくるかと

具体的なエラーレート改善方法は
・距離を変えて数回のリトライ(やり方によるがそこまで高負荷でもない)
・開始地点がなんかにめり込んでないかのチェック
 (検出が”面コリジョン”なのでめり込んでる中で実行するとすり抜ける)

検出したもんが何かを調べるのに一番確実なのは
UUID指定してのセンサーです

地面だったらNULL_KEY返ってきてるのでセンサー打たなくてもおk


ちょい処理増やすと壁の厚さとかも調べられるので
薄い壁程度なら貫通するタマとかも作れるっちゃ作れる


ってなところかねぇ



エフェクト再生用tips
ベクトルを方角仰角のrotationに変更する式

vector normal=<hoge>;
rotation rot_normal=llEuler2Rot(<0,-llAtan2(normal.z,llVecMag(<normal.x,normal.y,0>)),0>)
                                                                      *llEuler2Rot(<0,0,-llAtan2(normal.y,normal.x)>);

やってることはまぁ簡単です
アークタンジェントで角度計算して仰角>方角の順番で回してるだけ

まぁプリムによっては90度とかずれるだろうけどそこは各自どうにかしてくだちい


以上