物理挙動への制約
目次
はじめに
物理挙動は設定するだけで、物体に自然な動きをさせることができます。 しかし箱の山を作っただけでは、ゲームに使うには少し不便です。
タイヤが付いた乗り物のように移動方向が制約された物体や
回転扉のように回転だけしかしない物体など、一部の動きが制約された物体がゲームには必要になってきます。
setpos
やsetang
などで直接数値を指定して制御することもできますが、とても面倒です。また何より、せっかくの物理挙動を活かすことができません。
hgimg4では物理挙動を設定した物体に対して、gppset
命令で加えられた力に対する動きに制約(動きにくくする)を設定することができます。
正確には外力をそのまま物体に与えるのではなく、方向ごとに重み付け(部分的に弱く)した結果を物体に入力する方法です。
まずは「ある方向にだけ動かなくできる」と理解しておくとわかりやすいと思います。
回転
つまりどういうことかというと…とりあえず例を見てください。
; 回転方向に制約を付けるサンプル
#include "hgimg4.as"
title "HGIMG4"
; 物理エンジンテスト
randomize
; シーン作成
gpreset
setcls CLSMODE_SOLID, $808080 ; 画面クリア設定
; カメラを作成
setpos GPOBJ_CAMERA, 0,1,8 ; カメラ位置を設定
gplookat GPOBJ_CAMERA, 0,0.3,0 ; カメラから指定した座標を見る
; 箱を作成
gptexmat id_texmat, "res/qbox.png"
gpbox id_box, 1, -1, id_texmat ; 箱ノードを追加
setpos id_box, -3, 0, 0
gppbind id_box, 1 ; 箱の物理設定を行なう
gppset id_box, GPPSET_GRAVITY, 0, 0, 0 ; 重力なし
gppset id_box, GPPSET_DAMPING, 0, 0 ; 減衰なし
; 箱(クローン)を作成
dim pos_boxc, 3
repeat 3
gpclone id_boxc(cnt), id_box ; 箱をクローン
setpos id_boxc(cnt), 2.0 * (cnt + 1) - 3, 0, 0
gppbind id_boxc(cnt), 1
gppset id_boxc(cnt), GPPSET_GRAVITY, 0,0,0 ; 重力なし
gppset id_boxc(cnt), GPPSET_DAMPING, 0, 0 ; 減衰なし
loop
; Constraints(制約)
; 動かせる方向にConstraints(制約)を付けることができます。
; 1を指定した場合、特に制約を受けることなく回転します。
; 0を指定した方向には、物理的外力を加えても回転しなくなります。
;
; 正確には外部から入力されたトルクに対して、指定した値を掛け算しているようです。
; 例えば10を指定すると10倍回転しやすくなりますし、-1を指定すると逆回転します。
; UnityのConstraintのWeightが同じような機能らしいです。
gppset id_boxc(0), GPPSET_ANGULAR_FACTOR, 1, 0, 0 ; X軸周りにのみ回転
gppset id_boxc(1), GPPSET_ANGULAR_FACTOR, 0, 1, 0 ; Y軸周りにのみ回転
gppset id_boxc(2), GPPSET_ANGULAR_FACTOR, 0, 0, 1 ; Z軸周りにのみ回転
; 回転を設定
; GPPSET_ANGULAR_FACTORで制約を設定しても、gppsetで直接値を指定した場合は
; Constraintsを無視して回転します。
; 「if 1」に書き換えると挙動を確認できます。
if 0 {
gppset id_box, GPPSET_ANGULAR_VELOCITY, 1,1,1
repeat 3
gppset id_boxc(cnt), GPPSET_ANGULAR_VELOCITY, 1,1,1
loop
}
*main
stick key,15
key_x0 = key_x
key_y0 = key_y
key_z0 = key_z
getkey key_x, 'X'
getkey key_y, 'Y'
getkey key_z, 'Z'
if key&128 : end
if key&16 {
; 回転トルク+衝撃を追加
gppapply id_box, GPPAPPLY_TORQUE_IMPULSE, 1,1,1
repeat 3
gppapply id_boxc(cnt), GPPAPPLY_TORQUE_IMPULSE, 1,1,1
loop
}
if (key_x = 1) & (key_x0 = 0) {
; X 回転トルク+衝撃を追加
gppapply id_box, GPPAPPLY_TORQUE_IMPULSE, 1,0,0
repeat 3
gppapply id_boxc(cnt), GPPAPPLY_TORQUE_IMPULSE, 1,0,0
loop
}
if (key_y = 1) & (key_y0 = 0) {
; Y 回転トルク+衝撃を追加
gppapply id_box, GPPAPPLY_TORQUE_IMPULSE, 0,1,0
repeat 3
gppapply id_boxc(cnt), GPPAPPLY_TORQUE_IMPULSE, 0,1,0
loop
}
if (key_z = 1) & (key_z0 = 0) {
; Z 回転トルク+衝撃を追加
gppapply id_box, GPPAPPLY_TORQUE_IMPULSE, 0,0,1
repeat 3
gppapply id_boxc(cnt), GPPAPPLY_TORQUE_IMPULSE, 0,0,1
loop
}
; 描画
redraw 0 ; 描画開始
gpdraw ; シーンの描画
color 255,255,255
pos 8,8:mes "HGIMG4 sample"
mes "スペース:X,Y,Z軸方向に回転加速"
mes " X:X 軸方向に回転加速"
mes " Y:Y 軸方向に回転加速"
mes " Z:Z 軸方向に回転加速"
gpcnvaxis x,y,z, -3, -0.8, 0.5, 0 : pos x-16*2,y : mes "制約なし"
gpcnvaxis x,y,z, -1, -0.8, 0.5, 0 : pos x-16*2,y : mes "YZ軸制約\nX軸のみ回転"
gpcnvaxis x,y,z, 1, -0.8, 0.5, 0 : pos x-16*2,y : mes "XZ軸制約\nY軸のみ回転"
gpcnvaxis x,y,z, 3, -0.8, 0.5, 0 : pos x-16*2,y : mes "XY軸制約\nZ軸のみ回転"
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間
goto *main
実行すると、箱が4つ現れます。箱の下に、動きに制約をかけている方向が書いてあります。
左上の説明通りにキーを押すと、箱に対して指定の方向へトルク(GPPAPPLY_TORQUE_IMPULSE
)が与えられます。4つの箱すべて同時に同じ大きさのトルクを与えます。
一番左の箱は何も制約がないので、トルクを与えられればその方向に回転します。他の箱には、回らない方向が設定してあるので、回る方向にしか回りません。 適当に触っていただければ、どういうことかすぐにわかると思います。
HSP3で回転方向への制約(Constraints)を設定する場合、次のように記述します。X軸周りにのみ回転するようにする例です。
gppset id, GPPSET_ANGULAR_FACTOR, 1, 0, 0
0を指定するとその方向に回転しなくなります。1を設定しておけば、その方向へは通常通り回転します。
そしてさらに-1を設定すると、与えられたトルクと反対方向に回転します。 そうです。この機能は動く方向をON/OFFするものではなく、力に対する重み(weight)を指定するものです。 ですので、0.5なども指定できます。
この方法は、外部から入力されたトルクに対して重みを掛け算してから物体にトルクを入力しています。 例えば10を指定すると10倍回転しやすくなりますし、-1を指定すると逆回転します。 UnityのConstraintのWeightが同じような機能らしいです。
移動
移動方向についても、制約(正確には重み)を設定することができます。
次のように記述すると、X方向にだけ移動するようになります。(YZ方向に動かなくなる。)
gppset id, GPPSET_LINEAR_FACTOR, 1, 0, 0
移動の場合も回転同様に、動く方向をON/OFFするものではなく、力に対する重み(weight)を指定するものです。 ですので、0.5なども指定できます。
挙動については、サンプルで確認してください。
; 動きに制限をつけるサンプル
;
; 次の設定をテストするサンプルです。
;
; GPPSET_LINEAR_FACTOR ベクトルに沿った移動の設定
; GPPSET_ANGULAR_FACTOR ベクトルに沿った回転の設定
;
; 体当たりで押したり、床から落としたりして動きを確認してください。
;
#include "hgimg4.as"
title "HGIMG4 Test"
; 物理エンジンテスト
; カーソルキーで箱を動かすことができます
;
randomize
gpreset
setcls CLSMODE_SOLID, $808080 ; 画面クリア設定
setpos GPOBJ_CAMERA, 0,2,5 ; カメラ位置を設定
; 箱ノードを追加
gptexmat id_texmat, "res/qbox.png"
gpbox id_box, 0.5, -1, id_texmat
setpos id_box, 0, 3, 0
gppbind id_box, 1, 0.5 ; 箱の物理設定を行なう
; 床ノードを追加
gpfloor id_floor, 10,5, $404040
gppbind id_floor, 0 ; 床の物理設定を行なう
; 箱を追加
dz = 2.0
dim id_boxc, 8
repeat 8
gpclone id_boxc(cnt), id_box
dx = 1.0 * cnt - 4.0
setpos id_boxc(cnt), dx, 0.6, dz
gppbind id_boxc(cnt), 1, 0.5
loop
; 移動を固定
gppset id_boxc(0), GPPSET_LINEAR_FACTOR, 1,0,0 ; x方向のみ動く
gppset id_boxc(1), GPPSET_LINEAR_FACTOR, 0,1,0 ; y方向のみ動く
gppset id_boxc(2), GPPSET_LINEAR_FACTOR, 0,0,1 ; z方向のみ動く
gppset id_boxc(3), GPPSET_LINEAR_FACTOR, 0,0,0 ; 移動を固定
; 回転を固定
gppset id_boxc(4), GPPSET_ANGULAR_FACTOR, 1,0,0 ; x軸方向の回転のみ動く
gppset id_boxc(5), GPPSET_ANGULAR_FACTOR, 0,1,0 ; y軸方向の回転のみ動く
gppset id_boxc(6), GPPSET_ANGULAR_FACTOR, 0,0,1 ; z軸方向の回転のみ動く
gppset id_boxc(7), GPPSET_ANGULAR_FACTOR, 0,0,0 ; 回転を固定
repeat
stick key,15
if key&128 : end
; カーソルキーで箱を動かす
if key&1 : gppapply id_box,GPPAPPLY_IMPULSE, -0.1, 0, 0
if key&4 : gppapply id_box,GPPAPPLY_IMPULSE, 0.1, 0, 0
if key&8 : gppapply id_box,GPPAPPLY_IMPULSE, 0,0, 0.1
if key&2 : gppapply id_box,GPPAPPLY_IMPULSE, 0,0, -0.1
getpos id_box,dx,dy,dz
gplookat GPOBJ_CAMERA, dx,dy,dz ; カメラから指定した座標を見る
redraw 0 ; 描画開始
gpdraw ; シーンの描画
color 255,255,255
pos 8,8:mes "HGIMG4 sample"
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間
loop
左半分が移動を制約したもの。右半分が回転を制約しています。 押したり落としたりして挙動を確認してください。
Y軸方向にしか回転しないようにした箱は、少し不思議な動きをしています。箱の中心を軸に回転していませんね。 箱はX,Y軸方向に回転しないため、常に面同士で床と接触した状態です。そのために、回転中心が計算の優先順位等で決まってしまっているのかもしれません。 原因はわかりませんが、平面に置いた箱のX,Z軸方向を固定してしまうと角に限らず予期しない点を中心に回転してしまうことがあります。
さて、GPPSET_ANGULAR_FACTOR
、GPPSET_LINEAR_FACTOR
で指定する値は、係数として使用されるだけなので1.0以上やマイナス値も指定することもできます。
物理的な意味を理解した上で必要であれば、0.0~1.0以外の値を指定するのもいいと思います。
しかし、実際に指定してみると挙動が不自然なものになるので、基本的には0.0~1.0の間で指定するようにした方がいいようです。0.0~1.0の範囲外の値を指定すると、計算結果が正しいのかもちょっと怪しい動きをします。検証していないので断言できませんが避けた方がいいでしょう。
摩擦
gppsetを使うと、摩擦も方向に対して制約をつけることができます。
次のように記述すると、X方向の摩擦だけがなくなります。(YZ方向の摩擦はそのまま。)
gppset id, GPPSET_ANISOTROPIC_FRICTION, 0,1,1
摩擦の場合も移動同様に、摩擦力をON/OFFするものではなく、摩擦力に対する重み(weight)を指定するものです。 ですので、0.5なども指定できます。
摩擦も基本的には0.0~1.0を指定した方がいいようです。
摩擦を大きくしたい場合は、GPPSET_FRICTION
を使って全体の摩擦を大きくしてください。
GPPSET_ANISOTROPIC_FRICTION
で1.0以上を設定した場合と、GPPSET_FRICTION
で1.0以上を設定した場合とでは動作結果が異なります。
どうやら単純に摩擦が大きくなるわけではなさそうです。
サンプルを用意しました。回転するとわかりにくいので、回転は止めています。
; 動きに制限をつけるサンプル
;
; 次の設定をテストするサンプルです。
;
; GPPSET_LINEAR_FACTOR ベクトルに沿った移動の設定
; GPPSET_ANGULAR_FACTOR ベクトルに沿った回転の設定
;
; 体当たりで押したり、床から落としたりして動きを確認してください。
;
#include "hgimg4.as"
title "HGIMG4 Test"
; 物理エンジンテスト
; カーソルキーで箱を動かすことができます
;
randomize
gpreset
setcls CLSMODE_SOLID, $808080 ; 画面クリア設定
setpos GPOBJ_CAMERA, 0,2,5 ; カメラ位置を設定
; 箱ノードを追加
gptexmat id_texmat, "res/qbox.png"
gpbox id_box, 0.5, -1, id_texmat
setpos id_box, 0, 3, 0
gppbind id_box, 1, 0.5 ; 箱の物理設定を行なう
gppset id_box, GPPSET_ANGULAR_FACTOR, 0,0,0 ; 回転を固定
; 床ノードを追加
gpfloor id_floor, 30,30, $404040
gppbind id_floor, 0 ; 床の物理設定を行なう
; 箱を追加
dz = 2.0
dim id_boxc, 5
repeat 5
gpclone id_boxc(cnt), id_box
dx = 1.0 * cnt - 2.0
setpos id_boxc(cnt), dx, 0.6, dz
gppbind id_boxc(cnt), 1, 0.5
gppset id_boxc(cnt), GPPSET_FRICTION, 30 ; 摩擦を大きくする
loop
; 移動を固定
gppset id_boxc(0), GPPSET_ANISOTROPIC_FRICTION, 1,0,0 ; x方向以外の摩擦を0にする
gppset id_boxc(1), GPPSET_ANISOTROPIC_FRICTION, 0,1,0 ; y方向以外の摩擦を0にする
gppset id_boxc(2), GPPSET_ANISOTROPIC_FRICTION, 0,0,1 ; z方向以外の摩擦を0にする
gppset id_boxc(3), GPPSET_ANISOTROPIC_FRICTION, 0,0,0 ; すべての摩擦を0にする
repeat
stick key,15
if key&128 : end
; カーソルキーで箱を動かす
if key&1 : gppapply id_box,GPPAPPLY_IMPULSE, -0.1, 0, 0
if key&4 : gppapply id_box,GPPAPPLY_IMPULSE, 0.1, 0, 0
if key&8 : gppapply id_box,GPPAPPLY_IMPULSE, 0,0, 0.1
if key&2 : gppapply id_box,GPPAPPLY_IMPULSE, 0,0, -0.1
getpos id_box,dx,dy,dz
gplookat GPOBJ_CAMERA, dx,dy,dz ; カメラから指定した座標を見る
redraw 0 ; 描画開始
gpdraw ; シーンの描画
color 255,255,255
pos 8,8:mes "HGIMG4 sample"
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間
loop
乗り物系とか作れそうですね。
シーソーとすり抜け
では、これらの方法を応用して、身近で手軽に出来る物理おもちゃ「シーソー」を作ってみます。 公園に設置してあったり、天秤ばかりやテコの原理でもおなじみです。 ゲームにも使えそうですね。
では作ってみます。箱を細長く作って、
GPPSET_LINEAR_FACTOR, 0,0,0
で移動を止めて、
GPPSET_ANGULAR_FACTOR, 0,0,1
で回転を1方向にだけ動くように制約すれば完成です。
簡単ですね。
では、サンプルを見てみます。
サンプルは、シーソーの上に乗っている箱をカーソルキーで移動できます。 左右に動かしてシーソーを動かしてみてください。
#include "hgimg4.as"
title "HGIMG4 トルク"
; 物理エンジンテスト
; シーソー
; シーン作成
gpreset
setcls CLSMODE_SOLID, $808080
; カメラを作成
setpos GPOBJ_CAMERA, 0, 3, 10
gplookat GPOBJ_CAMERA, 0, 0.3, 0
; 床を作成
gpfloor id_floor, 30,30, $404040
setpos id_floor, 0, 0, 0
gppbind id_floor, 0
; マットを追加
; 「if 1」を「if 0」に書き換えるとマットを消せます。
if 1 {
gpbox id_mat, 0.5, $0055AA
setscale id_mat, 30, 0.1, 30
setpos id_mat, 0, 0.05, 0
gppbind id_mat, 1e10
; gppset id_mat, GPPSET_KINEMATIC, 1 ; 大丈夫
; gppbind id_mat, 0 ; すり抜ける
}
; シーソーを作成
gptexmat id_texmat, "res/qbox.png"
gpbox id_s, 1, -1, id_texmat
setscale id_s, 10, 0.2, 1
setpos id_s, 0, 1, 0
gppbind id_s, 1
gppset id_s, GPPSET_ANGULAR_FACTOR, 0,0,1 ; 回転を固定
gppset id_s, GPPSET_LINEAR_FACTOR, 0,0,0 ; 移動を固定
; gppset id_s, GPPSET_LINEAR_FACTOR, 0, 0, 1e-10 ; 移動を固定
; 箱ノードを追加
gpbox id_box, 0.5, -1, id_texmat
setpos id_box, 0, 3, 0
gppbind id_box, 1, 0.5
gppset id_box, GPPSET_LINEAR_FACTOR, 1,1,0 ; 移動を固定
gppset id_box, GPPSET_ANGULAR_FACTOR, 1,0,1 ; 回転を固定
*main
stick key,15
if key&128 : end
; カーソルキーで箱を動かす
if key&1 : gppapply id_box,GPPAPPLY_IMPULSE, -0.1, 0, 0
if key&4 : gppapply id_box,GPPAPPLY_IMPULSE, 0.1, 0, 0
getpos id_box,dx,dy,dz
gplookat GPOBJ_CAMERA, dx,dy,dz ; カメラから指定した座標を見る
; 描画
redraw 0 ; 描画開始
gpdraw ; シーンの描画
color 255,255,255
pos 8,8:mes "HGIMG4 sample"
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間
goto *main
ちゃんと左右に傾くシーソーができていますね。 シーソーから落ちたら戻れないのでEscキーを押して終了してください。
え、青い床が気になりますか。そうですか。 青いマットは「マットを追加」の「if 1」を「if 0」に書き換えると消すことができます。
シーソーが床に突き刺さりました。 どういうわけかシーソーを作ると、普段は衝突するものでも衝突しなくなる条件があるようです。バグかな?調査してみました。
すり抜ける物体
- 質量0の静的剛体
GPPSET_LINEAR_FACTOR
でどの方向にも完全に移動しないように設定した物体
すり抜けない対策(いずれか一つを対策すればOK)
- 床には質量がある物体を使用する。(サンプルで使用している方法)
- 床の固定には静的剛体ではなく、Kinematic設定を使用する。
- シーソー自体の移動を完全に固定しないようにする。
例:gppset id_s, GPPSET_LINEAR_FACTOR, 0, 0, 1e-10
このサンプルでは、物理設定だけ行った薄い板を床に敷いています。 軽いと跳ねたり動いたりしてしまうので、質量には大きな値を設定しています。
おそらく、GPPSET_LINEAR_FACTOR
での制約を全方向ゼロにしちゃうと、hgimg4内部での物理計算する際の処理方法が変わってしまうのだと思います。
移動は完全に固定せずに。どれか1方向だけでも影響がない程度の小さい値を設定するのが正解なのかなと思います。
シーソーのを元の姿勢に戻す
作ったシーソーは重心で支持されているので、上に物が乗っていなければ摩擦で止まったときの状態で静止してしまいます。
ゲーム的には元の姿勢に戻ってほしいですね。
物理設定を一時的に解除して、setang
で戻すのもいいのですが動きが不連続になるので不自然です。
また、「キャラクターがシーソーを離れた」などの条件分岐をその都度考えなければいけないのも面倒です。
シーソーには勝手に元の水平姿勢に戻ってもらいましょう。
#include "hgimg4.as"
title "HGIMG4 トルク"
; 物理エンジンテスト
; シーソー
;元に戻す機構
; シーン作成
gpreset
setcls CLSMODE_SOLID, $808080
; カメラを作成
setpos GPOBJ_CAMERA, 0, 3, 10
gplookat GPOBJ_CAMERA, 0, 0.3, 0
; 床を作成
gpfloor id_floor, 30,30, $404040
setpos id_floor, 0, 0, 0
gppbind id_floor, 0
; シーソーを作成
gptexmat id_texmat, "res/qbox.png"
gpbox id_s, 1, -1, id_texmat
setscale id_s, 10, 0.2, 1
setpos id_s, 0, 1, 0
gppbind id_s, 5
gppset id_s, GPPSET_ANGULAR_FACTOR, 0,0,1 ; 回転を固定
gppset id_s, GPPSET_LINEAR_FACTOR, 0, 0, 1e-10 ; 移動を固定
; 箱ノードを追加
gpbox id_box, 0.5, -1, id_texmat
setpos id_box, 0, 3, 0
gppbind id_box, 1, 0.5
gppset id_box, GPPSET_LINEAR_FACTOR, 1,1,0 ; 移動を固定
gppset id_box, GPPSET_ANGULAR_FACTOR, 1,0,1 ; 回転を固定
; 台
gpclone id, id_box
setscale id, 2, 2.5, 1
setpos id, 5.6, 0.6, 0
gppbind id, 0
gpclone id, id_box
setscale id, 1, 8, 1
setpos id, 6.5, 2, 0
gppbind id, 0
gpclone id, id_box
setscale id, 2, 2.5, 1
setpos id, -5.6, 0.6, 0
gppbind id, 0
gpclone id, id_box
setscale id, 1, 8, 1
setpos id, -6.5, 2, 0
gppbind id, 0
*main
stick key,15
if key&128 : end
; カーソルキーで箱を動かす
if key&1 : gppapply id_box,GPPAPPLY_IMPULSE, -0.2, 0, 0
if key&4 : gppapply id_box,GPPAPPLY_IMPULSE, 0.2, 0, 0
getpos id_box,dx,dy,dz
gplookat GPOBJ_CAMERA, dx,dy,dz ; カメラから指定した座標を見る
; シーソーを戻す
; シーソーの真下に重りを固定しているような状態を作っています。
getang id_s, x,y,z
gppapply id_s, GPPAPPLY_TORQUE, 0, 0, -80.0 * sin(z)
; 描画
redraw 0 ; 描画開始
gpdraw ; シーンの描画
color 255,255,255
pos 8,8:mes "HGIMG4 sample"
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間
goto *main
箱をシーソーから降ろしてみてください。シーソーがゆっくり水平に戻りましたね。 仕組みは簡単で、シーソーの下に重りを固定しています。正確には重りが固定されているかのようなトルクをシーソーに入力しています。 図にするとこのような感じです。
プログラム上では、このように実装しています。
getang id_s, x,y,z
gppapply id_s, GPPAPPLY_TORQUE, 0, 0, -80.0 * sin(z)
シーソーが傾く角度に応じて、元の姿勢に戻る方向のトルクを与えています。sinなので、シーソーの傾きが0度の時はトルクもゼロ、90度のときにトルクは最大になりますね。
この実装例の場合、シーソーの下に1mの棒を伸ばしてその先端におよそ8.1kgの重りをつけている状態です。
80N = 8.1kg * 9.8m/s^2 (青い矢印)
重心周りの力(赤い矢印)は、次のような式。
80N * sin(傾き角度)
サンプルで80と設定している係数に根拠はありません。様子を見ながら適当に調整しました。
全く同じ要領で水平以外の角度に戻るようなものも作ることができますね。
まとめ
GPPSET_LINEAR_FACTOR
移動する力を受ける大きさを方向ごとに変更。数値は0~1の係数。GPPSET_ANGULAR_FACTOR
回転する力を受ける大きさを軸方向ごとに変更。数値は0~1の係数。GPPSET_ANISOTROPIC_FRICTION
摩擦を受ける強さを方向ごとに変更。数値は0~1の係数。GPPSET_LINEAR_FACTOR
で移動を全方向完全に止めてしまうとすり抜けが発生することがある。移動を完全に止めなければ大丈夫。
方向ごとに差がある性質を与えることができるようになると、箱型形状だけでも出来ることが増えます。 ステージ上に配置するギミックも楽しいものが作れるようになります。