Rayを使った移動の方法

unity_chan_logo

概要

最終更新日:2020/03/15

Rayを使った移動方法について書いた記事です。
この記事は以下の内容を知りたい方に向けて書いています。
  • Rayとは何か知りたい
  • Rayでできることを知りたい
  • 2Dで斜面にそって移動したい

サンプル

サンプルはここからダウンロードできます。
環境については以下の内容となっています。

開発環境
VSのバージョン VisualStudio 2019
DirectXのバージョン DirectX9
説明 左右キーを押すことでキャラクターが動きます。


Rayとは

Rayとは「始点」と「方向と大きさ」で構成されているデータです。
Rayを使うことを「Rayを飛ばす」といいます。

このRayを使って線分や面との交点判定を行いますが、
この結果で得られる情報を用いて、ゲームでは様々なことが行われています。
以下はゲーム中のRayが使って行われていることの一例です。
  • 視線としてオブジェクト探索
  • 障害物検知
  • オブジェクトとの詳細な距離測定
  • レーザーなどの線分オブジェクトとしての当たりの形状
  • 地形判定

Rayを使った移動

2Dゲームの移動に使用する主な当たりの形状は矩形や円、マップチップですが、
これらの形状だけでは斜面にそった移動をすることは難しいため、
斜面の移動にはRayが使われていることが多いです。
先ほどの一例でいうと「地形判定」にあたります。

Rayを始点と方向

斜面の移動を調べるためのRayは以下の位置から下に飛ばします。
    オブジェクトの座標 + X軸の移動量
2d_game_0024

移動方法

移動の可否判定はRayと線分や矩形などとの交差判定で得られる交点を使用します。
Rayを下に飛ばして交点が見つかったら移動可能と判断して
交点の位置にオブジェクトの足元が来るように調整します。

2d_game_0025

もし交点が見つからなかったら移動できないと判断します。

2d_game_0026

Rayの始点の高さ

始点の高さによって移動できる傾斜の角度が変わります。
高いほど急な傾斜でも移動可能となり、低いほど小さな角度の傾斜しか移動できません。

2d_game_0027

移動できる傾斜の範囲を調整したい場合は、高さを調整してください。

実装方法

Rayによる移動の実装は以下の手順で行います。
  1. X軸の移動量を決める
  2. Rayを用意する
  3. Rayを飛ばして交点を取得する
  4. 交点の位置にオブジェクトを移動させる

X軸の移動量を決める

まずはオブジェクトのX軸に対しての移動量を決めますが、
これは通常の移動処理で使う移動量で問題ありません。
ただ、この移動量をすぐにオブジェクトに反映させないでください。
移動量の反映はRayの判定を使って行います。

if (OnKeyPush(RIGHT_KEY))
{
	horizontal += speed;
}
else if (OnKeyPush(LEFT_KEY))
{
	horizontal -= speed;
}

Rayを用意する

X軸の移動量が分かったら、Rayを用意します。
Rayに必要な情報は「始点」と「飛ばす方向と大きさを持ったベクトル」です。

Ray ray= Ray(
	// X => オブジェクトの中心 + X軸移動量 Y => オブジェクトの足元 - 3.0f
	Vec2(g_Player.Position.X + PlayerWidth / 2.0f + horizontal, g_Player.Position.Y + PlayerHeight - 3.0f),
	// 真下の方向に飛ばす
	Vec2(0.0f, vertical)
);

Rayを飛ばして交点を取得する

Rayの用意ができたら、線分との交点を求めます。
交点が見つかったら移動可能と判断します。

// 交差判定
Vec2 intersect_position;
if (CollisionMap(ray, intersect_position) == true)
{
	// 交点発見
}

交点の位置にオブジェクトを移動させる

交点が見つかって移動可能と判断したら、X軸に移動量を加算して、
Y軸は交点の位置に足元が来るように調整します。

// X軸移動量加算
g_Player.Position.X += horizontal;

// 交点の位置がオブジェクトの足元に来るように調整
g_Player.Position.Y = intersect_position.Y - PlayerHeight;

これで、Rayを使った移動の実装は完了です。



Rayは移動だけではなく様々なことで使えるのでぜひ使ってみてください。