Download

GetHitResultUnderCursorByChannel ignoring custom actor created in C++

Hi,
I’m creating a custom actor in C++ with the following code. Then in the game I use GetHitResultUnderCursorByChannel with trace channel “camera” this identify this obejct and select it. But this object is always ignored, the GetHitResultUnderCursorByChannel returns the floor. I tried many differnt combinations, but always ignored. If I create an Actor in the editor and spawn it, the GetHitResultUnderCursorByChannel properly finds it. But I need to create my items by code. Can you please help?

What is the difference between an Actor created in the editor and the one created by code below?


FActorSpawnParameters SpawnInfo;
SpawnInfo.Owner = this;
SpawnInfo.Instigator = Instigator;
ApsItemActor* obj = GetWorld()->SpawnActor<ApsItemActor>(ApsItemActor::StaticClass(), suggestedPos, GetActorRotation(), SpawnInfo);

UStaticMeshComponent* MyMeshComponent = NewObject<UStaticMeshComponent>(obj, UStaticMeshComponent::StaticClass(), TEXT("Mesh"));

UStaticMesh* MeshAsset = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), NULL, TEXT("StaticMesh'/Game/Weapons/axes/doubleaxe02abc.doubleaxe02abc'")));
UMaterial* MaterialAsset = Cast<UMaterial>(StaticLoadObject(UMaterial::StaticClass(), NULL, TEXT("Material'/Game/Weapons/axes/doubleaxe02c_Mat.doubleaxe02c_Mat'")));

MyMeshComponent->SetStaticMesh(MeshAsset);
MyMeshComponent->SetMaterial(0, MaterialAsset);
MyMeshComponent->SetWorldLocation(suggestedPos);
MyMeshComponent->SetIsReplicated(true);

// collision
MyMeshComponent->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
MyMeshComponent->BodyInstance.SetObjectType(ECollisionChannel::ECC_WorldStatic);
MyMeshComponent->BodyInstance.SetResponseToAllChannels(ECollisionResponse::ECR_Block);
MyMeshComponent->BodyInstance.SetResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Block);
MyMeshComponent->BodyInstance.SetResponseToChannel(ECollisionChannel::ECC_Visibility, ECollisionResponse::ECR_Block);

obj->AddOwnedComponent(MyMeshComponent);
MyMeshComponent->RegisterComponent();
obj->SetRootComponent(MyMeshComponent);

In addition I have used the debugger to check the values of the ResponseToChannel in my object after its created and these are the values:


BodyInstance
  CollisionResponses
    ResponseToChannels
        WorldStatic        2 '\x2'    unsigned char
        WorldDynamic        2 '\x2'    unsigned char
        Pawn            2 '\x2'    unsigned char
        Visibility        2 '\x2'    unsigned char
        Camera            2 '\x2'    unsigned char
        PhysicsBody        2 '\x2'    unsigned char
        Vehicle            2 '\x2'    unsigned char
        Destructible        2 '\x2'    unsigned char
        EngineTraceChannel1    2 '\x2'    unsigned char
        EngineTraceChannel2    2 '\x2'    unsigned char
        EngineTraceChannel3    2 '\x2'    unsigned char
        EngineTraceChannel4    2 '\x2'    unsigned char
        EngineTraceChannel5    2 '\x2'    unsigned char
        EngineTraceChannel6    2 '\x2'    unsigned char
        GameTraceChannel1    2 '\x2'    unsigned char
        GameTraceChannel2    2 '\x2'    unsigned char
        GameTraceChannel3    2 '\x2'    unsigned char
        GameTraceChannel4    2 '\x2'    unsigned char
        GameTraceChannel5    2 '\x2'    unsigned char
        GameTraceChannel6    2 '\x2'    unsigned char
        GameTraceChannel7    2 '\x2'    unsigned char
        GameTraceChannel8    2 '\x2'    unsigned char
        GameTraceChannel9    2 '\x2'    unsigned char
        GameTraceChannel10    2 '\x2'    unsigned char
        GameTraceChannel11    2 '\x2'    unsigned char
        GameTraceChannel12    2 '\x2'    unsigned char
        GameTraceChannel13    2 '\x2'    unsigned char
        GameTraceChannel14    2 '\x2'    unsigned char
        GameTraceChannel15    2 '\x2'    unsigned char
        GameTraceChannel16    2 '\x2'    unsigned char
        GameTraceChannel17    2 '\x2'    unsigned char
        GameTraceChannel18    2 '\x2'    unsigned char


This shows that ALL the channels are actually properly set to BLOCK, so my Trace should detect the object.

At the end I solved the problem by doing the following:

  1. Added in psItemActor.h

    UPROPERTY(EditAnywhere)
    UStaticMeshComponent* mesh;

  1. Added in psItemActor.cpp

ApsItemActor::ApsItemActor()
{
    bReplicates = true;
    mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
    RootComponent = mesh;
}

  1. Used the following code to change the mesh and material.

    FActorSpawnParameters SpawnInfo;
    SpawnInfo.Owner = this;
    SpawnInfo.Instigator = Instigator;

    ApsItemActor* obj = GetWorld()->SpawnActor<ApsItemActor>(ApsItemActor::StaticClass(), suggestedPos, GetActorRotation(), SpawnInfo);

    //UStaticMeshComponent* MyMeshComponent = NewObject<UStaticMeshComponent>(obj, UStaticMeshComponent::StaticClass(), TEXT("Mesh"));

    UStaticMesh* MeshAsset = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), NULL, TEXT("StaticMesh'/Game/Weapons/axes/doubleaxe02abc.doubleaxe02abc'")));
    UMaterial* MaterialAsset = Cast<UMaterial>(StaticLoadObject(UMaterial::StaticClass(), NULL, TEXT("Material'/Game/Weapons/axes/doubleaxe02c_Mat.doubleaxe02c_Mat'")));

    UStaticMeshComponent* MyMeshComponent = ((UStaticMeshComponent*)obj->GetDefaultSubobjectByName("Mesh"));
    MyMeshComponent->SetStaticMesh(MeshAsset);
    MyMeshComponent->SetMaterial(0, MaterialAsset);

    // Respond to trace hits
    MyMeshComponent->BodyInstance.SetObjectType(ECollisionChannel::ECC_WorldStatic);
    MyMeshComponent->BodyInstance.SetResponseToAllChannels(ECollisionResponse::ECR_Block);
    MyMeshComponent->BodyInstance.SetResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Block);
    MyMeshComponent->BodyInstance.SetResponseToChannel(ECollisionChannel::ECC_Visibility, ECollisionResponse::ECR_Block);
    MyMeshComponent->SetIsReplicated(true); // needed or the item doesnt show on client

My item now properly answers to GetHitResultUnderCursorByChannel