UE4: Actor disappears after play is hit - c++

I am using Unreal Engine version 4.25. I have created an actor and placed it on a blank template. The actor is visible in the editor but becomes invisible once the play button is hit. I am trying to move the object in circles with my code.
Here's the code:
MyActor.cpp
#include "MyActor.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;
Dimensions = FVector(10, 0, 0);
AxisVector = FVector(1, 0, 0);
Location = FVector(1, 0, 0);
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);
}
MyActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
UCLASS()
class ROBOTEURS_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// declare our float variables
UPROPERTY(EditAnywhere, Category = Movement)
float AngleAxis;
UPROPERTY(EditAnywhere, Category = Movement)
FVector Dimensions;
UPROPERTY(EditAnywhere, Category = Movement)
FVector AxisVector;
UPROPERTY(EditAnywhere, Category = Movement)
FVector Location;
UPROPERTY(EditAnywhere, Category = Movement)
float Multiplier;
};
What could have gone wrong?

This fixed it, I did not create a mesh:
https://www.youtube.com/watch?v=30XEdBoPw6c
I added the following:
.cpp
AMyActor::AMyActor()
{
...
Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
RootComponent = Root;
Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
Mesh->AttachTo(Root);
...
}
.h
public:
...
UPROPERTY()
USceneComponent* Root;
UPROPERTY(EditAnywhere)
UStaticMeshComponent* Mesh;
...

Related

Unreal Engine 4.9: Spawning Pawn at checkpoint location

