Jump to content
  • Advertisement
Sign in to follow this  
UtMan88

Unity3D C# - Spring Follow Camera

This topic is 1894 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

// 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?

Share this post


Link to post
Share on other sites
Advertisement
I only skimmed the code, but try calling FollowUpdate() from LateUpdate() rather than from Update().

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!