How to limit the camera on a isometric 2D game

292 Views Asked by At

I'm developing a 2D isometric game just like Age of Empires 2, TTD, Into the Breach, and so on. I'm using Unity and C#

Relevant fact: i'm using a Isometric Tilemap

I want the camera limits to stay aligned with the borders of the map just like the games cited above but i'm having difficulty and i have spent so much time on this that i start to question myself if it's worth to use Isometric Tilemap or do the usual approach and just make a regular 2D game with the camera rotated.

And this is my first question: does Isometric Tilemap really worth or usual approach is better (non-isometric 2D game with rotated camera)? If so, how to do that in Unity?

Despite that,the code i've implemented follow below but it have two bugs:

  • Camera get stuck on firstBase and thirdBase if the user press right/left key and up/down arow keys
  • If the camera is moving on the border it may escape it
    void Start(){
        CameraMovement_Limits();
    }

    void CameraMovement_Limits(){
        Vector3 gridOrigin = tilemapFloor.GetCellCenterWorld(tilemapFloor.origin);
        float gridHypotenuse = ((tilemapFloor.size.x - 1) * tilemapFloor.cellSize.y);

        homePlate = gridOrigin + new Vector3(0, 0, -10);
        firstBase = gridOrigin + new Vector3(gridHypotenuse, gridHypotenuse/2, -10);
        secondBase = gridOrigin + new Vector3(0, gridHypotenuse, -10);
        thirdBase = gridOrigin + new Vector3(-gridHypotenuse, gridHypotenuse/2, -10);
    }

    void Update(){
        CameraDiagonalMovement();
    }

    bool CheckCameraPosition(Vector2 p1, Vector2 p2, Vector2 pos){
        //This is what this function do:
        //find the linear equation for the line formed by 'p1' and 'p2' coordinates
        //insert 'pos' coordinate on the equation and stores the result in 'ind'
        //if 'ind' is positive, it means that 'pos' is above the line
        //if its negative, its above
        //if its zero, its on the line
        //resuming, this funtion tells if 'pos' is above or below a line formet by 'p1' and 'p2'
        float a = (p1.y - p2.y) / (p1.x - p2.x);
        float ind = pos.y - p2.y - (a * (pos.x - p2.x));

        return ind >= 0;
    }

    void CameraDiagonalMovement(){
        Vector3 vecZero = Vector2.zero;
        camPos = (Vector2)transform.position;
        
        //Going to the left
        if(Input.GetAxis("Vertical") < 0){
            if(CheckCameraPosition(homePlate, thirdBase, camPos) && CheckCameraPosition(homePlate, firstBase, camPos)){
                vecZero.y = Input.GetAxis("Vertical");
            }else if(!CheckCameraPosition(homePlate, thirdBase, camPos) && CheckCameraPosition(homePlate, firstBase, camPos)){
                vecZero.x = Input.GetAxis("Vertical") * .66f * -1;
                vecZero.y = Input.GetAxis("Vertical") * .33f;
            }else if(CheckCameraPosition(homePlate, thirdBase, camPos) && !CheckCameraPosition(homePlate, firstBase, camPos)){
                vecZero.x = Input.GetAxis("Vertical") * .66f;
                vecZero.y = Input.GetAxis("Vertical") * .33f;
            }
        }

        //Going to the right
        if(Input.GetAxis("Vertical") > 0){
            if(!CheckCameraPosition(secondBase, thirdBase, camPos) && !CheckCameraPosition(firstBase, secondBase, camPos)){
                vecZero.y = Input.GetAxis("Vertical");
            }else if(CheckCameraPosition(secondBase, thirdBase, camPos) && !CheckCameraPosition(firstBase, secondBase, camPos)){
                vecZero.x = Input.GetAxis("Vertical") * .66f;
                vecZero.y = Input.GetAxis("Vertical") * .33f;
            }else if(!CheckCameraPosition(secondBase, thirdBase, camPos) && CheckCameraPosition(firstBase, secondBase, camPos)){
                vecZero.x = Input.GetAxis("Vertical") * .66f * -1;
                vecZero.y = Input.GetAxis("Vertical") * .33f;
            }
        }

        //Going down
        if(Input.GetAxis("Horizontal") < 0){
            if(CheckCameraPosition(homePlate, thirdBase, camPos) && !CheckCameraPosition(secondBase, thirdBase, camPos)){
                vecZero.x = Input.GetAxis("Horizontal");
            }else if(!CheckCameraPosition(homePlate, thirdBase, camPos) && !CheckCameraPosition(secondBase, thirdBase, camPos)){
                vecZero.x = Input.GetAxis("Horizontal") * .66f;
                vecZero.y = Input.GetAxis("Horizontal") * .33f * -1;
            }else if(CheckCameraPosition(homePlate, thirdBase, camPos) && CheckCameraPosition(secondBase, thirdBase, camPos)){
                vecZero.x = Input.GetAxis("Horizontal") * .66f;
                vecZero.y = Input.GetAxis("Horizontal") * .33f;
            }
        }

        //Going up
        if(Input.GetAxis("Horizontal") > 0){
            if(CheckCameraPosition(homePlate, firstBase, camPos) && !CheckCameraPosition(firstBase, secondBase, camPos)){
                vecZero.x = Input.GetAxis("Horizontal");
            }else if(CheckCameraPosition(homePlate, firstBase, camPos) && CheckCameraPosition(firstBase, secondBase, camPos)){
                vecZero.x = Input.GetAxis("Horizontal") * .66f;
                vecZero.y = Input.GetAxis("Horizontal") * .33f * -1;
            }else if(!CheckCameraPosition(homePlate, firstBase, camPos) && !CheckCameraPosition(firstBase, secondBase, camPos)){
                vecZero.x = Input.GetAxis("Horizontal") * .66f;
                vecZero.y = Input.GetAxis("Horizontal") * .33f;
            }
        }

        Vector3 newPos = new Vector3(vecZero.x, vecZero.y, 0);
        transform.position += newPos * velocity * Time.deltaTime;
    }

0

There are 0 best solutions below