Download

Casting 101 Help

backstory: I am trying to write a teleporter to teleport the object I pick up(using a grabber handle) to another location when its placed on a custom trigger volume which holds the amount of objects that can be teleported, and the location to teleport to. Anyway long story short the rest of the code works, but I just can’t seem to call the function in my teleport script to activate the teleporting process. So how do I cast correctly to call the function I need to teleport the object I want?

TELEPORTER.H File // This is my trigger h file



public:
    //Asks Teleporter to Teleport an Actor    
    UFUNCTION()
    void TeleportME(AActor* OtherActor);

DefaultPawn.cpp // This is my Pawn code which calls the function above.



void AMyDefaultPawn::OnOverlapBegin(UPrimitiveComponent * OverlappedComp, AActor * OtherActor,
    UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
    //Super isn't relvent
    if (OtherActor->IsA(ATeleporter::StaticClass()))
    {
        UE_LOG(LogTemp, Warning, TEXT("Actor Overlap"));//This just confirms when the Pawn overlays the Trigger Volume


        if (Grabber->GetGrabbedActor()) //If it returns anything but nothing then (btw this is also checked several times in the other scipt to prevent errors)
        {
            //move the object that we are holding
            AActor *TeleportMe = Grabber->GetGrabbedActor(); //Sets Actor to be telported as the Object we are currently holding
            UE_LOG(LogTemp, Warning, TEXT("Actor Grabbed is %s"), *TeleportMe->GetName()) //Tests to see if we can get the object to teleport
            OtherActor = Cast<ATeleporter>(ATeleporter::TeleportME(TeleportMe));
        }
    }
}


The Error i’m getting is:
error C2352: ‘ATeleporter::TeleportME’: illegal call of non-static member function
note: see declaration of ‘ATeleporter::TeleportME’

So my question is how can I cast to the teleporter correctly to fire the event or how do I need to change my function so that it can be called, or both.

Long story short, you are calling the funtion like a static function which I suspect it is not. There are a couple of ways you can do this:

  1. You can skip the IsA() check and just cast your actor beforehand and check if the cast was successful. Like this:


void AMyDefaultPawn::OnOverlapBegin(UPrimitiveComponent * OverlappedComp, AActor * OtherActor,
UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
//Super isn't relvent
ATeleporter* CastedActor = Cast<ATeleporter>(OtherActor); // We cast the incoming actor to our desired class.
if (CastedActor != nullptr) // We check if the cast was successful.
{
UE_LOG(LogTemp, Warning, TEXT("Actor Overlap"));//This just confirms when the Pawn overlays the Trigger Volume


if (Grabber->GetGrabbedActor()) //If it returns anything but nothing then (btw this is also checked several times in the other scipt to prevent errors)
{
//move the object that we are holding
AActor *TeleportMe = Grabber->GetGrabbedActor(); //Sets Actor to be telported as the Object we are currently holding
UE_LOG(LogTemp, Warning, TEXT("Actor Grabbed is %s"), *TeleportMe->GetName()) //Tests to see if we can get the object to teleport
CastedActor->TeleportME(TeleportMe); // We call the function on our actor, NOT statically.
}
}
}


  1. You can just fix your current code by calling the function properly. Like this:


void AMyDefaultPawn::OnOverlapBegin(UPrimitiveComponent * OverlappedComp, AActor * OtherActor,
UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
//Super isn't relvent
if (OtherActor->IsA(ATeleporter::StaticClass()))
{
UE_LOG(LogTemp, Warning, TEXT("Actor Overlap"));//This just confirms when the Pawn overlays the Trigger Volume


if (Grabber->GetGrabbedActor()) //If it returns anything but nothing then (btw this is also checked several times in the other scipt to prevent errors)
{
//move the object that we are holding
AActor *TeleportMe = Grabber->GetGrabbedActor(); //Sets Actor to be telported as the Object we are currently holding
UE_LOG(LogTemp, Warning, TEXT("Actor Grabbed is %s"), *TeleportMe->GetName()) //Tests to see if we can get the object to teleport
OtherActor = Cast<ATeleporter>(OtherActor);
OtherActor->TeleportME(TeleportMe);
}
}
}


@Balgy
Thanks for your help I was able to understand what I was doing wrong.
I didn’t understand how casting worked and the person who explained it to me made me think it worked as follows



ActorCastingTo = Cast<CastToObject>(FunctionUsed);


So thanks for explaining it :). It worked right off the bat.
Btw as a follow up question would you ever call a function using the above code and if so when would that be?

Not within the casting code no.
But you can call static functions using your syntax in ATeleporter::TeleportMe()

This “::” accessor is used to access static member functions, meaning functions that are not specific to any instance of the class and belong to the class as a type.

Just an advice, every time you use Cast<>(), remember to test if the value receiver is != nullptr (as you did before) because as your code grows one single wrong line of code might start causing issues and if it is == nullptr you can log messages to tell about it. Sometimes this is not that much usefull in blueprints since they provide already a connection for a successfull cast, but in C++ it is a must to get this done right.