How to return FHitResult in Unreal Engine - c++

I created Action Mapping function for my Character Blueprint in UE4 with C++ and decided to call it on Blueprints, but i need to return FHitResult value to continue. I can't use return since C++ does not allow to return value that differs from functions type so i don't know what to do.
void AMeCharacter::Interact() {
FHitResult OutHit;
FVector Start = Camera->GetComponentLocation();
// alternatively you can get the camera location
// FVector Start = FirstPersonCameraComponent->GetComponentLocation();
FVector ForwardVector = Camera->GetForwardVector();
FVector End = ((ForwardVector * 150.f) + Start);
FCollisionQueryParams CollisionParams;
DrawDebugLine(GetWorld(), Start, End, FColor::Red, false, 3, 0.5);
bool bHit = GetWorld()->LineTraceSingleByChannel(OutHit, Start, End, ECC_Visibility, CollisionParams);
if (bHit)
{
if (!OutHit.GetActor())
return;
if (OutHit.GetActor()->GetClass()->ImplementsInterface(UInteractionInterface::StaticClass())) {
UE_LOG(LogTemp, Warning, TEXT("%s"), *OutHit.GetActor()->GetName());
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Implements Interface"));
}
else
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Doesn't implement interface"));
//IInteractionInterface* Interface = Cast<IInteractionInterface>(OutHit.GetActor());
//if (Interface) {
// Interface->OnInteracted();
//}
}
}

Related

[UE4][C++] How to access CharacterMovementComponent into ChildClass to implement Charge-Jump Logic?

First of all, I'd like to thank all of you for clicking on this question.
I am a beginner who has just started studying Unreal Engine C++.
and I ask for your generous understanding that the quality is poor because it is the first question left in the community.
My final goal is to implement the Charge-Jump Logic in UE5 without using ACharacter::Jump() and ACharacter::StopJump(). because my game needs logic that the character stays still until the gauge is charged, and the character moves when the gauge is charged as much as the player wants.
The Jump Gauge, Gauge Reset, and Logic call works fine, but ACharacter::LaunchCharacter does not work. I was looking for a way to make LaunchCharacter work, so I was trying to figure out about CharacterMovement, but this was beyond me. I didn't have access to the CharacterMovement and I don't even understand what the functional form of this is.
**So, What I want to ask you is
How to access the trigger of ACharacter::LaunchCharacter, CharacterMovement.
If I can't use LaunchCharacter, what is another way to give the character ZVelocity to jump momentarily?**
```
// This is My ChargeJump-Logic, Not Same bPressedJump between sPressdJump.
void ASlime::ChargeJump()
{
UE_LOG(LogTemp, Display, TEXT("JUMPBUTTON IS PUSHED"));
JumpCharge = 0.0f;
sPressedJump = true;
}
void ASlime::JumpGaugeCharge(float DeltaTime)
{
JumpCharge = 0.0f;
if (sPressedJump)
{
JumpChargeTime += DeltaTime;
JumpCharge = minJumpVelocity + JumpChargeTime / GaugeChargeSpeed;
UE_LOG(LogTemp, Display, TEXT("JUMPGAUGE NOW CHARGING... :: %02f"),JumpCharge);
if (JumpCharge >= maxJumpVelocity)
{
JumpCharge = maxJumpVelocity;
sPressedJump = false;
}
}
}
void ASlime::LaunchSlime()
{
UE_LOG(LogTemp, Display, TEXT("SLIME LAUNCH!!"), JumpCharge);
const FVector ForwardDir = GetRootComponent()->GetForwardVector();
FVector launchVelocity = ForwardDir * FVector(0, 0, 1) * JumpCharge* GetCharacterMovement()->JumpZVelocity;
LaunchCharacter(launchVelocity, false, true);
JumpStateReset(JumpCharge);
}
void ASlime::JumpStateReset(float Delta)
{
Delta = 0.0f;
JumpChargeTime = 0.0f;
sPressedJump = false;
}
```
```
// This is the function built into the Unreal Engine API, called ACharacter::LaunchCharacter.
void ACharacter::LaunchCharacter(FVector LaunchVelocity, bool bXYOverride, bool bZOverride)
{
UE_LOG(LogCharacter, Verbose, TEXT("ACharacter::LaunchCharacter '%s' (%f,%f,%f)"), *GetName(), LaunchVelocity.X, LaunchVelocity.Y, LaunchVelocity.Z);
if (CharacterMovement)
{
FVector FinalVel = LaunchVelocity;
const FVector Velocity = GetVelocity();
if (!bXYOverride)
{
FinalVel.X += Velocity.X;
FinalVel.Y += Velocity.Y;
}
if (!bZOverride)
{
FinalVel.Z += Velocity.Z;
}
CharacterMovement->Launch(FinalVel);
OnLaunched(LaunchVelocity, bXYOverride, bZOverride);
}
}
```

