Bootstrap

c++ 设置Collision 使用自定义ObjectChannel

1. 定义自定义的 ObjectChannel

在 Unreal Engine 中,自定义的 ObjectChannel 通常通过项目设置完成:

  • 打开 Edit > Project Settings。
  • 导航到 Collision 部分。
  • 在 Object Channels 下,添加一个新的通道并命名,比如 MyCustomChannel,并设置默认响应(例如 Block, Overlap, 或 Ignore)。

2. 在代码中设置 UStaticMeshComponent 使用自定义的 ObjectChannel

你需要在代码中设置该 ObjectChannel 并调整碰撞配置:

#include "Components/StaticMeshComponent.h"

void SetupStaticMeshComponent(UStaticMeshComponent* StaticMeshComponent)
{
    if (!StaticMeshComponent)
    {
        return;
    }

    // 设置 ObjectType 为自定义的 ObjectChannel
    StaticMeshComponent->SetCollisionObjectType(ECollisionChannel::ECC_GameTraceChannel1); // 根据你的通道编号调整

    // 可选:设置碰撞响应规则
    StaticMeshComponent->SetCollisionResponseToAllChannels(ECR_Ignore); // 默认忽略所有通道
    StaticMeshComponent->SetCollisionResponseToChannel(ECC_GameTraceChannel1, ECR_Block); // 对自定义通道设置阻挡
    StaticMeshComponent->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap);    // 对其他通道的自定义行为

    // 可选:设置碰撞启用方式
    StaticMeshComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);

    // 可选:打印调试信息
    UE_LOG(LogTemp, Log, TEXT("ObjectType: %d"), StaticMeshComponent->GetCollisionObjectType());
}

3. 在 Actor 或 Component 中使用

可以在 AActor 或自定义组件的初始化过程中调用上述方法:

void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    if (UStaticMeshComponent* MeshComponent = FindComponentByClass<UStaticMeshComponent>())
    {
        SetupStaticMeshComponent(MeshComponent);
    }
}

4. 注意事项

  • 匹配 ObjectChannel:确保项目设置中创建的 ObjectChannel 和代码中的通道编号匹配,例如 ECC_GameTraceChannel1 对应第一个自定义通道。
  • 碰撞调试:使用 ShowFlag.Collision 或 DrawDebugSphere 等工具检查碰撞设置是否正确。
  • 确保正确的物理行为:检查是否需要额外的物理设置,比如启用模拟物理(SetSimulatePhysics)。
  • 通过这些步骤,你可以成功为 UStaticMeshComponent 设置自定义的 ObjectChannel 和碰撞行为。

5. 遍历所有 Object Channels

要通过 UCollisionProfile::Get() 获取所有自定义的 Object Channels,可以利用 FCollisionProfile 的相关数据结构来获取信息。以下是获取所有自定义 Object Channels 的具体方法。

#include "Engine/CollisionProfile.h"

// 方法:遍历所有 Object Channels
void LogAllCustomCollisionChannels()
{
    // 获取 CollisionProfile 的实例
    const UCollisionProfile* CollisionProfile = UCollisionProfile::Get();
    if (!CollisionProfile)
    {
        UE_LOG(LogTemp, Error, TEXT("CollisionProfile is null!"));
        return;
    }

    // 遍历所有 Object Channels
    const TArray<FCollisionResponseTemplate>& Profiles = CollisionProfile->GetProfiles();
    UE_LOG(LogTemp, Log, TEXT("Listing all custom Object Channels:"));

    for (const FCollisionResponseTemplate& Profile : Profiles)
    {
        if (Profile.ObjectTypeName != NAME_None)
        {
            UE_LOG(LogTemp, Log, TEXT("Channel Name: %s, Collision Type: %d"), *Profile.ObjectTypeName.ToString(), Profile.ObjectType);
        }
    }
}

5.1 说明

  • GetProfiles() 返回所有 Collision Profiles,其中包含自定义的 Object Channels 和其设置。
  • ObjectTypeName 是每个通道的名称。
  • ObjectType 是对应的枚举值,比如 ECC_GameTraceChannel1。
  • 调试信息: 输出通道名称以及对应的枚举值。
;