I'm trying to use iTween (via C++, not BP) to rotate an actor to face another, but it throwing an exception in Actor.h that says:
I'm using the following code to start the tween:
AActor* actorToRotate = Cast<AActor>(this);
if (actorToRotate != nullptr && CharacterToAttack != nullptr)
{
FRotator rotationFrom = actorToRotate->GetActorRotation();
FRotator rotationTo = CharacterToAttack->GetActorRotation();
FName tweenName = TEXT("turret");
AiTweenEvent* TurretTween = UiTween::ActorRotateFromToSimple(tweenName, actorToRotate, rotationFrom, rotationTo, CoordinateSpace::world, false, 2.0f, easeInAndOutQuartic);
}
Rather than using the actorToRotate variable I've tried using this in ActorRotateFromToSimple() but I get the same error.
if (CharacterToAttack != nullptr)
{
FRotator rotationFrom = GetActorRotation();
FRotator rotationTo = CharacterToAttack->GetActorRotation();
FName tweenName = TEXT("turret");
AiTweenEvent* TurretTween = UiTween::ActorRotateFromToSimple(tweenName, this, rotationFrom, rotationTo, CoordinateSpace::world, false, 2.0f, easeInAndOutQuartic);
}
If anyone smarter than me shed some light onto this issue it would be greatly appreciated.
Additional information I think might be important:
actorToRotate is custom type of ATDWeapon that extends from AActor
CharacterToAttack is custom type of ATDAICharacter that extends from ATDCharacter
The function that executes this code is called by GetWorldTimerManager().SetTimer()
I've added #include "iTween/iTween.h" to the top of my TDWeapon.cpp file
Ah, the problem wasn't in the code. I was using "simulate in editor" in the UE4 Editor rather than "play in editor".
It appears that AiTweenEvent* UiTween::SpawnEvent(AiTAux* aux) needs a player controller and uses GetWorldLocal()->GetFirstPlayerController()->GetPawn()->GetTransform() to get it's transform. In my instance, "simulate in editor" doesn't spawn a player so GetPawn() returns nullptr which GetTransform() doesn't like.
Awesome.
Related
I tried implementing an RTS in unreal engine c++ and currently I can select and deselect units but they won't move though I already have a function for that. Could someone take a look what I am doing wrong? Here's my code:
void ACoba_PlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
InputComponent->BindAction("RightMouseClick", IE_Pressed, this, &ACoba_PlayerController::MoveReleased);
}
void ACoba_PlayerController::MoveReleased()
{
if (SelectedActors.Num() > 0)
{
for (int32 i = 0; i < SelectedActors.Num(); i++)
{
FHitResult Hit;
GetHitResultUnderCursor(ECC_Visibility, false, Hit);
FVector MoveLocation = Hit.Location + FVector(i / 2 * 100, i % 2 * 100, 0);
UAIBlueprintHelperLibrary::SimpleMoveToLocation(SelectedActors[i]->GetController(), MoveLocation);
}
}
}
Note: I've already setup the input for RightMouseClick at the input property.
Could someone help me please. Thank you.
Make sure you have set your PlayerController to receive input:
ACoba_PlayerController::ACoba_PlayerController()
{
AutoReceiveInput = EAutoReceiveInput::Player0;
/* ... */
}
I just tested the right button and it worked.
I'm using Unreal 4.24.2
I had the exact same issue, and after spending a day into it, i found out the problem is not in the code itself (mine is identical than the OP), the problem was that you need to add in your map a NavMeshBoundVolume in UE editor, this will make your map floor surface "walkable" by your actors, without this the SimpleMoveToLocation function won't do anything.
I found it very annoying that there is no warning or error displayed showing that you are missing a NavMeshBoundVolume, that would save a lot of time.
I've been working on converting some blueprint logic over to C++. One of the things I have is a button. The button can be pressed in VR and has a delegate that is called to notify any registered functions that the button press occurred. Here is how the delegate is declared in the AButtonItem.h class.
#pragma once
#include "BaseItem.h"
#include "ButtonItem.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FButtonItemPressedSignatrue);
UCLASS()
class AButtonItem : public ABaseItem
{
GENERATED_BODY()
protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Touch)
float myMaxButtonPress;
public:
UPROPERTY(EditAnywhere, Category = Callback)
FButtonItemPressedSignatrue ButtonItem_OnPressed;
};
The delegate's broadcast function is then being called when the button is pressed like so:
ButtonItem_OnPressed.Broadcast();
(This function should defiantly be called because I have a debug statement that prints right before the call. Its also important to note this was all working when it was blueprint logic.)
Here is where I try to register with the delegate and how I declared the function that will be called:
WeaponMaker.h:
UFUNCTION()
void OnNextBladeButtonPressed();
WeaponMaker.cpp:
void AWeaponMaker::BeginPlay()
{
Super::BeginPlay();
TArray<USceneComponent*> weaponMakerComponents;
this->GetRootComponent()->GetChildrenComponents(true, weaponMakerComponents);
for (int componentIndex = 0; componentIndex < weaponMakerComponents.Num(); componentIndex++)
{
if (weaponMakerComponents[componentIndex]->GetName().Equals("NextBladeButton") == true)
{
myNextBladeButton = (AButtonItem*)weaponMakerComponents[componentIndex];
break;
}
}
if (myNextBladeButton != NULL)
{
myNextBladeButton->ButtonItem_OnPressed.AddDynamic(this, &AWeaponMaker::OnNextBladeButtonPressed);
}
}
I put a breakpoint and a print statement in the function OnNextBladeButtonPressed so I should immediately know when it works but its never happening. I also re-created the blueprint itself from scratch but still no luck. Sometimes on compile I get a crash due to the InvocationList being invalid but I haven't found much info on that issue either. Bottom line is, OnNextBladeButtonPressed is not getting called when it should be.
Edit: Here is where I call the broadcast function in my AButtonItem code. It seems to be getting called since i see the UE_LOG output in the console:
void AButtonItem::Tick(float deltaTime)
{
FTransform buttonWorldTransform;
FVector buttonLocalSpacePos;
FVector ownerLocalSpacePos;
FVector localDiff;
float buttonPressAmount;
if (myHasStarted == true)
{
Super::Tick(deltaTime);
if (myButtonComponent != NULL)
{
if (myPrimaryHand != NULL)
{
//Get the world space location of the button.
buttonWorldTransform = myButtonComponent->GetComponentTransform();
//Convert the location of the button and the location of the hand to local space.
buttonLocalSpacePos = buttonWorldTransform.InverseTransformPosition(myInitialOverlapPosition);
ownerLocalSpacePos = buttonWorldTransform.InverseTransformPosition(myPrimaryHand->GetControllerLocation() + (myPrimaryHand->GetControllerRotation().Vector() * myPrimaryHand->GetReachDistance()));
//Vector distance between button and hand in local space.
localDiff = ownerLocalSpacePos - buttonLocalSpacePos;
//Only interested in the z value difference.
buttonPressAmount = FMath::Clamp(FMath::Abs(localDiff.Z), 0.0f, myMaxButtonPress);
localDiff.Set(0.0f, 0.0f, buttonPressAmount);
//Set the new relative position of button based on the hand and the start button position.
myButtonComponent->SetRelativeLocation(myButtonInitialPosition - localDiff);
//UE_LOG(LogTemp, Error, TEXT("buttonPressAmount:%f"), buttonPressAmount);
if (buttonPressAmount >= myMaxButtonPress)
{
if (myHasBeenTouchedOnce == false)
{
//Fire button pressed delegate
if (ButtonItem_OnPressed.IsBound() == true)
{
ButtonItem_OnPressed.Broadcast();
AsyncTask(ENamedThreads::GameThread, [=]()
{
ButtonItem_OnPressed.Broadcast();
});
}
myHasBeenTouchedOnce = true;
myButtonComponent->SetScalarParameterValueOnMaterials("State", 1.0f);
Super::VibrateTouchingHands(EVibrationType::VE_TOUCH);
}
}
}
else
{
//Slowly reset the button position back to the initial position when not being touched.
FVector newPosition = FMath::VInterpTo(myButtonComponent->GetRelativeTransform().GetLocation(), myButtonInitialPosition, deltaTime, 10.0f);
myButtonComponent->SetRelativeLocation(newPosition);
}
}
}
}
First of all:
UPROPERTY(EditAnywhere, Category = Callback)
FButtonItemPressedSignatrue ButtonItem_OnPressed;
This should be:
UPROPERTY(BlueprintAssignable, Category = Callback)
FButtonItemPressedSignatrue ButtonItem_OnPressed;
For convenience.
Secondly the tick function may be called before begin play is executed for a number of reasons. Your even't won't be broadcasted if the game hasn't begin play yet. So to avoid just add a check in your tick function.
if(bHasBegunPlay)
{
// .. your logics ...
}
Sometimes on compile I get a crash due to the InvocationList being invalid but I haven't found much info on that issue either. Bottom line is, OnNextBladeButtonPressed is not getting called when it should be.
I don't see any issue in the code from the question. At my glance, the issue could be in different location. I would suspect that AWeaponMaker had been deleted at moment of broadcasting.
I'm new in using c++ and UE.
I tried some simple programming but the editor crash.
#include "NewActorComponent.h"
#include "Runtime/Engine/Classes/GameFramework/Actor.h"
UNewActorComponent::UNewActorComponent()
{
PrimaryComponentTick.bCanEverTick = true;
GetOwner()->GetName();
}
I knew maybe the output is null so it is crashed,but idk how to expect the error without any crash.
It's possible the actor component is created but not initialized or attached to an object. You should gate these kind of checks behind IF statements, or use the assert/check macros.
Also, you may want to use the BeginPlay() function instead of the constructor. BeginPlay requires the component to be registered and initialized so it should have an owner.
GetName();
To find the owner of the component.
Ex: When inserting a component in the chair, a reference to the chair will be returned.
From Unreal Engine API Reference:
UObjectBaseUtility::GetName
Syntax: FString GetName()
Remarks
Returns the name of this object (with no path information)
OK, Follow this steps:
1) File -> New Project -> C++ -> Basic Code -> With Starter Content
2) Inside MinimalDefault Map select one chair and pick Add Component Button.
3) Choose New C++ Component
4) Choose Actor Component Class and click em Next Button
5) In Visual Studio inside NewActorComponent.cpp insert code below in BeginPlay() function
UNewActorComponent::UNewActorComponent()
{
PrimaryComponentTick.bCanEverTick = true;
FString ObjectName = GetOwner()->GetName();
UE_LOG(LogTemp, Warning, TEXT("ObjetctName: %s"), *Objectname);
}
6) Show Log Window in Unreal Engine 4
Log Windows
7) Compile!
8) See Results in Log Window
logwindowresults
Below Complete Code. It Works! Enjoy!
#include "NewActorComponent.h"
#include "Runtime/Engine/Classes/GameFramework/Actor.h"
UNewActorComponent::UNewActorComponent()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UNewActorComponent::BeginPlay()
{
Super::BeginPlay();
FString NameOfObject = GetOwner()->GetName();
UE_LOG(LogTemp, Warning, TEXT("Name is: %s"), *NameOfObject)
}
void UNewActorComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}
I've got a button that I need to be a toggle button for the sound of a game. I'm using the MenuSpriteItem class.
auto menuSoundOn = Sprite::createWithSpriteFrameName("soundOn.png");
auto menuSoundOff = Sprite::createWithSpriteFrameName("soundOff.png");
auto menuSoundBtn = MenuItemSprite::create(menuSoundOn, menuSoundOff, CC_CALLBACK_1(LevelsLayer::shutSound, this));
menuSoundBtn->setTag(0);
_mainMenu = Menu::create(menuSoundBtn, nullptr);
this->addChild(_mainMenu);
//Then in my shutSound method
auto menuSoundBtn = _mainMenu->getChildByTag(0);
if (_ifSound){
_ifSound = false;
//Do some stuff to shut the sound
menuSoundBtn->setSelectedImage("noSound.png");
}
else{
_ifSound = true;
//Do some stuff to bring the sound back
menuSoundBtn->setSelectedImage("sound.png");
}
The problem is that getting the Btn from his parent with getChildByTag(0) method I receive a Node according with the documentation, but setSelectedImage is not part of the Node class and there is an error telling me so, so what is the right way to access MenuSpriteItems from their Parents and then manipulate them as in this case by changing the Normal Image?
Greetings.
I've got the answer and It's really powerful and simple.
auto menuSoundBtn = dynamic_cast<MenuItemSprite*>(_mainMenu->getChildByTag(0));
This is the explanation from the guy:
This code will get the child with tag 0 and turn it into a MenuItemSprite* object if it is a MenuItemSprite* object, or it returns null if the object was not a MenuItemSprite*.
Hope it helps someone. Greetings.
Hey guys this is my code and i am relatively new to C++ and even coding really dont know why i am getting a parse error
though i as per my understanding i have placed the parenthesis properly anyone please suggest if i am missing anything here.
i am getting error at this line
class getProcessor()->RequestUIUpdate()// UI update must be done each time a new editor is constructed
Full Code:
StereoWidthCtrlAudioProcessorEditor::StereoWidthCtrlAudioProcessorEditor (StereoWidthCtrlAudioProcessor* ownerFilter)
: AudioProcessorEditor(ownerFilter)
{
addAndMakeVisible (WidthCtrlSld = new Slider ("Width Factor Slider"));
WidthCtrlSld->setRange (0, 5, 0.1);
WidthCtrlSld->setSliderStyle (Slider::LinearHorizontal);
WidthCtrlSld->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20);
WidthCtrlSld->addListener (this);
addAndMakeVisible (BypassBtn = new TextButton ("Bypass Button"));
BypassBtn->setButtonText (TRANS("Bypass"));
BypassBtn->addListener (this);
addAndMakeVisible (label = new Label ("new label",
TRANS("Stereo Width Factor:")));
label->setFont (Font (15.00f, Font::plain));
label->setJustificationType (Justification::centredLeft);
label->setEditable (false, false, false);
label->setColour (Label::textColourId, Colour (0xffa34747));
label->setColour (TextEditor::textColourId, Colours::black);
label->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
//[UserPreSize]
//[/UserPreSize]
setSize (600, 400);
//[Constructor] You can add your own custom stuff here..
class getProcessor()->RequestUIUpdate()// UI update must be done each time a new editor is constructed
startTimer(200)//starts timer with interval of 200mS
BypassBtn->setClickingTogglesState(true);
//[/Constructor]
}
StereoWidthCtrlAudioProcessorEditor::~StereoWidthCtrlAudioProcessorEditor()
{
//[Destructor_pre]. You can add your own custom destruction code here..
//[/Destructor_pre]
WidthCtrlSld = nullptr;
BypassBtn = nullptr;
label = nullptr;
//[Destructor]. You can add your own custom destruction code here..
//[/Destructor]enter code here
}
class is a keyword mainly used in declarations. You probably meant:
getProcessor()->RequestUIUpdate();