- Home /
Making a camera that follows a rigidbodied sphere.
Okay, last question before I get my game going. I need to make a script that allows a camera to follow and rotate around the ball that I am controlling. See my other posts:
I tried the preloaded smoothfollow script. But when I apply it, the camera seems to not be pointed straight, it looks about 90 degrees off of the correct placement. So if I was to control it to go forward, it would look like it's going to the left, not forward. Not to mention, when I do use it, the camera skips around while rotating, almost like it's jumping from a point to another point. Here is the code for the ball:
function FixedUpdate () {
if (Input.GetButton("W"))
{
rigidbody.AddTorque (Vector3.forward * 2);
rigidbody.AddForce (Vector3.forward * 2);
}
if (Input.GetButton("S"))
{
rigidbody.AddTorque (-Vector3.forward * 2);
rigidbody.AddForce (-Vector3.forward * 2);
}
if (Input.GetButton("A"))
{
rigidbody.AddTorque (Vector3.left * 2);
rigidbody.AddForce (Vector3.left * 2);
}
if (Input.GetButton("D"))
{
rigidbody.AddTorque (Vector3.right * 2);
rigidbody.AddForce (Vector3.right * 2);
}
}
And here is the code for the Smoothfollow script that I tried before. Although most of everyone should already have it:
/*
This camera smoothes out rotation around the y-axis and height.
Horizontal Distance to the target is always fixed.
There are many different ways to smooth the rotation but doing it this way gives you a lot of control over how the camera behaves.
For every of those smoothed values we calculate the wanted value and the current value.
Then we smooth it using the Lerp function.
Then we apply the smoothed values to the transform's position.
*/
// The target we are following
var target : Transform;
// The distance in the x-z plane to the target
var distance = 10.0;
// the height we want the camera to be above the target
var height = 5.0;
// How much we
var heightDamping = 2.0;
var rotationDamping = 3.0;
// Place the script in the Camera-Control group in the component menu
@script AddComponentMenu("Camera-Control/Smooth Follow")
function LateUpdate () {
// Early out if we don't have a target
if (!target)
return;
// Calculate the current rotation angles
wantedRotationAngle = target.eulerAngles.y;
wantedHeight = target.position.y + height;
currentRotationAngle = transform.eulerAngles.y;
currentHeight = transform.position.y;
// Damp the rotation around the y-axis
// Damp the height
currentHeight = Mathf.Lerp (currentHeight, wantedHeight, heightDamping * Time.deltaTime);
// Convert the angle into a rotation
currentRotation = Quaternion.Euler (0, currentRotationAngle, 0);
// Set the position of the camera on the x-z plane to:
// distance meters behind the target
transform.position = target.position;
transform.position -= currentRotation * Vector3.forward * distance;
// Set the height of the camera
transform.position.y = currentHeight;
// Always look at the target
transform.LookAt (target);
}
Thanks for the help ahead of time UnityAnswers!
Go accept the answer to
http://answers.unity3d.com/questions/140150/rigidbodyaddtorqueaddforce-question.html
before asking more.
Now unbold this question. Being loud doesn't get more answers.
Answer by aldonaletto · Jul 06, 2011 at 11:35 PM
I don't know if this is what you're looking for, but there it goes: with this script, the camera follows the target object while it moves on the ZX plane as if both were tied by a rope of distance length. The movement smoothness is controlled by damp, and the camera is kept at a maximum 45 degrees angle from the ground:
var target: Transform;
var damp: float = 0.2;
var distance: float = 50;
function Update(){
damp = Mathf.Clamp(damp, 0.01, 10); // clamps damping factor
var pCam = transform.position;
var pTarget = target.position;
var diff: Vector3 = pTarget - pCam; // diff = difference between positions
var dist = diff.magnitude; // dist = distance between them
if (Mathf.Abs(diff.y) < 0.7*distance){
diff.y = 0; // doesn't modify camera height unless angle > 45
}
if (dist>distance){ // if distance too big...
diff *= 1-distance/dist; // diff = position error
// move a FPS independent little step towards the ideal position
transform.position = pCam + diff * Time.deltaTime/damp;
}
transform.LookAt(pTarget);
}
I'll give this a shot aldonaletto. I'll give you a shout back if it's what I was looking for =D
Thanks Aldon, now all I have to do to get the main concepts of my game working is fix my spheres movement so it's relative to the way it's facing.
Answer by Owen-Reynolds · Jul 06, 2011 at 10:39 PM
The problem is that the script assumes you are an upright person, with your Y-axis straight up, so all of your turning is on that Y-axis with the blue arrow (z) the way you are moving.
But, the ball is a chaotic swirling, with Y not even close to the way you are facing (start moving and switch to scene view -- Y will be tumbling head over heels. Imagine the camera trying to put itself the way the blue (forwards) arrow is smashing around.
A fix is to align the camera on the way the ball is moving (code has been tested):
currentRotationAngle = transform.eulerAngles.y; // need to move this line up
// Calculate the current rotation angles
//wantedRotationAngle = target.eulerAngles.y; <-- old line
MV = target.rigidbody.velocity; MV.y = 0; // "flat" speed of ball
if(MV==Vector3.zero) wantedRotationAngle = currentRotationAngle;
else // get the Y-spin of ball's speed:
wantedRotationAngle = Quaternion.LookRotation(MV).eulerAngles.y;
This stays "behind" the ball, but makes a new problem. It's hard to steer with ASDW (`A` isn't left -- it's West.) You'd need to rewrite Ballmove to apply local thrust instead of global (drive around with a fixed cam and you'll see the problem.)
It might be better to just always put the camera 10 south of the ball, and forget the fancy "behind" stuff.
Well I think I got to the problem. It doesn't move anywhere and it doesn't complete a spin.
It sits behind the ball as well. Not meaning to bug you in any way but what I was hoping for was that when the ball changed direction, the camera would flip to that direction as well. I'll look over the source again and see if I can figure it out. But if you know that would be great.
This one does flip the way the ball is moving. The diff is, if the ball changes directions, this quickly flips the camera over to the new "behind" for which way the ball is moving. The other "rope" one really is like a rope -- it only faces the move direction when the ball moves enough to "pull" it that way. Both are interesting -- use the one that you can understand better.
Your answer
Follow this Question
Related Questions
Super Monkey Ball type Camera? 2 Answers
How do I make a camera look for a specific GameObject while networking? 1 Answer
Can anyone please tell me why this script doesnt work? - Raycasting 1 Answer
Camera following/looking at aircraft 1 Answer
Camera Follow Object While Looking At Other Target 2 Answers