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. Dismiss Notice

Problem with 2D orthographic camera bounds and player movement behaviour

Discussion in 'Scripting' started by Flammo, Jun 9, 2014.

  1. Flammo

    Flammo

    Joined:
    Jul 14, 2013
    Posts:
    2
    Hi people, i'm (still) fairly new to Unity and scripting at all. I started to meddle with Unit and C# last year but had to stop due to RL sucking up time...

    Anyhow, here are my two problems:
    For my current project (2D top down rpg) i need a camera with certain conditions:
    • I'm working with an orthographic camera that looks down on a fairly big "Worldmap" (2 sprites, one detailed map and one with a polygon collider for the obstacles on the map).
    • The camera should move up, down, left, right when the mouse comes close to the visible borders of the screen.
    • The camera should move up, down, left, right when the arrow keys or WASD are pressed/hold down.
    • The camera should stay within the visible dimensions of the "Worldmap" and NOT drift into space or show the empty background if it moves too far.
    I managed to move the camera when the mouse comes close to the borders (now tinkering with multiple keys)
    but i simply don't know how to restrict the camera movement to within the dimensions (2048x2048 - pixels to unit = 10) of the "Worldmap".




    Problem number two:
    Right now im using a very simple script to move the player to where i click with the left mousebutton and the player moves towards the coordinates.
    The player (a dot sprite :)) starts moving towards the coordinates until it runs into an obstacle and the players Rigidbody 2D collides with the Polygon Collider from the map.
    Now one of two things is happening, the player simply walks into said obstacle and after 3-4 seconds simply stops, or its trying to walk around the obstacle but goes for example a bit up, then down, up, down ect. and is stuck there.

    I assume that a good pathfinding system is way too complicated for my current level of understanding all of this, so it would suffice if someone could give me a hint on either why this is happening or just improve the basic script so that the player moves towards the mouse when i hold down the mousebutton instead of only walking towards the coordinates where the first click was made.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Player_Movement : MonoBehaviour
    6. {
    7.  
    8.     public float speed = 5.0f;
    9.     private Vector3 target;
    10.  
    11.     void Start ()
    12.     {
    13.         target = transform.position;
    14.     }
    15.  
    16.  
    17.     void Update ()
    18.     {
    19.         if (Input.GetMouseButtonDown(0))
    20.         {
    21.             target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    22.             target.z = transform.position.z;
    23.         }
    24.         transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);
    25.     }
    26. }
    27.  


    many thanks to everyone who read through all this and posting solutions,
    Flammo
     
    Last edited: Jun 9, 2014
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    After all other camera movement has happened, simply "clamp" its position based on the required bounds. Use something like:
    Code (csharp):
    1.  
    2. //on camera object
    3. float aspectRatio = Screen.width /  Screen.height;
    4. transform.position.x = new Vector3(
    5. Mathf.Clamp(transform.position.x, lowestPossibleXPosition + 0.5f * camera.fieldOfView * aspectRatio, highestPossibleXPosition - 0.5f * camera.fieldOfView * aspectRatio),
    6. Mathf.Clamp(transform.position.y, lowestPossibleYPosition + 0.5f * camera.fieldOfView, highestPossibleYPosition - 0.5f * camera.fieldOfView),
    7. 0f);
    8.  
    You can use mapCamera.ViewportToWorldPoint(0,0) and (1,1) to find the lowest and highest X and Y positions.

    Not if you're willing to spend a little money. You can buy Pro and use its Pathfinding which would work well in this situation, or grab one of the many pathfinding engines on the Asset Store, which can get pretty cheap. Most of them are as simple as "pathfindingAgent.SetDestination(someVector3)".
     
  3. Flammo

    Flammo

    Joined:
    Jul 14, 2013
    Posts:
    2
    Hey StarManta, thanks for your reply.
    Your post gave me a good direction on what to look for on the Unity Script Reference.
    Here is what i got working so far:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Camera_Test : MonoBehaviour
    5. {
    6.     Vector3 Hit_Position = Vector3.zero;
    7.     Vector3 Current_Position = Vector3.zero;
    8.     Vector3 Camera_Position = Vector3.zero;
    9.     Vector3 Map_Vector = Vector3.zero;
    10.  
    11.     private float Horizontal_Extent;
    12.     private float Vertical_Extent;
    13.     private float MapX = 49.95f;
    14.     private float MapY = 50.0f;
    15.     public float Speed = 20.0f;
    16.     public bool Left_Mouse_Down = false;
    17.  
    18.  
    19.  
    20.     void Start ()
    21.     {
    22.         Horizontal_Extent = Camera.main.orthographicSize * Screen.width / Screen.height;
    23.         Vertical_Extent = Camera.main.orthographicSize;
    24.     }
    25.  
    26.  
    27.  
    28.     void Update()
    29.     {
    30.         if(Input.GetMouseButtonDown(0))
    31.         {
    32.             Hit_Position = Input.mousePosition;
    33.             Camera_Position = transform.position;
    34.             Left_Mouse_Down = true;
    35.         }
    36.  
    37.         if(Input.GetMouseButtonUp(0))
    38.         {
    39.             Left_Mouse_Down = false;
    40.         }
    41.  
    42.         if(Input.GetMouseButton(0))
    43.         {
    44.             Current_Position = Input.mousePosition;
    45.             Left_Mouse_Drag();      
    46.         }
    47.  
    48.  
    49.         if (Input.GetKey(KeyCode.LeftArrow) && Left_Mouse_Down == false || Input.GetKey(KeyCode.A) && Left_Mouse_Down == false)
    50.         {
    51.             transform.position += Vector3.left * Speed * Time.deltaTime;
    52.         }
    53.  
    54.         if (Input.GetKey(KeyCode.RightArrow) && Left_Mouse_Down == false || Input.GetKey(KeyCode.D) && Left_Mouse_Down == false)
    55.         {
    56.             transform.position += Vector3.right * Speed * Time.deltaTime;
    57.         }
    58.  
    59.         if (Input.GetKey(KeyCode.UpArrow) && Left_Mouse_Down == false || Input.GetKey(KeyCode.W) && Left_Mouse_Down == false)
    60.         {
    61.             transform.position += Vector3.up * Speed * Time.deltaTime;
    62.         }
    63.  
    64.         if (Input.GetKey(KeyCode.DownArrow) && Left_Mouse_Down == false || Input.GetKey(KeyCode.S) && Left_Mouse_Down == false)
    65.         {
    66.             transform.position += Vector3.down * Speed * Time.deltaTime;
    67.         }
    68.     }
    69.  
    70.  
    71.  
    72.     void LateUpdate ()
    73.     {
    74.         Map_Vector = transform.position;
    75.         Map_Vector.x = Mathf.Clamp (Map_Vector.x, Horizontal_Extent - MapX, MapX - Horizontal_Extent);
    76.         Map_Vector.y = Mathf.Clamp(Map_Vector.y, Vertical_Extent - MapY, MapY - Vertical_Extent);
    77.         transform.position = Map_Vector;
    78.     }
    79.  
    80.  
    81.  
    82.     void Left_Mouse_Drag()
    83.     {
    84.         Current_Position.z = Hit_Position.z = Camera_Position.y;
    85.  
    86.         Vector3 direction = Camera.main.ScreenToWorldPoint(Current_Position) - Camera.main.ScreenToWorldPoint(Hit_Position);
    87.         direction = direction * -1;
    88.  
    89.         Vector3 position = Camera_Position + direction;
    90.         transform.position = position;
    91.     }
    92.  
    93.  
    94. }
    The script calculates the "Worldmap" boundarys based on Camera.main.orthographicSize, a MapX/MapY Unit value and a horizontal and vertical extent. This way i get the same boundarys for every resolution/aspect ratio.

    To move the camera around the "Worldmap" i chose to use Arrow Keys, WASD and a Drag'n'Drop method.
    Works like a charm for me.
    All that remains is the "Player Movement" problem which i'll tackle tomorrow. :)


    Thank you for helping me out,
    Flammo