Я когда-то делал, чтобы камера за плечом была.

public class CameraOrbit : MonoBehaviour {
public Transform target;
public Vector3 targetOffset = new Vector3(0, 1.5f, 0);
private Vector3 smoothTargetPosition;
public float minAngleX = -20, maxAngleX = 60;
private Vector3 angles;
private const float minDistance = 1.0f;
private float distance;
public float maxDistance = 7.0f;
public Vector3 cameraOffset = new Vector3(1, 0, 0);
void OnEnable() {
if( !target ) return;
angles = transform.eulerAngles;
distance = maxDistance;
smoothTargetPosition = target.TransformPoint(targetOffset);
}
void FixedUpdate() {
if( !target ) return;
Vector3 targetPosition = target.TransformPoint(targetOffset);
smoothTargetPosition = Vector3.Lerp(smoothTargetPosition, targetPosition, 20*Time.deltaTime);
}
void LateUpdate () {
if( !target ) return;
angles += GetInputRotation();
angles.x = ClampAngle(angles.x, minAngleX, maxAngleX);
Quaternion rotation = Quaternion.Euler(angles);
Quaternion smoothRotation = Quaternion.Slerp(transform.rotation, rotation, 20*Time.deltaTime);
ComputeTransform(smoothTargetPosition, smoothRotation, maxDistance, cameraOffset);
CollisionTest(smoothTargetPosition);
}
private void ComputeTransform(Vector3 targetPosition, Quaternion rotation, float distance, Vector3 cameraOffset) {
transform.rotation = rotation;
transform.position = targetPosition;
transform.Translate(0, 0, -distance);
transform.Translate(cameraOffset * distance);
}
private void CollisionTest(Vector3 targetPosition) {
float newDistance = CameraCollider.CollisionTest(camera, targetPosition, maxDistance);
newDistance = Mathf.Max(newDistance, 0.5f);
newDistance = Mathf.Lerp(distance, newDistance, 10*Time.deltaTime);
Vector3 dir = transform.position - targetPosition;
transform.position = targetPosition + dir.normalized * newDistance;
distance = newDistance;
}
private static float ClampAngle(float angle, float min, float max) {
if (angle < -360) angle += 360;
if (angle > 360) angle -= 360;
return Mathf.Clamp (angle, min, max);
}
private Vector3 GetInputRotation() {
#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
return MobileInput.GetRotation();
#else
if( !Input.GetMouseButton(1) ) return Vector2.zero;
float dx = Input.GetAxis( "Mouse X" )*4;
float dy = Input.GetAxis( "Mouse Y" )*4;
return new Vector2(-dy, dx);
#endif
}
}