unity3d (2d!) - La caméra se centre sur le joueur, mais ne jamais dépasser la “carte” des limites

Je suis entrain de créer un jeu qui a jusqu'à 4 orthographique caméras (jusqu'à 4 joueurs), les différents montants de l'écran, en fonction de la quantité de joueurs.

unity3d (2d!) - La caméra se centre sur le joueur, mais ne jamais dépasser la “carte” des limites

unity3d (2d!) - La caméra se centre sur le joueur, mais ne jamais dépasser la “carte” des limites

J'ai un script qui contrôle toutes les caméras, le réglage de leur position par rapport aux joueurs qu'ils sont à regarder.

Ce que je veux réaliser est un simple tête-coureur de style de mouvement, où la caméra suit le joueur, mais pas aller à l'extérieur des limites de la carte.

unity3d (2d!) - La caméra se centre sur le joueur, mais ne jamais dépasser la “carte” des limites

J'ai réussi à obtenir les limites de travail en haut à gauche de la caméra, lorsque les caméras sont "carrés" (comme dans le 4-joueur de mise en page). Cependant, les autres caméras de ne pas suivre correctement à tous, et dans le rectangle du mode 2 joueurs, le top de la caméra va encore trop loin à gauche et à droite. Je suis assez sûr que je sais exactement quelle ligne de code est à l'origine du problème... mais je ne sais pas ce que je dois faire pour le réparer...

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);
}

Donc je suis assez sûr que j'ai besoin d'être de la vérification des dimensions de la caméra et la position relative sur l'écran, mais je suis perdu pour exactement ce que je dois faire.

(edit)
Script explication:

  • Le script est un script global fixé à l'appareil photo principal objet, qui n'est jamais vu par le joueur
  • Les quatre joueurs cames (camPlayer1 - camPlayer4) sont des variables publics et affectés à l'script dans le concepteur
  • trackPlayer1-trackPlayer4 sont publiques gameobjects, qui sont attribués dans le concepteur - ils sont attribués au joueur des objets
  • Joueur de suivi fonctionne sur toutes les cams... par exemple si je change camPlayer2.transformer.position = new Vector3(Mathf.De serrage(trackPlayer2.transformer.position.x, leftBound, rightBound), Mathf.De serrage(trackPlayer2.transformer.position.y, topBound, bottomBound), camPlayer2.transformer.position.z); à camPlayer2.transformer.position = trackPlayer2.transformer.position;, le code a l'effet attendu, la caméra suit le joueur. C'est seulement de la plage de serrage pour les bornes de la carte que je vais avoir des problèmes avec
  • La caméra orthographique tailles sont fixés à 2

code des postes les caméras sur l'écran au démarrage:

    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;
}
}

modifier, afin que je puisse obtenir la première caméra de voies indépendamment de la forme (donc en mode 2 joueurs, avec une forme rectangulaire de la caméra, le joueur-1 cam respecter les limites de la carte) avec le code ci-dessous. Je devine alors que j'ai besoin d'appliquer un rajustement de la leftBound, rightBound, topBound et bottomBound dépend de la rects de l'autre cames. Comment établir et de calculer celles-ci, je n'ai aucune idée de

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??
Vous êtes le code est assez difficile à suivre. Il serait utile si vous avez ajouté des commentaires pour expliquer ce que vous essayez de calculer, à certaines parties. Avez-vous pris en compte le fait que la orthographicSize propriété est la moitié de la longueur verticale de l'écran et pas sur toute la longueur?
Donc je ne suis pas très familier avec l'Unité, mais j'imagine que la façon de calculer le ratio d'aspect est d'au moins une partie du problème. Vous calculez le ratio d'aspect pour chaque caméra comme Screen.width / Screen.height mais alors, manifestement, vous n'avez pas rendu à l'ensemble de la zone de l'écran. Vous avez besoin d'utiliser le ratio d'aspect de la caméra, qui peut être différente sur le rapport d'aspect de l'écran.
La recherche à l'Unité de l'Appareil photo de classe, vous pouvez probablement utiliser la rect propriété de la caméra pour calculer le ratio d'aspect pour chaque caméra.
Je dnt pense que c'est la question. ex 4 plyr mode, avec le script courant, cam1 pistes le joueur & respecte les limites de la carte/arrière-plan. C'est le même format que les autres caméras, qui ne respecte pas les limites (en fait le suivi va totalement à l'arrêt lorsque le serrage est appliquée, même pas en se concentrant sur le joueur). Je suppose ur droit qu'il a smthing 2 faire avec rect de la cam, mais je n'ai aucune idée de ce que, malheureusement. J'ai essayé d'utiliser cam1.cameraToWorldPoint() pour traduire en haut, en bas, à gauche et à droite de limites, puis en utilisant le cam2.worldToCameraPoint, mais juste rendre les choses encore plus bizzare.
Je pense que vous avez probablement un certain nombre de questions. Par exemple, SpriteRenderer::bounds::size est les dimensions de l'AABB et de ne pas tenir compte de la position. Vous devriez probablement utiliser la min et max propriétés de Bounds pour obtenir les coordonnées s'étend à la place.

OriginalL'auteur LairdPleng | 2015-01-03