yamonメモ.cpp

ue4で勉強中 日々の進捗を簡単に残します。

障害物を自動で避ける仕組みを実装してみた

前回のあらすじ
MovementComponentを作り始めてみた - yamonメモ.cpp

MovementComponentの基礎部分は実装できたので、
続いて、歩いているアクターが進行方向にある障害物を見つけると
自動で左右に避ける仕組みを作ってみることにした。

アクターAから見たアクターBが右側にいるかどうかを判定する

まず、必要になる情報が、
・LineTraceで前方に伸ばしたレイでヒットした障害物の原点
・現在進行中のアクター自身の回転値

アクターAからアクターBへの回転値(Yaw)を計算し、
自分の回転値(Yaw)と比較して大きければ右方向、小さければ左方向。
ソースだとこんな感じ。

auto LineTraceComp = Actor->GetLineTraceComponent();
if (!LineTraceComp)
{
	return;
}
FVector CurrentVel = Actor->GetVelocity();
if (CurrentVel.IsZero())
{
	// 動いていないアクターは対象外
	return;
}

// LineTraceでHitしたアクター位置を取得
FVector HitActorLocation = FVector::ZeroVector;
if (!LineTraceComp->GetNearestForwardHitActorLocation(&HitActorLocation))
{
	return;
}
const FRotator CurrentRot = Actor->GetCurrentRotation();
const FVector Dir = HitActorLocation - Actor->GetCurrentLocation();
const FRotator TargetRot = Dir.Rotation();

if (CurrentRot.Yaw > TargetRot.Yaw)
{
	// 対象はアクターから見て右にいる
}
else
{
	// 対象はアクターから見て左にいる
}

現在の移動速度に計算した避け具合を反映させる

対象が右にいるなら左に、左にいるなら右に移動値を反映する。

単純に現在の速度に加算してみた
f:id:yamonkj:20191115000725g:plain

避ける瞬間に加速する見た目になってしまった。
(避けられた方イラっとするだろうな…)

単純な速度の加算だとそうなってしまうので、
現在の速度から再設定を行うようにしてみる。

アクターの回転値をとってきて、
少し回転させた状態で同じように速度を与えてみる。

if (CurrentRot.Yaw > TargetRot.Yaw)
{
	// 対象はアクターから見て右にいる
	CurrentRot.Yaw += AvoidAddYaw;
}
else
{
	// 対象はアクターから見て左にいる
	CurrentRot.Yaw -= AvoidAddYaw;
}
	
const FVector NewVel = CurrentRot.Quaternion().GetAxisY();
Actor->SetVelocity(NewVel * Speed);

f:id:yamonkj:20191115001743g:plain

これでうまくいく避けてくれる感じを出すことができた。
f:id:yamonkj:20191115002343g:plain

向かい合わせてもそれっぽく避けてくれる。

気になる点

同じ速度のアクターを縦に連ねて配置し、後ろを追従させた場合、
追い抜けないのに横にずれてしまう。
当たりそうな対象の速度も見て追い抜けそうなら横にずれ、
追い抜けなさそうならそのままを維持するようにしてみたい。

前が詰まっている時(どこに避けてもぶつかってしまう場合)は
「止まる」を選択肢に入れる実装もしてみたい。

また今度気になったらやってみよう。

雑談

先日
UE4製TPSアクション EDF: IR事例解説セミナー in 大阪」
に行ってきました。

感想
ABPの設計って本当に難しい!
変に共通化しようとしても身動きとり辛いし…

コントローラー入力からモーションのブレンドに繋げる発想
凄い柔軟だしTPSにマッチしてて感動した。

Entryから空State(Entry)に繋くとTポーズの補間がかかってどうしようって問題。
自分も経験したことあるけど、
結局ゴリ押ししたような気がする(EntryにIdleのモーションを入れておくだけ)w
99秒の補間は盲点だった。

SubAnimInstanceって相当便利そうだな。
あまり個人だと使う機会少ないかもしれないけど。

感想終わり!楽しかった!

次は移動関連とはまた違うことがやりたいな。
・Statの表示を試してみる。
・フラスタムカリングを実装してみる。
マーケットプレイスからアセットを取り込んでみる。
・ポーズ機能を実装してみる

どれかをやります!