x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Subcomponents for logic?

Hi,

I have migrated over here from the CryEngine and am having a little trouble with UE4s class templates. I am currently building a character properties system that is split into different subsystems. So for example there is a system that manages health and a different system that handles a characters movement setup. The idea behind this setup is that you can combine different templates for the different systems into different characters. I had already programmed this for CryEngine and it worked. As I am currently migrating this into UE4 I ran into a problem with the UE4 classes. To enable reflection and blueprint setup, which seems to be key in UE4, my classes need to be subclasses of the UE class templates. I read the overview for the classes and decided to let my classes inherit from UActorComponent as my system would be a subobject of an Actor and it should be tickable. That seemed to work for a single component. But apparently ActorComponents can't be subobjects of ActorComponents, which admiditly makes sense but is also somewhat problematic as I now don't know from what class to inherit my classes...

To the technical part:

I want to build the following hierachy: Actor->HealthStats->Individual health components (Array)

Here the class HealthStats:

     #pragma once
     
     #include "HealthComponent.h"
     #include "Components/ActorComponent.h"
     #include "CharacterHealthStats.generated.h"
     
     UCLASS()
     class UCharacterHealthStats : public UActorComponent
     {
         GENERATED_UCLASS_BODY()
     
         enum EHealthComponents {
             HEALTH = 0,
             ARMOR,
             LAST
         };
         UPROPERTY(EditDefaultsOnly, Category = HealthComponents)
         TSubobjectPtr<UHealthComponent> m_healthComponents[LAST];
 
         Update(float frameTime);
     };
 
 // .CPP starts here
 
 UCharacterHealthStats::UCharacterHealthStats(const class FPostConstructInitializeProperties& PCIP)
     : Super(PCIP)
 {
     m_healthComponents[HEALTH] = PCIP.CreateDefaultSubobject<UHealthComponent>(this, TEXT("Health"));
     m_healthComponents[ARMOR] = PCIP.CreateDefaultSubobject<UHealthComponent>(this, TEXT("Armor"));
 }
 
 UCharacterHealthStats::Update(float frameTime) {
 //Call Update(frameTime) for all components
 }

Here is the code for UHealthComponent:

 #pragma once
 
 #include "HealthComponent.generated.h"
 
 UCLASS()
 class UHealthComponent : UActorComponent
 {
     GENERATED_UCLASS_BODY()
 
     UFUNCTION(BlueprintCallable, Category = Functions)
     void Update(float time);
 
     UFUNCTION(BlueprintCallable, Category = Functions)
     void Drain(float drain);
 
     UPROPERTY(EditDefaultsOnly, Category = Values)
     int32    m_maxValue;
 
     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Values)
     float    m_value;
 };
 
 UHealthComponent::UHealthComponent(const class FPostConstructInitializeProperties& PCIP)
 : Super(PCIP)
 {
     m_maxValue = 100;
     m_value = 100;
 }
 
 void UHealthComponent::Update(float frameTime) {
 //Do what needs to be done
 }

A few last things to note:

  • As you can see neither of the two need any kind of "worldly" representation

  • It doesn't matter to me wether the system itself or the actor ticks the classes, but I would prefer the Actor to do it.

So I hope this gives you enough information to be able to help me.

Best regards!

Product Version: Not Selected
Tags:
more ▼

asked Jun 22 '14 at 02:35 PM in C++ Programming

avatar image

Saniamos
6 2 4 4

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Main question is why would you want to make nested actor components ? It doesn't bring any benefits expect more complicated design.

What do you want to do, is to create AttributeComponent (or something like that), which will be simply attached to actor.

AttributeComponent will contain any attributes you want as UPROPERTY(), and any function helpers you may need to modify those attributes.

Also remember to override OnRegister(), as this is the place where you want to register all changes to your attributes if you have more complex setup like one attribute calculated from another.

You might also want to create UBlueprintFunctionLibrary with static functions which will be helping to work with your attributes.

If you want to take quick look at what I mean you can look at engine source for AbilitySystem module or on my Action RPG sample (in the works): https://github.com/iniside/ActionRPGGame/tree/master/Source/ActionRPGGame/Componenets For AttributeComponenets. I have finished implementing this (it boiled down to more pressing issues), but you can see beginings of the system. It also uses reflection system, to take arbitary properties out of class by specified their name.

more ▼

answered Jun 22 '14 at 03:02 PM

avatar image

iniside
1.6k 105 98 185

avatar image Saniamos Jun 22 '14 at 08:31 PM

Thanks for the quick reply!

After a quick look at your code I think it does what I want to do just one step higher in the hierachy. The nesting makes sense when you get to a higher level of complexity in the attributes you have to organize. The code I posted was a short version of my real system to convey the idea of the structure. My long version has 14 subcomponents with 9 attributes each which would clutter up the character-class and also make deriving from the character a lot more difficult.

Is there a template for an AttributeComponent or would I have to write it myself? And if I have to write it myself would I derive from Object or another class?

avatar image iniside Jun 22 '14 at 09:42 PM

Well for me the fact there there might 100 possible attributes in single class is not an problem. I never access them directly, I access them trough function and by specifing their name like:

GetAttribute("Health");

If that still doesn't suit you, you can pack attributes into structs like:

 USTRUCT(BlueprintType)
 struct FMyAttribute
 {
   UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Attribute")
   float Health;
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Attribute")
 float Mana;
 }

And then just declare them as:

 FMyAttribute MyAttribute:


Believe me it's better solution, that trying to over abstract and over organize everything ;). I've tried the more generic the better approach before, and all it does it. increase complexity in exponentially.

You can also create hierarchy of Componenets like:

 MyAttributeComponent : UActorComponent
 
 
 MyAwsomeAttribute : MyAttributeComponent;

etc.

But it will require some planning ahead of what you want at each level of hierarchy.

Least but not least. You can create nested Subobjects when you use UObject instead of ActorComponent. But this makes it hard to expose back to blueprint and edit properties inside editor.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question