Architecturing inheritance for actor component

Hi, quite new in UE4, coming from an Unity background, I’m struggling to wrap my head around an architecture for a camera spot system.

To explain it a bit, the concept is to have areas in the game on which, where the character enter, it switch the camera to that spot which has it own properties. For example, in this spot, the zoom is using a spline defined by a designer in the viewport, or a spring arm with arm length , etc…

The character itself will also have a camera spot attached to him where the camera will be by default when he’s not in special areas

So, I’ll stick with the zoom example which will be a base for various other properties…
I’m trying to understand how to setup everything on c++ side to have something as simple as that : The designer in the editor detail choose an enum value for zoom like that which will be a property in the CameraSpotActor :

UENUM()
enum class EZoomCameraMode : int8
{
Spline,
ArmLength,
None
};

Each of this enum will have a c++ class defined which derived from ZoomMode as :

  • IZoomMode inherit ASceneComponent
  • SplineZoomMode inherit IZoomMode - Has a property USplineComponent
  • ArmLengthZoomMode inehrit IZoomMode - Has a property USpringArmComponent

So I would like, when the designer select the enum ZoomMode, that It spawn this specific ZoomComponent based on it, where It spawn subcomponent coming from them but I’m don’t really know how to achieve this, do I need to use the PostEditChangeProperty or generally speaking, It is the good approch to this problem in UE ?

Thanks

So you want an actor that will have a different kind of component attached to it, depending on the setting of an enum?

If you don’t need to specify any parameters inside the components, you could just make a function that cleans up any un-necessary components (in the case of a change) and adds the correct component, which you can call from PostEditChangeProperty as well as BeginPlay. Without further knowledge, I can’t really foresee any issues that might crop up there.

If you do need to specify parameters, just forget about the Enum, and make a blueprint for each one that has the right kind of component.

Thanks for the answer! Yeah basically that the idea, having different kind of component based on that enum value which can be set in the detail panel.

About the parameters I’m afraid I do need to specify some, indeed each kind of component themselves contains other component (for example USplineZoomMode contains a USplineComponent that need to be defined, and some parameter attached to it for example the speed of the interp on that spline)

For the second part of your answer, I think that would add way too much complexity, I mean, the example here is simple, with the zoom, but the same principle will apply for LookAt, Follow, etc… of the camera in a Camera Spot, so defining all that combination is a bit overkill no ?

There is no other way to do it ?

I was thinking about something else, dunno if that could works :
The designer define either a SpringArm or a USplineComponent in the viewport of the Actor Camera Spot, and tag that one with something like “Rotation”, then in the begin play, I search for component with that tag, and I’ll know that if a USplineComponent with a tag “Rotation” is defined, it means that I need to handle the rotation based on that spline ?

You don’t need a different component. You can use the SetCameraTarget() function (which, confusingly, does not tell you what to point the camera at.)

So, build a trigger box for the volume where you want special camera. Add the camera you want to use to that same actor. Make the trigger only overlap player pawns. In the “On actor enter” callback, find the playercontroller of the player entering, and call SetViewTarget() on it, with yourself as the actor. In the “On actor leave” callback, find the playercontroller again, and call SetViewTarget() with null, or with the controlled Pawn as the view target, to give camera control back.

Thanks for the reply, but that’s not really what I am struggling with, the movement of the camera to be at the camera spot location is not the problem, I’m struggling with architecturing the various components inside this camera spot that are needed in order to know what it is possible and not possible to do with the camera

It’s kind of hard to me to understand what you’re trying to accomplish, because it sounds like you’re trying to use inheritance to solve a problem which would probably be solved some other way.
Inheritance is, generally speaking, a pretty blunt mechanism. Unreal uses it to establish interfaces for certain components that go together (actors and actorcomponents, say,) which is fine, but you should not necessarily try to jam every little change into that structure.

