I have a door derived from AActor
that can be locked. It contains several locking-related variables and functions, eg. bool isLocked
, uint32 keyID
, etc. Since doors aren’t the only thing in my game that can be locked, I decided to move those lock-related things into their own class, called Lockable
. The declaration of the door class is now like this:
UCLASS()
class ADoor : public AActor, public Lockable { ...
I want to be able to set isLocked
and keyID
in the properties panel of the editor when I drag a door actor onto the stage. Using the UPROPERTY()
macro in the Lockable
class does nothing. How can I accomplish this?
Also wondering if this would be possible for actors containing other actors, say I have an ALock*
object inside the door class and would like to set some variables of it.
I would also like to surface UPROPERTYs from other classes used as data members. However, I don’t think it’s possible. The only workaround I can think of is to copy the UPROPERTYs you want into the root class and forward changes to the object. For example in the header of my actor component I have:
UTestType* Test; // some object I delegate work to
UPROPERTY(EditAnywhere)
float Foo; // where Foo is actually a property on UTestType
and after the value is changed in editor, forward the message:
void UDistributeComponent::PostEditChangeProperty(struct FPropertyChangedEvent& e)
{
const FName PropertyName = e.Property->GetFName();
if (PropertyName == GET_MEMBER_NAME_CHECKED(UDistributeComponent, Foo))
{
Test->Foo = Foo; // forward message
}
You could have the Lockable class derive from AActor, and then have any lockable actors derive from it:
UCLASS()
class ALockable : public AActor {
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Locking")
bool isLocked;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Locking")
int32 keyID;
...
UCLASS()
class ADoor : public ALockable {...
UCLASS()
class ANotherLockableActor : public ALockable {...
This gets a little unwieldy if you have lots of combinations.
The other way to go about is by placing your Lockable functionality within a component.
//within LockableComponent.h
UCLASS()
class ULockableComponent : public UActorComponent {...
//within Door.h
UCLASS()
class ADoor : public AActor {
//constructor
ADoor::ADoor();
...
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
ULockableComponent* LockableComponent;
...
//within Door.cpp
ADoor::ADoor ()
:
AActor
{
...
LockableComponent = CreateDefaultSubobject<ULockableComponent>(TEXT("LockableComponentName"));
...
}
You can also use CreateOptionalDefaultSubobject in your constructor; or you can create the object dynamically after spawn in a separate method via NewObject.
In the editor your isLockable and keyID properties would appear as values within the LockableComponent property.