[英]Why variable is null in Unreal Engine?
I want to call function, which changes the text inside the widget.我想拨打 function,它会更改小部件内的文本。
There is a virtual
function NativeConstruct
, which calls automatically.有一个
virtual
的 function NativeConstruct
,自动调用。 And it changes text of widget, but I need to call function F1
and send a text to it, which I want to display.它改变了小部件的文本,但我需要调用 function
F1
并向它发送一个我想要显示的文本。 But when I call it, the variable Name
is nullptr
.但是当我调用它时,变量
Name
是nullptr
。 And by some reason, it is not nullptr
, when program call NativeConstruct
.由于某种原因,当程序调用
NativeConstruct
时,它不是nullptr
。
Name
is my text variable, which I want to change Name
是我要更改的文本变量dialogBottom
is the name of widget with this variable dialogBottom
是具有此变量的小部件的名称Edited已编辑
UAccessWidgetFromCpp* AccessWidgetFromCpp
= CreateWidget<UAccessWidgetFromCpp>(
GetWorld()->GetFirstPlayerController(), UAccessWidgetFromCpp::StaticClass()
);
if (AccessWidgetFromCpp)
{
AccessWidgetFromCpp->F1("222");
widgetDialogBottomInstance->AddToViewport();
}
UCLASS()
class HOME_API UAccessWidgetFromCpp : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* Name = nullptr;
UFUNCTION()
void F1(FString text);
};
void UAccessWidgetFromCpp::F1(FString text)
{
if (auto widget = dynamic_cast<UTextBlock*>(GetWidgetFromName(TEXT("Name"))))
{
Name = widget;
Name->SetText(FText::FromString(text));
}
}
Your UPROPERTY
the Name
has not initialized to nullptr
in the beginning.您的
UPROPERTY
Name
在开始时尚未初始化为nullptr
。 Therefore, it could contain any garbage value inside it .因此,它可以在其中包含任何垃圾值。
Initialize it to nullptr
in the class definition or in the constructor of UAccessWidgetFromCpp
(if any).在 class 定义或
UAccessWidgetFromCpp
的构造函数(如果有)中将其初始化为nullptr
。 For instance, this will fix the issue例如,这将解决问题
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* Name = nullptr;
// ^^^^^^^^^^
Regarding the new update:关于新的更新:
First of all, you should avoid using c-style casting in C++ .首先,你应该避免在 C++ 中使用 c 风格的转换。 Secondly, the function
GetWidgetFromName
returns, uobject widget corresponding to a given name.其次,function
GetWidgetFromName
返回, uobject widget对应给定名称。 Therefore you should be sure about having one with " Name
".因此,您应该确定拥有一个带有“
Name
”的。
Otherwise, make your code safe by double-checking the nullptr
scenarios.否则,通过仔细检查
nullptr
场景来确保您的代码安全。
if(auto widget = dynamic_cast<UTextBlock*>(GetWidgetFromName(TEXT("Name"))))
{
Name = widget;
Name->SetText(FText::FromString(text));
}
Even now you do not reach the line Name->SetText(FText::FromString(text));
即使现在您也没有到达
Name->SetText(FText::FromString(text));
这一行means either you have no widget called " Name
" or it is not possible to cast the UWidget*
to a UTextBlock*
.意味着您没有名为“
Name
”的小部件,或者无法将UWidget*
转换为UTextBlock*
。 You might need a redesign of how to do this.您可能需要重新设计如何执行此操作。
Remember to practise defensive programming.记住练习防御性编程。 Initialize ptr values to nullptr - never assume variables are initialised in C++.
将 ptr 值初始化为 nullptr - 永远不要假设变量是在 C++ 中初始化的。 The code
if(Name)
does not check if a UObject is valid, it just checks that there is some value in the variable - and that value will be some garbage value if the variable has not been initialised.代码
if(Name)
不检查 UObject 是否有效,它只检查变量中是否有某个值- 如果变量尚未初始化,则该值将是一些垃圾值。
Furthermore, I'd recommend checking variables (that might possibly be null) immediately prior to dereferencing them.此外,我建议在取消引用变量之前立即检查变量(可能为空)。
according to the UE4 docs : 根据 UE4 文档:
GetWidgetFromName
returns the uobject widget corresponding to a given nameGetWidgetFromName
返回与给定名称对应的 uobject 小部件
If there is no uobject widget corresponding to the given name (eg. due to a typo in the supplied text or some code logic error), the UE4 docs are not explicit and I haven't tested it personally, but I would assume that nullptr
will be returned.如果没有与给定名称对应的 uobject 小部件(例如,由于提供的文本中的拼写错误或某些代码逻辑错误),UE4 文档不明确并且我没有亲自测试过,但我会假设
nullptr
将被退回。 If so, the null return would happen after your if(Name)
check yielding a nullptr dereference.如果是这样, null 返回将在您的
if(Name)
检查产生 nullptr 取消引用之后发生。
ie. IE。
void UAccessWidgetFromCpp::F1(FString text)
{
if (Name)
{
Name = (UTextBlock*)GetWidgetFromName(TEXT("Name"));
// if there is no Widget with name "Name" then the variable Name
// may now be null even if it wasn't at the if check earlier
Name->SetText(FText::FromString(text));
}
}
Hope that clarifies (naming the widget variable "Name" certainly doesn't help).希望澄清(命名小部件变量“名称”当然没有帮助)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.