Download

Editor Crashing on cast to gamestate while trying to retrieve my item datatable.

I am trying to add my item to an inventory array which is a variable on an actor component. Everything works here except when I try and cast to the gamestate from my inventory component, the editor crashes. What is weird to me is that it doesnt crash from within the Item class when I am retrieving the meshes and such.
Also wondering if it is ok to create a function that returns my struct in the way that I did?

PicOne
pictwo
picthree

That Cast can’t crash unless GetWorld is failing. Are you sure ItemDBData isn’t null? Try adding a check(ItemDBData); before you use it.

1 Like

Yes, I believe you were right, I got that working but I am still having trouble adding to the array of structures. I have been using the debug mode to find what is going wrong but I have had no luck so far. The editor crashes anytime I use the Inventory.Add(). very weird considering everyone else seems to do it the same way.
Edit- to get a world pointer it has to be from the owner of the component because it needs a transform, this is what i understand based on my research.

Is it maybe because im missing something in regards to initializing the Inventory Array because I am doing the .add function within an actor component? The Item is getting the meshes from the datatable fine but when I run the additem function the Inventory.Add() causes the debug to say : Access violation reading location

Item -

// Called when the game starts or when spawned
void AMItem::BeginPlay()
{
	Super::BeginPlay();

	SetInfo();
}

UWorld* AMItem::GetItemWorld()
{
	return this->GetWorld();
}

AMGameGameModeBase* AMItem::GetMyGameMode()
{
	return Cast<AMGameGameModeBase>(GetItemWorld()->GetAuthGameMode());
}

FName AMItem::GetName()
{
	return ID;
}

void AMItem::SetInfo()
{
	AMGameGameModeBase* GameMode = GetMyGameMode();
	bool Found = false;
	FItem ItemFound = GameMode->FindItem(ID, Found);
	if (Found)
	{
		SkeletalMeshComponent->SetSkeletalMesh(ItemFound.Mesh.SkeletalMesh);
		StaticMeshComponent->SetStaticMesh(ItemFound.Mesh.StaticMesh);
	}
}

void AMItem::Interact_Implementation(AActor* Caller)
{
	InventoryComponent->AddItem(GetName(), this);
}

Inventory Component
add item -

void UMInventoryComponent::AddItem(FName ItemID, AMItem* Item)
{
	AMGameGameModeBase* GameMode = Item->GetMyGameMode();
	bool bItemFound = false;
	FItem ItemFound = GameMode->FindItem(Item->ID, bItemFound);
	if (bItemFound)
	{
		FItem NewItem;
		NewItem.ID = Item->ID;
		NewItem.Quantity = ItemFound.Quantity;
		NewItem.MainParameters.Abbreviation = ItemFound.MainParameters.Abbreviation;
		NewItem.MainParameters.EquipType = ItemFound.MainParameters.EquipType;
		NewItem.MainParameters.InspectImage = ItemFound.MainParameters.InspectImage;
		NewItem.MainParameters.InventoryImage = ItemFound.MainParameters.InventoryImage;
		NewItem.MainParameters.IsUsable = ItemFound.MainParameters.IsUsable;
		NewItem.MainParameters.Name = ItemFound.MainParameters.Name;
		NewItem.MainParameters.SizeX = ItemFound.MainParameters.SizeX;
		NewItem.MainParameters.SizeY = ItemFound.MainParameters.SizeY;
		NewItem.MainParameters.StackSize = ItemFound.MainParameters.StackSize;
		NewItem.MainParameters.UseType = ItemFound.MainParameters.UseType;
		NewItem.Mesh.SkeletalMesh = ItemFound.Mesh.SkeletalMesh;
		NewItem.Mesh.StaticMesh = ItemFound.Mesh.StaticMesh;
		

		Inventory.Add(NewItem);

		//Inventory.Add(NewItem);
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor(255, 255, 255), "SetInfo");
	}

}

What is Inventory? you access it, but there’s nowhere that you show that it’s being assigned to anything.

in inventory component header

	// Equipment inventory on UI and hands
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inventory")
		TArray<FItem> Inventory;

and what does the crash stack trace look like?

This is the crash

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x00000000000000c0

