Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by OutramJamie · Aug 26, 2020 at 06:01 PM · camera2d gamecamera-movement

2D Smooth Camera Movement

Just spent a long time figuring out a solution to this and thought I'd share/ask opinions; I need a function which I can call to zoom the camera centered on a specified point, I'm looking for a smooth motion so It needs to accelerate to a max speed then decelerate once it is close to the target. One big catch I'm struggling with is I want to be able to specify the transition time.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by OutramJamie · Aug 28, 2020 at 09:27 PM

My solution was to calculating the area under a ramp up and down speed function to get the current distance along each frame: alt text

Behavior script with example use case shown here:

 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Security.Cryptography;
 using UnityEditorInternal;
 using UnityEngine;
 
 public class CameraController : MonoBehaviour
 {
     //Place the camera to be moved in here
     public Camera selectedCamera;
 
     //Flag showing that the camera is moving
     public bool isCameraZooming { get; private set; }
     
     //All the information required to calculate the position and zoom
     private float originalSize;
     private float targetSize;
     private Vector2 originalPivot;
     private Vector2 targetPivot;
     private float transitionTime;
     private float remainingTime;
     private float rampTime;
 
     //Max speed values do not need to be calculated each frame
     private Vector2 _pivotVmax;
     private float _sizeVmax;
 
     private void Awake()
     {
         //Ensure the flag is initialized correctly
         isCameraZooming = false;
     }
 
     void Start()
     {
         //Example Zoom Trigger
         ZoomCameraWithRampUpDown(new Vector2(9, -9), 5f, 1f,0.5f);
     }
 
     // Update is called once per frame
     void Update()
     {
         if (isCameraZooming)
         {
             UpdateZoom();
         }
     }
 
     //Trigger for the camera movement
     public void ZoomCameraWithRampUpDown(Vector2 pivot, float size, float time, float rampTime)
     {
         if (isCameraZooming)
         {
             Debug.LogWarning("Camera already zooming");
             return;
         }
 
         //Set Values and Flags for zoom 
         this.originalSize = selectedCamera.orthographicSize;
         this.originalPivot = selectedCamera.transform.position;
         this.targetPivot = pivot;
         this.targetSize = size;
         this.transitionTime = time;
         this.remainingTime = time;
         this.rampTime = rampTime;
         this.isCameraZooming = true;
 
         //Calculate Max speed
         this._pivotVmax = CalcMaxSpeed(targetPivot - originalPivot, rampTime, transitionTime);
         this._sizeVmax = CalcMaxSpeed(targetSize - originalSize, rampTime, transitionTime);
 
     }
 
     //Calculates the peak velocity of the camera
     private float CalcMaxSpeed(float distance, float rampT, float transT)
     {
         if (transT <= 2 * rampT)
         {
             //If the ramp time is too large there is no middle platau
             //in this case the maximum speed reached is based on the total transition time i.e. rampTime = transitionTime/2
             return (2 * distance / transT);
         }
         else
         {
             return (distance / (transT - rampT));
         }
     }
     private Vector2 CalcMaxSpeed(Vector2 distance, float rampT, float transT)
     {
         return new Vector2(CalcMaxSpeed(distance.x, rampT, transT), CalcMaxSpeed(distance.y, rampT, transT));
     }
 
     //Method called every frame during zoom/movement
     private void UpdateZoom()
     {
         //Calculate new time independant of framerate
         remainingTime -= Time.deltaTime;
         float time = transitionTime - remainingTime;
 
         if(remainingTime<=0)
         {
             //if at the end of transition skip calculations
             selectedCamera.orthographicSize = targetSize;
             selectedCamera.transform.position = new Vector3(targetPivot.x, targetPivot.y, -10);
             //set flag at end of transition
             isCameraZooming = false;
         }
         
         //Calculate the new zoom and position values
         selectedCamera.orthographicSize = CalcRampedValue(originalSize, time, _sizeVmax);
         selectedCamera.transform.position = CalcRampedValue(originalPivot, time, _pivotVmax);
     }
     
     //Controls distance curve of zoom and position (t = 0 to transitiontime)
     private float CalcRampedValue(float startPoint, float t, float Vmax, float transT, float rampT)
     {
         //Ensure time given is within valid range
         t = Mathf.Clamp(t, 0, transT);
         
         
         double d = 0; //holds distance traveled
         //Depending on the given time select the correct calculations for distance
         if (t <= rampT)
         {
             //Ramp Up distance formula
             d = 0.5 / rampT * t * t;
         }
         else 
         {
             //Add Ramp Up total distance
             d += 0.5 * rampT; 
             if (t < transT - rampT)
             {
                 //Platau distance formula
                 d += (t - rampT);
             }
             else
             {
                 //Add Platau total distance
                 d += transT - 2 * rampT; 
                 //Ramp Down distance formula
                 d += 0.5 * (rampT - (transT - t)*(transT - t) / rampT);
             }
         }
         //Scale According to Max Velocity
         d *= Vmax;
         //Add starting Offset
         d += startPoint; 
         return (float)d;
     }
     float CalcRampedValue(float startPoint, float t, float Vmax)
     {
         return CalcRampedValue(startPoint, t, Vmax, transitionTime, rampTime);
     }
     Vector3 CalcRampedValue(Vector2 startPoint, float t , Vector2 Vmax)
     {
         return new Vector3(CalcRampedValue(startPoint.x, t, Vmax.x), CalcRampedValue(startPoint.y, t, Vmax.y), -10);
     }
 
 }
 

untitled.png (818 B)
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

314 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to stop the camera when the player has reached the edge of the level? 2 Answers

Camera moves impossibly fast, and can't see any object 1 Answer

Either my camera moves/changes size or my scene does... But why? Unity 2D 0 Answers

My explosion material is shown from the back of the screen but not from front 1 Answer

Trying to turn the Tank Game Camera script into perspective projection. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges