- Home /
3rd person platformer OrbitCamera.js : making offset local space causes jitter
So I'm using a slightly modified version of the OrbitCamera script from the third person platformer tutorial on Unity in a third person shooter game.
In order to make it like a shooter, I'm just copying the camera's y rotation to the target (the player model/object), like so:
target.rotation = Quaternion.Euler(0, transform.eulerAngles.y, 0);
Which works great. However, the script also has a public var "targetOffset", which is a Vector3 that offsets the camera position, which is great. So in order to make a third person shooter with an "over the shoulder" type of view, you would think you could just set the x value of targetOffset to 1, so it's one unit over. However, targetOffset is in world space, so it doesn't quite work out. It gets a bit weird when you rotate the character around (camera will be left of the character or right, depending on what world direction you are facing).
So, I tried convert targetOffset to the local space of the target before adding it to the camera position, like so:
var localTargetOffset = target.TransformDirection(targetOffset);
var targetPos = target.position + localTargetOffset;
This works beautifully, but it adds a visible jitter on the rotation of the player model when I rotate, and I can't for the life of me figure out why. The jitter is only there under these circumstances.
Here's the entirety of the script with my changes:
var target : Transform; var targetOffset = Vector3.zero; var distance = 4.0;
var lineOfSightMask : LayerMask = 0; var closerRadius : float = 0.2; var closerSnapLag : float = 0.2;
var xSpeed = 200.0; var ySpeed = 80.0;
var yMinLimit = -20; var yMaxLimit = 80;
private var currentDistance = 10.0; private var x = 0.0; private var y = 0.0; private var distanceVelocity = 0.0;
function Start () { var angles = transform.eulerAngles; x = angles.y; y = angles.x; currentDistance = distance;
// Make the rigid body not change rotation
if (rigidbody)
rigidbody.freezeRotation = true;
}
function LateUpdate () { if (target) { x += Input.GetAxis("Mouse X") xSpeed 0.02; y -= Input.GetAxis("Mouse Y") ySpeed 0.02;
y = ClampAngle(y, yMinLimit, yMaxLimit);
var rotation = Quaternion.Euler(y, x, 0);
var localTargetOffset = target.TransformDirection(targetOffset);
var targetPos = target.position + localTargetOffset;
var targetDistance = AdjustLineOfSight(targetPos, direction);
currentDistance = Mathf.SmoothDamp(currentDistance, targetDistance, distanceVelocity, closerSnapLag * .3);
transform.rotation = rotation;
transform.position = targetPos + direction * currentDistance;
target.rotation = Quaternion.Euler(0, transform.eulerAngles.y, 0);
}
}
function AdjustLineOfSight (target : Vector3, direction : Vector3) : float { var hit : RaycastHit; if (Physics.Raycast (target, direction, hit, distance, lineOfSightMask.value)) return hit.distance - closerRadius; else return distance; }
static function ClampAngle (angle : float, min : float, max : float) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp (angle, min, max); }
Your answer
Follow this Question
Related Questions
Orbit Camera around object 2 Answers
Getting a scrolling camera to orbit around a circular walkway, following the player? 1 Answer
Why is 2d camera not smooth at 30 FPS 0 Answers
Camera Orbiting Character: How to make an object move with another with no rotation 1 Answer
Close To Camera Objects 0 Answers