Hello,
I am receiving the following error after I am adding this line to my code:
ProjectileMesh->OnComponentHit.AddDynamic(this, &AProjectile::OnHit);
Compiles without error, crashes on Play:
Assertion failed: DelegateOwner->IsValidLowLevelFast(false) [File:D:\Epic Games\UE_4.27\Engine\Source\Runtime\CoreUObject\Public\UObject/SparseDelegate.h] [Line: 196]
UE4Editor_Core
UE4Editor_Core
UE4Editor_ToonTanks_8830!AProjectile::BeginPlay() [D:\repos\Unreal\ToonTanks\Source\ToonTanks\Projectile.cpp:25]
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_ToonTanks_8830!ABasePawn::Fire() [D:\repos\Unreal\ToonTanks\Source\ToonTanks\BasePawn.cpp:34]
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
UE4Editor
kernel32
ntdll
I have tried deleting Binaries, Saved, Intermediate folders and generate project again (as advised here Assertion failed: DelegateOwner->IsValidLowLevelFast(false)), but it does not work unfortunately. Any ideas how to overcome this?
Projectile.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Projectile.generated.h"
UCLASS()
class TOONTANKS_API AProjectile : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AProjectile();
float ProjectileInitialSpeed = 100.f;
float ProjectileMaxSpeed = 200.f;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
private:
UPROPERTY(EditDefaultsOnly, Category= "Combat")
UStaticMeshComponent* ProjectileMesh;
UPROPERTY(VisibleAnywhere, Category= "Combat")
UProjectileMovementComponent* ProjectileMovementComponent;
UFUNCTION()
void OnHit(UPrimitiveComponent* HitComp,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
FVector NormalImpulse,
const FHitResult& Hit);
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
Projectile.cpp:
// Fill out your copyright notice in the Description page of Project Settings.
#include "Projectile.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
AProjectile::AProjectile()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
ProjectileMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Projectile Mesh"));
RootComponent = ProjectileMesh;
ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("Projectile movement comp"));
ProjectileMovementComponent->InitialSpeed = ProjectileInitialSpeed;
ProjectileMovementComponent->MaxSpeed = ProjectileMaxSpeed;
}
// Called when the game starts or when spawned
void AProjectile::BeginPlay()
{
Super::BeginPlay();
ProjectileMesh->OnComponentHit.AddDynamic(this, &AProjectile::OnHit);
}
void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
FVector NormalImpulse, const FHitResult& Hit)
{
UE_LOG(LogTemp, Warning, TEXT("OnHit"));
}
// Called every frame
void AProjectile::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
BasePawn.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "BasePawn.generated.h"
UCLASS()
class TOONTANKS_API ABasePawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ABasePawn();
protected:
void RotateTurret(FVector LookAtTarget);
virtual void Fire();
private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
class UCapsuleComponent* CapsuleComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
UStaticMeshComponent* BaseMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
UStaticMeshComponent* TurretMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
USceneComponent* ProjectileSpawnPoint;
UPROPERTY(EditDefaultsOnly, Category = "Combat")
TSubclassOf<class AProjectile> ProjectileClass;
};
BasePawn.cpp:
// Fill out your copyright notice in the Description page of Project Settings.
#include "BasePawn.h"
#include "Projectile.h"
#include "Components/CapsuleComponent.h"
// Sets default values
ABasePawn::ABasePawn()
{
// 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;
CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Collider"));
RootComponent = CapsuleComp;
BaseMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Base mesh"));
BaseMesh->SetupAttachment(CapsuleComp);
TurretMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Turret mesh"));
TurretMesh->SetupAttachment(BaseMesh);
ProjectileSpawnPoint = CreateDefaultSubobject<USceneComponent>(TEXT("Projectile spawn point"));
ProjectileSpawnPoint->SetupAttachment(TurretMesh);
}
void ABasePawn::RotateTurret(FVector LookAtTarget)
{
FVector ToTarget = LookAtTarget - TurretMesh->GetComponentLocation();
FRotator LookAtRotation = FRotator(0.f, ToTarget.Rotation().Yaw, 0.f);
TurretMesh->SetWorldRotation(LookAtRotation);
}
void ABasePawn::Fire()
{
GetWorld()->SpawnActor<AProjectile>(
ProjectileClass,
ProjectileSpawnPoint->GetComponentLocation(),
ProjectileSpawnPoint->GetComponentRotation());
}