Why am I receiving an access violation error when attaching a weapon to player?

Hello guys!

I have this code to attach a weapon to my main character:

AHavenWeapon::AHavenWeapon(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	weaponMesh = PCIP.CreateDefaultSubobject<UStaticMeshComponent>(this,TEXT("weaponMesh"));
	this->RootComponent = weaponMesh;

	
}

void AHavenWeapon::BeginPlay()
{
	ULocalPlayer *localPlayer = GEngine->GetGamePlayer(GetWorld(), 0);
	AHavenCharacter *character = (AHavenCharacter *)localPlayer;
	this->RootComponent->AttachParent = character->Mesh;
}

The problem is that as soon as I hit play, Visual Studio comes up and tells me there is an access violation somewhere in the attachment code.
Does anyone know why this doesnt work?

Well, could you fix your code to check for null values and then see if it still happens?

ULocalPlayer *localPlayer = GEngine->GetGamePlayer(GetWorld(), 0);
if(localPlayer){
    AHavenCharacter *character = (AHavenCharacter *)localPlayer;
    if(character){
        this->RootComponent->AttachParent = character->Mesh;
    }
}

Edit:
Also, you might want to try some of the internal methods for attaching objects to each other as they do many checks to ensure proper attachment. I think this “brute force” assignment might be a problem.

Try:

weaponMesh->AttachTo(..., ..., ...);

or something of the like and see if that works too.

I checked the null-values and they are all valid.
I also tried the method AttachTo, which gives me an error as well, just in another internal method(its also an access violation)

Please post the code from the error.

