おまけみたいな感じですが、壁の回避行動をつけます。
現状、ユニットが壁を突き抜けるように移動することは有り得ません。
(壁が存在するところにグラフのノードが存在しないからです)
ただ、ユニットが重ならないよう押し合う処理があるため、
壁のほうに押されたユニットが、壁にめり込むないしは突き抜けることがあります。 これを回避するためには、移動先に壁があるかどうか確かめ、
このまま進んだら当たるな・・・という場合に、それを避けるような移動を行う必要があります。
//基準線の長さ
const double LEN = 5.0;
//壁回避
Vec2D MotionManager::AvoidWall()
{
Vec2D Force;
//壁に衝突しそうかを判断するための基準線
// - 全面、右斜め前、左斜め前
Vec2D V = m_pUnit->Velocity();
Vec2D P = m_pUnit->Pos();
Vec2D line[3] =
{
P + Vec2D(LEN, LEN),
P + Vec2D(LEN*cos(+PHI/4), LEN*sin(+PHI/4)),
P + Vec2D(LEN*cos(-PHI/4), LEN*sin(-PHI/4))
};
//複数の壁に衝突していることを考えて、
//自身の座標と最も近い交点をもつ壁を回避
Wall* closestWall = NULL;
double distClosestWall = DBL_MAX;
//最寄りの交点
Vec2D closestIP;
std::list& wList = WallManager::Instance().GetWallList();
std::list::iterator it;
Vec2D ip; //交点
//全 基準線にたいし検証
for(int i = 0; i From(), it->To(),
ip))
{
double dist = (ip-P).LengthSQ();
if(dist Normal() * over.Length();
}
}
return Force;
}
いくつかの基準線を用意します。(触覚みたいなものです)
それが壁にめりこんでいれば、そのめりこんだ分、ユニットを押し戻します。
そうすることによって、壁に距離に反比例して力が定まるので、
自然に壁を避けているように見えるはずです。
これをMotionManagerに追加し、フラグを付けて有効化すれば、
ユニットが壁にめり込むことがなくなります。
(”壁にめりこまなくなった”画像を用意するのは難しいので省きます。)