First, you can have as many camera components or actors as you want. When an actor is the ViewTarget, then the first camera component of that actor will by default be the active camera. Thus, you can create many camera actors, and when you want a different camera behavior, set the right-behaving camera actor as the view target.

Second, you can have a single camera component, but have it have different behaviors, built into the component update or Tick. It could even reference multiple different other components or actors, such as the “spline track” to follow, that it only uses when in certain modes. If you want the camera to behave differently, flip it into a different model.

Third, you could factor “camera behavior modes” into separate actor components, and have one camera components that they get to move around, and then have one actor component that’s the “current camera mode.” Changing the camera mode would imply changing which of the many behaviors is currently selected.

Fourth, if all else fails, then there’s the PlayerCameraManager, which you can subclass and implement in whatever way you want to do whatever you want with camera cuts and pans and other parameters.

Fifth, if you only need certain “fixed” behaviors in fixed situations, you can animate the cameras using timelines and/or cinematic clips.

That being said, I’m still not 100% sure of what you’re trying to do, because “moving a camera along a spline” is a camera dolly action, whereas “zooming” a camera means changing its focal length (and thus its field-of-view value.) Those are totally different actions.

Hi, thanks for your complete answer, I’ll try to give as much informations as possible in order to understand the issue, but just a tiny question before that about having multiple camera, it is impactfull in performance manner ? If the level have says 100 camera component / camera actor, does is impact performances ?

That being said, the idea for the inheritance is to have a flexible and evolutive way to implement various zoom technique / follow technique / look at technique basically for the camera

I’ll give a concrete example of a situation : the player character enter a room which has a ACameraSpot, and thus, that need to have the camera act differently than usual. In this situation, the camera need to follow a Spline in order to simulate a zoom, visualize the spline as a top down spline, going for an upper point of view to a closer one, it should also always look at the player no matter what, and finally, it follow the player with a second circular and flat spline, getting the closest point to the player and staying on that spline

So basically, my designer would assign something like that in the detail panel :

  • RotationMode : LookAtPlayer
  • ZoomMode : Spline
  • MoveMode : Spline

Then, he has to build 2 spline component which will be use for the ZoomMode & the MoveMode, the coding of zoom, move etc is not the problem, I’m struggling on how to architecture this in UE4 in order to have those various mode as plug&deplug component which can be set when designer choose a mode base on an enum for example

For the inheritance part, I’ll take only the Zoom example, and I would like to have something like this in pseudo code, it is where I’m struggling, knowing this that could work and if this is how I should handle it :

class UIZoomMode : USceneComponent
{
    UPROPERTY()
    float NumberZoomStep;
}

class USplineZoomMode : IZoomMode
{
    UPROPERTY()
    USplineComponent* Spline;
}

class ACameraSpot : AActor
{
    UPROPERTY()
    UIZoomMode ZoomMode;
}

First, if you have inactive actors and inactive components, they cost almost nothing. If you really care, you can explicitly enable/disable them with “set actor enabled.”
(Only the currently-active camera actually does rendering; the others don’t affect rendering at all; the only savings is the “actor management” bits which are very low overhead unless you have physical/collision geometry involved.)

If you want a particular camera animation when the player enters the room, this sounds very much like a job for matinee, not for any custom action in the camera player logic at all. Place a camera in the room, and a trigger volume. Build a matinee timeline that animates the camera as appropriate. When the player enters the trigger volume, cut to the matinee camera using SetViewTargetWithBlend, with some blend time of maybe 0.2 seconds (tune this,) and start the matinee sequence playing. The matinee sequence will temporarily take over “this is the active camera” and animate it as appropriate. When you’re done, call SetViewTargetWithBlend() again to smooth back to the player camera over whatever time interval you choose.

You need to do exactly zero custom work on the character, or on the character’s camera, to make this effect.
The ActorSequenceComponent is a little fiddly/experimental, but you can make it work that way.

The trick to the ActorSequenceComponent is to type in the key values manually in the left of the track, not trying to get mouse dragging components to work. (This is why it’s experimental, I think.)