實現步驟
- 設置動態生成導航,RecastNavMesh-->Runtime-->RuntimeGeneration=Dynamic;
- 設置組件是否能影響導航,bCanEverAffectNavigation = true;
- 設置CollisionEnabled 為QueryOnly或者QueryAndPhysics
- 設置碰撞響應,設置Pawn或者Vehicle為block;
talk is cheap, show me the code.
void UPrimitiveComponent::SetCollisionResponseToChannel(ECollisionChannel Channel, ECollisionResponse NewResponse)
{
BodyInstance.SetResponseToChannel(Channel, NewResponse);
OnComponentCollisionSettingsChanged();
}
void UPrimitiveComponent::OnComponentCollisionSettingsChanged()
{
if (IsRegistered() && !IsTemplate()) // not for CDOs
{
// changing collision settings could affect touching status, need to update
if (IsQueryCollisionEnabled()) //if we have query collision we may now care about overlaps so clear cache
{
ClearSkipUpdateOverlaps();
}
UpdateOverlaps();
// update navigation data if needed
const bool bNewNavRelevant = IsNavigationRelevant();
if (bNavigationRelevant != bNewNavRelevant)
{
bNavigationRelevant = bNewNavRelevant;
FNavigationSystem::UpdateComponentData(*this);
}
OnComponentCollisionSettingsChangedEvent.Broadcast(this);
}
}
bool UPrimitiveComponent::IsNavigationRelevant() const
{
if (!CanEverAffectNavigation())
{
return false;
}
if (HasCustomNavigableGeometry() >= EHasCustomNavigableGeometry::EvenIfNotCollidable)
{
return true;
}
const FCollisionResponseContainer& ResponseToChannels = GetCollisionResponseToChannels();
return IsQueryCollisionEnabled() &&
(ResponseToChannels.GetResponse(ECC_Pawn) == ECR_Block || ResponseToChannels.GetResponse(ECC_Vehicle) == ECR_Block);
}
FORCEINLINE bool CollisionEnabledHasQuery(ECollisionEnabled::Type CollisionEnabled)
{
return (CollisionEnabled == ECollisionEnabled::QueryOnly) ||
(CollisionEnabled == ECollisionEnabled::QueryAndPhysics);
}
代碼解釋的非常清楚