实现步骤
- 设置动态生成导航,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);
}
代码解释的非常清楚