Unity3d (2d!) - Camera to center on the player, but never exceeding the border of the "map"

I am creating a game in which there are up to 4 spelling cameras (up to 4 players) that occupy different screen sizes depending on the number of players.

2 cameras (with 0.7 each)

4 Cameras

I have a script that controls all the cameras, setting their position relative to the players they are viewing.

What I want to achieve is a simple movement style in which the camera will follow the player, but does not go beyond the map.

required behavior

, , "" ( 4- ). , , 2-player . , , ... , , ...

SpriteRenderer spriteBounds = GameObject.Find("Map").GetComponentInChildren<SpriteRenderer>();
float leftBound =0;
float rightBound =0;
float bottomBound =0;
float topBound = 0;

if((trackPlayer1 == null))
{
    camPlayer1.transform.position = this.transform.position;
}
else
{
    float vertExtent = camPlayer1.orthographicSize;
    float horzExtent = vertExtent * Screen.width / Screen.height; //I guess the problem is here... but how do I fix this??

    leftBound = (float)(horzExtent - spriteBounds.sprite.bounds.size.x / 2.0f);
    rightBound = (float)(spriteBounds.sprite.bounds.size.x / 2.0f - horzExtent);
    bottomBound = (float)(vertExtent - spriteBounds.sprite.bounds.size.y / 2.0f);
    topBound = (float)(spriteBounds.sprite.bounds.size.y / 2.0f - vertExtent);

    camPlayer1.transform.position = new Vector3(Mathf.Clamp(trackPlayer1.transform.position.x, leftBound, rightBound), Mathf.Clamp(trackPlayer1.transform.position.y, bottomBound, topBound), camPlayer1.transform.position.z);
}
if((trackPlayer2 == null))
{
    camPlayer2.transform.position = this.transform.position;
}
else
{
    float vertExtent = camPlayer2.orthographicSize ;
    float horzExtent = vertExtent * Screen.width / Screen.height; //I guess the problem is here... but how do I fix this??

    leftBound = (float)(horzExtent - spriteBounds.sprite.bounds.size.x / 2.0f);
    rightBound = (float)(spriteBounds.sprite.bounds.size.x / 2.0f - horzExtent);
    bottomBound = (float)(vertExtent - spriteBounds.sprite.bounds.size.y / 2.0f);
    topBound = (float)(spriteBounds.sprite.bounds.size.y / 2.0f - vertExtent);

    camPlayer2.transform.position = new Vector3(Mathf.Clamp(trackPlayer2.transform.position.x, leftBound, rightBound), Mathf.Clamp(trackPlayer2.transform.position.y, topBound, bottomBound), camPlayer2.transform.position.z);
}
if((trackPlayer3 == null))
{
    camPlayer3.transform.position = this.transform.position;
}
else
{
    float vertExtent = camPlayer3.orthographicSize;
    float horzExtent = vertExtent * Screen.width / Screen.height; //I guess the problem is here... but how do I fix this??

    leftBound = (float)(horzExtent - spriteBounds.sprite.bounds.size.x / 2.0f);
    rightBound = (float)(spriteBounds.sprite.bounds.size.x / 2.0f - horzExtent);
    bottomBound = (float)(vertExtent - spriteBounds.sprite.bounds.size.y / 2.0f);
    topBound = (float)(spriteBounds.sprite.bounds.size.y / 2.0f - vertExtent);

    camPlayer3.transform.position = new Vector3(Mathf.Clamp(trackPlayer3.transform.position.x, leftBound, rightBound), Mathf.Clamp(trackPlayer3.transform.position.y, topBound, bottomBound), camPlayer3.transform.position.z);         
}
if((trackPlayer4 == null))
{
    camPlayer4.transform.position = this.transform.position;
}
else
{
    float vertExtent = camPlayer4.orthographicSize;
    float horzExtent = vertExtent * Screen.width / Screen.height; //I guess the problem is here... but how do I fix this??

    leftBound = (float)(horzExtent - spriteBounds.sprite.bounds.size.x / 2.0f);
    rightBound = (float)(spriteBounds.sprite.bounds.size.x / 2.0f - horzExtent);
    bottomBound = (float)(vertExtent - spriteBounds.sprite.bounds.size.y / 2.0f);
    topBound = (float)(spriteBounds.sprite.bounds.size.y / 2.0f - vertExtent);

    camPlayer4.transform.position = new Vector3(Mathf.Clamp(trackPlayer4.transform.position.x, leftBound, rightBound), Mathf.Clamp(trackPlayer4.transform.position.y, topBound, bottomBound), camPlayer4.transform.position.z);
}

