# Quaternion.Lerp: How to interpolate faster to one axis than the other?

Hi,

I wrote a script where the camera follows a vehicle, optimized for loopings, jumps and “wall-rides”.

``````using UnityEngine;
using System.Collections;

public class CamFollow : MonoBehaviour {

public Transform target;
public Vector3 targetOffset = new Vector3(0f, 1f, 0f);
public Vector3 checkGroundOffset = new Vector3(0f, -0.5f, 0f);
public float distance = 10;
public float angle = 20;
public float turnSpeed = 1;
public float detectGroundSpeed = 5;

float onGround;
Quaternion smoothRot;

void FixedUpdate() {
Vector3 targetPos = target.position;
Quaternion targetRot = target.rotation;
// is the target touching ground?
if (Physics.Raycast(targetPos + targetRot * checkGroundOffset, -target.up, 1f)) {
onGround = Mathf.Lerp(onGround, 1f, Time.deltaTime * detectGroundSpeed);
} else {
onGround = Mathf.Lerp(onGround, 0f, Time.deltaTime * detectGroundSpeed);
}
// align target rotation
smoothRot = Quaternion.Lerp(smoothRot, targetRot, turnSpeed * Time.fixedDeltaTime * onGround);
// move camera to offset position
transform.position = targetPos + smoothRot * targetOffset;
// look-at target
Vector3 cameraLook = targetPos + smoothRot * (targetOffset - new Vector3(0, angle, angle-90f));
// up-vector
float misalign = 2f*(1f-Vector3.Dot(Vector3.up, target.up));
Vector3 camUp = Vector3.Lerp(Vector3.up, target.up, misalign * onGround);
transform.LookAt(cameraLook, camUp);
// move to distance
transform.Translate(0, 0, -distance);
}
}
``````

It works good so far, but I want that the helper rotation “smoothRot” aligns faster to the up-down movement than the left-right. So basically I want to somehow split this rotation into 2 parts to control each lerp speeds separately.

Maybe making a second helper rotation which aligns faster and than somehow combine both, but I’m not sure how exactly this could be achieved. I don’t think converting the Quaternions to Euler and than building an Euler from these would work, but any suggestion is appreciated.

You can split rotations like this:

``````using UnityEngine;
using System.Collections;

public class RotationTest : MonoBehaviour {

public Transform targetTM;
private Vector3 directionVec;
public float UpDownMultiplier = .05f;
public float RightLeftMultiplier = .01f;
private Vector3 upVec;
// Use this for initialization
void Start () {
directionVec = targetTM.forward;
upVec = targetTM.up;
}

// Update is called once per frame
void Update () {

Vector3 currentDirectionVec = targetTM.forward;
directionVec = new Vector3(Mathf.Lerp(directionVec.x, currentDirectionVec.x, RightLeftMultiplier),  currentDirectionVec.y,directionVec.z);
Vector3 currentUpVec = targetTM.up;
upVec = Vector3.Lerp(upVec, currentUpVec, UpDownMultiplier);
transform.rotation = Quaternion.LookRotation(directionVec, upVec);
}
}
``````

``````using UnityEngine;
using System.Collections;

public class RotationTest : MonoBehaviour {

public Transform target;
public float UpDownSpeed = 5;
public float RightLeftSpeed = 1;

Vector3 directionVec;
Vector3 upVec;

void Update() {
// align target rotation
directionVec = Vector3.Lerp(directionVec, target.right, RightLeftSpeed * Time.deltaTime);
upVec = Vector3.Lerp(upVec, target.up, UpDownSpeed * Time.deltaTime);
transform.rotation = Quaternion.FromToRotation(target.right, target.forward) * Quaternion.LookRotation(directionVec, upVec);
}
}
``````

Works 