x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Why does Unreal Engine crash when I call a method in a Pawn class from an Actor class

I am new to using C++ to code in Unreal Engine as a module for my university, what I have made so far is a space ship (SpaceShipPawn) that can shoot projectiles (ShipProjectile). When I fire the projectiles and they hit with something, they are supposed to call a method in the space ship pawn class, increment the int Score held in the pawn class, and print a debug message to the screen.

If I don’t call the method I am trying to call, the projectiles get destroyed like they are supposed to. Though when the projectiles hit anything when I include the method they cause Unreal Engine to freeze and become unresponsive. I am not sure what I am doing wrong, any help would be appreciated!

SpaceShipPawn.cpp

 ASpaceShipPawn::ASpaceShipPawn()
 {
     // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
     PrimaryActorTick.bCanEverTick = true;
     static ConstructorHelpers::FObjectFinder<UStaticMesh> ShipMesh(TEXT("/Game/Meshes/UFO.UFO"));
     ShipMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ShipMesh"));
     RootComponent = ShipMeshComponent;
     ShipMeshComponent->SetCollisionProfileName(UCollisionProfile::Pawn_ProfileName);
     ShipMeshComponent->SetStaticMesh(ShipMesh.Object);
 
     CanFire = true;
     FireRate = 1.0f;
     GunOffset = 70.0f;
     Score = 0;
 }
 
 {…
 Some more code for making the space ship work
 …}
 
 void ASpaceShipPawn::ScoreGained(){
     if (GEngine){
         GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Increment Score"));
     }
     Score++;
 }

ShipProjectile.cpp

 void AShipProjectile::OnHit(AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit){
     if (GEngine){
         GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("Hit ->") + OtherActor ->GetName());
     }
 
     ASpaceShipPawn test;
     test.ScoreGained();
 
     Destroy();
 }
Product Version: UE 4.8
Tags:
more ▼

asked Mar 19 '16 at 02:15 AM in C++ Programming

avatar image

Avenaught
1 2 2

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first
  ASpaceShipPawn test;
  test.ScoreGained();

This is wrong. You need to access a pointer to your pawn, not create a new pawn object. an example on doing this would be:

 if (GetWorld != nullptr && GetWorld()->GetFirstPlayerController() != nullptr)
 {
     ASpaceShipPawn* PawnPtr = Cast<ASpaceShipPawn>(GetWorld()->GetFirstPlayerController()->GetPawn());
     if (PawnPtr != nullptr)
     {
         PawnPtr->ScoreGained();
     }
 }


more ▼

answered Mar 19 '16 at 08:51 AM

avatar image

Narovana
26 2 2 7

avatar image Avenaught Mar 19 '16 at 10:05 AM

Ah, thank you!

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

Something that might help in general with this sort of stuff is running from the visual studio debugger. Instead of opening from the launcher, open your project's .sln file, and hit play. This run the editor from the debugger and will break on crashes like this(so you know what line it crashed on, and what memory looks like at the time it crashed). You can also set break points.

Anyway, your problem is probably that you're trying to create an actor incorrectly. An object that's put on the stack(created without 'new') like you've done here, will be destroyed when it leaves scope(after you leave the {} where it was created). So, this wouldn't work to begin with because you're creating a space ship pawn that will immediately be destroyed. Actors have a lot of complex state and they should be created through the SpawnActor functions:

https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/Engine/UWorld/SpawnActor/1/index.html

This will correctly create a new actor for you, and it will last until you call Destroy on it.

That might solve the crashing, but what I think you meant to do is take the space ship that owns the projectile that hit something, and call ScoreGained on that. For this you probably want to look into instigators. Instigators are pawns that are responsible for other actors(your space ship will be responsible for the projectiles it shoots.) An instigator can be set through the FActorSpawnParameters parameter of SpawnActor. You can then call GetInstigator on an actor to get the pawn who's responsible for it.

more ▼

answered Mar 19 '16 at 06:40 AM

avatar image

Bonnnnnn
135 8 15 23

avatar image Avenaught Mar 19 '16 at 10:06 AM

Thank you for the detailed response :) I will definitely be looking into instigators

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question