Crash for no reason | C++

So i have an interface for a character and MagicComponent, and when i using spells way this component for first 1-2 minutes all works good, but ater it it’s going to crash on the line with if(!==nullptr) check, interface header is included, and Owner have this component


i have a crash on line 61
and the crash screen

If it does not work could you post your .cpp file?
Instead of:

if (GetOwner())
{
   YourInterface->StartCasting();
}

I’d use:

if (YourInterface)
{
   IINF_MainChar::Execute_StartCasting(GetOwner);
}

I still have a crash on if(YourInterface), and cant upload a cpp file(because im a new user),

// Fill out your copyright notice in the Description page of Project Settings.


#include "MagicComponent.h"
#include "Spells_Base.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/Controller.h"
#include "UW_BlastCast.h"
#include "TimerManager.h"
#include "INF_MainChar.h"

// Sets default values for this component's properties
UMagicComponent::UMagicComponent()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;
	// ...
}

void UMagicComponent::ChangeSpell(TSubclassOf<class ASpells_Base> NewSpell)
{
	if(!bCanDoMagic) return;
	UE_LOG(LogTemp, Warning, TEXT("Before destroying CurrentSpell"));
	CurrentSpellClass = NewSpell;
if (CurrentSpell != nullptr)
{
    CurrentSpell->ConditionalBeginDestroy();
	CurrentSpell = nullptr;
}
CurrentSpell = NewObject<ASpells_Base>(this, CurrentSpellClass, NAME_None, RF_NoFlags, nullptr);
if(CurrentSpell)
{
	UE_LOG(LogTemp, Warning, TEXT("Spell changed to %s"),*CurrentSpell->SpellName);
}
}

void UMagicComponent::UseSpell()
{
	if(!bCanDoMagic || !GetOwner()|| !CurrentSpell || !CurrentSpellClass || 
	!GetOwner()->GetClass()->ImplementsInterface(UINF_MainChar::StaticClass()) || !Cast<IINF_MainChar>(GetOwner()))  return;
	if(!CurrentSpell->bNeedCast){
	   ASpells_Base* SpawnedSpell=GetWorld()->SpawnActor<ASpells_Base>(CurrentSpellClass);
	   SpawnedSpell->SetOwner(GetOwner());
	   SpawnedSpell->Activate();
	}
	else
	{
      UseSpellWithCast();
	}	
}

void UMagicComponent::UseSpellWithCast()
{
	IINF_MainChar* YourInterface = Cast<IINF_MainChar>(GetOwner());
	GetWorld()->GetTimerManager().SetTimer(MyTimerHandle, this, &UMagicComponent::Casting, 2.0f, false);
      if(CastWidget)
	  {
      CastWidget->AddToViewport();
	  }
      if(YourInterface) // i have a crash here, i tried with if(YourInterface) and if(Cast<IINF_MainChar>(GetOwner())) 
	  {// and if(GetOwner()->GetClass()->ImplementsInterface(UINF_MainChar::StaticClass())
		YourInterface->StartCasting();
	  }
	bCanDoMagic=false;
}

FString UMagicComponent::GetSpellName()
{
	if (CurrentSpell && !CurrentSpell->SpellName.IsEmpty())
    {
        return CurrentSpell->SpellName;
    }
	else if(!CurrentSpell->SpellName.IsEmpty())
	{
		return TEXT("you have only the spell name");
	}
	return TEXT("No Spell");
}

void UMagicComponent::Casting()
{
	bCanDoMagic=true;
	Cast<IINF_MainChar>(GetOwner())->EndCasting();
	GetWorld()->GetTimerManager().ClearTimer(MyTimerHandle);
	ASpells_Base* SpawnedSpell=GetWorld()->SpawnActor<ASpells_Base>(CurrentSpellClass);
	SpawnedSpell->SetOwner(GetOwner());
	SpawnedSpell->Activate();
}

// Called when the game starts
void UMagicComponent::BeginPlay()
{
	Super::BeginPlay();
	CurrentSpellClass = FirstSpellClass;
	//innit Cast widget to game
	if(SpellCastWidget)
	{
    UE_LOG(LogTemp, Warning, TEXT("SpellCastWidget"));
    CastWidget = CreateWidget(UGameplayStatics::GetPlayerController(GetWorld(),0),SpellCastWidget);
	}
	//adding spell to scene
	if(CurrentSpellClass)
	{
	CurrentSpell = NewObject<ASpells_Base>(this, CurrentSpellClass, NAME_None, RF_NoFlags, nullptr);
	}
	//getting owner
	if(GetOwner())
	CompOwner = Cast<IINF_MainChar>(GetOwner());
}


// Called every frame
void UMagicComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	// ...
}



Interface cant be UPROPERTY, and yes, was running this code(

the MagicComponent wherever it is attach to should be macro’ed as a UPROPERTY in it’s parent so it’s not garbage collected.

UPROPERTY(VisibleAnywhere)
class UMagicComponent* Magic;
in owner Class

Could you post your .h file too ( just post as text is better )?
It doesn’t make sense, the stacktrace shows line 51 and 61, there is no code in line 51, it’s just “}” like an old code.