The breakpoint happens in the AttachTo-method of the USceneComponent in SceneComponent.cpp.
The code is:
void USceneComponent::AttachTo(class USceneComponent* Parent, FName InSocketName, EAttachLocation::Type AttachType /*= EAttachLocation::KeepRelativeOffset */)
{
if(Parent != NULL)
{
if(Parent == this)
{
FMessageLog(“PIE”).Warning(FText::Format(LOCTEXT(“AttachToSelfWarning”, “AttachTo: ‘{0}’ cannot be attached to itself. Aborting.”),
FText::FromString(GetPathName())));
return;
}

		if(Parent->IsAttachedTo(this))  //here visual studio breaks with an access violation
		{
			FMessageLog("PIE").Warning(FText::Format(LOCTEXT("AttachCycleWarning", "AttachTo: '{0}' already attached to '{1}', would form cycle. Aborting."), 
				FText::FromString(Parent->GetPathName()), 
				FText::FromString(GetPathName())));
			return;
		}

//here would be much other code...

Here is my updated code after trying some things:
enter code here
AHavenWeapon::AHavenWeapon(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
weaponMesh = PCIP.CreateDefaultSubobject(this,TEXT(“weaponMesh”));
this->RootComponent = weaponMesh;

}

void AHavenWeapon::BeginPlay()
{
	Super::BeginPlay();

	ULocalPlayer *localPlayer = GEngine->GetGamePlayer(GetWorld(), 0);
	AHavenCharacter *character = (AHavenCharacter *)localPlayer;
	//UE_LOG(LogTemp, Error, TEXT("BEGIN PLAYER C++"));
	weaponMesh->AttachTo(character->Mesh);
	//weaponMesh->AttachParent = character->Mesh;
	
	//weaponMesh->AttachSocketName = FName(TEXT("socket_hand_r"));
}

Looking forward to your answer :slight_smile:

I’m not sure, but I think that an Actor must be attached to a USceneComponent, not a Mesh.
Try creating a mount point using a USceneComponent in your character and then attach to it.

If it does not work, perhaps you could try using the AttachRootComponentTo (https://docs.unrealengine.com/latest/INT/API/RuntimeModules/Engine/GameFramework/AActor/AttachRootComponentTo/index.html). I’m using it and it works for me. It even has a EAttachLocation::Type parameter to define the offset after attached.

character->Mesh is a USkeletalMeshComponent which inherits from USceneComponent, so shouldnt be a problem there.
I get a problem no matter what function i call. Could it be that somehow the things arent initialized in BeginPlay()?

That’s right about the inheritance, my bad.

I removed my previous comment because it made no sense after I read your problem once again. I don’t think I can help you on this one.

Ok… I’m a bit stumped but I have a hunch.

You are getting the error when trying to reference the AHavenCharacter or Parent variable in the AttachTo method. Also, you are getting the error in the old code when you try to reference the character->mesh. I would think that there is some issue reading the character variable… in other words, trying to access the AHavenCharacter. I have never seen attaching done like this before so again… I’m a bit stumped.

I do have a suggestion though… and equipping things the way the developers of the engine do in their samples might be the way to go. Read on if you are interested in a test that might fix this issue and also help you learn a better way to equip items and weapons at the start of the game.

I’m sorry I don’t know why it’s currently causing the error for you. Another method of implementing the same thing is not a great fix but it might help =/

I think proper implementation of weapon equipping is needed here. If you have no desire to use this method of equipping items just ignore the rest of this post… but this is the way it’s done in all the examples and in 2 of my current projects. Not only is it extendable, but it works perfectly.

You are trying to start the game and have the AHavenWeapon attach itself to a AHavenCharacter you get by querying the UWorld and grabbing a reference to the first ULocalPlayer in the list of GamePlayers and then casting it to AHavenCharacter.

I know nothing of your implementation or other classes but I would suggest this…

Control your weapon attaching from your AHavenCharacter class…

To do this, in your AHavenCharacter class you create a variable that you will assign your weapon Blueprint to in the editor. Then, in your AHavenCharacter class you spawn that weapon from the class variable and assign it to a CurrentWeapon pointer variable. You then call a function in that CurrentWeapon to attach that weapon to yourself, the current AHavenCharacter. This seems to be the default way to equip weapons and it always seems to work.

Steps:

In your AHavenCharacter class header file, create a variable for the weapon class and the CurrentWeapon in the header file.

//  weapon class
UPROPERTY(EditDefaultsOnly, Category = Inventory)
class AHavenWeapon WeaponClass;

// weapon
UPROPERTY()
class AHavenWeapon* CurrentWeapon;

In your AHavenWeapon class create a method for attaching and call it whatever you want… I’ll call it TestAttachWeapon.

void AHavenWeapon::TestAttachWeapon(class AHavenCharacter* MyPawn){
    
    if(!MyPawn) return;
    
    weaponMesh->AttachTo(MyPawn->YOUR_MESH_COMPONENT_NAME);

}

So, now back to your AHavenCharacterClass. In the BeginPlay method…

void AHavenCharacter::BeginPlay(){
    Super::BeginPlay();
    // if WeaponClass not null
    if(WeaponClass){
        // Create some parameters for spawning
        FActorSpawnParameters SpawnInfo;
	SpawnInfo.bNoCollisionFail = true;
        // Spawn the weapon from the class
        CurrentWeapon = GetWorld()->SpawnActor<AHavenWeapon>(WeaponClass, SpawnInfo);
        // if CurrentWeapon not null [spawn successful]
        if(CurrentWeapon){
            // Attach it to myself
            CurrentWeapon->TestAttachWeapon(this);
        }
}

Again, to do this you will need a Blueprint of your AHavenCharacter and optionally your AHavenWeapon. You just create those Blueprints in the editor from the classes.

In the editor, you simply set the AHavenWeapon WeaponClass variable in the Default values of the Character blueprint.

Now, I have mine set up for a TArray of Weapons. You will have the “Inventory” tab, but you will only see one spot with a drop down to put your AHavenWeapon.

So what you do is select your AHavenWeapon class or AHavenWeapon Blueprint there and it will be used to spawn one in the game and attach it to your character.

Thank you very much! Got it working now. I still dont know why that my previous code did not work^^

I’m not sure either, I’m glad this worked for you though!

Hmmm, this method doesnt seem to work for me. I’m having serious trouble trying to create a Weapon class, unless thats a type and you meant function.
Im getting an error for trying to include the .generated.h file for the weapons class I created.
I think I found a typo:
class AHavenWeapon WeaponClass;
should be
class AHavenWeapon* WeaponClass;