【发布时间】:2019-11-11 06:09:34
【问题描述】:
我一直致力于将一些蓝图逻辑转换为 C++。我有一个按钮。可以在 VR 中按下按钮,并调用一个委托来通知任何已注册的函数按下了按钮。下面是在 AButtonItem.h 类中声明委托的方式。
#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;
};
当按下按钮时,代理的广播函数会被调用,如下所示:
ButtonItem_OnPressed.Broadcast();
(应该坚决调用这个函数,因为我有一个在调用之前打印的调试语句。同样重要的是要注意,当它是蓝图逻辑时,这一切都有效。)
这是我尝试向委托注册的地方以及我如何声明将被调用的函数:
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);
}
}
我在函数 OnNextBladeButtonPressed 中放置了一个断点和一个打印语句,所以我应该立即知道它什么时候工作,但它永远不会发生。我还从头开始重新创建了蓝图,但仍然没有运气。有时在编译时由于 InvocationList 无效而导致崩溃,但我也没有找到关于该问题的太多信息。底线是,OnNextBladeButtonPressed 没有被调用。
编辑:这是我在 AButtonItem 代码中调用广播函数的地方。因为我在控制台中看到 UE_LOG 输出,所以它似乎被调用了:
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);
}
}
}
}
【问题讨论】:
-
是的,看起来我在打它,这是一个屏幕截图:i.imgur.com/AVrySOw.png
-
AWeaponMaker 是 AActor 而不是 UObject。在按钮类中,它看起来好像是未绑定的(屏幕截图:i.imgur.com/eE1nTJo.png)?即使 AddDynamic 正在被调用。我在 AddDynamic 之后注意到它说绑定但对象已过时,这是一个屏幕截图:(i.imgur.com/30G2oMs.png)。
-
我再次运行它,它看起来像是在 AddDynamic 之后绑定的,我添加了一个打印语句,它在 AddDynamic 之后立即显示。但是当它到达按钮类时,它是未绑定的吗?它有时也会像这样在 AddDynamic 调用中崩溃:i.imgur.com/lCze5kv.png
-
蓝图有一堆子actor(AButtonItems),蓝图的父类是AWeaponMaker。蓝图称为 WeaponMakerBlueprint 蓝图放置在持久关卡中。
标签: c++ events callback delegates unreal-engine4