C# Smooth Follow Space Ship
Hello. I have this space ship that has a camera as a child of it. Before, the camera would just stay behind the space ship in the position where I placed it as a child. Now, I want to have the camera follow the ship smoothly, and I want the ship to turn smoothly to make it look more legit. The problem is, when I use scripts for smooth following from the standard asset package and other questions, the camera does not follow the ship right. Here is the script for the ship. There is no script for the camera.
using UnityEngine;
using System.Collections;
public class Player1 : MonoBehaviour
{
public float yawSpeed;
public float rollSpeed;
public float pitchSpeed;
public float BoostSpeed;
public float BrakeSpeed;
public float ShipSpeed;
public Rigidbody projectile;
public float ProjSpeed;
public Transform Launch;
public float DefaultSpeed;
void Start () {
ShipSpeed = DefaultSpeed;
Screen.lockCursor = true;
}
void Update ()
{
transform.Translate(Vector3.forward * ShipSpeed * Time.deltaTime);
if(Input.GetKey(KeyCode.W)){ //accelerate
ShipSpeed = BoostSpeed;}
else if(Input.GetKey(KeyCode.S)) {//decelerate
ShipSpeed = BrakeSpeed;}
else {
ShipSpeed = DefaultSpeed;}
if (Input.GetAxis("MouseX") < 0) //yaw left
transform.Rotate(Vector3.up, -yawSpeed * Time.deltaTime);
if (Input.GetAxis("MouseX") > 0) //yaw right
transform.Rotate(Vector3.up, yawSpeed * Time.deltaTime);
if (Input.GetAxis("MouseY") < 0)//pitch down
transform.Rotate(Vector3.right, -pitchSpeed * Time.deltaTime);
if (Input.GetAxis("MouseY") > 0) //pitch up
transform.Rotate(Vector3.right, pitchSpeed * Time.deltaTime);
/*if(Input.GetKey(KeyCode.E)) //roll right
transform.Rotate(Vector3.forward, -rollSpeed * Time.deltaTime);
if(Input.GetKey(KeyCode.Q)) //roll left
transform.Rotate(Vector3.forward, rollSpeed * Time.deltaTime);*/
if(Input.GetKeyDown(KeyCode.Space)){ //Shooting
Rigidbody InstantPro = Instantiate(projectile, Launch.position, Launch.rotation) as Rigidbody;
InstantPro.AddForce(transform.forward * ProjSpeed * Time.deltaTime);
}
}
}
This question is very vague. What does "the camera does not follow the ship right." mean? If there is no script for the camera, how should it be following? Please be more specific when submitting questions to Unity Answers, and review the FAQ suggestions on how to write good questions http://answers.unity3d.com/page/faq.html
It's difficult to explain, so I didn't want to further confuse people. The script from standard assets just makes the camera flip around, and it doesn't always return to exactly the right target spot.
Answer by degraffenried · Jul 31, 2016 at 07:34 PM
I was looking for the same answer, and used a smooth follow script that was ported to C#, and modified it for 3D space. The trick is to use quaternions. I'm still getting used to the quaternion libraries that Unity uses, but in the past I did transformations directly using the matrices. Fortunately Unity has those libraries available. So, here is my code, just tweak it a bit to make it perform the way you need.
using UnityEngine;
using System.Collections;
[AddComponentMenu("Camera-Control/Smooth Follow 3D CSharp")]
public class SmoothFollow3D : MonoBehaviour
{
// The target we are following
public Transform target;
// The distance in the x-z plane to the target
public float distance = 10.0f;
// the height we want the camera to be above the target
public float height = 5.0f;
// How much we
public float heightDamping = 2.0f;
public float rotationDamping = 3.0f;
void LateUpdate ()
{
// Early out if we don't have a target
if (!target)
return;
Vector3 followpos = new Vector3(0.0f, height, -distance);
Quaternion lookrotation = Quaternion.identity;
lookrotation.eulerAngles = new Vector3(30.0f, 0.0f, 0.0f);
Matrix4x4 m1 = Matrix4x4.TRS(target.position, target.rotation, Vector3.one);
Matrix4x4 m2 = Matrix4x4.TRS(followpos, lookrotation, Vector3.one);
Matrix4x4 combined = m1 * m2;
// THE WAY TO GET POSITION AND ROTATION FROM A MATRIX4X4:
Vector3 position = combined.GetColumn(3);
Quaternion rotation = Quaternion.LookRotation(
combined.GetColumn(2),
combined.GetColumn(1)
);
Quaternion wantedRotation = rotation;
Quaternion currentRotation = transform.rotation;
Vector3 wantedPosition = position;
Vector3 currentPosition = transform.position;
currentRotation = Quaternion.Lerp(currentRotation, wantedRotation, rotationDamping * Time.deltaTime);
currentPosition = Vector3.Lerp(currentPosition, wantedPosition, heightDamping * Time.deltaTime);
transform.localRotation = currentRotation;
transform.localPosition = currentPosition;
}
}