Redpoll's 60
第2章 2D空間におけるオブジェクトの運動
$§$2-1 オブジェクトの初期状態$§$2-17 衝突判定 5
$§$2-2 行列による変換の詳細 1$§$2-18 初期状態における頂点情報の取得について
$§$2-3 行列による変換の詳細 2$§$2-19 衝突判定 6 (軸平行な長方形同士の衝突)
$§$2-4 自転と公転$§$2-20 衝突判定 7 (円盤 vs 長方形)
$§$2-5 一体化したオブジェクトの運動 1$§$2-21 衝突判定 8 (回転した長方形同士の衝突)
$§$2-6 一体化したオブジェクトの運動 2$§$2-22 衝突判定 9 (「倉庫番」プログラムの作成)
$§$2-7 一体化したオブジェクトの運動 3$§$2-23 衝突判定 10 (円盤 vs 三角形)
$§$2-8 指定方向へのオブジェクトの移動 1$§$2-24 衝突判定 11 (直線 vs 長方形、円盤、直線)
$§$2-9 指定方向へのオブジェクトの移動 2$§$2-25 円と直線による補間曲線 1
$§$2-10 指定方向へのオブジェクトの移動 3$§$2-26 円と直線による補間曲線 2
$§$2-11 指定方向へのオブジェクトの移動 4 (連射プログラムの実装)$§$2-27 その他の重要事項 1 (UnityのTransformクラスによる記述 ; カメラ移動の基本)
$§$2-12 指定方向へのオブジェクトの移動 5$§$2-28 その他の重要事項 2 (画面に表示されるXY平面の範囲 ; ミニマップの実装)
$§$2-13 衝突判定 1 (点 vs 円盤、長方形 ; ローカル座標からワールド座標への変換 2D)$§$2-29 その他の重要事項 3 (スクリーン座標からワールド座標への変換 2D; スクリーンショットの撮影範囲)
$§$2-14 衝突判定 2$§$2-30 課題 1
$§$2-15 衝突判定 3$§$2-31 課題 2
$§$2-16 衝突判定 4

$§$2-1 オブジェクトの初期状態


本章以降では「オブジェクトの初期状態」という言葉が頻繁に現れる。本節ではその具体的な意味を解説する。

この講義で使われるオブジェクトは一部の例外を除いてすべてDCCツール(Digital Content Creation Tool)であるBlenderで作成したものである。オブジェクトの初期状態とは簡単に言えば、BlenderなどのDCCツールを使用してオブジェクトを作成した際の、オブジェクトの保存された状態(あるいは、より直接的にはFBXファイルやOBJファイルなどの外部ファイルに出力された状態)のことを意味している。以下に順を追って説明しよう。

図1 Blenderの作業画面
図2 DiskB (Blenderでの表示 ; この状態でFBXファイルに出力する)

今、Blenderによって図2に示されるオブジェクトDiskBを作成したとしよう。DiskBは半径$1$の円形オブジェクトであり、その中心が原点に置かれている (やや暗くて分かりずらいがBlenderにおいても赤い軸がx軸で、緑の軸がy軸である)。この状態で保存したオブジェクトをFBXファイルに出力し(図3)、Unity側でそのFBXファイルをロードする(図4)。そして下記のプログラムを使って、Unity側にロードされたDiskBを表示した結果が図5である。

// DiskBに対してidentity行列を実行
DiskB.SetMatrix(THMatrix3x3.identity);

  • 図3 Blenderで作成したDiskBをFBXファイルへ出力
  • 図4 UnityでのFBXファイルの読み込み (FBXファイルをドラッグ&ドロップする)
  • 図5 DiskB (Unityでの表示)

図2と図5を比較すれば、DiskBは位置、大きさ、向きに関して両者で全く同じであることが分かるであろう(半径1の円で、その中心が原点に置かれ、色の薄い部分がx軸のプラス方向を向いている)。
プログラム2行目では DiskBに対して identity行列がセットされている。
1-4節において、オブジェクトに対してidentity行列をセットすることは、オブジェクトを何の変換も受けていない状態(何の変換も実行していない状態)にすることであると述べた。つまり、オブジェクトに平行移動や回転、スケールなどの変換がどれだけ実行されていても、identity行列をオブジェクトにセットすればオブジェクトは何の変換も受けていない状態に戻るのであった。
今回の例でいえば、UnityにロードされたDiskBに対して何も変換を実行せずに表示すると、その表示結果はBlenderでFBXファイルに出力したときの状態(位置、大きさ、向き)と全く同じ状態で表示されるのである。
このようにBlenderなどのDCCツールで作成されたオブジェクトを、FBXファイルやOBJファイルなどの外部ファイルに出力する際のオブジェクトの状態を、本節以降、「オブジェクトの初期状態」と呼ぶことにする。

次に図6のオブジェクトDiskRをBlenderで作成し、図6に示される状態(中心が$x = 2$の位置に置かれている)でFBXファイルに出力したとしよう。このDiskRをUnityにロードして上記のプログラム中のDsikBをDiskRに変えて実行した結果が図7である。

図6 DiskR (Blenderでの表示 ; この状態でFBXファイルに出力する)
図7 DiskR (Unityでの表示)

DiskRの初期状態は、その中心が原点ではなく$x = 2$の位置に置かれているので、Unity側で何も変換を実行しなければDiskRはやはり、$x = 2$の位置に置かれるのである。

# Code1
DiskB, DiskRをx軸方向に$1$だけ平行移動させるプログラムとその実行結果を以下に示す。

[Code1]  (実行結果 図8、図9)
THMatrix3x3 T = TH2DMath.GetTranslation3x3(1, 0);
DiskB.SetMatrix(T);

図8 Code1 実行結果 (DiskB ; 中心は x=1)
図9 Code1 実行結果 (Code1の2行目をDiskRとして実行した結果 ; 中心は x=3)

DiskB、DiskRともに初期状態の位置からx軸方向に$1$だけ移動した結果になっている。


# Code2
次に原点中心の回転を両者に実行する。
プログラムは1-10節のCode4と同じものである。

[Code2]  (実行結果 図10、図11)
i_degree += 1;        
THMatrix3x3 R = TH2DMath.GetRotation3x3(i_degree);
DiskB.SetMatrix(R);

図10 Code2 実行結果 (DiskB)
図11 Code2 実行結果 (Code2の3行目をDiskRとして実行した結果)

DiskBは初期状態でその中心が原点に置かれているので、原点周りの回転は図10のような結果になる。DiskRは初期状態でその中心が$x = 2$の位置に置かれているので、原点周りの回転を実行すると、原点を中心とする半径$2$の円周上を回転するようになる(図11)。

このように初期状態におけるオブジェクトの配置の仕方は、その後にオブジェクトに変換を実行していく上で重要な影響を持ってくるのである。特に今回のDiskBのように回転の発生する2Dオブジェクトの場合は、初期状態でオブジェクトの中心が原点と一致するように置くことが基本である。
例えば次の図12、図13には風車形状のオブジェクトが異なる初期状態で置かれている。図12の方はオブジェクトの中心が原点に一致するように置かれ、図13の方は中心が$y = 3$の位置に置かれている。

図12 中心が原点に置かれている
図13 中心がy= 3に置かれている

両者に上のCode2を実行した結果が次の図である(回転速度を少し変えてある)。

図14
図15

初期状態においてオブジェクトの中心が原点に置かれていた場合は、回転を実行すると風車の回転として期待通りの結果になるが(図14)、初期状態における中心の位置が原点でない場合には、回転を実行すると図15のように、ある円周上の回転になってしまうのである。












© 2020-2024 Redpoll's 60 (All rights reserved)