, , , , .

() Script :

  • script - script, ,
  • (camPlayer1 - camPlayer4) script
  • trackPlayer1-trackPlayer4 , -
  • ... , camPlayer2.transform.position = new Vector3 (Mathf.Clamp(trackPlayer2.transform.position.x, leftBound, rightBound), Mathf.Clamp(trackPlayer2.transform.position.y, topBound, bottomBound), camPlayer2.transform.position.z); to camPlayer2.transform.position = trackPlayer2.transform.position; , . ,
  • 2

:

    switch (playerCount)
    {
        case 1:
            camPlayer1.enabled = true;
            camPlayer2.enabled = false;
            camPlayer3.enabled = false;
            camPlayer4.enabled = false;

            camPlayer1.rect = new Rect(0, 0, 1, 1);
            camPlayer1.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer2.rect = new Rect(0, 0, 0, 0);
            camPlayer2.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer3.rect = new Rect(0, 0, 0, 0);
            camPlayer3.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer4.rect = new Rect(0, 0, 0, 0);
            camPlayer4.orthographicSize = CamManager.CAMERA_SIZE;

            break;
        case 2:
            camPlayer1.enabled = true;
            camPlayer2.enabled = true;
            camPlayer3.enabled = false;
            camPlayer4.enabled = false;


            camPlayer1.rect = new Rect(0, 0.5f, 0.7f, 0.5f);
            camPlayer1.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer2.rect = new Rect(0.3f, 0, 0.7f, 0.5f);
            camPlayer2.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer3.rect = new Rect(0, 0, 0, 0);
            camPlayer3.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer4.rect = new Rect(0, 0, 0, 0);
            camPlayer4.orthographicSize = CamManager.CAMERA_SIZE;


            Destroy(play3);
            Destroy(play4);

            break;
        case 3:
            camPlayer1.enabled = true;
            camPlayer2.enabled = true;
            camPlayer3.enabled = true;
            camPlayer4.enabled = false;

            camPlayer1.rect = new Rect(0, 0.5f, 0.5f, 0.5f);
            camPlayer1.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer2.rect = new Rect(0.5f, 0.5f, 0.5f, 0.5f);
            camPlayer2.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer3.rect = new Rect(0.25f, 0, 0.5f, 0.5f);
            camPlayer3.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer4.rect = new Rect(0, 0, 0, 0);
            camPlayer4.orthographicSize = CamManager.CAMERA_SIZE;

            Destroy(play4);


            break;
        case 4:
            camPlayer1.enabled = true;
            camPlayer2.enabled = true;
            camPlayer3.enabled = true;
            camPlayer4.enabled = true;

            camPlayer1.rect = new Rect(0, 0.5f, 0.5f, 0.5f);
            camPlayer1.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer2.rect = new Rect(0.5f, 0.5f, 0.5f, 0.5f);
            camPlayer2.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer3.rect = new Rect(0, 0, 0.5f, 0.5f);
            camPlayer3.orthographicSize = CamManager.CAMERA_SIZE;

            camPlayer4.rect = new Rect(0.5f, 0, 0.5f, 0.5f);
            camPlayer4.orthographicSize = CamManager.CAMERA_SIZE;

            break;
    }
}

, ( , , -1 ) . , LeftBound, rightBound, topBound bottomBound, .

