Unity3D C# - Spring Follow Camera

Started by
2 comments, last by Archivampire 10 years, 9 months ago
// Originally posted here on Unity3D forums

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?
Keith M. Programming - My Game Dev Blog.
Tutorials. Games. Code Snippets. Bad Jokes. I got 'em all.

Follow me on Twitter. [twitter]KeithMaggio[/twitter]
Listen to me yap about programming and games and junk.
Advertisement
I only skimmed the code, but try calling FollowUpdate() from LateUpdate() rather than from Update().

I only skimmed the code, but try calling FollowUpdate() from LateUpdate() rather than from Update().


They told me to try this on the Unity forums too. It only reduced some of the gitching.
Keith M. Programming - My Game Dev Blog.
Tutorials. Games. Code Snippets. Bad Jokes. I got 'em all.

Follow me on Twitter. [twitter]KeithMaggio[/twitter]
Listen to me yap about programming and games and junk.

Thanks for code

This topic is closed to new replies.

Advertisement