This is the ABallCharacter.cpp
#include "BallCharacter.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/Controller.h"
#include "GunBaseActor.h"
#include "Components/SkeletalMeshComponent.h"
// Sets default values
ABallCharacter::ABallCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ABallCharacter::BeginPlay()
{
Super::BeginPlay();
PlayerController = GetController();
BallMesh = GetMesh();
GunSetupLeft(LeftGun);
GunSetupRight(RightGun);
}
void ABallCharacter::Shoot()
{
LeftGun->PullTrigger();
}
void ABallCharacter::UpdatePlayerPOV()
{
// Get Player Point Of View(POV) to be used for rotating pawn to face direction of player.
FVector POV_Location;
FRotator POV_Rotation;
PlayerController->GetPlayerViewPoint(POV_Location, POV_Rotation);
FRotator NewRotation = FRotator(GetActorRotation().Pitch, POV_Rotation.Yaw, GetActorRotation().Roll);
// Set the pawn to face the direction of player's POV'
SetActorRotation(FQuat(NewRotation));
}
void ABallCharacter::GunSetupLeft(AGunBaseActor* GunLeft)
{
if (GunLeftClass == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("There is no GunLeftClass!!"));
return;
}
GunLeft = GetWorld()->SpawnActor<AGunBaseActor>(GunLeftClass);
FAttachmentTransformRules GunLeftAttachmentRules = FAttachmentTransformRules(EAttachmentRule::KeepRelative, EAttachmentRule::KeepWorld, EAttachmentRule::KeepRelative, true);
GunLeft->AttachToActor(this, GunLeftAttachmentRules);
GunLeft->SetActorRelativeRotation(FRotator(0.0f, 90.0f, 0.0f) ,true);
GunLeft->SetActorRelativeLocation(FVector(12.0f, -35.0f, 0.0f), true);
MoveIgnoreActorAdd(GunLeft);
GunLeft->SetOwner(this);
}
void ABallCharacter::GunSetupRight(AGunBaseActor* GunRight)
{
if (GunRightClass == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("There is no GunRightClass!!"));
return;
}
GunRight = GetWorld()->SpawnActor<AGunBaseActor>(GunRightClass);
FAttachmentTransformRules GunRightAttachmentRules = FAttachmentTransformRules(EAttachmentRule::KeepRelative, EAttachmentRule::KeepWorld, EAttachmentRule::KeepRelative, true);
GunRight->AttachToActor(this, GunRightAttachmentRules);
GunRight->SetActorRelativeRotation(FRotator(0.0f, 90.0f, 0.0f) ,true);
GunRight->SetActorRelativeLocation(FVector(12.0f, 22.f, 0.0f), true);
MoveIgnoreActorAdd(GunRight);
GunRight->SetOwner(this);
}
Then I use a custom PlayerController to call the PullTrigger as shown below.
// Called to bind functionality to input
void ABallPlayerController::PushInputComponent(UInputComponent* PlayerInputComponent)
{
Super::PushInputComponent(PlayerInputComponent);
PlayerCharacter = Cast<ABallCharacter>(this->GetCharacter());
if (PlayerCharacter)
{
// Axis Bindings
PlayerInputComponent->BindAxis("MoveForward", PlayerCharacter, &ABallCharacter::BallMoveForward);
PlayerInputComponent->BindAxis("Strafe", PlayerCharacter, &ABallCharacter::BallStrafe);
// Action Bindings
PlayerInputComponent->BindAction("Jump", IE_Pressed, PlayerCharacter, &ABallCharacter::BallJump);
PlayerInputComponent->BindAction("Shoot", IE_Pressed, PlayerCharacter, &ABallCharacter::Shoot);
}
else
{
UE_LOG(LogTemp, Error, TEXT("Player Pawn is null!!"));
}
}
Then Finally the PullTrigger called from the AGunBaseActor.cpp
#include "GunBaseActor.h"
#include "Components/StaticMeshComponent.h"
#include "GameFramework/Controller.h"
// Sets default values
AGunBaseActor::AGunBaseActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SceneGunRoot = CreateDefaultSubobject<USceneComponent>(TEXT("Scene Gun Root"));
SetRootComponent(SceneGunRoot);
GunMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Gun Mesh"));
GunMesh->SetupAttachment(SceneGunRoot);
}
// Called when the game starts or when spawned
void AGunBaseActor::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AGunBaseActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AGunBaseActor::PullTrigger()
{
if (IsValid(GetOwner()))
{
GunOwner = Cast<APawn>(GetOwner());
OwningController = GunOwner->GetController();
FHitResult TraceResult;
FVector PlayerViewPointLocation;
FRotator PlayerViewPointRotation;
OwningController->GetPlayerViewPoint(PlayerViewPointLocation, PlayerViewPointRotation);
FVector TraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * ShootRange;
bool TraceSuccess = GetWorld()->LineTraceSingleByChannel(TraceResult, PlayerViewPointLocation, TraceEnd, ECollisionChannel::ECC_Visibility);
if (TraceSuccess)
{
UE_LOG(LogTemp, Warning, TEXT("Line was traced!!"));
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("There is no valid gun owner!!!"));
}
}
The moment I hit the Left Mouse Button, it crashes with this message.
LoginId:
EpicAccountId:
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x000000e8
UE4Editor_Test_4600!AGunBaseActor::PullTrigger() >[D:\UnrealProjects\Test\Source\Test\GunBaseActor.cpp:37]
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