HGIMG4
サーバー側では、HGIMG4が使えないことが判明したため、ゲームロジックの計算のみ行い、クライアント側で受け取った情報をもとに3D描画する方向で進行中。
クライアント側からは「キーデータ」のみを送る形で。
色々と対応すべき問題があり、一筋縄ではいかない模様
ネット対戦機能を勉強中
2024年に向けて!現在は希望的観測、、、、、!!!
たまねチャット(超β版) ver0.2
解凍して、exeを起動してハンドルネームを入力したら、「JOIN」してください。発言するには、文字を入力して「Ctrl+Enter」です。
「←↑↓→」でたまねちゃんが動きます。
コメントが残るようになったので、足跡を残していってくださいませ
正月の間くらいとか、しばらく起動したままにする予定なので、ふらりとログインしてください、、、、↓zipダウンロード
実行ファイル形式(テキトー版なのでヨロシク)
ソースコード等(内容は未完成なので保証しません。参考程度に)
pcbnet2というプラグインを使用しています。(「さめたすたすのお家」を参照ください。元々の本家HPは閉鎖された模様。)めたすたすの
発言ログとかは、残さずに消しちゃいますので、よろしく。
2024.1.26 たまねチャット更新
2024.1.20 レンタルサーバーでhgimg4が使えないことが判明。。サーバープログラムは標準機能のみで実装する方向で方針変更(大変)
2024.1,4 全然誰も来ねぇ、、('ω')
2024.1.1 Ver0.2
2023.12.31 Ver0.1
2024年に向けて
次はオープンワールド?無理無理ww
ちょっとだけ進化しました。
GPB File Viewer 1.0
非常に簡単でありますが、GPBファイルをダブルクリックで開いて確認できたらべんりだなぁというわけで作成してみました。
・見た目がアレなのは、今後の改良で、、、
・アニメーションGPBは、現状では単純に内蔵アニメーション全てを再生します。
・GPBファイルをEXEファイルに放り込むか、GPBファイルの関連付けを行ってください。
・GPBファイルがダブルクリックで開くと確認しやすくてよいです。
・HGIMG4の仕様上、テクスチャのフォルダは通常「res」フォルダになると思いますので、普段使う「res」フォルダの直上フォルダにEXEを置いてください🐷
HGIMG4のgppraytest
gppraytestの覚書(方向が分からなくなるので、メモ)
NULLオブジェクトの正方向(Z+青い矢印)
Rayのdistanceの正方向(Z-赤い線)
Nullに限らず、カメラ、ライトもZ-の方をデフォルトで向いている。
しかし、オブジェクトとしてのZ+方向は手前であるので、混乱しないように。
gpcnvaxis ヘルプの覚書
3D座標の変換を行なう
gpcnvaxis var_x,var_y,var_z,x,y,z,mode
var_x : X値が代入される変数
var_y : Y値が代入される変数
var_z : Z値が代入される変数
x(0.0) : 変換元のX値
y(0.0) : 変換元のY値
z(0.0) : 変換元のZ値
mode(0) : 変換モード
(プラグイン / モジュール : hgimg4)
解説
決められたモードに従って、(x,y,z)の3D座標を変換します。
結果は、var_x,var_y,var_zで指定された変数に実数型で代入されます。(変数型は自動的に設定されます)
モード値による変換の内容は以下の通りです。
モード 内容
-----------------------------------------------
0 描画される2D座標(X,Y)位置+Zバッファ値
1 0と同じだが(X,Y)座標が正規化されたもの
2 ビュー(カメラから見た状態)変換を行なった(X,Y,Z)座標
3 ワールド(カメラを含まない)変換を行なった(X,Y,Z)座標
モード0と1は、スクリーン上に2D投影を行なった際のX,Y座標、及びZバッファ値に変換します。
モード2では、カメラ位置を考慮したビュー変換を行なったX,Y,Z座標値に変換します。
モード3では、カメラ位置を考慮しないワールド変換を行なったX,Y,Z座標値に変換します。
⇒カメラ位置・カメラ視点を中心とした相対位置x,y,zを返します。
カメラの設定に関する覚書
⇒望遠モード⇒
FOVを変更することで、望遠レンズを表現できる(右の画像)
・gpcamera命令について
gpcameraでは、FOV(field of view)の設定ができますが、現在使用しているカメラに対してgpcameraで設定しようとすると「強制終了」してしまいます。
回避策(というかこれが正しいのか)として、一旦ダミーのカメラを用意しておき、メインのカメラにgpcameraする直前にダミーカメラに切り替えます。gpcameraの設定が終わったら、gpusecameraでメインカメラに戻します。こうすることで、カメラのズームイン・ズームアウトができるようになります。⇒gpcameraで設定を変更したら、gpusecameraでアクティブにする必要があるようです。
また、私の環境では、gpusecameraでダミーカメラに切り替えると、メインのカメラの位置(x,y,z)がゼロになってしまいます。(なんか原因が別にあるようだ)
回避策としては、ダミーに切り替える直前にgetposで保存しておき、メインカメラに切り替えた後にsetposで戻します。
なんとかコレで、スナイパーライフルが実現できればいいんですが。。。(可能ですが、間に合うのかどうか)⇒なんとか完成し、間に合いました。
#include "hgimg4.as"
chdir dir_exe+"\\sample\\hgimg4"
gpreset
setcls CLSMODE_SOLID, $000000 ; 画面クリア設定
gpnull id_camera //メインカメラ
gpcamera id_camera, 45, 1.5, 0.5, 768//デフォルト設定
setpos id_camera,0,0,-20
gpusecamera id_camera //カメラを指定
gpbox id_box,10,$ffffff //箱
setpos id_box,0,0,-10
gpload id_model,"res/duck" //アヒル
setscale id_model,50,50,50
*main
redraw 0
stick keys,1+4
if keys&1{
_fov=_fov+1
}
if keys&4{
_fov=_fov-1
}
gpcamera id_camera, 45+_fov, 1.5, 0.5, 768 //FOV変更
gpusecamera id_camera //カメラ指定⇒これがないと落ちる
gpdraw
pos 0,0
color 255,255,255
mes "fov:"+(_fov+45)
await 1000/60
redraw 1
goto *main
物理エンジンに関する覚書
・GPPBINDにおける「GPPBIND_MESH」オプションについて
gploadしたユーザーモデルに対する「GPPBIND_MESH」は、有効ですが、「KINEMATIC」オプションが上手く動作しないようです。
gpboxで作成した四角形は、「GPPBIND_MESH」したものでも「KINEMATIC」が動作します。
「KINEMATICK」は、mass重量を「0以外」に設定しておかないと機能しませんが、それを設定してもユーザーモデルでは「KINEMATIK」による動作ができません(2023.6月 ver3.7β5)
・スケーリングについて
ver3.7β5現在において、「GPPBIND_MESH」したモデルの衝突判定に、スケーリングが適用されるようになっています。
これにより、ようやくサイズを合わせてモデリングする負担が軽減されたといえます。良い知らせです。
( gpdraw ,GPDRAW_OPT_DEBUG_PHY ;物理デバッグオプションによる確認)
・物理挙動について
物理エンジンに関する単位や挙動に関する考察は、GENKIさんのHPに詳細に記載されています。大変参考になりました。
そこでさらに、それを踏まえてゲームとして利用するにはということを試してみました。
成功したこと(ヘリコプター)
gameplay3Dにおける世界の重力加速度は地球と同じ9.8であると先のページで検証されています。
ここで、おおよそ1500(kgと仮定)の地上に止まっているヘリコプターを動かすには、gppbindで重さを1500に設定したオブジェクトに対して(摩擦は地面0.5 オブジェクト0.5の既定値)、gpp apply_forceによって1500✖️9.8=14700以上の力を加えると動き出します。
重力によって常に下方向に14700の力がかかっているので、上方向に14700以上の力を加えていくとヘリコプターが上昇していきます。力の向きを変えれば、現実のヘリコプターに近い動きで前進後退(力の向きをX軸回転させる)横移動(力の向きをZ軸回転)ができます。さらにY軸回転トルクをかけてヘリコプターの向きを変える(テールローターの働き)こともでき、かなりそれっぽい動きになりました。
(空中なので摩擦は影響しない)
失敗したこと(自動車)
ヘリコプターは思った感じになりましたが、自動車の動きはそう簡単にはいきませんでした。gppapply_forceで動かすことはできますが、あの横滑り感が納得いかず、なんとかならないかと挑戦しました。
そもそも自動車はタイヤで走りますが、これはどういうことかと考えると、円形のタイヤなので気付きませんでしたが、前へ前へ連続的に倒れていくことで前に進んでいると考えられます。地面とタイヤの摩擦の範囲内(グリップ内)で、後ろから押されて、摩擦で進めず、仕方なく倒れていく、、、つまりサイコロが転がるのと同じことだということです。
これを表現するには、、、そうトルクだと。X軸にトルク(回転)をかければいいんだと思い至ったわけです。
実際に、球形のオブジェクトにx軸でGPPAPPLY_TORQUEで回転トルクさせると、前に転がっていきます。
gppapply_forceで動くというのは、摩擦を超えて力がかかっている、常時ドリフト状態といえます。あの横滑り感も納得です。摩擦力を超えてドリフトしているので曲がらない。ここまでは理解でき、うまく行きました。
そこで、
問題1
自動車のタイヤのようにするために、メタセコイアで円筒形を横に倒したオブジェクトを用意してみました。お菓子のチップスターの箱を転がす感じです。これでgppbind_meshすればいいのではと。しかし、綺麗な円筒形のはずなのに、きれいな地面(gpfloor)で引っかかって跳ね回ってしまいます。色々と形を変えてみましたが、うまく転がりません。どうもオブジェクトの物理形態認識では、綺麗な円筒形になっていないようです。このあたりの具合はわかりませんでした。
問題2
円筒形でダメだったので、一旦gppbind_meshを指定せずに実行すると、球体として認識されました。オブジェクトを包むような形で球体と認識されるようです。
この状態であれば、綺麗に転がっていきます。
ここからが問題で、この球体を「曲げる」にはどうするのか。
転がっている球体にY軸のトルクをかければ左右に曲がると思ったのですが、どうもうまくいきません。
円筒形の場合、跳ね回りながらも、Y軸に曲がっていたようにも見えましたが、球体だと自由に回転してしまうのか、うまくいきませんでした。
尚、止まっている状態でY軸にトルクをかけると左右を向きました。回転状態が影響しているのかな。
未検証問題1
球体と円筒形は、とりあえず失敗しましたが、割り切って四角のキューブだとどうだろう。
転がってうまく曲がるだろうか。
人間は、前に倒れていくと右足を出し、摩擦で止まる。さらに倒れていって左足を出して摩擦で止まる。これを繰り返して前に進む。
そう考えるとキューブ型の方がしっくりくるかもしれない。
あとはうまく方向転換できればいいのですが。
未検証問題2
gppapply_TORQUE_impulseは、マニュアルには「捻り」と「衝撃」を与えるとありますが、ここに何かヒントがあるのかないのか未検証です。わざわざこの項目があるという意味がわかりません。
トルク「と」インパルスなのか、トルク「の」インパルスなのか。マニュアルは前者と書いてますが、後者の意味かもと思っています。たぶんそう。回転だけで移動する力は発生しませんでした。
未検証問題3
gpbファイルで複数のメッシュオブジェクトを持つモデルを読み込むと、親子関係を元々設定していたメッシュは、その通りの位置関係を維持します。親子関係の設定がないメッシュは、連動して動くことなく、離れ離れになります。
また、物理設定が適用されるのは、1番目のメッシュで、それ以後のメッシュに物理設定は適用されません。
自動車のタイヤのようなものを表現するには、親子関係を維持しながらそれぞれ物理設定されると良いと思うのですが、現状はできないようです。gameplay3Dにその機能がないのか、HGIMG4が対応していないのかはわかりません。
gppbindを子オブジェクトに実行してもエラーにはなりませんでしたが、gppapply命令はエラーとなりました。
未検証問題4(gpbコンバータ)
gpbコンバータにおいて、ボーンではなく、メッシュの親子関係があるfbxを変換すると、1番目のメッシュが消えてしまいます。
私はメタセコイアで作成しているので、ダミーの親オブジェクトをひとつ作って変換することで対応しています。バグなのか私が間違っているのか不明です。
gpnodeinfo命令について
すごく扱いが難しい。。。。HELPの補足として参考になれば幸いです🐽
オプション値 | 取得される内容
--------------------------------------------------------------
GPNODEINFO_NODE 該当するノードを示すオブジェクトID
GPNODEINFO_MODEL 該当するモデルノードを示すオブジェクトID
※取得されるIDは、参照型?なので、新たにgpnodeinfoを呼び出すたびに無効化されてしまう。直前に取得して対応
GPNODEINFO_NAME 該当するノード名(*)
※特に注意点なし
GPNODEINFO_CHILD 階層が持つ子のノード名(*)
※未検証 特に注意点なし。呼び出すたびに次のノードが取得される?
GPNODEINFO_SIBLING 同じ階層にある隣のノード名(*)
※未検証 特に注意点なし。呼び出すたびに次のノードが取得される?
GPNODEINFO_SKINROOT スキンメッシュが持っているノード名(*)
※スキンメッシュに影響を与えるボーン名称が取得される。サンプルのtamaneの場合、bodyの他、合計4つのメッシュに対して同じボーンツリーが影響するように設定されている。したがって、それぞれのメッシュノードにおいて、ボーン名称が取得されてしまう。
階層としてmod_gp_utilで取得すると、ボーンツリーが4つあるように文字列が取得されるが、実際は同じボーンを共有しているだけである。
またボーンツリーは厳密には影響メッシュの子ノードではなく、逆にボーンの動きにメッシュが連動する関係上、注意して階層を扱う必要がある。
(*) 結果の文字列が代入されます
階層モデルの位置、姿勢、スケールについて
gpnodeinfoで取得した階層モデルの子オブジェクトに対するgetposやgetquatのまとめ。
めちゃくちゃクセが強い。。というかアカンやろ。
getpos→ カメラ位置姿勢及び親モデルの位置、姿勢、スケールをゼロとした場合の「ワールドpos」((# ゚Д゚)使いにくい!!)
→追記R5.7.28 HSP3.7beta6において、親ノードに対するローカル座標が、子ノードへの「getwork」で取得できるようになりました。
おにたま様に感謝いたします。
getquat→ ローカルquatが取得される
※ただし名称が“”空白のルートノードに対するgetquatはカメラ角度が取得される?((# ゚Д゚)わけわからん!!)
setpos →ローカルposを指定することになる
setquat→ローカルquatを指定することになる
addpos→機能しない(HSP3.7b4) (# ゚Д゚)なんでや!!不便すぎる!)
addang→機能しない(HSP3.7b4) (# ゚Д゚)なんでや!!不便すぎる!)
ローカル姿勢について
姿勢は、現在のローカル姿勢は、getquat、新しいローカル姿勢はsetquatで問題なく取得設定できる
ローカル位置とワールド姿勢について
位置は、setposでローカル位置を指定することになる。
現在のローカル位置をgetposで知るには、直接の手段がない、ワールドクオータニオンも直接取得できない、、ので、
ハシケムさんの以下の回答を使う(すばらしい解決策ですが、もう少し改造できたものをアップする目標です🐽)
hashikemu
https://hsp.tv/play/pforum.php?mode=all&num=95343
なお、スケール系は、わりとすんなり動く模様
これらの仕様により、解決するためにクオータニオンに関する理解が深まった点は、とても良かったです。。。