I am working with Unreal Engine 4.9 and I am creating a rolling ball game using mostly C++, I am avoiding using Blueprints.
What I am trying to do is put in place some checkpoints where the player can spawn if they fall off the map (aka. they die).
I have an actor which is the box that represents the checkpoint and a pawn which represents the rolling ball.
So far, I was able to put in place an overlap function so that when the ball overlaps with the box (BoxActor.cpp), it prints out the location of the box and a debug message coming from the pawn (TestBallBall.cpp).
For BoxActor.cpp, this is the code I have so far:
#include "BoxActor.h"
#include "Components/BoxComponent.h"
#include "Engine/Engine.h"
#include "EngineGlobals.h"
#include "Engine.h"
#include "Runtime/Engine/Classes/Kismet/GameplayStatics.h"
// Sets default values
ABoxActor::ABoxActor()
{
// 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;
CollisionBox = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxComponent"));
CollisionBox->SetBoxExtent(FVector(32.f, 32.f, 32.f));
CollisionBox->SetCollisionProfileName("Trigger");
RootComponent = CollisionBox;
CollisionBox->OnComponentBeginOverlap.AddDynamic(this, &ABoxActor::OnOverlapBegin);
CollisionBox->OnComponentEndOverlap.AddDynamic(this, &ABoxActor::OnOverlapEnd);
}
// Called when the game starts or when spawned
void ABoxActor::BeginPlay()
{
Super::BeginPlay();
Ball = Cast<ATestBallBall>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
}
void ABoxActor::OnOverlapBegin(AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
Ball->AddDebugMessage();
Location = this->GetActorLocation();
GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("Checkpoint location is: %s"), *Location.ToString()));
}
void ABoxActor::OnOverlapEnd(AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
}
For my TestBallBall.cpp, this is what I have so far:
#include "TestBallBall.h"
#include "Engine/Engine.h"
#include "EngineGlobals.h"
#include "Engine.h"
ATestBallBall::ATestBallBall()
{
static ConstructorHelpers::FObjectFinder<UStaticMesh> BallMesh(TEXT("/Game/Rolling/Meshes/BallMesh.BallMesh"));
// Create mesh component for the ball
Ball = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Ball0"));
Ball->SetStaticMesh(BallMesh.Object);
Ball->BodyInstance.SetCollisionProfileName(UCollisionProfile::PhysicsActor_ProfileName);
Ball->SetSimulatePhysics(true);
Ball->SetAngularDamping(0.1f);
Ball->SetLinearDamping(0.01f);
Ball->BodyInstance.MassScale = 3.5f;
Ball->BodyInstance.MaxAngularVelocity = 800.0f;
Ball->SetNotifyRigidBodyCollision(true);
RootComponent = Ball;
// Create a camera boom attached to the root (ball)
SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm0"));
SpringArm->AttachTo(RootComponent);
SpringArm->bDoCollisionTest = false;
SpringArm->bAbsoluteRotation = true; // Rotation of the ball should not affect rotation of boom
SpringArm->RelativeRotation = FRotator(-45.f, 0.f, 0.f);
SpringArm->TargetArmLength = 1200.f;
SpringArm->bEnableCameraLag = false;
SpringArm->CameraLagSpeed = 3.f;
// Create a camera and attach to boom
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera0"));
Camera->AttachTo(SpringArm, USpringArmComponent::SocketName);
Camera->bUsePawnControlRotation = false; // We don't want the controller rotating the camera
// Set up forces
RollTorque = 30000000.0f;
JumpImpulse = 500000.0f;
bCanJump = true; // Start being able to jump
jumps = 0;
}
void ATestBallBall::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
// set up gameplay key bindings
InputComponent->BindAxis("MoveRight", this, &ATestBallBall::MoveRight);
InputComponent->BindAxis("MoveForward", this, &ATestBallBall::MoveForward);
InputComponent->BindAction("Jump", IE_Pressed, this, &ATestBallBall::Jump);
}
void ATestBallBall::MoveRight(float Val)
{
const FVector Torque = FVector(-1.f * Val * RollTorque, 0.f, 0.f);
Ball->AddTorque(Torque);
}
void ATestBallBall::MoveForward(float Val)
{
const FVector Torque = FVector(0.f, Val * RollTorque, 0.f);
Ball->AddTorque(Torque);
}
void ATestBallBall::Jump()
{
// Allow only 2 jumps
if(bCanJump)
{
if (jumps < 2){
const FVector Impulse = FVector(0.f, 0.f, JumpImpulse);
Ball->AddImpulse(Impulse);
jumps++;
}
else
bCanJump = false;
}
}
void ATestBallBall::NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit)
{
Super::NotifyHit(MyComp, Other, OtherComp, bSelfMoved, HitLocation, HitNormal, NormalImpulse, Hit);
bCanJump = true;
jumps = 0;
}
void ATestBallBall::AddDebugMessage()
{
UE_LOG(LogActor, Warning, TEXT("AddDebugMessage Function On ATestBallBall Called"));
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, "AddDebugMessage Function On ATestBallBall Called");
}
Thank you in advance for your help and sorry for the long post.

How to use input mapping context in UE5 (without blueprint)

