为什么在BlueprintRead*中会与Visible*/Edit* UPROPERTY说明符一起使用?

9
Unreal Engine 4提供了三个修饰符,用于控制通过UPROPERTY()在蓝图中暴露的C++类成员的可见性和可编辑性。 UE4源代码中的文档(另请参见UE4 wikiUE4文档)对可编辑性的说明如下:
  • 对于 VisibleAnywhere, VisibleInstanceOnly, VisibleDefaultsOnly:
  • ... 无法进行编辑。

  • 对于 EditAnywhere, EditInstanceOnly, EditDefaultsOnly:
  • ... 可以进行编辑。

  • 对于 BlueprintReadOnly:

    ... 可以被蓝图读取,但无法修改。

    BlueprintReadWrite:

    ... 可以在蓝图中读取或写入。

问题:

  1. Since the Visible* specifiers already restrict the usage to read only in Blueprints, why it is used in conjunction with BlueprintReadOnly? Isn't the second specifier superfluous? Example:

    UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly)
    UMyActorComponent* MyActorComponent;
    
  2. Even more confusing is the usage of Edit* specifiers, which allow read and write in Blueprint, together with BlueprintReadOnly which restricts to read only in Blueprint. Aren't both specifiers opposing each other? Example:

    UPROPERTY(EditAnywhere, BlueprintReadOnly)
    UMyActorComponent* MyActorComponent;
    
  3. Are the Visible*/Edit* specifiers valid in a different context than the BlueprintRead* specifiers? (the question is not about InstanceOnly (property windows for instances), DefaultsOnly (property windows for archetypes) and Anywhere (instances & archetypes))
1个回答

20

tl;dr: Visible*/Edit* allows direct access/modify of a variable in Blueprint Editor, while BlueprintRead* allows getting/setting the value of a variable in the Event Graph during Visual Scripting.

// The zooming speed
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera Zoom")
float ZoomSpeed;

// The FOV after zoom in
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera Zoom")
float ZoomInFov;

// The default FOV
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera Zoom")
float DefaultFov;

它们都被指定为EditDefaultsOnly,这意味着在我们基于该C++类创建一个名为TpsCharacter_BP的蓝图类并打开此蓝图后,这3个变量的值将在此蓝图类的详细信息面板中可编辑,如图所示:Blueprint Editor snapshot for TpsCharacter_BP

当然,通过使用Visible*说明符,它们是只读的(在详细信息面板中呈灰色),因此您无法更改它们的值。

现在让我们回到您的MyActorComponent。像我说的那样,Component的说明符工作方式有些不同。

  1. Component和其所有者类一起出现在蓝图编辑器中的组件面板中,而不是像非Component变量那样出现在详细信息面板中。
  2. 当您既没有Visible*也没有Edit*说明符时,该Component本身将始终出现在编辑器中,但您无法访问其中的属性/变量,并且该Component详细信息面板将为空。
  3. Visible*说明符允许您通过其详细信息面板访问Component的属性,就像访问我的TpsCharacter_BP类中的3个变量一样。但是,当您将其声明为Edit*时,详细信息面板将显示有线设置,允许您修改此Component指针值而不是其内容。这绝对是您应该始终避免的事情。

Component的一般准则:永远不要将它们声明为Edit*,因为这会允许您更改指针值以指向其他内容;总是使用Visible*。对于非Component对象,您可以自由设置Edit*

现在更容易理解BlueprintRead*说明符了。有了Visible*,它是否多余?BlueprintReadOnly是否与Edit*说明符相抵触?绝对不是。它们在不同的上下文中有效吗?是的。BlueprintRead*说明符允许您在蓝图编辑器的事件图表中读取/写入变量,也就是在进行蓝图可视化脚本编写时。对于上面的TpsCharacter类,由于所有3个变量都声明为BlueprintReadOnly,因此我可以在事件图表中获取它们的值,如下所示: Get variable from Event Graph

您也可以为MyActorComponent执行相同的操作。通过使用BlueprintReadWrite,您还可以在事件图表中设置这些变量的值。

我写了这么长的答案来解释它们可能会让初学者感到困惑,尽管它们实际上是简单的概念。


非常有见地,这确实帮助我理解从Unity发生了什么。 - Zamaroht

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接