# Clamp camera view angles relative to moving object

I have a camera attached to an entity that moves in a circular pattern around a fixed center position. I am attempting to clamp the rotation of the camera such that it can only look inward toward the center of the circle.

I have tried for some time to accomplish this but haven't had much luck.

Simply clamping the angles like this will not work:

rotation = Vector3.Clamp(rotation, new Vector3(-50.0f, rotationY, 40.0f), new Vector3(-20.0f, rotationY, 100.0f));


(the rotation angles are relative to world space, and not the local rotation of the entity)

I need to get a clamp value that is relative to the direction the entity is facing.

Is there any way I can accomplish this?

Update-

Adding the rotation of the entity to the camera rotation like in the following seems to work intermittently, but now it seems the camera starts stuttering at certain points around the circle.

Still stuck.

Vector3 clampMin = new Vector3(-50.0f, 0, 40.0f);
Vector3 clampMax = new Vector3(-20.0f, 0, 100.0f);

public void Update()
{
// adding the users input
rotation = camera.Rotation + (new Vector3(GetInputY(), 0, GetInputX()) * 4.0f);

float clampX = ClampAngle(rotation.X, clampMin.X, clampMax.X);

float clampZ = ClampAngle(rotation.Z,
entity.Rotation.Z + clampMin.Z,
entity.Rotation.Z + clampMax.Z);

camera.Rotation = new Vector3(clampX, 0, clampZ);

}

• To reduce stutter, you might try lerping the angles? Something like lerp(lastangle,newangle,0.2) – Felsir Nov 17 '16 at 12:34

You can set the position of the camera as an offset to the entity relative to the center. Then you can focus the ViewDirection of the camera directly on this center.

float scale;
Vector3 center;
var altitudeOffset = new Vector3(0, 0, x);
var entityRelativeToCenter = entity.Position - center;

// you can also use '+ scale'
camera.Position = entityRelativeToCenter * scale + altitudeOffset + center;
camera.ViewDirection = center;


If you wanted to move freely without the camera moving constantly, you can Clamp it with a range.

float allowedAngle;
var minRange = entityRelativeToCenter.Rotate2D(-allowedAngle);
var maxRange = entityRelativeToCenter.Rotate2D(allowedAngle);
camera.Position = Vector3.Clamp(camera.Position, minRange, maxRange);

• Thanks for the response, but in my case i'm trying to clamp the rotation of the camera and not the position. I've updated my post with a solution that is partly working but i'm still having problems. Mainly, the camera starts stuttering at different points in its rotation. Any ideas? – Cam Aug 9 '16 at 23:15
• you are playing with hard values, can you give all hard values like camera.Position and center? – Greaka Aug 10 '16 at 8:30
• I think I over-complicated my question when I talked about the circular pattern. Forget that. Basically all I want to do is have it so the camera is locked within a particular range, pointing to the relative left of the entity position. I want it to stay looking to the left, regardless of how the entity is oriented in the world. I then want the player to be able to rotate the camera within this fixed range. The problem is, I need to calculate the clamp values based on the entity orientation, since fixed values will only be relative to world space and not the local rotation of the entity/ cam. – Cam Aug 11 '16 at 20:40

The reason you are getting stutters is because you might be updating the camera position before the position of the moving object is updated.

You can fix this by moving your camera code into LateUpdate() or by adding script execution orders to both the object and camera scripts and setting the camera script's order to a higher value. You can set this under Edit->Project Settings->Script Execution Order.