unreal engine C++ / Calculate Movement Angle from projectile

I want to Calculate the Movement Angle an NOT the Rotation from an Moving Actor (to be specific = from a Bullet). First of, I´ve got the Location of the Actor and the Location one Frame before, then calculating the distance between them with FVector::Dist... After that I got the height difference between the current and last Location. Then the A-Tangents from these two variables. I put all these Variables into a Raycast.
When I shoot the Actor forwards it looks good;
Straight
but when I shoot the Bullet up, the Raycast gets messed up:
UP
CODE:
`void ABullet::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (Counter == true)
{
FVector TraceLoc = GetActorLocation();
FRotator TraceRot = GetActorRotation() + FRotator(0.f, 90.f, 0.f);
float Distance = FVector::Dist(LastActorLoc, TraceLoc);
heightdiff = TraceLoc.Z - LastActorLoc.Z;
TraceRot.Pitch = (atan(heightdiff / Distance)) * (180.f / 3.141592f);
UE_LOG(LogTemp, Warning, TEXT("Out: %f"), TraceRot.Pitch);
FVector Start = TraceLoc;
FVector End = Start + (TraceRot.Vector() * Distance);
LastActorLoc = TraceLoc;
LastActorRot = TraceRot;
FCollisionQueryParams TraceParamsBullet;
bool bHitBullet = GetWorld()->LineTraceSingleByChannel(TraceHitResultBullet, Start, End, ECC_Visibility, TraceParamsBullet);
DrawDebugLine(GetWorld(), Start, End, FColor::Red, false, 15.f, 30.f);
}
if (Counter == false)
{
Counter = true;
LastActorLoc = GetActorLocation();
LastActorRot = GetActorRotation() + FRotator(0.f, 90.f, 0.f);
}
}`

EXCEPTION_ACCESS_VIOLATION when using RandomPointInBoundingBox method of KismetLibrary

I am facing an issue while generating a random point in a volume using KismetLibrary,
there is the code
#include "Spawner.h"
#include "Components/BoxComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "BaseCell.h"
// Sets default values
ASpawner::ASpawner()
{
// 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;
SpawningVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("SpawnVolumeBox"));
RootComponent = SpawningVolume;
Cell = ABaseCell::StaticClass();
}
// Called when the game starts or when spawned
void ASpawner::BeginPlay()
{
Super::BeginPlay();
SpawnCells();
}
// Called every frame
void ASpawner::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ASpawner::SpawnCells()
{
if(Cell != NULL)
{
UWorld* const World = GetWorld();
if (World) {
FVector Origin = SpawningVolume->Bounds.Origin;
FVector Extent = SpawningVolume->Bounds.BoxExtent;
FVector SpawnLocation = UKismetMathLibrary::RandomPointInBoundingBox(Origin, Extent);
FRotator SpawnRotation;
SpawnRotation.Pitch = FMath::FRand() * 360.0f;
SpawnRotation.Roll = FMath::FRand() * 360.0f;
SpawnRotation.Yaw = FMath::FRand() * 360.0f;
ABaseCell* SpawnedCell = World->SpawnActor<ABaseCell>(Cell, SpawnLocation, SpawnRotation);
}
}
}
I should be able to generate without using Kismet the random point but i thought if this kind of library exists we should use them...
it's throwing the following error: https://i.stack.imgur.com/6nG45.png
EDIT
when trying to debug i figured that actually it's when i'm accessing private property "SpawningVolume" that error is thrown... still can't figure why
here is the Spawner.h
#include "BaseCell.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Spawner.generated.h"
UCLASS()
class LIFE_API ASpawner : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ASpawner();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Spawnable
UPROPERTY(EditAnyWhere, category="Spawning")
TSubclassOf<class ABaseCell> Cell;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
private:
// SpawningVolume as BoxComponent
UPROPERTY(VisibleAnyWhere, category="Spawning", meta=(AllowPrivateAccess="true"))
class UBoxComponent* SpawningVolume;
void SpawnCells();
};
EDIT 2
Just added this condition and it seems that "SpawningVolume" is "nullptr" so i don't know what i'm doing wrong but i keep investigating
void ASpawner::SpawnCells()
{
if(Cell != NULL)
{
UWorld* const World = GetWorld();
if (World) {
// Added condition
if (SpawningVolume != nullptr) {
FVector Origin = SpawningVolume->Bounds.Origin;
FVector Extent = SpawningVolume->Bounds.BoxExtent;
FVector SpawnLocation = UKismetMathLibrary::RandomPointInBoundingBox(Origin, Extent);
FRotator SpawnRotation;
SpawnRotation.Pitch = FMath::FRand() * 360.0f;
SpawnRotation.Roll = FMath::FRand() * 360.0f;
SpawnRotation.Yaw = FMath::FRand() * 360.0f;
ABaseCell* SpawnedCell = World->SpawnActor<ABaseCell>(Cell, SpawnLocation, SpawnRotation);
}
}
}
}
ERROR
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x000000000000012c
UE4Editor_Life_0001!ASpawner::SpawnCells() [C:\Users\Benja\OneDrive\Documents\Unreal Projects\Life\Source\Life\Spawner.cpp:46]

