俺に解るように説明する "Armory Engine" 入門+

ゲームエンジン Armory Engine (Armory3D) の使い方を手探りで学んで入門しようって感じかな。

P5.エアホッケー.16「プレーヤーのマレットでパックを跳ね返す(1/3)」

f:id:ore2wakaru:20190528041227p:plain

パックをマレットで跳ね返すには、「A.パックがマレットに接触したか」を調べ、接触してたら「B.反射させる方向と距離(反射ベクトル)を割り出し」て移動させればいい。物理を有効にしてればこんなのは自動でやってくれるんだが、今回は "NO 物理" なので自力で計算するのだ。また、"反射ベクトル"に関しては先にググっておくことをお勧めする。

On Initに追加

パックに貼ってるノードトゥリー "nPack" のOn Init部に3つのプロパティを追加(下図)。こうしたいから先に "myDir" の設定をイベント化してたわけだ。やってないとゴチャゴチャして見づらいだろ。

f:id:ore2wakaru:20190527121323p:plain

 "N": これは Normal(発:ノーマル 意:法線) を入れるもの。ノーマルっていうのは、「面から垂直に伸びる線(垂線)で、かつ、長さが "1" のもの」のこと。パックがマレットに当たった時の反射ベクトルを求める時に使う。(でも、なんでノーマルって言うんだろ? なぞ! 普通、ノーマルって言ったら「普通」じゃろ、普通。)

 "hanP": これはパックと自マレットがぶち当たった時立てるフラグ。パックとマレットが当たったら反射させればいいんだけど、場合によって反射した行き先がまだマレットの中の時がある。そこで、再度反射ベクトルを求めないようにするために使う。2度漬け禁止じゃないけど、2度当たり(連続当たり)を禁止するためのモノ。

 "hanC": こっちのはパックと敵マレットの2度当たり禁止用フラグ。

On Updateに追加

On Update部の一番最後に追加する。位置はココ(下図)。

f:id:ore2wakaru:20190527200434p:plain

で、ちっさくって見えないので拡大(下図)。

f:id:ore2wakaru:20190527201334p:plain

まずはGateの左部分だが、ひとつだけ新ノードかな?

Get Distance: 2つのオブジェクトの距離を出す。互いのオブジェクトの中心の距離ね。これで、2つのオブジェクトの中心の距離が何メートルあるか分かる。(ピンの色 Float型。)

で、ここでは一番初めに言った「A.パックがマレットに接触したか」を調べている。もしパックとマレット(今回は自マレット)の中心の距離が2.5mなら2つのオブジェクトはぴったりくっついている状態だろ。パックの半径は1mで、マレットの半径は1.5mだからな。

だから、Get Distanceで出したパックと自マレットの距離2.5を比較し、距離がこれ以下なら接触したと判断して True へ、これより大きければ接触と判断し False へ処理を流す。もちろん、スピードが出てればパックはマレットにめり込むから、2.5「以下Less Equal)」 で判断しているんだぞ。

Gateの右部分は、

  • True: 接触したと判断したら、専用のイベント("HANSYA_P")に飛ばす。この "HANSYA_P" イベントは「B.反射させる方向と距離(反射ベクトル)を割り出し」、"myDir" にセットするまとまり。(これからつくる。)
  • False: 接触してない時は、"hanP" を False としておく。"hanP" を True にするのは接触した時ね。

という事。

今回はマレットの接触判定だけを考えよう。マレットの場合はこれをちょっと変えて、後ろに付ければイイだけだからね。

イベント "HANSYA_P" 作成

では "HANSYA_P" を作成だ。下図。

f:id:ore2wakaru:20190527210950p:plain

糞長いしちっさくて見えないので2分割して解説する。

 前半部分: 反射ベクトルを求めるには反射面のノーマルが必要なので、これを求める。

f:id:ore2wakaru:20190527212315p:plain

1 イベント "HANSYA_P" スタート。コレはイイだろう。

2 2フレーム連続の当たりを防ぐため、"hanP" が False の時のみ先に進ませる。

3 パックの反射は2次元で考えればいい。パックは Z 方向には動かないのでな。で、反射を考える上で、パックと自マレットを真上から見ると、こう。下図。

f:id:ore2wakaru:20190528000945p:plain

つまり、反射面のノーマルは2つのオブジェクトの中心を結んだ線でいいわけだ。コレは楽勝。ただし、反射面から伸びている必要があるので、ベクトルの引き算の際、どっちからどっちを引けばいいのか間違わない事! 表面方向に伸びるベクトルを求めよ。(つまり、マレットからパック側に伸びるベクトルを求める事。これがひっくり返っていると反射面がひっくり返っていることになってしまうぞ。)

4 ノーマルは、長さが "1" である必要があるので、ここでノーマライズする。ノーマライズとはベクトルの長さ(大きさ)を "1" にすること。

やりかたは、上図の通り、Vector Mathノーマライズしたいベクトルを上のピンに入れ、"Normalize" を選べばよい。(上のピンに入れてね。下のピンは使わないからね。)

5 で、求めた値を "N" に入れる。

前半終了。

 後半部分: 反射ベクトルを出す

とおもったが、後半はちょっとしんどいので次回に回します。

本日のポイント
  • ノーマル: 長さ "1" の垂線。法線ベクトル。
  • Get Distance: 2つのオブジェクトの中心距離。
  • ノーマライズは、Vector Mathの "Normalize"。

 次回、後半戦。