[DB - AL] Camera dans le dos de mon perso

Modérateur : Administrateurs Suppléants

Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Avatar de l’utilisateur
laurent357
Messages : 90
Inscription : 23 Juil 2012 16:35
Localisation : Belgique

[DB - AL] Camera dans le dos de mon perso

Message par laurent357 » 12 Fév 2018 15:10

Bonjour à toutes et à tous,

J'ai fait un petit script permettant à ma caméra de toujours rester dans le dos de mon perso lorsqu'il se déplace.
J'ai cherché des exemples sur le web, mais rien ne correspondait vraiment au truc simple que je voulais faire.
Je pourrais également faire de ma caméra un sous-objet du personnage et la positionner dans son dos, mais en plus d'être vite limité pour ajouter des effets à la caméra, je ne trouve pas ça très pro ...

Le problème, c'est que je pense que mon script est trèèès compliqué :aille: et qu'Unity et ses fonctions intégrées permettent fort probablement de faire les choses de manière beaucoup plus simple (j'ai utilisé la trigonométrie) et moins gourmande en ressources ... :oops:

Voici mon script basique placé sur la caméra :

Code : Tout sélectionner


[SerializeField]
private Transform tr_goToFollow; // player à suivre
[SerializeField]
private float fl_offset; // offset de la camera / hypoténuse

private void Update()
{
	Quaternion playerQtrAngle = tr_goToFollow.rotation; // rotation du player
	Vector3 playerEulrAngle = playerQtrAngle.eulerAngles; // rotation en degré

	Vector3 playerV3Position = tr_goToFollow.transform.position; // position du player
	float posX = playerV3Position.x;
	float posZ = playerV3Position.z;

	//calcul des coordonnées de la camera
	// [-1 pour tourner dans le bon sens] [+90 pour positionner la caméra derrière le player] [Mathf.Pi/180 --> deg en rad] [+ posX ou  + posY pour le déplacement] 
	float x = (Mathf.Cos((playerEulrAngle.y * (-1) + 90) * (Mathf.PI / 180)) * fl_offset) + posX; 
	float y = this.transform.position.y;
	float z = (Mathf.Sin((playerEulrAngle.y * (-1) + 90) * (Mathf.PI / 180)) * fl_offset) + posZ;        

	this.transform.position = new Vector3(x, y, z);        
        
	this.transform.LookAt(tr_goToFollow); // la camera regarde toujours le player
}

Voilà, ça marche parfaitement bien ... ça a même marché du premier coup (ça m'inquiète un peu d'ailleurs ...).
Mais je suis persuadé que ce n'est pas la bonne méthode ...

Merci pour conseils, pistes et autres précisions ::d

[Laurent]
[Laurent]

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 4632
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: [DB - AL] Camera dans le dos de mon perso

Message par boubouk50 » 12 Fév 2018 16:02

Déjà, tu pourrais simplement commencer par optimiser ton code pour éviter des appels et des déclarations inutiles. Par exemple créer des variables temporaires à chaque Update (). Même si pour la lecture c'est plus simple, pour la mémoire c'est beaucoup de déchets. Par exemple playerQtrAngle et playerV3Position sont totalement inutiles, tu devrais travailler directement avec tr_goToFollow.

Sinon, qu'en est-il de simplement travailler avec le vecteur Forward de ton player?
S'il est bien orienté, le GameObject qui te sers de cible doit avoir son Forward qui indique son devant. L'arrière est donc le -Forward. Il ne te reste donc plus qu'à placer la caméra à X mètre derrière selon cet axe et bingo.
Donc pour résumer, la caméra copie le transform du personnage auquel tu fais un offset sur l'axe -Forward local.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
laurent357
Messages : 90
Inscription : 23 Juil 2012 16:35
Localisation : Belgique

Re: [DB - AL] Camera dans le dos de mon perso

Message par laurent357 » 13 Fév 2018 12:37

Salut Boubouk,

Merci pour tes conseils, voici un code plus concis ou je remplace le LookAt par le forward :

Code : Tout sélectionner

[SerializeField]
private Transform tr_goToFollow; // player à suivre
[SerializeField]
private float fl_offset; // offset de la camera / hypoténuse

private void Update()
{
	//calcul des coordonnées de la camera
	// [-1 pour tourner dans le bon sens] [+90 pour positionner la caméra derrière le player] [Mathf.Pi/180 --> deg en rad] [+ posX ou  + posY pour le déplacement] 
	float x = (Mathf.Cos((tr_goToFollow.rotation.eulerAngles.y * (-1) + 90) * (Mathf.PI / 180)) * fl_offset) + tr_goToFollow.transform.position.x;
	float y = this.transform.position.y;
	float z = (Mathf.Sin((tr_goToFollow.rotation.eulerAngles.y * (-1) + 90) * (Mathf.PI / 180)) * fl_offset) + tr_goToFollow.transform.position.z;

	this.transform.position = new Vector3(x, y, z);
	this.transform.forward = tr_goToFollow.transform.forward;
}
Ce script fonctionne.
Par contre, vu que la camera en même temps que de s'orienter dans le même sens que mon perso, doit également décrire un cercle autour de lui (un peut comme la lune autour de la terre si je ne dis pas de conneries ... parce qu'il m'arrive souvent d'en dire :rouge: ), je ne vois pas comment me passer de la trigono ...

Merci.
[Laurent]

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 4632
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: [DB - AL] Camera dans le dos de mon perso

Message par boubouk50 » 13 Fév 2018 12:48