try


void UMagicComponent::UseSpellWithCast()
{
if(GetOwner() != nullptr)
{
	if (GetOwner()->GetClass()->ImplementsInterface(UINF_MainChar::StaticClass())) {	
		GetWorld()->GetTimerManager().SetTimer(MyTimerHandle, this, &UMagicComponent::Casting, 2.0f, false);
		if(CastWidget != nullptr)
		{
			CastWidget->AddToViewport();
		}	  
		IINF_MainChar::Execute_StartCasting(GetOwner());
		bCanDoMagic=false;
	}
}
}
1 Like

i cant understand it too)
this is header
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

include “CoreMinimal.h”
include “Components/ActorComponent.h”
include “MagicComponent.generated.h”

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT2_API UMagicComponent : public UActorComponent
{
GENERATED_BODY()

public:
// Sets default values for this component’s properties
UMagicComponent();

void UseSpell();
void UseSpellWithCast();
UFUNCTION(BlueprintCallable)
void ChangeSpell(TSubclassOf<class ASpells_Base> NewSpell);
FString GetSpellName();

bool bCanDoMagic=true;

class UUserWidget* CastWidget;
UPROPERTY(EditAnywhere)
TSubclassOf<class UUserWidget> SpellCastWidget;
FTimerHandle MyTimerHandle;
void Casting();

class IINF_MainChar* CompOwner;

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

public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

UPROPERTY(EditAnywhere)
TSubclassOf<class ASpells_Base> MagicImpulseClass;
UPROPERTY(EditAnywhere)
TSubclassOf<class ASpells_Base> MagicBlastClass;

UPROPERTY()
class ASpells_Base* CurrentSpell;

private:

UPROPERTY(EditAnywhere)
TSubclassOf FirstSpellClass;

TSubclassOf CurrentSpellClass;

};

Also take into account that casts actually return a bool if they are working or if they fail

So even if you go with you old code you can do


if(IINF_MainChar* YourInterface = Cast<IINF_MainChar>(GetOwner()))
{
///... rest of the code only works if cast is ok :)

}


tried that too)

i tried with if(YourInterface) and if(Cast<IINF_MainChar>(GetOwner()))
and if(GetOwner()->GetClass()->ImplementsInterface(UINF_MainChar::StaticClass())
and if(IINF_MainChar* YourInterface = Cast<IINF_MainChar>(GetOwner())),all the ways of “if” check i tried

Try this code:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

include "CoreMinimal.h"
include "Components/ActorComponent.h"
include "MagicComponent.generated.h"

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT2_API UMagicComponent : public UActorComponent
{
	GENERATED_BODY()

	public:
		UMagicComponent();
		
		virtual void BeginPlay() override;
		virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

		void UseSpell();
		void UseSpellWithCast();

		FString GetSpellName();
		void Casting();
		
		UFUNCTION(BlueprintCallable)
		void ChangeSpell(TSubclassOf<class ASpells_Base> NewSpell);

	public:
		UPROPERTY(EditAnywhere)
		TSubclassOf<class ASpells_Base> MagicImpulseClass;

		UPROPERTY(EditAnywhere)
		TSubclassOf<class ASpells_Base> MagicBlastClass;

		UPROPERTY()
		TObjectPtr<ASpells_Base> CurrentSpell;

		UPROPERTY(EditAnywhere)	
		TObjectPtr<UUserWidget> CastWidget;

		UPROPERTY(EditAnywhere)
		TSubclassOf<class UUserWidget> SpellCastWidget;

		UPROPERTY()
		TScriptInterface<IINF_MainChar> CompOwner;
		
		FTimerHandle MyTimerHandle;
		bool bCanDoMagic=true;

	private:
		UPROPERTY(EditAnywhere)
		TSubclassOf FirstSpellClass;

		UPROPERTY()
		TSubclassOf CurrentSpellClass;

};

To use TScriptInterface<>:
https://isaratech.com/ue4-declaring-and-using-interfaces-in-c/

If it still doesn’t work:

  • Restart the editor
  • Delete your Character Blueprint, restart the Editor and create it again.

CastTest.zip (38.7 KB)

Rewrote part of your project to use interfaces in full.

OK, thank you guys, i cant try it now(00:00 on the watch), i will try it tomorrow, and will give feedback, TY

still crashing, added Execute system for interfaces, and UPROPERTY(BlueprintNativeEvent), i have a problem with if() check

crash screen

Clear your project cache

  • intermediate folder
  • derived data cache
  • binaries
  • .vs
    .vsconfig
    you sln file
    and regenerate your project. You must have some bad cache causing errors. The code I sent works

did all of it, and still have a crash :neutral_face:
even reinstalling of the UE didnt help(
i deleted line 61 and stiil have crash on this line

In what situation are you calling the UseSpellWithCast() ?
Could it be that the character is being destroyed during the call an is maybe no longer valid while checking the interface?