UE4 C++: Can't move Actor in circular path

I am using Unreal Engine 4.25. I am trying to move an Actor, which is a sphere, in a circular path. However the sphere only moves back and forth in a straight line.
Here is MyActor.cpp code:
#include "MyActor.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
AMyActor::AMyActor()
{
// 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;
Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
RootComponent = Root;
Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
Mesh->AttachTo(Root);
Dimensions = FVector(30, 0, 0);
AxisVector = FVector(0.01, 0.01, 0);
Location = FVector(0.1, 0.1, 0.1);
Multiplier = 50.f;
}
// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AMyActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Updates the angle of the object
AngleAxis += DeltaTime * Multiplier;
if (AngleAxis >= 360.0f)
{
AngleAxis = 0;
}
//Rotates around axis
FVector RotateValue = Dimensions.RotateAngleAxis(AngleAxis, AxisVector);
Location.X += RotateValue.X;
Location.Y += RotateValue.Y;
Location.Z += RotateValue.Z;
SetActorLocation(Location, false, 0, ETeleportType::None);
}
Please let me know if I need to add any more information.
Disclaimer: I am completely new to UE4. My apologies if it is a dumb question.

How to move an entity with a mouse click?

Ok i now manage to figure out the problem but now another issue appear, my robot seem to move on its own to another point which i have no idea where its from. Here my code
His code make this robot move to the location i click on the terrain.
bool DemoApp::nextLocation(void){
mDestination = mtoward;
mRobotDir = mDestination - mRobotNode[0]->getPosition();
mDistance = mRobotDir.normalise();
return true;
}
bool DemoApp::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
if (mRobotDir == Ogre::Vector3::ZERO) {
if (nextLocation()) {
// Set walking animation
mAnimationState = mRobot[0]->getAnimationState("Walk");
mAnimationState->setLoop(true);
mAnimationState->setEnabled(true);
}//if
}else{
Ogre::Real move = mWalkSpeed * evt.timeSinceLastFrame;
mDistance -= move;
if (mDistance <= 0.0f){
mRobotNode[0]->setPosition(mDestination);
mRobotDir = Ogre::Vector3::ZERO;
// Set animation based on if the robot has another point to walk to.
if (!nextLocation()){
// Set Idle animation
mAnimationState = mRobot[0]->getAnimationState("Idle");
mAnimationState->setLoop(true);
mAnimationState->setEnabled(true);
}else{
// Rotation Code will go here later
Ogre::Vector3 src = mRobotNode[0]->getOrientation() * Ogre::Vector3::UNIT_X;
if ((1.0f + src.dotProduct(mRobotDir)) < 0.0001f) {
mRobotNode[0]->yaw(Ogre::Degree(180));
}else{
Ogre::Quaternion quat = src.getRotationTo(mRobotDir);
mRobotNode[0]->rotate(quat);
} // else
}//else
}else{
mRobotNode[0]->translate(mRobotDir * move);
} // else
} // if
mAnimationState->addTime(evt.timeSinceLastFrame);
}
Here is the raycast code for my mouse click
Ogre::Terrain* pTerrain = mTerrainGroup->getTerrain(0, 0);
Ogre::Viewport* vp = this->mWindow->getViewport(0);
Ogre::Ray mouseRay = mCamera->getCameraToViewportRay(static_cast<float>(mMouse->getMouseState().X.abs)/mMouse->getMouseState().width, static_cast<float>(mMouse->getMouseState().Y.abs)/mMouse->getMouseState().height);
std::pair <bool, Ogre::Vector3> result;
result = pTerrain->rayIntersects(mouseRay, true, 0);
if (result.first = true)
{
mtoward = result.second - mRobotNode[0]->_getDerivedPosition();
mRobotNode[0]->translate(mtoward, Ogre::Node::TS_LOCAL);
}