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.
Related
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);
}
}
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.
According to the unreal documentation, GetRelativeRotation is a member variable of USceneComponent. However, when I run my code, it tells me that it's not. I have tried switching my Camera to a UCameraComponent(as it was originally before I checked the documenation) and still no luck. Any ideas? heres the code for the .cpp file:
#include "FirstPersonCharacter.h"
AFirstPersonCharacter::AFirstPersonCharacter()
{
PrimaryActorTick.bCanEverTick = true;
AutoPossessPlayer = EAutoReceiveInput::Player0;
bUseControllerRotationYaw = false;
Cam = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
Cam->AttachTo(RootComponent);
Cam->SetRelativeLocation(FVector(0.f, 0.f, 40.f)); //places the camera 40cm above the centre of the body.
}
void AFirstPersonCharacter::BeginPlay()
{
Super::BeginPlay();
}
void AFirstPersonCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AFirstPersonCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
InputComponent->BindAxis("HorizontalMovement", this, &AFirstPersonCharacter::HorizontalMove);
InputComponent->BindAxis("VerticalMovement", this, &AFirstPersonCharacter::VerticalMove);
InputComponent->BindAxis("VerticalLook", this, &AFirstPersonCharacter::VerticalRot);
InputComponent->BindAxis("HorizontalLook", this, &AFirstPersonCharacter::HorizontalRot);
}
void AFirstPersonCharacter::HorizontalMove(float value)
{
if (value) //make sure it doesn't constantly call on addmovementinput if theres no value to add to it
{
AddMovementInput(GetActorRightVector(), value);
}
}
void AFirstPersonCharacter::VerticalMove(float value)
{
if (value) //make sure it doesn't constantly call on addmovementinput if theres no value to add to it
{
AddMovementInput(GetActorForwardVector(), value);
}
}
void AFirstPersonCharacter::HorizontalRot(float value)
{
if (value)
{
AddActorLocalRotation(FRotator(0, value, 0));
}
}
void AFirstPersonCharacter::VerticalRot(float value)
{
if (value)
{
float temp = Cam->GetRelativeRotation().Pitch + value; //THIS IS WHERE THE ISSUE IS
if (temp < 65 && temp > -65)
{
Cam->AddLocalRotation(FRotator(value, 0, 0));
}
}
and the code for the header file:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Components/InputComponent.h"
#include "Components/SceneComponent.h"
#include "Camera/CameraComponent.h"
#include "FirstPersonCharacter.generated.h"
UCLASS()
class MOMENTUMPROJECTMAIN_API AFirstPersonCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AFirstPersonCharacter();
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;
private:
void HorizontalMove(float value);
void VerticalMove(float value);
void HorizontalRot(float value);
void VerticalRot(float value);
//allows me to edit in the editor, without going into source code.
UPROPERTY(EditAnywhere, Category = "Camera")
UCameraComponent* Cam;
};
thanks.
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;
...
So I'm trying to create a simple app using cocos2d-x newest build and for some reason can't get my touch wired up. Here are my classes:
class GameLayer : public cocos2d::Layer
{
public:
static cocos2d::Layer* createLayer();
void update(float dt);
virtual bool init();
CREATE_FUNC(GameLayer);
private:
bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event);
void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event);
};
cocos2d::Layer* GameLayer::createLayer()
{
GameLayer *layer = GameLayer::create();
return layer;
}
bool GameLayer::init()
{
if (!cocos2d::Layer::init())
{
return false;
}
this->schedule(schedule_selector(GameLayer::update));
this->setTouchEnabled(true);
return true;
}
void GameLayer::update(float dt)
{
}
bool GameLayer::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event)
{
cocos2d::log("You touched %f, %f", touch->getLocationInView().x, touch->getLocationInView().y);
return true;
}
void GameLayer::onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event)
{
}
void GameLayer::onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event)
{
}
I noticed when I call into the setTouchEnabled call that an internal flag called _running is set to false so it doesn't actually register my touch events. However I can't seem to figure out why that is the case. Am I calling things incorrectly or in the wrong order?
Currently, cocos2dx is going through a major overhauling of the library and many things have changed including Touch registration and propagation. Here is how it works now:
GameLayer.h
class GameLayer : public cocos2d::Layer
{
public:
static cocos2d::Layer* createLayer();
void update(float dt);
virtual bool init();
CREATE_FUNC(GameLayer);
private:
virtual void onEnter();
virtual void onExit();
bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event);
void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event);
};
GameLayer.cpp
cocos2d::Layer* GameLayer::createLayer()
{
GameLayer *layer = GameLayer::create();
return layer;
}
bool GameLayer::init()
{
if (!cocos2d::Layer::init())
{
return false;
}
this->schedule(schedule_selector(GameLayer::update));
return true;
}
void GameLayer::onEnter()
{
Layer::onEnter();
// Register Touch Event
auto dispatcher = Director::getInstance()->getEventDispatcher();
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this);
dispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
void GameLayer::onExit()
{
// You don't need to unregister listeners here as new API
// removes all linked listeners automatically in CCNode's destructor
// which is the base class for all cocos2d DRAWING classes
Layer::onExit();
}
void GameLayer::update(float dt)
{
}
bool GameLayer::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event)
{
cocos2d::log("You touched %f, %f", touch->getLocationInView().x, touch->getLocationInView().y);
return true;
}
void GameLayer::onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event)
{
}
void GameLayer::onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event)
{
}
Hope it helps!