Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Issues with resetting camera (using Lerp)

Discussion in 'Scripting' started by jourdanr, Apr 28, 2017.

  1. jourdanr

    jourdanr

    Joined:
    Sep 13, 2016
    Posts:
    4
    Hello All,

    I've been working on an endless runner and I wanted to add a feature in the CameraController which is able to zoom into the player when an object enters a circle trigger collider and then resets the camera once that object leaves the camera (trying to make near misses feel more cinematic). Problem is, the zooming in works but the zooming out doesn't. I'm using the same method for both zooming in and out, but for some reason the zoom out never works.

    Here's my code for the camera controller:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CameraController : MonoBehaviour
    5. {
    6.  
    7.     private Camera _camera;
    8.     private float defaultCameraHeight;
    9.     protected CircleCollider2D playerCollider;
    10.     private Vector3 defaultCameraPosition;
    11.     private Vector3 lastPlayerPosition;
    12.     private float DistanceToMove;
    13.     private bool hazardIsInTrigger;
    14.  
    15.  
    16.  
    17.     public float targetCameraSize;
    18.     public float zoomSpeed;
    19.  
    20.  
    21.     private Player player;
    22.  
    23.  
    24.     void Start ()
    25.     {
    26.  
    27.         _camera = GetComponent<Camera>();
    28.         player = FindObjectOfType<Player>();
    29.         lastPlayerPosition = player.transform.position; //the initial position at start, and the position on the last frame
    30.  
    31.         defaultCameraPosition = _camera.transform.position;
    32.         defaultCameraHeight = _camera.orthographicSize; //camera size is a real number, so we use floats. Ortho camera sizes only measure from middle to top in viewpoint
    33.     }
    34.  
    35.  
    36.    public void ActivateZoomMethod()
    37.     {
    38.         hazardIsInTrigger = true;
    39.         StartCoroutine(ZoomInOnPlayer());
    40.     }
    41.  
    42.    public  void DeactivateZoomMethod()
    43.     {
    44.         Debug.Log("Reset Camera Position");
    45.         hazardIsInTrigger = false;
    46.     }
    47.  
    48.     IEnumerator ZoomInOnPlayer() //runs when called, waits until boolean is true before zooming in. Once false, it should zoom out
    49.     {
    50.         while (hazardIsInTrigger)
    51.         {
    52.             CircleCollider2D target = GetTarget();
    53.             OrthoZoom(target.bounds.center, targetCameraSize);
    54.             Time.timeScale = 0.8f; //slowdown time
    55.  
    56.             yield return null;
    57.         }
    58.  
    59.          Debug.Log("The boolean has been set to false");
    60.  
    61.          CameraReset();
    62.         Time.timeScale = 1f;
    63.     }
    64.  
    65.     void CameraReset()
    66.     {
    67.         Debug.Log("Resetting camera...");
    68.         OrthoZoom(defaultCameraPosition, defaultCameraHeight);
    69.  
    70.     }
    71.  
    72.     void OrthoZoom(Vector2 center, float regionHeight) // uses lerp to move the camera position to desired position and reduce the camera size.
    73.     {
    74.         _camera.transform.position = Vector3.Lerp(_camera.transform.position, new Vector3(center.x, center.y, defaultCameraPosition.z), Time.deltaTime * zoomSpeed);
    75.         _camera.orthographicSize = Mathf.Lerp(_camera.orthographicSize, regionHeight, Time.deltaTime * zoomSpeed);
    76.     }
    77.  
    78.     CircleCollider2D GetTarget() //gets the player collider so that I can zoom in on the player directly.
    79.     {
    80.  
    81.         playerCollider = player.GetComponent<CircleCollider2D>();
    82.         return playerCollider;
    83.     }
    84.  
    85.      public void FixedUpdate ()
    86.     {
    87.         DistanceToMove = player.transform.position.x  - lastPlayerPosition.x;
    88.         transform.position = new Vector3 (transform.position.x + DistanceToMove, transform.position.y, transform.position.z);
    89.         lastPlayerPosition = player.transform.position;
    90.     }
    91.  
    92. }
    93.  
    And here's the playercontroller, which calls the necessary methods in the cameracontroller once the trigger is entered:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Events;
    4.  
    5. public class Player : MonoBehaviour
    6. {
    7.  
    8.     public float speed;
    9.     public float thrust;
    10.  
    11.     public LayerMask colliderMask;
    12.  
    13.     private bool grounded = true;
    14.     private Rigidbody2D _playerRigidbody;
    15.     private GameManager gameManager;
    16.  
    17.  
    18.     private CameraController cameraController;
    19.  
    20.     private bool _isThePlayerStillAlive = true;
    21.  
    22.  
    23.     void Start()
    24.     {
    25.         _playerRigidbody = GetComponent<Rigidbody2D>();
    26.         gameManager = FindObjectOfType<GameManager>();
    27.         cameraController = FindObjectOfType<CameraController>();
    28.  
    29.  
    30.     }
    31.  
    32.     void OnCollisionExit2D(Collision2D other)
    33.     {
    34.  
    35.         if (other.collider.gameObject.GetComponent<Wave>())
    36.         {
    37.             Debug.Log("Player has just jumped off" + other.gameObject.name);
    38.             grounded = false;
    39.             PlayerJump();
    40.         }
    41.     }
    42.  
    43.     void PlayerJump()
    44.     {
    45.         if (!grounded)
    46.         {
    47.             Debug.Log("Jump!");
    48.             _playerRigidbody.AddForce(transform.up * thrust);
    49.             grounded = true;
    50.         }
    51.     }
    52.  
    53.     void OnTriggerEnter2D(Collider2D other)
    54.     {
    55.         if (other.gameObject.GetComponent<Hazards>())
    56.         {
    57.            cameraController.ActivateZoomMethod();
    58.         }
    59.  
    60.     }
    61.  
    62.     void OnTriggerExit2D(Collider2D other)
    63.     {
    64.         if (other.gameObject.GetComponent<Hazards>())
    65.         {
    66.             cameraController.DeactivateZoomMethod();
    67.  
    68.  
    69.             if (_isThePlayerStillAlive)
    70.             {
    71.                 Debug.Log("Our hero lives on!");
    72.             }
    73.  
    74.         }
    75.     }
    76.  
    77.     void FixedUpdate()
    78.     {
    79.         _playerRigidbody.AddForce(transform.right * speed);
    80.     }
    81.  
    82.     public void KnockedOff()
    83.     {
    84.         _isThePlayerStillAlive = false;
    85.         if (!_isThePlayerStillAlive)
    86.         {
    87.             Debug.Log("Player should be knocked off, we'll play an animation.");
    88.             gameManager.PlayerHasBeenHit();
    89.             cameraController.DeactivateZoomMethod();
    90.         }
    91.     }
    92. }
    93.  
    There are a fair few Debugging statements; those are just for me to monitor what's going on in scene.

    If anyone can see what the problem is with these classes and the methods, please let me know!
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    You call OrthoZoom many times on the way in, but only once on the way out. You're also using Lerp "incorrectly" (in quotes because long story), which can cause the camera behavior to vary drastically with different framerates; MoveTowards would be more recommended here.

    Allow me to suggest an alternative algorithm. Since you have a hazardIsInTrigger boolean, you're actually better set up to do this in LateUpdate() and can skip the coroutine entirely:
    Code (csharp):
    1.  
    2. void LateUpdate() {
    3. if (hazardIsInTrigger) {
    4. CircleCollider2D target = GetTarget();
    5. OrthoZoom(target.bounds.center, targetCameraSize);
    6. Time.timeScale = 0.8f; //slowdown time
    7. }
    8. else {
    9. time.timeScale = 1f;
    10. OrthoZoom(defaultCameraPosition, defaultCameraHeight);
    11. }