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.
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.
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??
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
Vous devez vous connecter pour publier un commentaire.
Il ya plusieurs problèmes avec vos calculs. Je pense que c'est juste de la chance que cela fonctionne pour certaines situations. Alors que votre idée générale est correcte, vous êtes le calcul avec le mauvais propriétés. Fondamentalement, vous avez besoin de comprendre le ratio d'aspect de la photo, la boîte englobante de votre carte et comment un appareil doit se comporter à l'intérieur des frontières.
Nous avons besoin de l'aspect ratio de l'appareil photo pour calculer la largeur ou l'étendue.
Comme vous pouvez le voir dans l'image,
Screen.width
etScreen.height
sont en faisant référence au jeu de la fenêtre ou de la résolution de l'écran dans le cas où vous êtes en cours d'exécution le jeu en plein écran. Vous pouvez également voir que les caméras peuvent avoir un ratio d'aspect différent, comparativement à la fenêtre de jeu. La bonne nouvelle, c'est que l'Unité fournit une propriété afin d'obtenir l'appareil photo, l'aspect ratio.Maintenant que nous avons la caméra extensions, nous allons jeter un oeil à votre carte et sa boite.
- Vous essayé de calculer avec
bounds.size
, mais comme vous pouvez le voirbounds.size.x
est la largeur de la boîte englobante. À l'aide de la taille ne fonctionnera que si votre carte en bas à gauche commence à (0,0) dans le monde de l'espace. Une meilleure approche est d'utiliserbounds.min
etbounds.max
déjà de retour de coordonnées dans l'espace.Votre but ultime est que la caméra doit rester dans les limites de la carte, c'est à dire, sa position est limité par les quatre conditions suivantes:
Maintenant vous avez seulement besoin de prendre la position du joueur et de limiter la caméra à ces conditions:
Si toutes les caméras ont la même taille et de proportions, vous pouvez utiliser les mêmes limites pour les joueurs de tous des caméras et seulement calculer
camX
etcamY
pour chaque joueur.Je pense qu'il y a quelques copier&coller des erreurs. Vérifiez si vous utilisez le lecteur correct et de la caméra variables pour chaque caméra. Si vous ne trouvez pas une erreur, vous pouvez coller votre code à pastebin.com et le lien dans un commentaire.
Étonnant de voir les fautes de frappe d'une fatigue des yeux peut manquer... oui, il y avait en effet un couple de c&p erreurs sur cam1 et 4. Excellente réponse, très bien expliqué. Merci.
OriginalL'auteur Stefan Hoffmann
J'aimerais vous proposer une autre approche pour votre problème.
Est-il possible pour vous d'ajouter les collisionneurs à la frontière de votre carte, et un collisionneur de la caméra? Ensuite, vous pouvez apporter l'appareil photo suit le joueur (l'utilisation de la physique!), et lorsque le joueur atteint une limite, la caméra ne sera pas, en raison de la collider.
Ensuite, vous pouvez facilement diviser l'écran en sachant que le nombre de joueurs que vous avez.
Un joueur? --> tous taille de l'écran
Deux joueurs? --> caméra 1 se termine ad hauteur de l'écran /2, appareil photo 2 débute à l'écran en hauteur /2 +1
et ainsi de suite
Il est utilisé comme dans les Mmorpg à ne pas rendre l'appareil photo passe en dessous du terrain (c'était mon cas, c'était en 3D bien sûr). Je ne me souviens pas ce que j'ai cherché il y a 2 ans, mais certains indices peuvent être trouvés ici answers.unity3d.com/questions/14693/... ou answers.unity3d.com/questions/19864/... je pense que le même principe peut être appliqué à votre 2D
OriginalL'auteur Gounemond
Salut tout le monde pour certaines personnes qui ont besoin de code complet pour le travail en objet de jeu avec de nombreux enfants les sprites dans les Vides Gameobject comme:
Ce Code sera boucle en arrière-plan de l'objet et de prendre les tenus de tous les enfants sprites :D, je fais un Frankestein code hahhaa grâce à @Stefan Hoffmann explication. J'espère que ce sera utile à d'autres, Désolé pour mon mauvais anglais 🙁
OriginalL'auteur Diego Cortés
Vous devez utiliser cette de cette simple mais utile l'unité appareil 2d suivre script
également disponible sur github.
https://gist.github.com/unity3diy/5aa0b098cb06b3ccbe47
Cela n'a rien à voir avec ce que l'OP a été d'en parler.
OriginalL'auteur NabeelSaleem