I am a beginner in UE5 (I started learning yesterday), and I am now working on a simple task. It takes the WSAD and mouse to do simple movement and camera operations using input mapping context.
However, after my self-learning, I end up with this:
UCLASS()
class ASSIGNMENT1_API AFirstPersonCharactor : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AFirstPersonCharactor();
UPROPERTY(EditAnywhere, Category = "Components|Camera")
UCameraComponent* camera;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
UInputAction *IA_KB_CM_InOut;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
UInputAction* IA_KB_CM_LeftRight;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
UInputAction* IA_KB_CL_UpDown;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
UInputAction* IA_KB_CL_LeftRight;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
TSoftObjectPtr<UInputMappingContext> IMCControls;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
void KB_CM_InOut(const FInputActionInstance& Instance);
void KB_CM_LeftRight(const FInputActionInstance& Instance);
void KB_CL_UpDown(const FInputActionInstance& Instance);
void KB_CL_LeftRight(const FInputActionInstance& Instance);
};
and this is my cpp file:
// Sets default values
AFirstPersonCharactor::AFirstPersonCharactor()
{
PrimaryActorTick.bCanEverTick = true;
camera = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
camera->SetupAttachment(RootComponent);
camera->SetRelativeLocation(FVector(0));
}
void AFirstPersonCharactor::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AFirstPersonCharactor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void AFirstPersonCharactor::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(GetController()))
{
if (UEnhancedInputLocalPlayerSubsystem* InputSystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
{
InputSystem->AddMappingContext(IMCControls.LoadSynchronous(),10);
}
}
UEnhancedInputComponent* input = Cast<UEnhancedInputComponent>(PlayerInputComponent);
if (IA_KB_CM_InOut) {
input->BindAction(IA_KB_CM_InOut, ETriggerEvent::Started, this, &AFirstPersonCharactor::KB_CM_InOut);
}
if (IA_KB_CM_LeftRight) {
input->BindAction(IA_KB_CM_LeftRight, ETriggerEvent::Started, this, &AFirstPersonCharactor::KB_CM_LeftRight);
}
if (IA_KB_CL_UpDown) {
input->BindAction(IA_KB_CL_UpDown, ETriggerEvent::Started, this, &AFirstPersonCharactor::KB_CL_UpDown);
}
if (IA_KB_CL_LeftRight) {
input->BindAction(IA_KB_CL_LeftRight, ETriggerEvent::Started, this, &AFirstPersonCharactor::KB_CL_LeftRight);
}
}
void AFirstPersonCharactor::KB_CM_InOut(const FInputActionInstance &Instance)
{
printf("a");
float FloatValue = Instance.GetValue().Get<float>();
if (FloatValue != 0) {
AddMovementInput(GetActorForwardVector(),FloatValue);
}
}
void AFirstPersonCharactor::KB_CM_LeftRight(const FInputActionInstance& Instance)
{
float FloatValue = Instance.GetValue().Get<float>();
if (FloatValue != 0) {
AddMovementInput(GetActorRightVector(), FloatValue);
}
}
void AFirstPersonCharactor::KB_CL_LeftRight(const FInputActionInstance& Instance)
{
float FloatValue = Instance.GetValue().Get<float>();
if (FloatValue != 0) {
AddControllerYawInput(FloatValue);
}
}
void AFirstPersonCharactor::KB_CL_UpDown(const FInputActionInstance& Instance)
{
float FloatValue = Instance.GetValue().Get<float>();
if (FloatValue != 0) {
AddControllerPitchInput(FloatValue);
}
}
This ends with no bug, and I have the inputAction and inputMappingContext assets set in the outliner. But no matter which key I press, there are always no behaviours I can observe.
EDIT: after I add GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("haha")); to debug, I found that my SetupPlayerInputComponent is working, but
if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(GetController()))
probably not.
You shouldn't be trying to cast your controller to local player, and also you'd rather setup MappingContext in BeginPlay() rather than in SetupInputComponent(...).
So instead of doing that cast and then trying to add mapping context do this:
if (auto PlayerController = Cast<APlayerController>(Controller))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}

How to use OnActorBeginOverlap in UE4 C++

