Best practice for an actor component to interact with another actor component

Hello, I’m writing an actor component that gives fighting abilities to a character. Currently the actor component I’m creating only works with an ACharacter since it uses it’s movement component to block movements, detect if the player tried to jump and stuff like that.

I’m not happy with this design however, I think an actor component should work for any type of actor and be independant of any other component (I might be wrong), so I though why not redesign my component so that it “requests” the actor that owns it to do these actions (block movements, detect jump, etc.). But again it raises another issue, my component looses it’s “plug and play” aspect and requires the developer to implement some features, which might be wrongly implemented which is even worse.

So I’m really scratching my head wondering if I should redesign the component to do this “request” thing, which would allow it to work with any type of actor and then create a ready-to-use character derived class that implements the required features to gain some time, or leave it as is and make it only work with characters.

Character and Character Movement are extremely tightly coupled and cannot operate independently of one another (you can’t add a character movement component to a non-character, for example).

If you’re designing something to work exclusively with a character, there’s nothing wrong with assuming it also has a character movement component.

Indeed a character always owns a movement component but I’m more bothered by the fact that my component only works with characters, I was wondering how I could extend that and I could only find one way of doing so

It really depends on the design of your component. I doubt a component that adds fighting abilities would make sense if applied to a static mesh actor for example, so I don’t see a huge issue in creating a dependency between that component and a certain type of base class. If you are reliant on features of the Character, you don’t have much choice really.

As an alternative, you could create an Interface/Component combination. The actor would have to inherit from a common Interface class and would provide functions that must be implemented by the actor, then the component can interface with it’s owning actor by casting it to an interface. Interfaces work best when they are CPP-only - reflected interfaces require a lot of jumping through hoops.



class ISomeInterface
{
    virtual void SomeCommonFuction() = 0;
}

class AMyCharacter, public ACharacter, public ISomeInterface
{

}

class ASomeOtherActor, public AActor, public ISomeInterface
{

}




void UMyFightingComponent::DoSomething()
{
    ISomeInterface* TheOwner = Cast<ISomeInterface>(GetOwner();
    if (TheOwner)
    {
        TheOwner->SomeCommonFunction();
    }
}


This only works in very specific scenarios though. Again if you are dependent on Character features, there’s nothing wrong with only allowing the component to be used by a Character class.

Thanks, that was really helpful, I will keep it that way and if I ever need to change I know I can use interfaces.