Timon Doo
Timon Doo

Reputation: 153

Unreal crashes when calling AI MoveToLocation

I tested the following Code in Blueprint first and wanted to translate it into C++. I'm trying to create a npc with a triggerSphere that activates onOverlap and lets the Npc walk away in the opposite direction the player came from. When I'm playing the unreal Editor and getting close to the Npc it crashes. The Problem is with the MoveToLocation from the AiController, but I'm not sure why.

Here is the Blueprint (sry if the quali ist bad) enter image description here

Here are the AiController files of the Npc .h File:

#include "CoreMinimal.h"
#include "AIController.h"
#include "SpiderAIController.generated.h"

/**
 * 
 */
UCLASS()
class SPIDERPROJECT0710_API ASpiderAIController : public AAIController
{
    GENERATED_BODY()

protected:
    virtual void BeginPlay() override;
    
    

public:
    UFUNCTION()
    void WalkAway(FVector Location, float Var); 
};

the .cpp

#include "SpiderAIController.h"

void ASpiderAIController::BeginPlay()
 {
    Super::BeginPlay();   
 }

 void ASpiderAIController::WalkAway(FVector Location, float Var)
 {
    
    MoveToLocation(Location, Var);
 }

Here are the Files of the Npc:

necessery part of the .h file

private:
    UPROPERTY(VisibleAnywhere, Category = "Switch Components")         class USphereComponent* TriggerSphere;

    UPROPERTY()
    class ASpiderAIController* AIController;
     
    UFUNCTION()
    void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

    
    //UFUNCTION()
    //void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

};

The cpp file:

#include "SpiderCharacter.h"
#include "Components/SphereComponent.h"
#include "SpiderAIController.h"

// Sets default values
ASpiderCharacter::ASpiderCharacter()
{
    // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    TriggerSphere = CreateDefaultSubobject<USphereComponent>(TEXT("Trigger Sphere"));
    TriggerSphere->InitSphereRadius(105.0f);
    TriggerSphere->SetCollisionProfileName(TEXT("Trigger"));
    TriggerSphere->SetupAttachment(RootComponent);

    TriggerSphere->OnComponentBeginOverlap.AddDynamic(this, &ASpiderCharacter::OnOverlapBegin); 
    AIController = Cast<ASpiderAIController>(GetController());

    
}

void ASpiderCharacter::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
    if (OtherActor && (OtherActor != this) && OtherComp) 
    {
        //get Location and Roation of PlayerCharacter
        FVector PlayerPosition = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation();
        FRotator PlayerRotation = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorRotation();
        FVector NewLocation = FVector(PlayerPosition.X -500.f,PlayerPosition.Y - 500.f, PlayerPosition.Z);
        float Var = 100.f;

        SetActorRotation(PlayerRotation);
        AIController->WalkAway(NewLocation, Var);
        //SetActorLocation(NewLocation);

        
        UE_LOG(LogTemp,Warning,TEXT("MyCharacter's Location is %s"),  *OtherActor->GetName());
    }
} 

The Error message from Unreal:

LoginId:c4c2e10f47cd9a4f6992fd821aae5406 EpicAccountId:92760ac7ea0e4f249688fd7737d3a55d

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x00000000000003b0

UE4Editor_AIModule UE4Editor_SpiderProject0710_4739!ASpiderAIController::WalkAway() [C:\Users\alexa\OneDrive\Desktop\Udemy\Unreal Engine\SpiderProject0710\Source\SpiderProject0710\SpiderAIController.cpp:19] 
UE4Editor_SpiderProject0710_4739!ASpiderCharacter::OnOverlapBegin() [C:\Users\alexa\OneDrive\Desktop\Udemy\Unreal Engine\SpiderProject0710\Source\SpiderProject0710\SpiderCharacter.cpp:62] 
UE4Editor_SpiderProject0710_4739!ASpiderCharacter::execOnOverlapBegin() [C:\Users\alexa\OneDrive\Desktop\Udemy\Unreal Engine\SpiderProject0710\Intermediate\Build\Win64\UE4Editor\Inc\SpiderProject0710\SpiderCharacter.gen.cpp:38] 
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Core
UE4Editor_Core
UE4Editor_Core
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_UnrealEd
UE4Editor_UnrealEd
UE4Editor
UE4Editor
UE4Editor
UE4Editor
UE4Editor
kernel32
ntdll

Upvotes: 1

Views: 1584

Answers (1)

Timon Doo
Timon Doo

Reputation: 153

I found the problem. I needed to get the PlayerPawn and AiController on BeginPlay, not in the class constructor. I refactored the code as well.

The npc .h:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "SpiderCharacter.generated.h"

UCLASS()
class SPIDERPROJECT0710_API ASpiderCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    // Sets default values for this character's properties
    ASpiderCharacter();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    // Called to bind functionality to input
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;


private:
    UPROPERTY(VisibleAnywhere, Category = "Switch Components")         class USphereComponent* TriggerSphere;

    UPROPERTY()
    class ASpiderAIController* AIController;

    UPROPERTY()
    class APawn* PlayerPawn;
     
    UFUNCTION()
    void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

    
    //UFUNCTION()
    //void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

};

and the cpp:

#include "SpiderCharacter.h"
#include "Components/SphereComponent.h"
#include "SpiderAIController.h"
#include "Kismet/GameplayStatics.h"

// Sets default values
ASpiderCharacter::ASpiderCharacter()
{
    // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    TriggerSphere = CreateDefaultSubobject<USphereComponent>(TEXT("Trigger Sphere"));
    TriggerSphere->InitSphereRadius(105.0f);
    TriggerSphere->SetCollisionProfileName(TEXT("Trigger"));
    TriggerSphere->SetupAttachment(RootComponent);

    TriggerSphere->OnComponentBeginOverlap.AddDynamic(this, &ASpiderCharacter::OnOverlapBegin); 
    


    
}

// Called when the game starts or when spawned
void ASpiderCharacter::BeginPlay()
{
    Super::BeginPlay();
    AIController = Cast<ASpiderAIController>(GetController());
    PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
    //UE_LOG(LogTemp,Warning,TEXT("MyCharacter is %s"),  *PlayerPawn->GetName());
    
}

// Called every frame
void ASpiderCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void ASpiderCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

}

//Overlap Function
void ASpiderCharacter::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
    if (OtherActor && (OtherActor != this) && OtherComp) 
    {
        //get Location and Roation of PlayerCharacter
        //FVector PlayerPosition = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation();
        //FRotator PlayerRotation = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorRotation();
        FVector PlayerPosition = PlayerPawn->GetActorLocation();
        FRotator PlayerRotation = PlayerPawn->GetActorRotation();

        FVector NewLocation = FVector(PlayerPosition.X -500.f,PlayerPosition.Y - 500.f, PlayerPosition.Z);
        float Var = 100.f;

        SetActorRotation(PlayerRotation);
        AIController->WalkAway(NewLocation, Var);
        //SetActorLocation(NewLocation);

        
        UE_LOG(LogTemp,Warning,TEXT("MyCharacter's Location is %s"),  *OtherActor->GetName());
    }
} 

Upvotes: 1

Related Questions