I'm working on a small game in UE4 and hit a small issue.
So far, I've got the player dealing damage to enemies (via raycast/line trace) all in C++. Now I'm trying to make the enemy cause damage to the player when their collision boxes overlap.
The player uses the TakeDamage() function as does the enemy to deal damage to each other.
Currently, the enemy does deal damage to the player with this Blueprint setup when both of the collisons overlap.
I'm trying to translate this into C++.
I have been looking at many websites which say to use either OnActorBeginOverlap() or OnComponentBeginOverlap() with the AddDynamic() function. However, when trying to call OnActorBeginOverlap() it doesn't appear when I do BoxCollider-> but OnComponentBeginOverlap() does, but does not have the AddDynamic() function. From what I understand, AddDynamic is a macro which I'm not too familiar with. OnActorBeginOverlap() does appear without the BoxCollider->. Both objects are Actors.
Any ideas?
Code Example:
BasicZombie.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "BasicZombie.generated.h"
UCLASS()
class MERCENARIES_API ABasicZombie : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ABasicZombie();
void Destroy();
UPROPERTY(EditAnywhere)
UBoxComponent* BoxCollider;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) override;
private:
UPROPERTY(EditDefaultsOnly)
float maxHealth = 100.0f;
UPROPERTY(VisibleAnywhere)
float health;
void DealDamage();
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
BasicZombie.cpp
#include "BasicZombie.h"
#include "MainCharacter.h"
#include "GameFramework/Actor.h"
#include "DrawDebugHelpers.h"
#include "Engine/Engine.h"
// Sets default values
ABasicZombie::ABasicZombie()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
BoxCollider = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxCollider"));
BoxCollider->OnComponentBeginOverlap.AddDynamic(this, &AMainCharacter::OnCollision);
health = maxHealth;
}
// Called when the game starts or when spawned
void ABasicZombie::BeginPlay()
{
Super::BeginPlay();
}
float ABasicZombie::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser)
{
float DamageToApply = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
DamageToApply = FMath::Min(health, DamageToApply);
health -= DamageToApply;
UE_LOG(LogTemp, Warning, (TEXT("Health Remaining: %f")), health);
//GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, FString::Printf(TEXT("Health Remaining: %f"), health));
Destroy();
return DamageToApply;
}
//void ABasicZombie::DealDamage()
//{
//
//}
void ABasicZombie::Destroy()
{
if (health <= 0)
{
UWorld* WorldRef = GetWorld();
AMainCharacter* mainCharacter = Cast<AMainCharacter>(WorldRef->GetFirstPlayerController()->GetCharacter());
mainCharacter->currentScore += 500;
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, FString::Printf(TEXT("Score: %i"), mainCharacter->currentScore));
AActor::Destroy();
}
}
// Called every frame
void ABasicZombie::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
MainCharacter.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/PlayerController.h"
#include "MainCharacter.generated.h"
class AHandgun;
UCLASS()
class MERCENARIES_API AMainCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AMainCharacter();
void OnCollision(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& Hit);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) override;
private:
UPROPERTY(EditDefaultsOnly)
TSubclassOf<AHandgun> HandgunClass;
UPROPERTY()
AHandgun* Handgun;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
//Handles Input for moving FORWARD and BACK
UFUNCTION()
void MoveForward(float value);
//Handles input for moving RIGHT and LEFT
UFUNCTION()
void MoveRight(float value);
UFUNCTION()
void Shoot();
UFUNCTION()
void printHealth();
//FPS camera
UPROPERTY(VisibleAnywhere)
UCameraComponent* MainCharacterCameraComponent;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
FVector MuzzleOffset;
UPROPERTY()
int32 playerScore;
UPROPERTY()
int32 currentScore;
UPROPERTY()
float maxHealth = 1000.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float currentHealth;
};
MainCharacter.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MainCharacter.h"
#include "Engine/Engine.h"
#include "GameFramework/Actor.h"
#include "Handgun.h"
#include "GameFramework/Character.h"
#include "Components/SkeletalMeshComponent.h"
// Sets default values
AMainCharacter::AMainCharacter()
{
// 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;
//Create a first person camera component
MainCharacterCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
check(MainCharacterCameraComponent != nullptr);
//Attach the camera component to our capsule component
MainCharacterCameraComponent->SetupAttachment(CastChecked<USceneComponent, UCapsuleComponent>(GetCapsuleComponent()));
//Position the camera slightly above the eyes
MainCharacterCameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f + BaseEyeHeight));
//Enable the pawn to control camera rotation
MainCharacterCameraComponent->bUsePawnControlRotation = true;
currentHealth = maxHealth;
playerScore = currentScore;
}
// Called when the game starts or when spawned
void AMainCharacter::BeginPlay()
{
Super::BeginPlay();
check(GEngine != nullptr);
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, TEXT("[MainCharacter DEBUG] - MainCharacter in use."));
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, FString::Printf(TEXT("[MainCharacter DEBUG] - Current Score: %f"), playerScore));
Handgun = GetWorld()->SpawnActor<AHandgun>(HandgunClass);
Handgun->AttachToComponent(GetMesh(), FAttachmentTransformRules::KeepRelativeTransform, TEXT("WeaponSocket"));
Handgun->SetOwner(this);
}
// Called every frame
void AMainCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//printHealth();
}
// Called to bind functionality to input
void AMainCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
//Set up movement bindings.
PlayerInputComponent->BindAxis("MoveForward", this, &AMainCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AMainCharacter::MoveRight);
//Set up Look Bindings
PlayerInputComponent->BindAxis("Turn", this, &AMainCharacter::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &AMainCharacter::AddControllerPitchInput);
//Setup Weapon Shooting
PlayerInputComponent->BindAction(TEXT("Fire"), EInputEvent::IE_Pressed, this, &AMainCharacter::Shoot);
PlayerInputComponent->BindAction(TEXT("printHealth"), EInputEvent::IE_Pressed, this, &AMainCharacter::printHealth);
}
void AMainCharacter::Shoot()
{
Handgun->Shoot();
}
void AMainCharacter::printHealth()
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, FString::Printf(TEXT("[MainCharacter DEBUG] - Current Health: %f"), currentHealth));
}
float AMainCharacter::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser)
{
float DamageToApply = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
DamageToApply = FMath::Min(currentHealth, DamageToApply);
currentHealth -= DamageToApply;
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, FString::Printf(TEXT("Health Remaining: %f"), currentHealth));
if (currentHealth <= 0)
{
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, TEXT("You're Dead!"));
}
return DamageAmount;
}
void AMainCharacter::MoveForward(float value)
{
//Find out which way is "forward" and reocrd that the player wants to move that way
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, value);
}
void AMainCharacter::MoveRight(float value)
{
//Find out which way is "right" and record that the player wants to move that way
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, value);
}
However, the BoxCollider->OnComponentBeginOverlap.AddDynamic(this, &AMainCharacter::OnCollision); in BasicZombie.cpp has a red line under AddDynamic.
I am in a Discord Server for UE4 development, but I haven't had much luck getting any help from there.
Can I see your C++ code? Are you calling AddDynamic from the UBoxComponent?
Try this
UPROPERTY(EditAnywhere)
UBoxComponent* BoxCollider = nullptr;
BoxCollider = GetOwner()->FindComponentByClass<UBoxComponent>();
BoxCollider->OnComponentBeginOverlap.AddDynamic(this, &YourActor::OnCollision);
Use this as your OnCollision signature
void OnCollision(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& Hit);
Also when I was learning unreal engine I dealt with a lot of pitfalls. Try to find a community of unreal engine developers and learn with them.