UE4Editor_MGame_0063!UMInventoryComponent::AddItem() [c:\users\dhaoh\documents\unreal projects\mgame\source\mgame\minventorycomponent.cpp:49]
UE4Editor_MGame_0063!AMItem::Interact_Implementation() [c:\users\dhaoh\documents\unreal projects\mgame\source\mgame\mitem.cpp:69]
UE4Editor_MGame_0063!AMItem::execInteract() [c:\users\dhaoh\documents\unreal projects\mgame\intermediate\build\win64\ue4editor\inc\mgame\mitem.gen.cpp:64]
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_Engine
UE4Editor_MGame_0063!IInteract::Execute_Interact() [c:\users\dhaoh\documents\unreal projects\mgame\intermediate\build\win64\ue4editor\inc\mgame\interact.gen.cpp:146]
UE4Editor_MGame_0063!AMCharacter::OnInteract() [c:\users\dhaoh\documents\unreal projects\mgame\source\mgame\mcharacter.cpp:106]
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

and this is what I see from the debugger

In the debugger it shows that new item is a FItem and has all the values, so im so lost as to why it just wont work.
I also added a watch to the .add part and this is what it says. idk if this is the problem.

InventoryComponent is null.

Am I constructing it incorrectly?

InventoryComponent = CreateDefaultSubobject<UMInventoryComponent>(TEXT("InventoryComponent"));
	UPROPERTY(VisibleAnywhere, Category = Inventory)
		UMInventoryComponent* InventoryComponent;

Or am i missing doing something?

component header

UCLASS( ClassGroup=(Inventory), meta=(BlueprintSpawnableComponent) )
class MGAME_API UMInventoryComponent : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UMInventoryComponent();

	UFUNCTION(BlueprintCallable)
		void AddItem(FName ItemID, AMItem* Item);

	// Equipment inventory
	UPROPERTY(EditAnywhere)
		TArray<FItem> Inventory;

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

cpp

// Sets default values for this component's properties
UMInventoryComponent::UMInventoryComponent()
{

}

// Called when the game starts
void UMInventoryComponent::BeginPlay()
{
	Super::BeginPlay();

}

void UMInventoryComponent::AddItem(FName ItemID, AMItem* Item)
{
	AMGameGameModeBase* GameMode = Item->GetMyGameMode();
	bool bItemFound = false;
	FItem ItemFound = GameMode->FindItem(Item->ID, bItemFound);
	if (bItemFound == true)
	{
		FItem NewItem;
		NewItem.ID = Item->ID;
		NewItem.Quantity = ItemFound.Quantity;
		NewItem.MainParameters.Abbreviation = ItemFound.MainParameters.Abbreviation;
		NewItem.MainParameters.EquipType = ItemFound.MainParameters.EquipType;
		NewItem.MainParameters.InspectImage = ItemFound.MainParameters.InspectImage;
		NewItem.MainParameters.InventoryImage = ItemFound.MainParameters.InventoryImage;
		NewItem.MainParameters.IsUsable = ItemFound.MainParameters.IsUsable;
		NewItem.MainParameters.Name = ItemFound.MainParameters.Name;
		NewItem.MainParameters.SizeX = ItemFound.MainParameters.SizeX;
		NewItem.MainParameters.SizeY = ItemFound.MainParameters.SizeY;
		NewItem.MainParameters.StackSize = ItemFound.MainParameters.StackSize;
		NewItem.MainParameters.UseType = ItemFound.MainParameters.UseType;
		NewItem.Mesh.SkeletalMesh = ItemFound.Mesh.SkeletalMesh;
		NewItem.Mesh.StaticMesh = ItemFound.Mesh.StaticMesh;
		
		Inventory.Add(NewItem);
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor(255, 255, 255), "ADD ITEM");
	}
}

Your previous code used the variable as InventoryComponent, not MInventoryComponent. Do you have it declared twice?

no once on the item

	UPROPERTY()
		class UMInventoryComponent* InventoryComponent;

and on character

	UPROPERTY(VisibleAnywhere, Category = Inventory)
		UMInventoryComponent* InventoryComponent;

ill change the code in examples to have what i have. i was changing the names and left that sorry for confusion.

Also when i run the additem function with the inventory.add commented out the addonscreendebug works fine.

Do you construct it on character or on item? And how is it given from one to the other? This is hard to understand one small code fragment at a time

Yes I agree, I uploaded the source to git here. Thank you all for the responses! GitHub - rmuar/MGame: testingThings

the inventory component is on the character

Like I said, nothing sets the value of AMItem::InventoryComponent, it is null.

DUHHHHHH, You were so right!!! Thank you so much, this fixed it

	AMCharacter* PlayerCharacter = Cast<AMCharacter>(Caller);

	AMGameGameModeBase* GameMode = GetMyGameMode();
	bool Found = false;
	FItem ItemFound = GameMode->FindItem(ID, Found);
	if (Found)
	{
		PlayerCharacter->InventoryComponent->AddItem(ItemFound.ID, this);
	}

Thank you!