简体   繁体   English

为什么变量在虚幻引擎中是null?

[英]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 .但是当我调用它时,变量Namenullptr 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 name GetWidgetFromName返回与给定名称对应的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM