How to make a character orbit a target with AddMovementInput

I’m trying to make a character orbit its target in a 3rd-person 3d game, similar to the way zelda or dark souls does it. With what I have now the character spirals out the longer you press the strafe button.
I’m trying to take the velocity vector that the movement component creates and angle it so it falls on the orbit path.
The formula I’m using for the rotation angle (the one under the character) is:

Angle = ArcCos(.5*V/R)

where V is the speed and R is the circle’s radius (distance to target).

This is the blueprint I have. The output vector goes straight into the add movement input node with a scale of ABS(axis input).

What am I doing wrong here? Is there a simpler way to do the same thing?

What is your camera doing during all this? If your character’s rotation is always following the camera, and the camera is always facing directly at the target, then your strafe should be constantly adjusting to a 90 degree angle at all times, creating a perfect circle on its own.

My character is constantly rotating to face the target, which is a function I call from tick. The camera is rinterped to follow with a slight lag. I originally tried what you described, because it sounds like it should work, but it makes the spiralling even worse.

Here’s the camera/actor rotate function (get control rotation should be connected to the rinterp node):

Ok, yeah i tried it out and I see what you mean. It doesn’t really make sense. Regardless, I’ve come up with a way to compensate for it. It’s a bit brute force, but it seems to work fairly well in my test.

I made a custom event that gets the vector length between the target and the player and puts it in float variable, let’s call it “TargetDistance”.

I trigger this event (to update the target distance) when I initially lock on and every time the absolute of the InputForwardAxis is greater than .1.

Then, at the end of the rotate function (every tick) I check to see if the current vector length is equal to the “TargetDistance”.

If not, I set the current location of the character forward/backwards by adding/subtracting any increment to the forward vector. It will do this every tick until it matches the “TargetDistance” again.

Using this method I was able to keep the player on a perfect radius around the target at all times without any significant side effects. You might have to finesse some of the minor details but the concept seems to work. Let me know if you want pictures.

Thanks, the orbiting works now, but it won’t let me move forward or backward. I’m probably doing something dumb though, I’ll check it again tomorrow.