いつもお世話になっております。
ナビメッシュを検索する際の、パラメータの考え方について質問させてください。
ソースを確認したところ、UCharacterMovementComponent::FindNavFloorで、エージェントの半径を2倍したものを、検索の半径としています。
こちら、2倍している意味を把握したいです。
bool UCharacterMovementComponent::FindNavFloor(const FVector& TestLocation, FNavLocation& NavFloorLocation) const
{
const ANavigationData* NavData = GetNavData();
if (NavData == nullptr)
{
return false;
}
INavAgentInterface* MyNavAgent = CastChecked(CharacterOwner);
float SearchRadius = 0.0f;
float SearchHeight = 100.0f;
if (MyNavAgent)
{
const FNavAgentProperties& AgentProps = MyNavAgent->GetNavAgentPropertiesRef();
SearchRadius = AgentProps.AgentRadius * 2.0f;
SearchHeight = AgentProps.AgentHeight * AgentProps.NavWalkingSearchHeightScale;
}
return NavData->ProjectPoint(TestLocation, NavFloorLocation, FVector(SearchRadius, SearchRadius, SearchHeight));
}
ナビメッシュの領域についての理解なのですが、ナビメッシュをエディタで確認したところ、障害物とナビメッシュの間の距離は、エージェントの半径と同じ値のようにみえます。これは、ナビメッシュの端(移動可能な領域と移動不能な領域の境界)であれば、キャラクタのカプセルが、障害物には衝突しない…という実装だと考えています。
そこで、エージェントの半径に、キャラクターのカプセルの半径に相当する値を設定してみたのですが、場合によっては、障害物を貫通してしまう事がありました。
上記の2倍した半径によって、障害物の反対側にあるナビメッシュ領域を拾っているようなのですが、
2倍の意味を、どのように考えれば良いでしょうか。
お世話になっております。
ソースを確認したところ、UCharacterMovementComponent::FindNavFloorで、エージェントの半径を2倍したものを、検索の半径としています。こちら、2倍している意味を把握したいです。
SearchRadiusはキャラクターの原点座標からNavmeshのPolygonを検索するためのExtend範囲(X,Y)を示すものになりますが、ここで2倍という数値に深い意図は無く、単に半径の倍の距離を検索するだけのものとなります(これはNavmeshWalkingモードが実装された4.8から一貫して変更が無いマジックナンバーのような値です)。
ナビメッシュの領域についての理解なのですが、ナビメッシュをエディタで確認したところ、障害物とナビメッシュの間の距離は、エージェントの半径と同じ値のようにみえます。これは、ナビメッシュの端(移動可能な領域と移動不能な領域の境界)であれば、キャラクタのカプセルが、障害物には衝突しない…という実装だと考えています。
ナビメッシュの領域についてはRecastNavmeshのCellSizeで調整可能なように、一貫してエージェントの半径の値というわけではありません。障害物に貫通してしまう事があったとのことですが、StaticMeshなどの障害物に対してNavmeshがキャラクターに貫通する位置まで生成されているのであれば、貫通してしまうことも考えられます。
そこで、エージェントの半径に、キャラクターのカプセルの半径に相当する値を設定してみたのですが、場合によっては、障害物を貫通してしまう事がありました。上記の2倍した半径によって、障害物の反対側にあるナビメッシュ領域を拾っているようなのですが、2倍の意味を、どのように考えれば良いでしょうか。
例えばACharacterクラスのようなSimpleCylinderCollisionを持つ場合、CharacterMovementのAgentPropertyの値ではなくカプセルの持つ値で上書きされます。これはキャラクターの判定で使用しているカプセルの判定に準拠するためです。これは UNavMovementComponent::UpdateNavAgent(const AActor& Owner)
、 UNavMovementComponent::UpdateNavAgent(const UCapsuleComponent& CapsuleComponent)
で上書きされますので、上書きされたくない場合は UNavMovementComponent::UpdateNavAgentWithOwnersCollision
のチェックを外して下さい。また、2倍の値を適用したくない場合は UCharacterMovementComponent::FindNavFloor
を独自の UCharacterMovementComponent
クラスでOverrideして頂ければと思います。
よろしくお願いします。