Get Actor to stay on top of terrain during movement

Hi everyone I have a quick question for my camera/Actor setup.

For my camera (RTS style) I decided to have the camera component attached to a root component via a spring Arm.
This allows me to easily zoom and rotate the camera in a RTS like manner.
Moving the camera is then achieved using AddActorWorldOffset on the Camera Actor.

This works quite well on plain terrain. However when I move towards a slope or hill, I would like the Camera Actor to always stay on top of the terrain.
In my current setup the Actor is just pushed under the terrain and the Z position is not adjusted.

What would be a good approach? (C++ implementation).
I already tried to use a sphere component to give my actor collision but I am unsure if I have to change anything in particular to get my desired result.
I saw in other general UE tutorials that Pawns and Characters have slope walking functions already implemented. However my Camera Actor is derived from AActor and I would like to keep it that way.

One other solution that I came up with would be to send out an ray every tick to check for the distance to the ground and adjust it accordingly. But perhaps there is a native function in unreal for this.

Thanks for any suggestions!
If additional information is required feel free to reach out

 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	RootScene = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
	RootComponent = RootScene;

	sphere = CreateDefaultSubobject<USphereComponent>(TEXT("Sphere"));

	springArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
	springArm->ProbeChannel = ECollisionChannel::ECC_WorldStatic;
	springArm->bDoCollisionTest = true;
	springArm->ProbeSize = 12;
	springArm->SetRelativeRotation(FRotator(-50, 0, 0));

	camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));

I’ve use something like this before which works fine. I’m curious why don’t want to use a pawn for this though? There is a floating movement component which has some nice built in functions that could be useful to you as well.

Hey @Bizes firstly, welcome to the forums! This is a bit of a matter of preference in my opinion, I personally tend to go with the ray to terrain and adjust height based on hits there. However as Arlyn was saying we also have the option of using the UfloatingPawnMovement component which does lots of the movement code for you but would still require the ray or a special spring arm set up with collision. Here’s the documentation on that if you’d like it!

Hi @Arlyn & @SupportiveEntity ,

thanks for your ideas.

Well the reason for not using a Pawn for my camera Actor was that I already have a Pawn actor in the scene which is always possessed by the player.
So far I assumed that having another pawn and moving it would also require possession by the player. Seems like I haven’t fully understood the Pawn/Character system yet :D.

I will look at the UFloatingPawnMovement and see if I can use it. If not I’ll go with the ray.


You’re correct that you can only possess one pawn as a player, (I also thought RTS which would mean the player is the camera/controller haha) however possession isn’t the only way to use the pawn’s native functions. Since you’re working in C++ you could also feasibly extend it if you wanted, but either way a simple ray would probably be the easiest to implement if your camera already has all the functionality. Let me know if you have any questions and good luck with the implementation!

oh thanks for the information. Yeah it is a bit weird. We have a separate Pawn that handles all the inputs. I am not even sure anymore why but it is how we have it implemented currently.

I tried to convert the camera class to a Pawn and then use the UFloatingPawnMovement, but I cant get it to work.
I was able to add the component but regardless of what I change it does not affect the movement in any way.

However the ray works perfectly and I will stick with it for now.
Thanks for the help!

1 Like