Search Unity

2D Platformer Camera Issue

Discussion in 'Scripting' started by maltadirk, Mar 12, 2015.

  1. maltadirk

    maltadirk

    Joined:
    Mar 12, 2014
    Posts:
    43
    Hi all,

    I'm running in a bit of an issue. I'm currently in the process of re-working the way the camera is working for a platform game I'm working on. As shown in the following video the camera is having the following issues:
    - Shifting too fast when player changes direction
    - The camera is constantly moving. As shown in the image below, I would like to have the section in red in the middle of the screen where the camera doesn't move while the player is in those bounds.





    Here is the code I'm using to get the results shown in the above video:

    Code (CSharp):
    1.  
    2. public class BuzzCameraController : MonoBehaviour
    3. {
    4.    public Transform player;
    5.    public Vector2 Margin, Smoothing;
    6.    public BoxCollider2D Bounds;
    7.    public bool IsFollowing { get; set; }
    8.    public BlobMove PlayerInfo;
    9.  
    10.    private Vector3 _min, _max;
    11.  
    12.    void Start ()
    13.    {
    14.      _min = Bounds.bounds.min;
    15.      _max = Bounds.bounds.max;
    16.      
    17.      IsFollowing = true;
    18.    }
    19.  
    20.    void Update ()
    21.    {
    22.      var x = transform.position.x;
    23.      var y = transform.position.y;
    24.  
    25.      if (IsFollowing)
    26.      {
    27.        if (Mathf.Abs(x - player.position.x) > Margin.x)
    28.        {
    29.          //Following IF statement checks if Player is Facing in the Right direction
    30.          if (PlayerInfo.IsMovingRight())
    31.          {
    32.            x = Mathf.Lerp(x, player.position.x + 2f, Smoothing.x * Time.deltaTime);
    33.          }
    34.          else
    35.          {
    36.            x = Mathf.Lerp(x, player.position.x - 2f, Smoothing.x * Time.deltaTime);
    37.          }
    38.        }
    39.        if (Mathf.Abs(y - player.position.y) > Margin.y)
    40.        {
    41.          y = Mathf.Lerp(y, player.position.y, (Smoothing.y * Time.deltaTime));
    42.        }
    43.      }
    44.      //The following 3-lines of code is used to contrain the camera from not going out of the bounds I have set.
    45.      var cameraHalfWidth = Camera.main.orthographicSize * ((float)Screen.width / Screen.height);
    46.      x = Mathf.Clamp (x, _min.x + cameraHalfWidth, _max.x - cameraHalfWidth);
    47.      y = Mathf.Clamp (y, _min.y + Camera.main.orthographicSize, _max.y - Camera.main.orthographicSize);
    48.      
    49.      transform.position = new Vector3 (x, y, transform.position.z);
    50.    }
    51. }
    52.  
    For a perfect example of how I would like the camera to work here's an example from Leo's Fortune:



    - Dirk
     
  2. Kamadake

    Kamadake

    Joined:
    Oct 12, 2013
    Posts:
    12
    Hi Dirk. It's William from Malta.

    Regarding the speed of the transition when you change direction, I don't know if that can be solved with a smoothdamp rather than Lerp. Since the distance it has to reach is further away, it's going to get there at a faster rate since you're using the same speed. Lerp maintains linear consistency but smoothdamp is a curve.

    For clamping the camera, I don't know what you're doing wrong, are you trying to clamp by min and max length of the screen? With my camera for example I tell it the furthest X and Y position it could keep going.

    Code (CSharp):
    1. targetX = Mathf.Clamp(targetX, minXAndY.x, maxXAndY.x - cam.ScreenExtents.width);
    cam.ScreenExtents is a variable from the 2D Toolkit but it should be similar to what you're doing with the orthographic size. Make sure about the values they are returning, I remember having a problem with Chaos Control.
     
    maltadirk likes this.
  3. Cybertiger

    Cybertiger

    Joined:
    Dec 19, 2013
    Posts:
    35
    Hi Dirk,

    Awfully Nice Studios here if you remember me from GDC Europe last year. ;)

    Here is my pseudo code that should do what you wanted. you would put this script in a class and attach it to your camera... the "smoothTime" adjusts your falloff.

    Code (CSharp):
    1.     public Transform     playerTrans;
    2.     public float         smoothTime = 1.5f;
    3.     private Vector3     velocity;
    4.  
    5.     // Update is called once per frame
    6.     void Update ()
    7.     {
    8.         updateCameraPos();
    9.     }
    10.  
    11.     void updateCameraPos()
    12.     {
    13.             transform.position = Vector3.SmoothDamp(this.transform.position, playerTrans.position, ref velocity, smoothTime);
    14.     }
    15.  
     
    maltadirk likes this.
  4. maltadirk

    maltadirk

    Joined:
    Mar 12, 2014
    Posts:
    43
    Thanks for the input @Kamadake. Yeah looks like i need to rework the transition using SmoothDamp.
    Thanks @Cybertiger :) I tried implementing the following using SmoothDamp but getting weird movement, probably something silly I'm doing:


    Code (CSharp):
    1. public Transform player;
    2. public Vector2 Margin, Smoothing;
    3. public BoxCollider2D Bounds;
    4. //Following determines if we are following the Player or Not
    5. public bool IsFollowing { get; set; }
    6. public BlobMove PlayerInfo;
    7.  
    8. private Vector3 _min, _max;
    9. private Vector3  velocity, NewPosition;
    10.  
    11. void Start ()
    12. {
    13.     _min = Bounds.bounds.min;
    14.     _max = Bounds.bounds.max;
    15.    
    16.     IsFollowing = true;
    17. }
    18.  
    19. void Update ()
    20. {
    21.     velocity = new Vector3(PlayerInfo.GetPlayerVelocity().x, PlayerInfo.GetPlayerVelocity().y, -10f);
    22.    
    23.     if (IsFollowing)
    24.     {
    25.         if ((Mathf.Abs(x - player.position.x) > Margin.x) || (Mathf.Abs(y - player.position.y) > Margin.y))
    26.         {
    27.             if (PlayerInfo.IsMovingRight())
    28.             {
    29.                 NewPosition = Vector3.SmoothDamp(transform.position,
    30.                                                  new Vector3(    player.position.x + 2f,
    31.                                                                 player.position.y,
    32.                                                                 -10f),
    33.                                                  ref velocity,
    34.                                                  1.5f);
    35.             }
    36.             else
    37.             {
    38.                 NewPosition = Vector3.SmoothDamp(transform.position,
    39.                                                  new Vector3(    player.position.x - 2f,
    40.                                                                 player.position.y,
    41.                                                                 -10f),
    42.                                                  ref velocity,
    43.                                                  1.5f);
    44.             }
    45.         }
    46.     }
    47.     transform.position = NewPosition;
    48. }
    BTW I'm using the following tutorial to create the camera controller:
     
  5. Kamadake

    Kamadake

    Joined:
    Oct 12, 2013
    Posts:
    12
    Is the player moving with FixedUpdate by any chance? Usually when there's that stutter the issue is because the player and the camera are not moving at equal speeds.

    When I had that stutter once, the problem was because my player moved with FixedUpdate and the camera moved with Update and Update is called more often.