Summary
The editor behavior of components is somewhat incorrect compared to what you would normally get statically flagged at compile time in code.
Some of it was mentioned in the following report but none of it was actually addressed: [Major] Many `@editable` values cannot be set any more (Scene Graph)
Please select what you are reporting on:
Unreal Editor for Fortnite
What Type of Bug are you experiencing?
UI/Tools
Steps to Reproduce
Here’s the code to reproduce the behaviors.
vz_test_non_concrete_editables_component := class<final><final_super>(component) {
@editable
ENonConcrete: vz_non_concrete_class
@editable
ESetNonConcrete: vz_non_concrete_class = vz_non_concrete_class { Number := 42 }
@editable
EOptionalNonConcrete: ?vz_non_concrete_class
@editable
ESetOptionalNonConcrete: ?vz_non_concrete_class = false
@editable
ENonConcreteArray: []vz_non_concrete_class
}
vz_non_concrete_class := class {
@editable
Number: int
}
Expected Result
NonConcrete
field should say Set to Value
EOptionalNonConcrete
field’s drop down options should present None
as an option
ESetOptionalNonConcrete
should be set to None
- All fields that have no default value in code should have NO default value assigned by the editor, regardless of the type being
concrete
(source of bugs). Therefore the Number
field should say Set to Value
instead of 0
.
Index [...]
element of ENonConcreteArray
should not default to the base class.
- When a value is not set, it should say
Set to Value
instead of None
. None
should be reserved for representing false
of an optional type of if potentially an enum
with an explicit None
case.
Observed Result
ENonConcrete
field says None
, but it really should be saying Set to Value
EOptionalNonConcrete
field correctly says Set to Value
but the drop down menu does not provide the None
as an option. The type is ?vz_non_concrete_class
so false
aka None
should be an option
ESetOptionalNonConcrete
incorrectly says Set to Value
, but it really should say None
as the value is explicitly set in code to false
ENonConcreteArray
automatically assumes we want to use the vz_non_concrete_class
class as its new element even if there could be more subclasses. Additionally if we set the the type to the class, all concrete
fields are automatically initialized with a default value, this is a source of bugs. In code initialization process is explicit for a good reason and types without a value, even if they are concrete
cannot be omitted from the explicit user written initialization process. The editor circumvents this by giving types that are concrete
a sort of “convenience”, but in reality this will lead to wrongly / unintentionally set values when using the editor workflow.
Platform(s)
PC / UEFN
(Fowarded from an outside-forum conversation)
Basically, comparing “current” to “expected” editable behaviors:
-
some_property
(non concrete reference to property):
—> Currently is “None
”, which is misleading and confusing comparing to other scenarios;
—> The expected should be “Set to Value
”, since the concrete value needs to be set and can’t be left unset;
-
?some_property
(non concrete optional reference to property):
—> Currently is “Set to Value
”, wich is fine and coherent to understand (This is Ok);
—> Currently after setting the value to something, the optional can’t be set back to “Blank/None/false”;
—> The expected should be after setting to value, displaying “None
” (blank/false optional) in a dropdown, together with other possible value selector options;
-
?some_property = false
(concrete optional reference initialized as blank/false):
—> Currently is “Set to Value
”, which is confusing and not coherent comparing to other scenarios;
—> The expected should be None
, meaning that the value is set, but the editable is blank/false;
-
[]some_class
(non concrete array of some class type):
—> Currently when adding a element to the array, the element is defaulted to the base class type (some_class
) on this example, which is confusing and prone to errors on the user configuration;
—> The expected should display the new array element as “Set to Value
”, and then the user hand-picking a base class to derivate from it on. (such as ex. child_class
);
-
class_with_properties
(non concrete reference to a non concrete class):
—> Currently when setting it to a value, it will auto-fill all the class properties with “default” values that doesn’t exist (such as MyInt : int
gets defaulted to 0
or MyString : string
to ""
). This is not supposed to happen and prone to cause errors when working with editables, due to it auto-setting wrong values that may cause diferent functionality on the component logic;
—> The expected should be all class fields being unitialized, displaying as “Set to Value
”, without pre-filling it at all;
some_class := class{}
child_class := class(some_class){}
class_with_properties := class {
@editable
MyInt : int
@editable
MyString : string
@editable
MyFloat : float
@editable
MyLogic : logic
@editable
MyColor : color
}
my_class := class {
@editable # `some_property` example
MyValue0 : int
@editable # `?some_property` example
MyValue1 : ?int
@editable # `?some_property = false` example
MyValue2 : ?int = false
@editable # `[]some_class` example
MyValue3 : []some_class
@editable # `class_with_properties` example
MyValue4 : class_with_properties
}
Property1: some_type # Should never prefill with a default value when the type is `concrete`, should always display `set to value`
Property2: ?some_type # Should display `set to value` -> dropdown should present a list of options where `None` is the top most option
Property3: ?some_type = false # Should display `None` -> dropdown should present a list of options where `None` is the top most option
Property4: []some_type # Should display `set to value` -> initial interaction should make it EMPTY -> any new elements should provide a list of `some_type` subtype options, any `some_type` properties should never prefill with value just like `Property1` unless they already have a default value in code
Regarding a potential collision with an enum
that has a None
case of its own.
some_enum := enum {
None
Something
}
Just display a dropdown menu which has a clear hairline to partition the two sets of possible values. This should apply to any ?some_type
and ?some_type = false
values.
None <- represents `false` value
--------------- <- hairline
None <- `some_enum.None`
Something <- `some_enum.Something`
In case of ?some_class
:
None
---------------
some_class
some_other_subclasses
In case of ?int
None
---------------
int <- display the type
When int
is picked present an empty textbox, DO NOT prefill with 0
as a default value, keep the value still uninitialized, but the editor already would know that the user wants to set an actual integer here. Keep presenting the red
symbol until the value is actually properly set by the user.
FORT-901741 has been added to our ‘To Do’ list. Someone’s been assigned this task.