laurent357 a écrit :
12 Fév 2018 15:10
J'ai fait un petit script permettant à ma caméra de toujours rester dans le dos de mon perso lorsqu'il se déplace.
laurent357 a écrit :
12 Fév 2018 15:10
Par contre, vu que la camera en même temps que de s'orienter dans le même sens que mon perso, doit également décrire un cercle autour de lui
Faudrait savoir...

Tu peux tout simplement gérer un offset de rotation.
Tu récupères le forward, tu l'appliques à ta caméra (donc position et rotation de ton perso), tu tournes ta caméra selon l'offset de rotation (donc position du perso mais rotation différente), puis tu recules ta caméra de la distance voulue et c'ets bon.

Sinon, tu mets un empty gameObject (appelons le orbitGO) enfant de ton perso, orienté comme le perso. Tu attaches ensuite ta caméra à orbitGO avec le recul souhaité. Ensuite, il ne te reste plus qu'à tourner orbitGO selon son axe vertical pour tourner autour de ton perso.

Il te faut néanmoins surement penser plus loin (je ne connais pas ton gamePlay):
- Est-ce que le personnage peut ne plus être vertical -> La caméra suivra et sera penchée: peut-être souhaites-tu qu'elle reste tout le temps sur le plan horizontal? Aussi, elle pourrait se retrouver sous le sol...
- Quand est-il des collisions? Ta caméra traversera-t-elle des murs/sols/etc
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
laurent357
Messages : 90
Inscription : 23 Juil 2012 16:35
Localisation : Belgique

Re: [DB - AL] Camera dans le dos de mon perso

Message par laurent357 » 13 Fév 2018 15:34

boubouk50 a écrit :
13 Fév 2018 12:48
Faudrait savoir...
Désolé, j'ai pas été clair :gene:

En gros, c'est comme dans un jeu de voiture (par exemple "Need For Speed"),
Ta camera est derrière ton véhicule, et lorsque tu tournes avec ta voiture (avec les flèches du clavier, le joystick ...), la camera tourne tout en restant collée au dos de ta voiture. Donc elle tourne sur elle même tout en décrivant un arc de cercle autour de la voiture pour la suivre à une distance définie.
En fait, si mon perso tournait en permanence sur lui même, on pourrait dire que ma camera est en orbite géostationnaire autour de mon perso, la hauteur d'orbite étant la distance que je décide entre mon perso et la camera.

D'ou mon (ma mauvaise) idée d'utiliser la trigono, en considérant que la distance player-camera est l’hypoténuse et en récupérant la rotation de mon perso (que j'applique avec les flèches du clavier).
Sinon, tu mets un empty gameObject (appelons le orbitGO) enfant de ton perso, orienté comme le perso. Tu attaches ensuite ta caméra à orbitGO avec le recul souhaité. Ensuite, il ne te reste plus qu'à tourner orbitGO selon son axe vertical pour tourner autour de ton perso.
Oui, mais je préfère tout dissocier ...

Tu peux tout simplement gérer un offset de rotation.
Tu récupères le forward, tu l'appliques à ta caméra (donc position et rotation de ton perso), tu tournes ta caméra selon l'offset de rotation (donc position du perso mais rotation différente), puis tu recules ta caméra de la distance voulue et c'ets bon.
Si je fais :

Code : Tout sélectionner

this.transform.forward = tr_goToFollow.transform.forward;
Je récupère parfaitement la rotation de l'objet, mais pas sa position (ma caméra tourne, mais reste en place...)
Il y a un truc qui m'échappe. Si je n'utilise pas un transform.position, je ne comprends pas comment faire.

Je suis désolé (à plat ventre sur un sol parsemé de tessons de bouteilles et avec un bonnet d'âne !), mais j'ai beau retourner ton explication dans tout les sens dans ma tête .. je pige pas ... :pleur4:

J'ai parcouru plusieurs fois la doc sur le "forward" (translate, rigidbody, addforce ...), mais je ne comprends pas comment cela pourrait résoudre mon problème ...

Merci pour ton aide.
[Laurent]

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 4632
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: [DB - AL] Camera dans le dos de mon perso

Message par boubouk50 » 13 Fév 2018 16:35

??
Faut pas tout prendre au pied de la lettre... Evidemment qu'il faut passer par la position pour placer la caméra au bon endroit. Le forward c'est pour te donner le vecteur sur lequel il faut déplacer la caméra pour qu'elle soit toujours derrière.

J'ai peut-être une solution plus simple alors:
Tu crées un empty GameObject (Cam_OrbitalPos) dont le seul script est de copier-coller la position du perso. Comme ça tu simules la parentée sans avoir la rotation et tu gardes l'intégrité de ta hiérarchie.
Tu crées un autre empty GameObject (Cam_OrbitalRot) enfant de Cam_OrbitalPos dont le seul script est de tourner autour de son axe Y pour pouvoir gérer la rotation.
Tu attaches ensuite ta caméra à Cam_OrbitalRot à une distance X pour qu'elle soit toujours à la même distance du perso.

Ce n'est pas forcément judicieux tel quel, parce que ce n'est pas aussi simple de faire la caméra de Need For Speed, mais dans l'idée, tu recrées la hiérarchie souhaitée par copier-coller (en séparant les transform), vu que tu préfères dissocier la caméra du perso...
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
laurent357
Messages : 90
Inscription : 23 Juil 2012 16:35
Localisation : Belgique

Re: [DB - AL] Camera dans le dos de mon perso

Message par laurent357 » 21 Fév 2018 09:49

Bonjour Boubouk,

Désolé de te répondre si tard, j'ai été envoyé sur autre chose ....

Merci pour ta solution, je teste cela.

Bonne journée :-)
[Laurent]

Répondre

Revenir vers « (C#) CSharp »