Cet article est la traduction de l'article "Common Gotchas" paru sur ce même site en Anglais. L'informatique est un domaine international où l'Anglais domine (le langage, pas le gars bien sur...). De ce fait, certains mots seront laissés en Anglais, pas les plus compliqués, promis.
Il existe un certain nombre de "pièges" qui ont frappé presque tous les débutants de Unity. Parfois, cela est dû au fait que vous débutez la programmation en général mais c'est parfois dû au fait que Unity utilise une méthode légèrement inhabituelle d'attacher plusieurs scripts sur un objet.
Cet aperçu tente de vous guider à travers ceux que nous voyons le plus souvent sur le forum de réponses Unity. Ce tutoriel s'adresse donc aux nouveaux venus, les noobs.
Les Traquenards
Comment accéder à une variable d'un autre script ou d'un autre objet
Comment accéder à une variable d'un autre script ou d'un autre objet
Donc, vous avez préparé deux scripts et vous voulez accéder à des variables ou des méthodes d' un script à partir de l'autre, mais obtenir une référence au script ou comment obtenir la variable reste un mystère. Appelons le script qui veut accéder à la variable le caller (appeleur) et le script qui contient la variable ou la méthode de la target (cible).
Pour obtenir le script target, nous devons trouver l'objet auquel il est attaché. Il existe cinq manières:
1. Le script target est attaché a même object que le script caller.
Dans ce cas, vous devez placer un appel à la fonction GetComponent, qui retourne une reference au script target attaché au même object. GetComponent sans rien devant cherche dans l'objet.
Avec UnityScript, on utilise GetComponent de cette manière:
GetComponent(ScriptTarget).uneVariable = uneValeur;
GetComponent(ScriptTarget).UneMethode();
Avec C#:
GetComponent<ScriptTarget>().uneVariable = uneValeur; GetComponent<ScriptTarget>().UneMethode();
2. Vous voulez accéder un script target script attaché à un autre objet parce que vous venez d'entrer en collision avec ce dernier, ou invoqué une trigger sur le script caller.
Dans ce cas, votre méthode devrait déjà inclure une référence à l'autre objet soit en tant que Collider pour OnTriggerXXX ou en tant que Collision pour OnCollisionXXX.
Dans ce cas, il vous est seulement nécessaire d'appeler GetComponent sur la référence.
Avec UnityScript:
function OnTriggerEnter(reference : Collider)
{
reference.GetComponent(ScriptTarget).uneVariable = uneValeur;
}
Avec C#
void OnTriggerEnter(Collider reference)
{
reference.GetComponent<ScriptTarget>().uneVariable = une Valeur;
}
Dans une collision, vous avez juste besoin d'obtenir quelque chose qui représente l'autre objet et appeler GetComponent dessus:
function OnCollisionEnter(reference : Collision)
{
reference.collider.GetComponent(ScriptTarget).uneVariable = uneValeur;
}
Avec C#:
Or in C#
void OnCollisionEnter(Collision reference)
{
reference.GetComponent<ScriptTarget>().uneVariable = uneValeur;
}
If for some reason you want to set a variable on some child of the object you triggered or collided with then you can use GetComponentInChildren.
Si pour une quelconque raison, vous souhaitez modifer une variable se trouvant sur un child de l'objet vous venez d'entrer en collision, vous pouvez utiliser GetComponentInChildren.
3. Vous avez une relation entre deux objets que vous pouvez créer en utilisant l'éditeur ou définir à l'aide de script lorsque la relation est créée
Donc dans ce cas vous avez une relation entre deux objets, non pas parce qu'ils sont en train d'interagir, mais plutôt parce qu'ils ont une autre relation à long terme. Par exemple, un ennemi peut courir après le joueur, un joueur peut avoir «verrouillé» une arme sur un ennemi, ou peut-être le joueur est actuellement dans ou sur un certain véhicule.
Dans ce cas, vous voulez avoir une variable dans votre script caller qui fait référence à votre script target. Le plus simple est de définir cette variable comme étant de type NomScriptTarget,cela peut aussi être un autre type de variable référence comme GameObject ou Transform.
You will assign the variable using the inspector if the relationship can be created at editing time - or if you assign it at runtime you will use either method 2 (above) or method 4 (below) to get the component and set up the variable.
Vous pouvez assigner la variable dans l'inspecteur si la relation peut être créé au moment de l'édition - ou si vous l'assignez pendant l'exécution, utilisez soit la méthode 2 (ci-dessus) ou la méthode 4 (ci-dessous) pour obtenir le composant et définir la variable.
Voici un exemple de création d'une relation à long terme à partir d'une trigger:
var targetScript : TargetScript; //Le script est directement placé dans l'emplacement de l'inspecteur
function Update(){
//Si nous avons une target et elle est prête à être utilisée
if(targetScript && targetScript.uneVariable > 100){
//Action
}else{
//Une autre action
}
}
function OnTriggerEnter(other : Collider){
//Vérifions si l'objet avec lequel nous entrons en collision peut être une target
var target = other.GetComponent(ScriptTarget);
if(target){
//Si possible
targetScript = target;
}
}
4. Vous pouvez trouver l'objet qui contient la target en cherchant par nom ou tag
Une fois l'objet trouvé, on retourne à la méthode 2 avec GetComponent.
Il est possible de trouver un objet de différentes manières - avec GameObject.FindWithTag ou GameObject.Find pour chercher l'inégralité de la scène. Ou bien transform.Find pour chercher seulement dans la hierarchie de l'objet en question et limiter la recherche à ses children. Peu importe le processus, la methode 2 revient pour accéder au script dont vous avez besoin. Vous pouvex tout autant cacher le résultat en le storant dans une variable pour obtenir une relation à long terms et utiliser la methode 3 pour manipuler l'objet.
TargetScriptName targetScript;
void Start()
{
targetScript = GameObject.Find("NomObjet").GetComponent<TargetScriptName>();
}
void Update()
{
if(Vector3.Distance(targetScript.transform.position, transform.position) < 10)
{
targetScript.uneVariable -= uneValeur;
}
}
5. Vous avez un autre composant sur l'objet mais ce n'est pas celui avec le script que vous voulez
Ceci arrive souvent quand vous traversez la hierarchie ou vous avez un autre script sur le même objet. En quelque sorte, on revient à la methode 2.
Par exemple, vous souhaitez accéder un script contenu dans chacun des children de votre caller:
for(var t : Transform in transform)
{
target = t.GetComponent(TargetScriptName);
target.DoSomething();
target.someVariable = someValue;
}
en C#:
foreach (Transform t : in transform)
{
target = t.GetComponent<TargetScriptName>();
target.Action();
target.uneVariable = uneValeur;
}
Vous pouvez regarder la vidéo démonstrative ci-dessous (en Anglais pour le moment)
Rigidbody, à quoi ça sert?
Rigidbody, à quoi ça sert?
Donc vous venez de passer les 3 derniers jours sans dormir à essayer de faire en sorte que votre objet ait un semblant de réalisme. Alors vous faites la tournée des sites de physique pour comprendre les principes de gravité, friction, collision et autres. Puis vous entendez parler du Rigidbody et sentez une montée de sueur. Et là vous vous dites, "Non vas-y quoi!!!".
Maintenant comment l'utiliser? Pour cela, je vous suggère de télécharger ce projet et vous pouvez trouver les explication sur cette vidéo en fr:
Comment s'assurer que les fonctions OnCollisionXXX et OnTriggerXXX sont appelées dans votre script.
Comment s'assurer que les fonctions OnCollisionXXX et OnTriggerXXX sont appelées dans votre script.
Tout d'abord pour détecter une collision, les deux objets doivent avoir un composant collider attaché. Pour que OnCollisioXXX fonctionne, isTrigger ne doit pas être sélectionné, en contrepartie pour que OnTriggerXXX fonctionne, il vous faut sélectionner isTrigger. Vous devez aussi suivre les règles suivantes:
L'objet qui contient le script avec OnCollisionXXX, OnTriggerXXX doit avoir un composant rigidbody attaché.
Au moins un des partis doit avoir un rigidbody qui ne soit pas endormi
Dans un souci d'optimisation, Unity place automatiquement en sommeil les rigidbodys qui ne bougent pas. Une collision avec un autre rigidbody le réveillera, considérant que ce rigidbody n'est pas lui même endormi. Dans la cas où chaque parti est endormi, la collision est simplement ignorée.
D'autres importantes considérations
Vous pouvez construire des colliders à partor de colliders primitifs. Il est ainsi possible de reproduire des objets complexes sans pour autant puiser dans les resources. Il vous suffit d'attacher des game objects sur l'objet et attacher les colliders sur ces objets. Le composant rigidbody est attaché au parent (root). Un voiture qui devrait comporter des centaines voire des milliers de polygones peut être réduite à quatre colliders pour les roues et deux larges colliders pour les parties hautes et basses.
Détecter l'Input convenablement
Détecter l'Input convenablement
Les débutants finissent souvent devant leur programme à se demander pourquoi la pression d'une touche est parfois non détectée. Ils ont tout bien fait en suivant la documentation à la lettre (du moins c'est ce qu'ils croient) mais ils ont le sentiment que certaines fois rien ne se passe. La plupart du temps, ce genre de problème survient lors du dévelopement de la partie physique du jeu via l'Input. Puisque la physique se passe dans la FixedUpdate, il serait logique que l'INput en rapport avec la physique y soit aussi. Beh non...
La fonction Update est dépendante de la machine sur laquelle le programme fonctionne. Cela signifie donc que chaque ordinateur peut avoir un FPS (Frame Per Second, combien de fois chaque script est pris en charge par seconde) différent en fonction du processeur et des différents programmes qui tournent.
La fonction FixedUpdate est définie par l'utilisateur. Il vous est possible de modifer sa valeur via le Physics Manager sur le menu, Edit->Project Settings->Physics. La valeur par défaut est 0.02 qui représente 50fps. Une valeur plus petite demandera au système de tourner plus vite. Notez que la valeur est une requête mais peut ne pas être garantis si vous demandez une valeur que le processeur ne peut fournir.
Update et FixedUpdate tourne indépendamment, cela signifie que pour une Update, on peut avoir une, plusieurs ou aucune FixedUpdate. Si votre ordinateur tourne à 100fps mais FixedUpdate est définie à 50fps, pour deux Updates, on a seulement une FixedUpdate.
Voici ce qu'il ne fait pas faire:
using UnityEngine;
public class Test:MonoBehaviour{
void FixedUpdate(){
if(Input.GetKeyDown(KeyCode.Space)){
//Action
}
}
}
Ce que vous devez faire:
using UnityEngine;
public class Test:MonoBehaviour{
bool action = false;
void Update(){
if(Input.GetKeyDown(KeyCode.Space)){
action = true;
}
}
void FixedUpdate(){
if(action){
//Action
action = false;
}
}
}
L'Input dans l'Update est détectée chaque frame ce qui garantit qu'aucune Input ne peut être ignorée. Une variable globale est modifiée pour indiquer à la FixedUpdate qu'une Input a été détectée. FixedUpdate utilise cette variable et la définit à nouveau comme false de manière à ce que l'action ne se répète pas indéfiniment.
Action dans le futur
Action dans le futur
Les coroutines sont un sujet particulièrement pointilleux pour faire que quelque chose arrive plus tard. Il est préférable de les oublier pour le moment surtout si vous débutez avec Unity. Voyons plutôt ce que nous pouvons faire
Juste pour le principe, voici un minuteur (timer) par code:
float timer;
int attente;
void Update(){
timer += Time.deltaTime;
if(timer > attente){
//Action
timer = 0;
}
}
La variable timer croît chaque frame en ajoutant deltaTime (le temps écoulé depuis le dernier frame). La variable est comparée cahque frame avec attente. Quand timer devient plus grand que attente, la déclaration est vraie, l'action est lancée et timer est remis à zéro. Cerner le timer avec un boolean permet de lancer le timer sous une certaine condition:
using UnityEngine;
using System.Collections;
public class Test:MonoBehaviour{
float timer;
int attente;
bool inside;
void Start(){
timer = 0.0;
attente = 2;
inside = false;
}
void Update(){
if(inside){
timer += Time.deltaTime;
if(timer > attente){
//Action
timer = 0;
}
}
}
void OnTriggerEnter(Collider other){
if (other.gameObject.tag=="Joueur")inside = true;
}
void OnTriggerExit(Collider other){
if (other.gameObject.tag =="Joueur"){
inside=false;
timer = 0;
}
}
}
L'exemple ci-dessus montre comment créer un minuteur pour lancer une action tant que le joueur reste dans la zone trigger. Par exemple, si le joueur marche sur du feu, si nous blessons le joueur à chaque frame, il va vite se retrouver à 0. Avec un minuteur, on peut le blesser chaque x secondes.
Cependant, Unity offre de meilleures solutio.
Limiter le temps de vie d'un object
Si vous souhaitez qu'un object n'apparaisse que pour une période déterminée de quelques secondes, vous pouvez le detruire dans la fonction Start. Destroy prend un second paramètre qui correspond à la durée de vie avant la mort définitive (...).
void Start()
{
//Détruire l'objet après 5 secondes
Destroy(gameObject, 5);
}
Il est ainsi possible de garder un objet pour une durée déterminée avant de la faire disparaître:
int vie = 10;
void Update(){
if(vie <= 0)
//Détruire l'objet après 2 secondes
Destroy(gameObject, 2);
}
Une fois l'objet mort par le manque de vie (oh la la...), il meurt une deuxième fois après 2 secondes. Ce procédé est souvent utilisé, un personnage est tué mais son corps reste sur le sol pour une durée.
Retarder une action
Vous voulez qu'une action se fasse et une autre action d'attendre un certain temps avant de se faire, la première étant décisive. UnityScript et C# offrent des méthodes différentes pour le même résultat. dans les examples ci-dessous, la variable check est nécessaire pour entrer dans la commande. En entrant, check devient false, après 2 secondes elle redevient true.
UnityScript:
#pragma strict
var check :boolean =true;
var i:int =0;
function Update () {
if(Input.GetKeyDown(KeyCode.A)&&check){
check = false;
print("Dedans" + i++);
WaitForIt();
}
}
function WaitForIt(){
yield WaitForSeconds(2.0f);
check=true;
}
C#:
using UnityEngine;
using System.Collections;
public class Wait : MonoBehaviour {
public bool check =true;
int i =0;
void Update () {
if(Input.GetKeyDown(KeyCode.A)&&check){
check = false;
print("Inside" + i++);
StartCoroutine(WaitForIt());
}
}
IEnumerator WaitForIt(){
yield return new WaitForSeconds(2.0f);
check=true;
}
}
Notez le type que renvoie la fonction, IEnumerator Ce type est utilisé pour toutes les fonctions qui sont mise en attente par le système. dans notre cas WaitForIt est lancée une première fois, yield return WaitForSeconds(2.0f); est retournée. Le système met la fonction dans une liste. Au frame suivant, le système soustarait le temps écoulé depuis le dernier frame et verifie si le temps correspondant au paramètre s'est écoulé depuis le premier appel. Et ainsi de suite.Notez aussi la manière d'appeler une coroutine en C#, Unity nécessite l'utilisation de StartCoroutine(Fonction());.
Si vous lancez ces deux scripts, vous verrez que vous pouvez appuyer sur A et la console imprime, il vous faudra attendre 2 secondes avant que l'action ne puisse se répéter.
Faire quelque chose dans quelques secondes
Si vous voulez que quelque chose se fasse quelques secondes après une autre, vous pouvez simplement utiliser Invoke. Vous déclarez la fonction vous souhaitez utiliser et vous l'invoquez ainsi Invoke("NomFonction",retardEnSeconde); Dans l'exemple ci-dessous, la fonction TurnMeBlue est appelée après 2 secondes.
UnityScript:
function Start(){
//Change l'object en bleu dans 2 sec
Invoke("TurnMeBlue", 2);
}
void TurnMeBlue(){
renderer.material.color = Color.blue;
}
Vous pouvez même faire plusieurs invocations:
var startPosition : Vector3;
var health = 100.0;
var respawning = false;
function Start(){
startPosition = transform.position;
}
//Repositione l'objet
function Respawn(){
transform.position = startPosition;
health = 100;
renderer.enabled = true;
respawning = false;
}
//Cacher le personnage
function Hide(){
renderer.enabled = false;
transform.position = new Vector3(1000,1000,1000);
}
function Update(){
if(health < 0 && !respawning){
respawning = true;
animation.Play("die");
Invoke("Hide", 3);
Invoke("Respawn", 10);
}
}
Ce script utilise Invoke pour appeler une animatin de mort et ensuite replace le personnage. Quand la vie descend en dessous de 0, l'animation "die" est jouée. Le modèle est caché (et retiré du champs) 3 secondes aprés et réapparait après 10 secondes.
Faire une action régulièrement
Au lieu de déclarer une fonction et la placer dans une boucle avec un minuteur, on peut simplement utiliser la focntion InvokeRepeating("NomFonction", retardPremierAppel,frequenceAppelSuivant);
Il est possible d'annuler la répétition avec CancelInvoke("NomeFonction"); pour annuler un appel en particulier ou sans paramètre pour annuler tous les appels.
float sante = 100f;
void Start()
{
InvokeRepeating("Soigne", 2, 2);
}
void Soigne()
{
sante = Mathf.Clamp(health + 1, 0, 100);
}
InvokeRepeating("Fonction",0,001f,2.0f);
Quand utiliser une coroutine
Une coroutine peut s'avérer utile lorsque vous avez besoin de lancer une action qui devrait être placée dans l'Update mais vous ne le voulez pas pour simplifier la chose.
Par example, il se pourrait que vous vouliez changer la rotation d'un objet dans une fonction, dela peut se faire avec une coroutine. Dans l'example suuivant, l'appel de TourneToi change la rotation de l'objet avec un angle sur une période de temps.
function OnMouseUp()
{
TournToi(Vector3(0,90,0),2);
}
function TourneToi(angle : Vector3, time : float)
{
var maRotation = transform.rotation;
var targetAngle = currentRotation.eulerAngles + angle;
var targetRotation = Quaternion.Euler(targetAngle);
var t = 0;
while(t < 1)
{
transform.rotation = Quaternion.Slerp(maRotation, targetRotation, t);
t += Time.deltaTime / time;
yield null;
}
transform.rotation = targetRotation;
}
Avec UnityScript, une fonction devient une coroutine en ajoutant le mot-clé yield. Malheureux, jamais ôh grand jamais de faire ça dans l'Update.
La vidéo ci-dessous montre ce qui vient d'être expliqué par l'exemple. Malheureusement, c'est encore en Anglais.
Comment utiliser Vector3.Lerp
Comment utiliser Vector3.Lerp
Vous avez défini votre ligne de code mais pour une quelconque rien ne se passe ou tout se passe mais pas comme vous le dîtes (à voix haute) à l'ordinateur. Lerp qui signifie Linear Interpolation ou interpolation linéaire. On change une valeur entre une valuer de départ et une valeur cible par un ratio.
transform.position = Vector3.Lerp(depart, cible, ratio);
Le ratio représente le pourcentage de déplacement entre les deux valeurs.
Si le ratio est 0, alors rien ne bouge, si 1 depart devient cible.
Si vous souhaitez déplacer unobjet entre deux points en t secondes, il vous faut enregistrer la position de départ et croitre le ratio (généralement par un facteur Time.deltaTime/nombreDeSecondes) et l'objet atteindra la destination quand ratio est égal à 1.
Vector3 _depart;
Vector3 _target;
float _t;
void Update()
{
transform.position = Vector3.Lerp(_depart, _target, _t);
_t += Time.deltaTime/2; //Take 2 seconds
}
public void SetTargetPosition(Vector3 newTargetPosition)
{
_depart = transform.position;
_target = newTargetPosition;
_t = 0;
}
Si vous souhaitez un effet plus délicat (car vous l'êtes) depuis le point où se trouve l'objet vers la cible, pour ce cas vous passez la position actuelle à Lerp.
Vous prenez depart (probablement transform.position) et vous regardez vers target. Puis vous bougez l'objet par le ratio. Avec ratio = 1, le mouvement est 100% de la distance. Avec ratio = 0.5 le mouvement représente 50% de la distance entre les deux points.
void Update(){
transform.position = Vector3.Lerp(transform.position, target.position, Time.deltaTime);
}
Si 10 m sépare transform(0) et target(10) et deltaTime est 0.2 (20%) alors (deltaTime a peu de chance d'être 0.2 mais pour l'exemple il le sera):
- 20% de target-transform (10-0) = 2m donc transform = 2
- 20% de target-transform (10-2) = 1.6m donc transform = 3.6
- 20% de target-transform (10-3.6) = 1.28m donc transform = 4.88
- Et ainsi de suite
Notez que l'objet n'atteind jamais sa cible mais s'en approche sans jamais la toucher similaire à la limite en algèbre. Il est possible de stopper la focntion en ajoutant une condition. Lerp est utilisé quand vous souhaitez déplacer un objet progressivement, cela peut être une porte qui glisse lentement pour s'ouvrir ou encore la caméra sur un 3rdPersonController utilise ce procédé pour ne pas bouger de manière top abrupte.
Stocker une liste d'objets qui peut grandir
Stocker une liste d'objets qui peut grandir
En C# il vous faut ajouter en haut de page:
using System.Collections.Generic;
UnityScript n'a besoin de rien.
Au lieu d'utliser Array ou ArraList, utiliser les List génériques. Avec les Lists, vous pouvez ajouter ou retirer des objets pendant l'execution, Lists continennent de nombreuses fonctions pour faciliter leur utilisation, telles que Sort pour arranger l'ordre. Elles peuvent aussi être changée en tableau si nécessaire.
Travailler avec une liste:
//Definir une liste avec UniyScript var myList = new List.<int>(); var anotherList = new List.<SomeClass>(); //Definir une liste avec C# List<int> myList = new List<int>(); List<SomeClass> anotherList = new List<SomeClass>(); //Ajouter un élément à une liste myList.Add(someValue); //Ajouter de multiples éléments à la liste myList.AddRange(someListOrArrayOfValues); //Vider la liste myList.Clear(); //Insérer dasn une liste myList.Insert(1, someValue); //Insérer de multiples éléments myList.InsertRange(1, someListOrArrayOfValues); //Retirer un élément en particulier myList.Remove(someValue); //Retirer à un index myList.RemoveAt(1); //Trouver l'index d'un élément var index = myList.IndexOf(someValue); //Trouver l'index d'un éleément avec une fonction en UnityScript var index = anotherList.FindIndex(function(entry) entry.someValue == something); //Faire un tableau avec une liste var myArray = myList.ToArray(); //Trouver l'index d'un objet avec une fonction en C# var index = anotherList.FindIndex((entry) => entry.someValue == something) //Taille de la liste (nombre d'éléments) var itemCount = myList.Count
Les dictionnaires sont les tableaux associatifs génériques de .NET:
//Définir un dictionnaire de string pour integer en UnityScript
var myDic = new Dictionary.<String, int>();
//Définir un dictionnaire de GameObject pour classe in UnityScript
var anotherDic = new Dictionary.<GameObject, SomeClass>();
//String pour int den C#
Dictionary<string, int> myDic = new Dictionary<string, int>();
//GameObejct pour classe en C#
Dictionary<GameObject, SomeClass> anotherDic = new Dictionary<GameObject, SomeClass>();
//Ajouter un élément
myDic["Something"] = someIntValue;
//Obtenir une valeur
var someValue = myDic["Something"];
//Obtenir une valeur complexe et modifier ses attributs
anotherDic[gameObject].someProperty = someValue;
//Vérifier si une valeur existe
if(myDic.ContainsKey("Something")) { }
//Retirer un élément
myDic.Remove("Something');
//Iteration de chaque clé en UnityScript
for(var key : String in myDic.Keys) { }
//Iteration de chaque valeur en C#
foreach(int value in myDic.Values) { }
//Vider le dictionnaire
myDic.Clear();
//Nombre de valeurs
var count = myDic.Count;
Comment bouger un rigidbody
La physique est votre ami, elle vous fera beaucoup de bien alors il vous faut bien en prendre soin!
Si votre balle semble tomber trop vite, a-t-elle la taille d'un berlon (ou une bille)? Essaeyez de faire tomber un berlon sur votre table, vous verrez que ça va vite. Pour un effet plus "flottant", il vous faut une balle bien plus grosse et lus loin de la caméra.
Le Character Controller, à quoi donc que ça sert?
Le Character Controller, à quoi donc que ça sert?
Le Character Controller peut être utilisé pour le joueur et les NPC (personnages IA). Le bon point c'est que le CC prend en charge des mesures et des logiques qui seraient compliquées de coder soi-même. Par exemple, bouger sur une plate-forme ou entrer en collision avec l'environement et les autres personnages.
De nombreaux jeux, n'utilisent pas le CC, alors assurez-vous que ce soit bien ce dont vous avez besoin et si vous d´cidez de l'utiliser, réservez le pour les objets qui en ont besoin (Pas de CC pour une voiture par exemple).
Vous pensez programmez en Java ou Javascript
Vous pensez programmez en Java ou Javascript
Tout d'abord, Unity dit utiliser Javascript. Javascript n'est pas Java et ne partage que peu ou pas de fonctionalités.Au départ, Javascript (la langage browser) se nommait LiveScript. Java était (et est encore) populaire à cette époque, alors il fut renommé JavaScript
La coroutine ne semble pas s'arrêter après le yield ou wait
La coroutine ne semble pas s'arrêter après le yield ou wait
Cela arrive souvent lorsque vous desactiver le script qui contient la coroutine ou détruit l'objet qui contenait le script qui contenait la coroutine. SOuvent, lorsque un objet meurt, on lance une coroutine ou appelle Invoke pour que quelque chose se fasse après l'animation de mort, une mise à jour des scores ou quelconque autre processus de retard.
Pas bien:
void Update() {
if(health < 0) {
StartCoroutine(Die());
Destroy(gameObject); //ou enabled = false;
}
}
IEnumerator Die() {
animation.Play("wobble");
yield return new WaitForSeconds(3);
//Cela n'arrivera jamais
animation.Play("meurir");
}
Bien:
bool estMort;
void Update() {
if(estMort) return;
if(health < 0) {
StartCoroutine(Meurt());
}
}
IEnumerator Meurt() {
estMort = true;
animation.Play("wobble");
yield return new WaitForSeconds(3);
animation.Play("meurir");
yield return new WaitForSeconds(3);
Destroy(gameObject);
}
Accéder un script en C# avec UnityScript et inverse
Accéder un script en C# avec UnityScript et inverse
UnityScript et C# ne sont pas compilés avec le même assembleur, c'est pourquoi il n'est pas possible de simplement accéder un fichier via un autre puisque les deux langages ne se comprennent pas. Un script placé dans Plugins, Standard Asset ou Pro Standard Asset est compilé en premier en IL (Intermediate Language). IL est le langage assembleur de .NET. De nombreux langages peuvent utiliser .NET et se mêler parce qu'en bout de chaîne, tout le monde se retrouve convertit en un langage commun. Une fois les scripts compilés, les autre scripts placés dans d'autres fichiers peuvent y accéder.
Ainsi, un script en C# peut accéder un script en UnityScript si ce dernier est placé dans un des fichiers Standard Asset, Pro Standard Asset ou Plugins (ou n'importe quel fichier sous leur hiérarchie). Et ce la fonctionne aussi dans l'autre sens.
Gardez tête qu'un script en UnityScript placé dans un de ces fichiers spéciaux ne pourra voir un script en C# où qu'il soit et vice-versa. La hiérarchie fait que si un script est placé dans un fichier spécial, il peut voir les autres scripts de même langage placés en dessous (compilés ultérieurement) mais ne peut voir aucun script de l'autre langage. Par logique, on retombe dans le même problême de départ. C'est pour cela qu'il vous faut éviter autant que faire se peut (rooh le langage!!) de mélanger les langages et essayer de tout faire en un seul (autant que faire se peut).
Modifier la rotation d'un objet avec Quaternion
Modifier la rotation d'un objet avec Quaternion
Évitez (ne faites pas) de modifer x, y, z, et w d'un quaternion sauf dans le cas peu probable où vous savez exactement ce que vous faites. Si vous souhaitez modifer une rotation par degrés, utilisez .eulerAngles.
Si vous souhaitez en savoir plus sur les quaternions, tout d'abord bonne chance, c'est un sujet lourd qui laisse nombre de programmeurs sur le carreau. Vous pouvez toujours en savoir un peu plus en lisant ce tutoriel.
Voici comment définir une rotation avec un ensemble d'angles:
transform.rotation.eulerAngles = new Vector3(100,0,100);

November 24, 2012 - 4:24 pm
Enfin un bon tutoriel en francais merci beaucoup
November 25, 2012 - 2:59 pm
Roooh, merci beaucoup pour la traduction !
Bravo a toute l’équipe pour le travail de qualité effectué sur ce site.
November 30, 2012 - 8:20 am
Bravo pour le travail et merci.
December 21, 2012 - 5:30 am
Je viens juste vous dire Merci pour les tutoriaux gratuit et surtout, très bien expliqué en français.
J’espère que ça durera avec d’autres tutoriels.
Merci et bonne continuation !
January 29, 2013 - 3:45 pm
Hop favoris!
Merci beaucoup!