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:
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.
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.
- 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.
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:
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.