if((trackPlayer1 == null))
{
 camPlayer1.transform.position = this.transform.position;
}
else
{
 float vertExtent = camPlayer1.orthographicSize;
 float horzExtent = vertExtent * (Screen.width * (camPlayer1.rect.width * 2)) / Screen.height; //I guess the problem is here... but how do I fix this??
+4
4

. , , . , . , , .

, . aspect ratios and screen size

, Screen.width Screen.height , . , . , Unity .

float camVertExtent = cam.orthograpicSize;
float camHorzExtent = cam.aspect * camVertExtent;

, , . bounding box and camera position

bounds.size, , , bounds.size.x - . , (0,0) . bounds.min bounds.max, .

, , .. :

(cam.transform.position.x - camHorzExtent) >= bounds.min.x // left
(cam.transform.position.x + camHorzExtent) <= bounds.max.x // right
(cam.transform.position.y - camVertExtent) >= bounds.min.y // bottom
(cam.transform.position.y + camVertExtent) <= bounds.max.y // top

:

float leftBound   = bounds.min.x + camHorzExtent;
float rightBound  = bounds.max.x - camHorzExtent;
float bottomBound = bounds.min.y + camVertExtent;
float topBound    = bounds.max.y - camVertExtent;

float camX = Mathf.Clamp(player.transform.position.x, leftBound, rightBound);
float camY = Mathf.Clamp(player.transform.position.y, bottomBound, topBound);

cam.transform.position = new Vector3(camX, camY, cam.transform.position.z);

, camX camY .

+9

.

? ( !), , - .

, , . ? → ? → 1 /2, 2 /2 +1 ..

+2

, sprites Empty Gameobject, :

Background
--mountains1(sprite)
--mountains2(sprite)
--mountains3(sprite)

: D, Frankestein hahhaa @Stefan Hoffmann. , , : (

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraFollow : MonoBehaviour
{

    private float rightBound;
    private float leftBound;
    private float topBound;
    private float bottomBound;
    private Vector3 pos;
    private Transform target;

    private Camera cam;
    private Bounds bounds;


    // Use this for initialization
    void Start()
    {
        target = GameObject.FindWithTag("Player").transform;


        foreach (SpriteRenderer spriteBounds in GameObject.Find("Background").GetComponentsInChildren<SpriteRenderer>())
        {
            bounds.Encapsulate(spriteBounds.bounds);
        }


        cam = this.gameObject.GetComponent<Camera>();
        float camVertExtent = cam.orthographicSize;
        float camHorzExtent = cam.aspect * camVertExtent;

        Debug.Log(camVertExtent);
        Debug.Log(camHorzExtent);
        Debug.Log(cam.aspect);
        Debug.Log(cam.orthographicSize);



        leftBound = bounds.min.x + camHorzExtent;
        rightBound = bounds.max.x - camHorzExtent;
        bottomBound = bounds.min.y + camVertExtent;
        topBound = bounds.max.y - camVertExtent;

        Debug.Log("leftBound=" + leftBound);
        Debug.Log("rightBound=" + rightBound);
        Debug.Log("bottomBound=" + bottomBound);
        Debug.Log("topBound=" + topBound);
    }

    // Update is called once per frame
    void Update()
    {


        float camX = Mathf.Clamp(target.transform.position.x, leftBound, rightBound);
        float camY = Mathf.Clamp(target.transform.position.y, bottomBound, topBound);

        cam.transform.position = new Vector3(camX, camY, cam.transform.position.z);
    }

}
0
source

You should use this simple but useful unity of the 2d camera, following the script are
also available on github. https://gist.github.com/unity3diy/5aa0b098cb06b3ccbe47


using UnityEngine;
using System.Collections;

public class FollowCamera : MonoBehaviour {

public float interpVelocity;
public float minDistance;
public float followDistance;
public GameObject target;
public Vector3 offset;
Vector3 targetPos;
// Use this for initialization
void Start () {
    targetPos = transform.position;
}

// Update is called once per frame
void FixedUpdate () {
    if (target)
    {
        Vector3 posNoZ = transform.position;
        posNoZ.z = target.transform.position.z;

        Vector3 targetDirection = (target.transform.position - posNoZ);

        interpVelocity = targetDirection.magnitude * 5f;

        targetPos = transform.position + (targetDirection.normalized * interpVelocity * Time.deltaTime); 

        transform.position = Vector3.Lerp( transform.position, targetPos + offset, 0.25f);

    }
  }
 }
-1
source

Source: https://habr.com/ru/post/1569797/


All Articles