Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Spring Follow Camera (C#)

Discussion in 'Scripting' started by KMGameDev, Mar 8, 2011.

  1. KMGameDev

    KMGameDev

    Joined:
    Mar 8, 2011
    Posts:
    17
    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#

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class SpringFollow : MonoBehaviour
    5. {
    6.     public Transform Target;
    7.     public Camera SpringCamera = Camera.mainCamera;
    8.  
    9.     public float Stiffness = 1800.0f;
    10.     public float Damping = 600.0f;
    11.     public float Mass = 50.0f;
    12.     public Vector3 DesiredOffset = new Vector3(0.0f, 3.5f, -4.0f);
    13.     public Vector3 LookAtOffset = new Vector3(0.0f, 3.1f, 0.0f);
    14.  
    15.     private Vector3 desiredPosition = Vector3.zero;
    16.     private Vector3 cameraVelocity = Vector3.zero;
    17.  
    18.     // Use this for initialization
    19.     void Start ()
    20.     {
    21.    
    22.     }
    23.  
    24.     void FollowUpdate()
    25.     {
    26.         Vector3 stretch = SpringCamera.transform.position - desiredPosition;
    27.         Vector3 force = -Stiffness * stretch - Damping * cameraVelocity;
    28.  
    29.         Vector3 acceleration = force / Mass;
    30.  
    31.         cameraVelocity += acceleration * Time.deltaTime;
    32.  
    33.         SpringCamera.transform.position += cameraVelocity * Time.deltaTime;
    34.  
    35.         Matrix4x4 CamMat = new Matrix4x4();
    36.         CamMat.SetRow(0, new Vector4(-Target.forward.x, -Target.forward.y, -Target.forward.z));
    37.         CamMat.SetRow(1, new Vector4(Target.up.x, Target.up.y, Target.up.z));
    38.         Vector3 modRight = Vector3.Cross(CamMat.GetRow(1), CamMat.GetRow(0));
    39.         CamMat.SetRow(2, new Vector4(modRight.x, modRight.y, modRight.z));
    40.  
    41.         desiredPosition = Target.position + TransformNormal(DesiredOffset, CamMat);
    42.         Vector3 lookat = Target.position + TransformNormal(LookAtOffset, CamMat);
    43.  
    44.         SpringCamera.transform.LookAt(lookat, Target.up);
    45.         //SpringCamera.projectionMatrix = Matrix4x4.Perspective(SpringCamera.fieldOfView, SpringCamera.aspect, SpringCamera.near, SpringCamera.far);
    46.  
    47.         print("cam = " + SpringCamera.transform.position.ToString());
    48.     }
    49.    
    50.     // Update is called once per frame
    51.     void Update ()
    52.     {
    53.         FollowUpdate();
    54.     }
    55.  
    56.     Vector3 TransformNormal(Vector3 normal, Matrix4x4 matrix)
    57.     {
    58.         Vector3 transformNormal = new Vector3();
    59.         Vector3 axisX = new Vector3(matrix.m00, matrix.m01, matrix.m02);
    60.         Vector3 axisY = new Vector3(matrix.m10, matrix.m11, matrix.m12);
    61.         Vector3 axisZ = new Vector3(matrix.m20, matrix.m21, matrix.m22);
    62.         transformNormal.x = Vector3.Dot(normal, axisX);
    63.         transformNormal.y = Vector3.Dot(normal, axisY);
    64.         transformNormal.z = Vector3.Dot(normal, axisZ);
    65.  
    66.         return transformNormal;
    67.  
    68.     }
    69. }
    70.  
    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?
     
    Last edited: Mar 8, 2011
  2. Dusho

    Dusho

    Joined:
    Jul 10, 2010
    Posts:
    22
    try calling it from within LateUpdate instead of Update.. (twitching)
     
  3. KMGameDev

    KMGameDev

    Joined:
    Mar 8, 2011
    Posts:
    17
    Well, the twitching still happens, but it smoothed out :p Improvement?
     
  4. JamesArndt

    JamesArndt

    Unity Technologies

    Joined:
    Dec 1, 2009
    Posts:
    2,913
    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?
     
    Last edited: Jan 18, 2014
  5. JamesArndt

    JamesArndt

    Unity Technologies

    Joined:
    Dec 1, 2009
    Posts:
    2,913
    No one has any ideas? If someone can help correct this I have some 3d models to give away!