Spring Follow Camera (C#)

So, I’ve written spring cameras before in other APIs, but I can’t seem to wrap my head around Unity’s (I’m still fairly new to it). Here is my SpringFollow camera script in C#

using UnityEngine;
using System.Collections;

public class SpringFollow : MonoBehaviour
{
    public Transform Target;
    public Camera SpringCamera = Camera.mainCamera;

    public float Stiffness = 1800.0f;
    public float Damping = 600.0f;
    public float Mass = 50.0f;
    public Vector3 DesiredOffset = new Vector3(0.0f, 3.5f, -4.0f);
    public Vector3 LookAtOffset = new Vector3(0.0f, 3.1f, 0.0f);

    private Vector3 desiredPosition = Vector3.zero;
    private Vector3 cameraVelocity = Vector3.zero;

	// Use this for initialization
	void Start () 
    {
	
	}

    void FollowUpdate()
    {
        Vector3 stretch = SpringCamera.transform.position - desiredPosition;
        Vector3 force = -Stiffness * stretch - Damping * cameraVelocity;

        Vector3 acceleration = force / Mass;

        cameraVelocity += acceleration * Time.deltaTime;

        SpringCamera.transform.position += cameraVelocity * Time.deltaTime;

        Matrix4x4 CamMat = new Matrix4x4();
        CamMat.SetRow(0, new Vector4(-Target.forward.x, -Target.forward.y, -Target.forward.z));
        CamMat.SetRow(1, new Vector4(Target.up.x, Target.up.y, Target.up.z));
        Vector3 modRight = Vector3.Cross(CamMat.GetRow(1), CamMat.GetRow(0));
        CamMat.SetRow(2, new Vector4(modRight.x, modRight.y, modRight.z));

        desiredPosition = Target.position + TransformNormal(DesiredOffset, CamMat);
        Vector3 lookat = Target.position + TransformNormal(LookAtOffset, CamMat);

        SpringCamera.transform.LookAt(lookat, Target.up);
        //SpringCamera.projectionMatrix = Matrix4x4.Perspective(SpringCamera.fieldOfView, SpringCamera.aspect, SpringCamera.near, SpringCamera.far);

        print("cam = " + SpringCamera.transform.position.ToString());
    }
	
	// Update is called once per frame
	void Update () 
    {
        FollowUpdate();
	}

    Vector3 TransformNormal(Vector3 normal, Matrix4x4 matrix)
    {
        Vector3 transformNormal = new Vector3();
        Vector3 axisX = new Vector3(matrix.m00, matrix.m01, matrix.m02);
        Vector3 axisY = new Vector3(matrix.m10, matrix.m11, matrix.m12);
        Vector3 axisZ = new Vector3(matrix.m20, matrix.m21, matrix.m22);
        transformNormal.x = Vector3.Dot(normal, axisX);
        transformNormal.y = Vector3.Dot(normal, axisY);
        transformNormal.z = Vector3.Dot(normal, axisZ);

        return transformNormal;

    }
}

I originally did this code in XNA a while back, which may be painfully evident with me manually adding in the TransformNormal(Vector3 normal, Matrix4x4 matrix) function. The result I’m getting from this is a camera that’s attached to the side of my target and has twitchy behavior. So what am I doing horribly wrong?

try calling it from within LateUpdate instead of Update… (twitching)

Well, the twitching still happens, but it smoothed out :stuck_out_tongue: Improvement?

Old thread I know, but I’m trying to figure out how to decrease the “stretch” amount so the vehicle doesn’t go so far ahead of the camera. I am kinda learning C# at the moment, so it’s a bit of a struggle.

I think it’s this line

Vector3 stretch = SpringCamera.transform.position - desiredPosition;

Those are all Vector3s, but I suppose I need to try and clamp the desiredPosition? Can I clamp a Vector3?

No one has any ideas? If someone can help correct this I have some 3d models to give away!