OnMousePress script don't work in UE4

I want to open the door when pressing left mouse button, but nothing happens
OpenDoor.h
UCLASS()
class HOME_API ADoorOpen : public APawn
{
GENERATED_BODY()
public:
ADoorOpen();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UPROPERTY()
USceneComponent* Root;
UPROPERTY(EditAnywhere)
UStaticMeshComponent* Door;
UPROPERTY(EditAnywhere, Category = "DoorOpen")
float rotateValue;
UPROPERTY(BlueprintReadOnly, Category = "DoorOpen")
FRotator doorRotation;
UPROPERTY(BlueprintReadOnly, Category = "DoorOpen")
bool open;
UFUNCTION(BlueprintCallable, Category = "DoorOpen")
void OpenCloseDoor();
};
OpenDoor.cpp
#include "DoorOpen.h"
#include "DrawDebugHelpers.h"
#include "Engine.h"
ADoorOpen::ADoorOpen()
{
PrimaryActorTick.bCanEverTick = true;
rotateValue = 0.0f;
open = false;
Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
RootComponent = Root;
Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Door"));
Door->SetRelativeLocation(FVector(0.f, 50.f, -50.f));
Door->SetupAttachment(RootComponent);
}
void ADoorOpen::OpenCloseDoor()
{
// don't see this while playing
GEngine->AddOnScreenDebugMessage(-1, 0.f, FColor::Red, "OpenCloseDoor");
//...
}
void ADoorOpen::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Can't call this
PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &ADoorOpen::OpenCloseDoor);
}
Increase the display time for AddOnScreenDebugMessage
GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, "OpenCloseDoor");
Otherwise, the text will show for just a frame.

