Why the UPROPERTY specifiers Visible*/Edit* are used together with BlueprintRead*
Asked Answered
M

1

10

Unreal Engine 4 provides three specifiers to control the visibility and editability of an C++ class member exposed to Blueprint via UPROPERTY().

The documentation in the UE4 source code (see also UE4 wiki, UE4 documentation) says the following regarding editability:

  • For VisibleAnywhere, VisibleInstanceOnly, VisibleDefaultsOnly:

    ... cannot be edited at all.

  • For EditAnywhere, EditInstanceOnly, EditDefaultsOnly:

    ... can be edited ...

  • For BlueprintReadOnly:

    ... can be read by blueprints, but not modified.

    and BlueprintReadWrite:

    ... can be read or written from a blueprint.

Questions:

  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))
Mono answered 25/8, 2018 at 11:51 Comment(0)
K
22

tl;dr

  • Visible*/Edit* specifiers allow you (typically a game designer) to access/modify a variable directly in Blueprint Editor for quick configurations of class properties.
  • BlueprintRead* allow you to get/set the value of a variable in the Event Graph when you're doing Visual Scripting.

Explanation:

Some namings and explanations in the official documentation are indeed a little ambiguous, especially for beginners. In a nutshell, both Visible*/Edit* and BlueprintRead* expose a variable in a class to the Unreal Engine, but do different things. In fact, both question 2 and 3 can be answered via question 1. Let's see your question 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;

Here you're exposing an ActorComponent to the Engine. Here I'll explain a non-Component member variable first, because specifiers for Component "appears" to work differently from non-Component variables.

Suppose I have a TpsCharacter class for a Third Person Shooter character, which has the following 3 float variables:

// 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;

They're all specified as EditDefaultsOnly, which means that, after we create a Blueprint class called TpsCharacter_BP based on this C++ class and open this Blueprint, the values of these 3 variables are editable in the Details Panel for this Blueprint class, as shown in the picture: Blueprint Editor snapshot for TpsCharacter_BP

Of course, by using Visible* specifiers, they are read-only (greyed out in the Details Panel) so you can't change their values.

Now let's get back to your MyActorComponent. Like I said, specifiers for Component works somewhat differently.

  1. Component appear in the Components Panel together with its owner class in the Blueprint Editor instead of in Details Panel like a non-Component variable.
  2. When you have neither Visible* nor Edit* specifiers for a Component, this Component itself will always appear in the Editor, but you can't access properties/variables inside this Component., and Details Panel for this Component will be empty.
  3. Visible* specifier allows you to access the Component's properties via its Details Panel, just like accessing the 3 variables in my TpsCharacter_BP class. However, when you declare it as Edit*, the Details Panel will show wired settings, allowing you to modify the Pointer value of this Component rather than its contents. This is definitely one thing you should always avoid.

Rule of thumb for Component: NEVER declare them as Edit* because it allows you change the pointer value to point to other things; always do Visible*. For a non-Component object you're free to set Edit*.

Now it's much easier to understand BlueprintRead* specifier. Is it superfluous with the presence of Visible*? Is BlueprintReadOnly opposing Edit* specifiers? Absolutely no. Are they valid in different context? Yes. The BlueprintRead* specifier allows you to read/write a variable in the Event Graph in the Blueprint Editor, that is, when you're doing Blueprint Visual Scripting. For my TpsCharacter class above, since all 3 variables are declared BlueprintReadOnly, I can get their values inside the Event Graph as shown here: Get variable from Event Graph

You can do the same for your MyActorComponent. By using BlueprintReadWrite, you can also set the value for these variables in Event Graph.

I write such long answer to explain because they can really confuse beginners though they're actually simple concepts.

Karlynkarma answered 25/8, 2018 at 18:31 Comment(1)
So insightful, this really helped me understand what's going on coming from UnityFasten

© 2022 - 2024 — McMap. All rights reserved.