- Home /
Reposition camera behind the player character during movement
Hi all,
I'm currently using the MouseOrbit.js script from the standard assets to allow the player to rotate the camera around the main character during the game. I'd now like to have the camera reposition itself behind the player character when she moves, so that the camera always faces in the direction the player character is moving.
I found a fascinating thread on the forums where they were attempting to recreate the camera system from WoW. I haven't played it myself, but from the descriptions it sounds like the camera repositions itself behind the player character. In particular i've borrowed a couple of lines from that script and amended my MouseOrbit script (specifically the if statement in the LateUpdate function):
var target : Transform; var distance = 10.0;
var xSpeed = 250.0; var ySpeed = 120.0;
var yMinLimit = -20; var yMaxLimit = 80;
private var x = 0.0; private var y = 0.0;
var rotationDampening = 3.0;
@script AddComponentMenu("Camera-Control/Mouse Orbit")
function Start () { var angles = transform.eulerAngles; x = angles.y; y = angles.x;
// Make the rigid body not change rotation
if (rigidbody)
rigidbody.freezeRotation = true;
}
function LateUpdate () {
if (target) {
// this is the part I believe I am repositioning the camera
if(Input.GetAxis("Vertical") || Input.GetAxis("Horizontal")) {
var targetRotationAngle = target.eulerAngles.y;
var currentRotationAngle = transform.eulerAngles.y;
x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
} else {
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 position = rotation * Vector3(0.0, 0.0, -distance) + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
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); }
It works but with two problems:
1) When I press Play, the camera jumps to a rotation looking at the player depending on where the mouse pointer is on screen when I start the game, rather than initially starting behind the player.
2) When I move the player character, the camera repositions itself in front of the player character rather than behind. The values must be reversed in some way, I need to figure out how to flip them.
I make a point of never using a script unless I at least understand what it does (preferably how it does it) since I don't subscribe to the "write my script for me" ethos. But I have to admit I don't really understand what's going on here. If I did, i'd probably be able to work out myself how to fix the two problems above.
If someone could enlighten me, i'd be extremely grateful.
Answer by sean · May 07, 2010 at 07:32 PM
(1) is likely some function of your default camera transform... I'm not seeing anything in the update script that does more than apply an offset to the existing camera position/rotation. That Else clause just takes the amount the mouse has moved this frame, scales it a bit, and adjusts the script's own notion of what the camera x & y rotations should be. Check that the camera as it exists in your scene prior to running the game is in the position and facing the direction you want, and isn't being affected by any scripts before this one, because up in Start, this one sets its own internal x and y to the camera transform as of application start. Alternatively, you may try moving the first 3 lines of Start into the top of LateUpdate so when LateUpdate does its x+=/y+= stuff, it's offsetting the most recent camera position. This will, however, screw up the auto lerp-angle generation in the first part of the If clause, and consequently screw up your follow-target-motion effect :P
(2) may indicate your models are set up in a different axis orientation than the target used by the original author (e.g. your models face X+, theirs faced X-). Just add +180 to the targetRotationAngle and CurrentRotationAngle lines, or alternatively, just after the LerpAngle() where x is assigned. I'd imagine that does it.
Hi Sean, thanks for your answer, that cleared up a lot of confusion! At first neither worked, but re. #2 I 'forgot' that I used an empty gameObject as my target so I could reposition it for a better view (I realise now I could have just moved my camera, but it turns out I do have an orientation problem with my model so this actually fixes that). Looking at the empty more closely, when I reset its x/z positions to 0, I must have forgotten to change its rotation. It was set to 180 in the y-axis. Changing this to zero has fixed both problems above and it works perfectly now. Thank you!