Bad Access exception in Cocos2d-x

I am somewhat new to C++ programming and to Cocos2d-x and I am having some trouble with my first Cocos2d-x game. I am literally just trying to simulate gravity and update the player's position based on that. I am running Xcode 4.6.1 and for some reason I keep getting a BAD_ACCESS exception after one run (if I restart it seems to work). It happens at libobjc.A.dylib`objc_release. I have tried doing an allexceptions breakpoint and it breaks at a memory address in the dylib. This only happened after I added a velocity variable to my Player class, so maybe I am not properly allocating pointers and the such? Here are the relevant classes I believe.
#include "cocos2d.h"
using namespace cocos2d;
class Player : public Sprite{
private:
Point velocity;
public:
static Player* create(const char *filename);
void update(float delta);
void setVelocity(const Point &v);
const Point& getVelocity() const;
~Player();
};
#include "Player.h"
USING_NS_CC;
using namespace cocos2d;
Player::~Player(){
}
Player* Player::create(const char *filename){
Player* self = (Player *) Sprite::create(filename);
self->setVelocity(Point::ZERO);
return self;
}
void Player::update(float delta){
log("In player update");
Point gravity = Point(0.0, -450.0);
Point gravityStep = gravity * delta;
this->setVelocity(this->getVelocity() + gravityStep);
log("Velocity after setting: %f", getVelocity().y);
Point stepVelocity = this->getVelocity() * delta;
this->setPosition(this->getPosition() + stepVelocity);
log("Position after setting: %f, %f", getPosition().x, getPosition().y);
}
void Player::setVelocity(const Point &v){
this->velocity = v;
}
const Point& Player::getVelocity() const
{
return this->velocity;
}
#include "GameLayer.h"
USING_NS_CC;
Scene* GameLayer::scene()
{
// 'scene' is an autorelease object
Scene *scene = Scene::create();
// 'layer' is an autorelease object
GameLayer *layer = GameLayer::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
GameLayer::~GameLayer(){
CC_SAFE_RELEASE(player);
CC_SAFE_RELEASE(map);
}
bool GameLayer::init()
{
if ( !Layer::init() )
{
return false;
}
LayerColor *blueSky = LayerColor::create(*new Color4B(100, 100, 250, 255));
this->addChild(blueSky);
map = TMXTiledMap::create("level1.tmx");
this->addChild(map);
player = Player::create("koalio_stand.png");
player->setPosition(Point(100,50));
map->addChild(player, 15);
setKeyboardEnabled(true);
this->scheduleUpdate();
return true;
}
void GameLayer::update(float dt){
player->update(dt);
}
EDIT: So I figured out that the constructor of player was the problem. However, I'm wondering if it is kosher to do the following (since Player inherits from Sprite) to copy the Sprite function:
Sprite* Sprite::create(const char *filename)
{
Sprite *sprite = new Sprite();
if (sprite && sprite->initWithFile(filename))
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE(sprite);
return NULL;
}
and have the Player function be:
Player* Player::create(const char *filename){
Player *sprite = new Player();
if (sprite && sprite->initWithFile(filename))
{
sprite->setVelocity(Point::ZERO);
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE(sprite);
return NULL;
}
Or perhaps is there a cleaner way to call the create of Sprite, but to create a Player object which inherits and sets the velocity?