Raenerys
(Raenerys_)
December 18, 2023, 3:52pm
1
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
SolidSk
(SolidSk)
December 18, 2023, 6:06pm
2
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);
}
Raenerys
(Raenerys_)
December 18, 2023, 7:43pm
4
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);
// ...
}
Raenerys
(Raenerys_)
December 18, 2023, 8:26pm
6
Interface cant be UPROPERTY, and yes, was running this code(
3dRaven
(3dRaven)
December 18, 2023, 8:31pm
7
Raenerys_:
MagicComponent
the MagicComponent wherever it is attach to should be macro’ed as a UPROPERTY in it’s parent so it’s not garbage collected.
Raenerys
(Raenerys_)
December 18, 2023, 8:39pm
8
UPROPERTY(VisibleAnywhere)
class UMagicComponent* Magic;
in owner Class
SolidSk
(SolidSk)
December 18, 2023, 8:45pm
9
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.
3dRaven
(3dRaven)
December 18, 2023, 8:51pm
10
SolidSk:
::Execute_
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
Raenerys
(Raenerys_)
December 18, 2023, 8:54pm
11
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;
};
3dRaven
(3dRaven)
December 18, 2023, 8:58pm
12
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 :)
}
Raenerys
(Raenerys_)
December 18, 2023, 9:02pm
14
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
SolidSk
(SolidSk)
December 18, 2023, 9:04pm
15
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.
3dRaven
(3dRaven)
December 18, 2023, 9:43pm
16
CastTest.zip (38.7 KB)
Rewrote part of your project to use interfaces in full.
Raenerys
(Raenerys_)
December 18, 2023, 9:50pm
17
OK, thank you guys, i cant try it now(00:00 on the watch), i will try it tomorrow, and will give feedback, TY
Raenerys
(Raenerys_)
December 19, 2023, 9:15am
18
still crashing, added Execute system for interfaces, and UPROPERTY(BlueprintNativeEvent), i have a problem with if() check
Raenerys
(Raenerys_)
December 19, 2023, 7:46pm
21
did all of it, and still have a crash
even reinstalling of the UE didnt help(
i deleted line 61 and stiil have crash on this line
3dRaven
(3dRaven)
December 19, 2023, 7:56pm
22
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?