Uploaded by Yousra Aarab

Les scripts CSharp

advertisement
Les Scripts Unity 3D en C#
Khalid NAFIL
13-02-2018
Auteur : Khalid Nafil
Ecole : ENSIAS
Filière : IWIM
Twitter : @khalidnafil
Version : 1.1
Année : Février 2018
Unity version : 2017.3.0f3
Ce document présente les scripts de base d’Unity qui permettent d’élaborer des jeux simples à
base du langage C#. Plusieurs concepts fondamentaux sont également présentés.
La lecture de ce document est nécessaire pour comprendre la philosophie ainsi que la logique
de Unity 3d.
Il est à noter également que ce document s’inspire des éléments de script présents sur le site
officiel de Unity 3d.
Table des matières
Table des matières
Activer les GameObjects
Exemple
Les fonctions Translate et Rotate
Exemple
LookAt
Exemple
Destroy
Exemple
GetButton et GetKey
Exemple
Script
GetAxis
Exemple
Script
OnMouseDown
Exemple
Script
GetComponent
Exemple
Script
DeltaTime
Exemple
Script
Data Types
Exemple
Script
Les Classes
Exemple
Script
Instantiate
Exemple
Script
1
1
4
4
5
5
5
6
8
8
10
10
11
12
13
13
13
13
14
14
14
15
16
17
17
17
17
18
20
20
24
24
26
1
Arrays
Exemple
Script
Invoke
Exemple
Script
Enumerations
Exemple
Script
Switch Statements
Exemple
Script
Collision
Étapes
TP Cubes à Colorer et Redimensionner
Script “ColoriageAleatoire” :
26
26
27
28
28
29
29
30
30
32
32
33
34
34
36
36
2
Activer les GameObjects
Pour activer ou désactiver un objet via le scripting, on peut utiliser la fonction SetActive.
Cela va permettre de faire switcher l’objet entre les deux états ‘on’ et ‘off’ au niveau de
la scène. Dans l’exemple ci dessous, nous avons une simple fonction Start qui contient
gameObject.SetActive(false).
Pour ce faire, créer un objet GameObject et lui associer le composant script
“ActiveObjects”. En exécutant le jeu, vous allez voir que GameObject n’est plus actif,
(Vous pouvez associer ce script comme composant de l’objet “Lumière”). Cependant, si
nous travaillons avec la hiérarchie des objets, il est important de souligner qu’un objet
parent peut être désactivé, ce qui va rendre tous ses objets fils désactivés dans la
scène. Cependant il va rester actif avec sa hiérarchie.
Exemple
//Script 1
using UnityEngine;
using System.Collections;
public class ActiveObjects : MonoBehaviour
{
void Start ()
{
gameObject.SetActive(false);
}
}
3
Les fonctions Translate et Rotate
Les fonctions Translate et Rotate sont communément utilisées pour changer la position
et la rotation d’un GameObject. Dans l’exemple ci-dessous, on essaie de voir la fonction
Translate. On peut voir que l’argument de Translate prend un Vector3. Dans cet
exemple on va uniquement translater l’axe des Z par 1 par frame puisque le script est
situé dans la fonction Update. Dans ce script on multiplie la vitesse de translation par le
paramètre Time.deltaTime pour que le déplacement soit mesuré en mètre par seconde
et non en mètre par frame. La fonction Rotate fonctionne de la même façon que la
fonction Translate quoique elle est responsable d’appliquer la rotation à l’objet en
question. Pour cela, créez le script suivant et l’associer au gameobject ‘Sphere’ que
vous allez ajouter pour cette fin.
NB : veuillez modifier GetKey par GetKeyDown pour voir la différence entre les deux.
Exemple
using UnityEngine;
using System.Collections;
public class TransformFunctions : MonoBehaviour
{
public float moveSpeed = 10f;
public float turnSpeed = 50f;
void Update ()
{
if (Input.GetKey (KeyCode.UpArrow))
transform.Translate (Vector3.forward * moveSpeed *
Time.deltaTime);
if (Input.GetKey (KeyCode.DownArrow))
transform.Translate (-Vector3.forward * moveSpeed *
Time.deltaTime);
if (Input.GetKey (KeyCode.LeftArrow))
transform.Rotate (Vector3.up, -turnSpeed * Time.deltaTime);
if (Input.GetKey (KeyCode.RightArrow))
4
transform.Rotate (Vector3.up, turnSpeed * Time.deltaTime);
}
}
//Vector3.up c’est pour faire tourner l’objet selon l’axe des Y à 1 degré par seconde.
5
LookAt
LookAt peut être utilisée pour permettre à un GameObject de suivre le mouvement d’un
autre objet cible. Dans cet exemple, nous allons permettre au Cube de suivre le
mouvement de l’objet Sphere. Pour ce faire, nous allons modifier le script
Comportement associé à l’objet Cube et après nous allons faire glisser à partir de la
hiérarchie l’objet Sphere au niveau du paramètre target du Cube au niveau de la fenêtre
Inspecteur.
Exemple
using UnityEngine;
using System.Collections;
public class Comportement : MonoBehaviour
{
public Transform target;
void Update ()
{
transform.LookAt(target);
}
}
6
Destroy
La fonction Destroy peut être utilisée pour supprimer les GameObjects ou les
composants à partir des GameObject en mode exécution. Cela peut être fait aussi avec
un time delay en utilisant son deuxième paramètre, un nombre float
Destroy(GameObject/Composant , optional delay).
Pour supprimer un GameObject par exemple, nous pouvons simplement faire référence
au GameObject avec qui le script est attaché. Dans cet exemple, considérons le script
DestroyBasic que nous allons associer à un nouvel objet Plan(1) que nous allons créer.
En mode exécution, lorsqu’on va appuyer sur la touche “espace”, l’objet Plan(1) va être
supprimé.
Considérons maintenant le script DestroyOther associé toujours avec le même objet
Plan(1). Dans ce script, nous avons ajouté un attribut public “other” de type
GameObject. En mode édition, nous allons glisser l’objet Cube à partir de la fenêtre
Hiérarchie vers le paramètre “other” de l’objet Plan(1) au niveau de la fenêtre
Inspecteur. En mode Play, lorsqu’on appuie sur la touche “Espace” l’objet Cube est
alors supprimé.
Pour le troisième script DestroyComponent, nous allons l’associer par exemple à l’objet
Sphere. En mode play, lorsqu’on va appuyer sur la touche “Espace”, le composant
MeshRenderer est alors supprimé et du coup l’objet Sphere n’est plus visible dans le
jeu mais il n’est pas supprimé du jeu.
Nous pouvons toujours associer le paramètre delay avec la fonction Destroy pour que
la suppression puisse avoir lieu après une attente en secondes définie par le paramètre
delay. Par exemple, Destroy(gameObject, 3f) va supprimer l’objet “gameObject” après 3
secondes.
Exemple
public class DestroyBasic : MonoBehaviour
{
void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Destroy(gameObject);
7
}
}
}
public class DestroyOther : MonoBehaviour
{
public GameObject other;
void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Destroy(other);
}
}
}
public class DestroyComponent : MonoBehaviour
{
void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Destroy(GetComponent<MeshRenderer>());
}
}
}
8
GetButton et GetKey
Dans Unity, GetKey et GetButton sont utilisés pour recevoir des entrées à partir des
touches de clavier ou à partir des boutons joystick au niveau des manettes de jeu. La
différence principale entre les deux est que le GetKey attribue des noms de touches en
utilisant les codes de touches. Par exemple, la barre d’espace est représentée par
“KeyCode.Space”. Cela fonctionne bien avec le clavier, par contre il est recommandé
d’utiliser le GetButton à la place et spécifier vos propres contrôles. Le “Gestionnaire des
entrées” vous donne la possibilité de nommer une entrée et lui associer une clé ou un
bouton et pourrait être accessible en choisissant Edit > Project Setting > Input. On peut
référencer un nom en utilisant une chaîne. Par exemple “Jump”, est une entrée par
défaut représentée par la barre d’espace, mais on peut mettre à la place un code
bouton ou une clé différente pour changer l’entrée qui peut représenter “Jump”. En
appelant ce bouton, nous pouvons référencer le nom en utilisant la chaîne “Jump”.
Pour savoir quoi écrire dans le bouton positif, il va falloir consulter la référence dans la
documentation
ou
suivre
ce
lien
https://docs.unity3d.com/Manual/class-InputManager.html
Lorsque nous utilisons les entrées GetKey ou GetButton, nous disposons alors de trois
états qui retournent tous un booléen. Le premier est GetKey ou GetButton. Cela va
enregistrer true ou false, dépendamment du bouton s’il a été pressé ou non. Si la clé
n’a pas été pressée, alors GetButton va retourner false. Lorsque nous appuyons sur la
clé la première fois, elle va retourner true au niveau de la première frame, après lorsque
nous progressons à travers les autres frames, appuyer sur le bouton GetButtonDown va
retourner false. GetButton est toujours égal à true, donc on peut vérifier si le bouton est
toujours appuyé. Après, lorsqu’on relâche le bouton, GetButtonUp retourne true, mais
seulement lors du premier frame. En continuant, toutes les valeurs affichent false, donc,
lorsque le bouton n’est pas appuyé, tout est faux, lorsque nous appuyons la première
fois sur le bouton, nous vérifions cela au niveau de GetButtonDown, qui va retourner
true. De plus, GetButton va retourner true. Après la première frame, GetButtonDown
retourne à false, nous pouvons utiliser cela pour des tâches telles que tirer avec son
arme la première fois. En continuant d’appuyer, seul GetButton retourne true. Lorsqu’on
relâche le bouton, GetButtonUp retourne true pour un seul frame et après retourne à
false. Notons que GetKey se comporte exactement de la même façon, seulement le
code qui est écrit diffère un peu. Pour vérifier l’état d’un bouton, nous utilisons la chaîne
du titre placée dans le gestionnaire des entrées (Input Manager), Jump (bool down =
Input.GetButtonDown(“Jump”)). Lorsque nous vérifions l’état pour une clé spécifique
nous pouvons utiliser KeyCodes parce que cela ne concerne que la clé exacte, par
9
ailleurs il est recommandé d’utiliser GetButton et spécifier les entrées en utilisant le
gestionnaire des entrées.
Exemple
Dans cet exemple, nous utilisons un objet “GamePlayer” où on va placer un objet
“Sphere” par exemple. Nous allons associer le script ci-dessous au GamePlayer. Cela
consiste à faire bouger l’objet “Sphere” sur l’axe des “Z” lorsqu’on appuie sur les flèches
de direction haut et bas, et sur l’axe des “X” lorsqu’on appuie sur les flèches de
direction droite et gauche en utilisant Input.GetKey (voir exemple). On pourrait
également faire sauter l’objet “Sphere” sur l’axe des “Y” en utilisant
Input.GetAxis(“Jump”) (voir exemple).
Script
using UnityEngine;
using System.Collections;
public class TransformPlayer : MonoBehaviour {
private Transform playerTransform;
private float decalMove = 1.0f;
private float coefMove = 3.0f;
private float jumpCoeff = 5.0f;
void Start () {
playerTransform = GetComponent<Transform> ();
}
// Update is called once per frame
void Update () {
if (Input.GetKey(KeyCode.UpArrow)){
playerTransform.position = new Vector3 (playerTransform.position.x,
playerTransform.position.y, playerTransform.position.z + decalMove);
}
if (Input.GetKey(KeyCode.DownArrow)){
playerTransform.position = new Vector3 (playerTransform.position.x,
playerTransform.position.y, playerTransform.position.z - decalMove);
}
10
if (Input.GetKey(KeyCode.RightArrow)){
playerTransform.position = new Vector3 (playerTransform.position.x +
decalMove, playerTransform.position.y, playerTransform.position.z);
}
if (Input.GetKey(KeyCode.LeftArrow)){
playerTransform.position = new Vector3 (playerTransform.position.x decalMove, playerTransform.position.y, playerTransform.position.z);
}
transform.Translate (0,Input.GetAxis("Jump") * Time.deltaTime * jumpCoeff,
Input.GetAxis("Vertical") * coefMove * Time.deltaTime);
}
}
11
GetAxis
Input.GetAxis fonctionne de la même façon que GetButton et GetKey mais avec des
différences majeures. GetKey et GetButton retournent tous les deux un booléen, bouton
pressé ou non, alors que GetAxis retourne une valeur de type float entre -1 et 1. Les
axes sont prédéfinis dans le Gestionnaire des entrées (Input Manager) qu’on peut
accéder via le menu Edit > Project Settings > Input. Lorsque le bouton est pressé nous
allons considérer la valeur positive, alors qu’avec Axis nous devons considérer à la fois
les boutons positifs et négatifs.
Exemple
Dans cet exemple, nous créons un GameObject auquel on va ajouter un composant
GUI Text en sélectionnant Component > Rendering > GUI Text. Nous repositionnons
correctement ce composant pour qu’il apparaisse sur la vue “Game”. Nous créons
après un objet “Sphere” auquel nous associons le script ci-dessous. Au niveau de
l’éditeur, nous allons faire glisser le GameObject vers le champ “textOutPut” de l’objet
“Sphere”. Dans ce script, nous récupérons la position sur l’axe horizontal de l’objet
“Sphere” que nous multiplions par une constante “range” à définir au niveau de l’éditeur.
À l’aide de l’instruction transform.position, nous allons faire déplacer l’objet “Sphere” sur
l’axe Horizontal.
Script
public float range;
public GUIText textOutput;
void Update ()
{
float h = Input.GetAxis("Horizontal");
float xPos = h * range;
transform.position = new Vector3(xPos, 2f, 0);
textOutput.text = "Value Returned: " + h.ToString("F2");
}
12
OnMouseDown
L'événement “OnMouseDown” peut être utilisé pour détecter le clic sur un Collider ou
un élément GUI Text.
Exemple
Dans cet exemple, nous avons un objet “Cube” qui dispose d’un Box Collider et d’un
Rigidbody. Nous allons disposer notre objet “Cube” sous forme de porte entre deux
autres objets “Cube” qui chacun dispose d’un Rigidbody. Nous associons une masse à
notre objet “Cube” égale à 0.20 pour qu’il puisse bouger correctement suite à
l’application de notre force (voir script ci-dessous). N’oubliez pas de décocher la case
“Gravity” de l’objet “Cube”.
Script
using UnityEngine;
using System.Collections;
public class MouseClick : MonoBehaviour
{
void OnMouseDown ()
{
GetComponent<Rigidbody>().AddForce(-transform.forward * 500f);
GetComponent<Rigidbody>().useGravity = true;
}
}
13
GetComponent
La fonction GetComponent permet d’adresser les propriétés des autres scripts ou
composants qui constituent la scène.
Exemple
Dans cet exemple, nous considérons deux cubes “Cube1”, “Cube2” et trois scripts
“UsingOtherComponent”, “AnotherComponent”, “YetAnotherComponent” (voir ci
dessous). Nous associons les deux premiers scripts à “Cube1” et le dernier à “Cube2”.
Nous glissons après “Cube2” sur le paramètre “GameObject” de “Cube1”. Vérifiez aussi
que “Cube2” dispose d’un “BoxCollider”.
Script
//UsingOtherComponent Script
using UnityEngine;
using System.Collections;
public class UsingOtherComponents : MonoBehaviour
{
public GameObject otherGameObject;
private AnotherScript anotherScript;
private YetAnotherScript yetAnotherScript;
private BoxCollider boxCol;
void Awake ()
{
anotherScript = GetComponent<AnotherScript>();
yetAnotherScript =
otherGameObject.GetComponent<YetAnotherScript>();
14
boxCol = otherGameObject.GetComponent<BoxCollider>();
}
void Start ()
{
boxCol.size = new Vector3(3,3,3);
Debug.Log("The player's score is " + anotherScript.playerScore);
Debug.Log("The player has died " +
yetAnotherScript.numberOfPlayerDeaths + " times");
}
}
//AnotherScript script
using UnityEngine;
using System.Collections;
public class AnotherScript : MonoBehaviour
{
public int playerScore = 9001;
}
//YetAnotherScript script
using UnityEngine;
using System.Collections;
public class YetAnotherScript : MonoBehaviour
{
public int numberOfPlayerDeaths = 3;
}
15
DeltaTime
Le terme Delta veut dire différence entre deux valeurs. La propriété deltaTime de la
classe “time” est essentiellement le temps écoulé entre deux appels de fonction update
ou fixed update. Cela peut être invoqué pour lisser les valeurs utilisées pour le
mouvement et autres calculs incrémentiels. Le temps entre les frames n’est pas
constant. Nous utilisons cette propriété pour que le jeu soit indépendant du taux des
frames. Si vous utilisez ce script par exemple : float translation = Time.deltaTime
* 10; c’est que vous exprimez le besoin de déplacer l’objet de 10 mètres par seconde
au lieu de 10 mètres par frame.
Exemple
Créez un objet “Sphere” et lui associer ce script. En mode play, l’objet “Sphere” va
bouger d’un taux de 10 mètre par seconde au lieu de 10 mètre par frame.
Script
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
void Update() {
float translation = Time.deltaTime * 10;
transform.Translate(0, 0, translation);
}
}
16
Data Types
Toutes les variables sous Unity possèdent un Data Type. Unity dispose de deux types
de Data Types : Value et Reference.
Le type de données Value contient par exemple des variables tels que : int, float,
double, bool, char, Structs (tel que : Vector3 et Quaternion).
Le type de données Reference contient par exemple des classes. Parmi les classes les
plus utilisées on trouve Transform et GameObject.
Exemple
Dans cet exemple, nous considérons un objet “Sphere” auquel nous associons le script
ci-dessous. Dans la première partie, la sphère ne va pas bouger parce que nous avons
utilisé une variable de type Valeur, par contre dans la deuxième partie, la sphère va
bouger puisque nous avons utilisé une variable de type Reference.
Script
using UnityEngine;
using System.Collections;
public class DatatypeScript : MonoBehaviour
{
void Start ()
{
//Value type variable
Vector3 pos = transform.position;
pos = new Vector3(0, 2, 0);
//Reference type variable
Transform tran = transform;
17
tran.position = new Vector3(0, 4, 0);
}
}
18
Les Classes
Dans Unity, chaque script contient une définition pour une classe. Si les variables sont
considérées comme des boîtes et les fonctions comme des machines, alors les classes
seront considérées comme les usines qui vont contenir ces boîtes et machines. Chaque
fois que vous créez un script, automatiquement Unity crée une classe ( public class …)
pour vous si vous programmez en C#. Cette classe aura le même nom que celui du
script. La classe est un conteneur de variables et de fonctions et fournit, moyennant
d’autres choses un bon moyen de grouper les objets qui travaillent ensemble. C’est un
outil organisationnel qui nous permet d’organiser un seul script en plusieurs scripts,
chacun jouant un seul rôle par exemple. Une classe est censée être dédiée à une seule
tâche.
Exemple
Dans cet exemple, nous avons un script qui manipule un certain nombre de tâches, que
nous allons éclater en trois petits scripts pour le rendre plus facile à gérer. Ce script par
exemple manipule l’inventaire, le mouvement et le tir de balles. Ce script va être attaché
à notre objet “Cube” à créer. Pour ce faire, nous allons créer un objet “Cube” que nous
positionnons à (0, 1.30, 0). Nous positionnons ensuite l’objet “Camera” à (0.2, 1, -5).
Nous créons ensuite un objet “Sphere” que nous positionnons à (-1.5, 1.3, 0) et sa taille
à (0.1, 0.1, 0.1) et nous lui ajoutons après un composant “Rigidbody”. Après nous
glissons l’objet “Sphere” dans le dossier “Prefabs” et nous le supprimons de la
hiérarchie. Nous créons ensuite un GameObject vide auquel nous ajoutons un
composant “Rigidbody” et nous décochons “Gravity”. Nous glissons après ce
Gameobject dans le dossier “Prefabs” et nous le supprimerons ensuite de la hiérarchie.
Après nous glissons le Gameobject depuis le dossier “Prefabs” à l’intérieur de l’objet
“Cube”. Nous positionnons ensuite “GameObject” à (-0.15, -0.05, 0.2).
Après avoir associé le script “SingleCharacterScript” à l’objet “Cube”, nous allons
apercevoir dans l’inspecteur cinq paramètres. Nous mettons respectivement les valeurs
des paramètres Speed, TurnSpeed et Bullet Speed à 7, 90 et 900. Après nous glissons
le “GameObject” vers le paramètre “Fire Position” et l’objet “Sphere” vers le paramètre
“Bullet Prefab”.
19
Script
//Premier Script avec une seule classe “SingleCharacterScript”
using UnityEngine;
using System.Collections;
public class SingleCharacterScript : MonoBehaviour
{
public class Stuff
{
public int bullets;
public int grenades;
public int rockets;
public Stuff (int bul, int gre, int roc)
{
bullets = bul;
grenades = gre;
rockets = roc;
}
}
public Stuff myStuff = new Stuff (10, 7, 25);
public float speed;
public float turnSpeed;
public Rigidbody bulletPrefab;
public Transform firePosition;
public float bulletSpeed;
void Update ()
{
Movement();
Shoot();
}
void Movement ()
{
float forwardMovement = Input.GetAxis("Vertical") * speed * Time.deltaTime;
20
float turnMovement = Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime;
transform.Translate(Vector3.forward * forwardMovement);
transform.Rotate(Vector3.up * turnMovement);
}
void Shoot ()
{
If (Input.GetButtonDown("Fire1") && myStuff.bullets > 0)
{
Rigidbody bulletInstance = Instantiate(bulletPrefab, firePosition.position,
firePosition.rotation) as Rigidbody;
bulletInstance.AddForce(firePosition.forward * bulletSpeed);
myStuff.bullets--;
}
}
}
//
//
//Notre classe SingleCharacterScript on va l’éclater en trois classes : Inventory,
MovementControls et Shooting
//
//Script classe Inventory
//
using UnityEngine;
using System.Collections;
public class Inventaire : MonoBehaviour
{
public class Munition
{
public int bullets;
public int grenades;
public int rockets;
public float fuel;
public Munition (int bul, int gre, int roc)
{
bullets = bul;
21
grenades = gre;
rockets = roc;
}
public Munition (int bul, float fu)
{
bullets = bul;
fuel = fu;
}
// Constructor
public Munition ()
{
bullets = 1;
grenades = 1;
rockets = 1;
}
}
// Creating an Instance (an Object) of the Stuff class
public Munition maMunition = new Munition (50, 5, 5);
public Munition monAutreMunition = new Munition (50, 1.5f);
void Start()
{
Debug.Log (maMunition.bullets);
}
}
//
//Script de la classe MovementControls
//
using UnityEngine;
using System.Collections;
public class MovementControls : MonoBehaviour
{
public float speed;
public float turnSpeed;
22
void Update ()
{
Mouvement ();
}
void Mouvement ()
{
float forwardMouvement = Input.GetAxis ("Vertical") * speed * Time.deltaTime;
float turnMouvement = Input.GetAxis ("Horizontal") * turnSpeed *
Time.deltaTime;
transform.Translate (Vector3.forward * forwardMouvement);
transform.Rotate (Vector3.up * turnMouvement);
}
}
//
//Script de la classe Shooting
//
using UnityEngine;
using System.Collections;
public class Shooting : MonoBehaviour
{
public Rigidbody bulletPrefab;
public Transform firePosition;
public float bulletSpeed;
private Inventory inventory;
void Awake ()
{
inventory = GetComponent <Inventory> ();
}
void Update ()
{
Shoot ();
23
}
void Shoot ()
{
if (Input.GetButtonDown ("Fire1") && inventory.maMunition.bullets > 0)
{
Rigidbody bulletInstance = Instantiate (bulletPrefab, firePosition.position,
firePosition.rotation) as Rigidbody;
bulletInstance.AddForce (firePosition.forward * bulletSpeed);
inventory.maMunition.bullets--;
}
}
}
24
Instantiate
Instantiate est une fonction utilisée pour créer des clones pour les GameObjects.
Généralement, elle est utilisée dans le contexte de cloner un prefab. Un prefab est
simplement un objet préconfiguré sauvegardé dans les assets du projet.
Exemple
Dans cet exemple nous considérons des tirs de rockets à partir d’un Bazooka. Chacune
des rockets a besoin d’être instanciée dans le jeu pour qu’on puisse la tirer. Nous
utilisons dans cet exemple “Fire1” pour déclencher une fonction Instantiate. La forme la
plus basique de la fonction Instantiate est lorsqu’elle prend un seul paramètre : l’objet
que nous voulons cloner. Dans cet exemple, nous avons créé une variable public
appelée “rocketPrefab” que nous passerons dans la commande Instantiate comme
paramètre. Cependant cela veut dire que le prefab va être instancié à sa position par
défaut, qui est 0. Dans notre exemple, cette position est le centre du jeu, le centre où la
“bazooka” est positionnée pour le moment. C’est ainsi que lorsqu’on appuie sur “Play”,
ces rockets apparaissent au centre du “bazooka”. Pour changer cela, nous aurons
besoin de trois paramètres de Instantiate, l’objet à instancier qui est dans notre cas la
“rocketPrefab”, et la position et rotation à attribuer au nouveau clone du prefab. Pour
cela, nous créons un GameObject vide qui va être positionné devant la barell du
bazooka. Nous allons pour ce faire utiliser une variable public appelée “BarellEnd” et
nous utiliserons les valeurs de la position et la rotation de ce composant comme valeurs
à attribuer au nouveau clone du prefab “rocket”. Donc en glissant cette nouvelle location
vide sur notre script dans l’inspecteur nous pouvons dès lors recevoir la transform
position et rotation en utilisant la variable “barellEnd”.
Script
//
// Script de la classe UsingInstantiate
//
using UnityEngine;
using System.Collections;
public class UsingInstantiate : MonoBehaviour
25
{
public Rigidbody rocketPrefab;
public Transform barrelEnd;
void Update ()
{
if(Input.GetButtonDown ("Fire1"))
{
Rigidbody rocketInstance;
rocketInstance = Instantiate (rocketPrefab, barrelEnd.position,
barrelEnd.rotation) as Rigidbody;
rocketInstance.AddForce (barrelEnd.forward * 5000);
}
}
}
//
//Script de la classe RocketDestruction
//
using UnityEngine;
using System.Collections;
public class RocketDestruction : MonoBehaviour
{
void Start()
{
Destroy (gameObject, 1.5f);
}
}
26
Arrays
Les tableaux permettent de stocker une collection de données de même type.
Exemple
Dans cet exemple, nous créons trois GameObjects auxquels nous assignons le tag à
“Player”. À partir du script ci dessous, nous allons chercher ces trois objets par leur tag
et nous allons les placer dans une structure de tableau. Après, nous pouvons dérouler
une boucle pour afficher le nom de ces trois objets successivement.
Script
using UnityEngine;
using System.Collections;
public class Arrays : MonoBehaviour
{
public GameObject[] players;
void Start ()
{
players = GameObject.FindGameObjectsWithTag("Player");
for(int i = 0; i < players.Length; i++)
{
Debug.Log ("Player Number "+i+" is named "+players[i].name);
}
}
}
27
Invoke
La méthode Invoke permet de contrôler l’exécution de fonctions en définissant un temps
d’attente au niveau de son paramètre.
Exemple
Dans cet exemple, au niveau de la classe InvokeScript, nous faisons appel à la
méthode Invoke avec les deux paramètres “SpawnObject” et 2. Cela veut dire que la
fonction “SpawnObject” va être appelée 2 secondes après le Start. Pour ce faire, nous
allons créer un GameObject vide dans lequel nous allons mettre un objet “Sphere” et le
tout on va le glisser vers le dossier “Fablabs”, après le GameObject sera supprimé de la
hiérarchie.
On remarque que la fonction “SpawnObject” est invoquée une seule fois. Si par contre
nous voulons que cette fonction soit invoquée plusieurs fois dans le temps, alors dans
ce cas nous allons utiliser la fonction “InvokeRepeating” à la place de la fonction
“Invoke” et qui prend trois paramètres : le premier c’est la fonction à invoquer, le
deuxième c’est la durée de temps à attendre avant d’invoquer la fonction, le troisième
est la durée de temps à attendre avant d’invoquer la fonction pour les prochaines fois et
c’est répétitif, voir script “InvokeRepeating”. Par ailleurs, pour pouvoir arrêter l’exécution
de InvokeRepeating, on va faire appel à la fonction “CancelInvoke” en lui passant
comme paramètre le nom de la fonction à arrêter et que nous allons placer au niveau
de la fonction Start() par exemple.
Script
//
// Script de la classe InvokeScript
//
using UnityEngine;
using System.Collections;
28
public class InvokeScript : MonoBehaviour
{
public GameObject target;
void Start()
{
Invoke ("SpawnObject", 2);
}
void SpawnObject()
{
Instantiate(target, new Vector3(0, 2, 0), Quaternion.identity);
}
}
//
// Script de la classe InvokeRepeating
//
using UnityEngine;
using System.Collections;
public class InvokeRepeating : MonoBehaviour
{
public GameObject target;
void Start()
{
InvokeRepeating("SpawnObject", 2, 1);
}
void SpawnObject()
{
float x = Random.Range(-2.0f, 2.0f);
29
float z = Random.Range(-2.0f, 2.0f);
Instantiate(target, new Vector3(x, 2, z), Quaternion.identity);
}
}
30
Enumerations
L’Enumeration nous permets de créer une collection de constantes reliées. Les valeurs
d’une énumération par défaut sont des entiers. La première valeur d’une énumération
est attribuée à 0, la deuxième à 1, etc. Sinon on peut changer ces valeurs par défaut
(voir documentation officielle).
Exemple
Dans cet exemple nous définissons une énumération Direction qui va contenir quatre
valeurs : North, South, East and West. Après nous allons faire des tests successifs sur
ces valeurs via le script Unity.
Script
using UnityEngine;
using System.Collections;
public class EnumScript : MonoBehaviour
{
enum Direction {North, East, South, West};
void Start ()
{
Direction myDirection;
myDirection = Direction.North;
}
Direction ReverseDirection (Direction dir)
{
31
If (dir == Direction.North)
dir = Direction.South;
else if (dir == Direction.South)
dir = Direction.North;
else if (dir == Direction.East)
dir = Direction.West;
else if (dir == Direction.West)
dir = Direction.East;
return dir;
}
}
32
Switch Statements
Les états switch sont utilisés pour comparer une seule variable avec une série de
constantes.
Exemple
Dans cet exemple, nous définissons une variable “intelligence” initialisée à 5. Après
nous utilisons l’instruction switch combinée à case pour évaluer la valeur de la variable
“intelligence” et la comparer avec les valeurs successives 5, 4, 3, 2, 1 et defaut au cas
où la variable est différente de toutes les valeurs proposées.
Script
//
// Script de la classe ConversationScript
//
using UnityEngine;
using System.Collections;
public class ConversationScript : MonoBehaviour
{
public int intelligence = 5;
void Greet()
{
switch (intelligence)
{
case 5:
print ("Why hello there good sir! Let me teach you about
Trigonometry!");
break;
33
case 4:
print ("Hello and good day!");
break;
case 3:
print ("Whadya want?");
break;
case 2:
print ("Grog SMASH!");
break;
case 1:
print ("Ulg, glib, Pblblblblb");
break;
default:
print ("Incorrect intelligence level.");
break;
}
}
}
34
Collision
Dans ce Tp, nous allons considérer une sphère et un cube en prefabs. Le jeu va générer
aléatoirement plusieurs cubes qui vont tomber du ciel, et la sphère pouvant se déplacer
horizontalement doit essayer de ne toucher aucun de ces cubes, sinon elle est écrasée suite à
cette collision.
Étapes
1. Créez un nouveau projet sous Unity 3d.
2. Créez un objet Sphère.
3. Créez le script ‘seDeplacer’ et l’associer à l’objet ‘Sphère’ :
a. void Update() {
b. transform.position += new Vector(Input.GetAxis(“Horizontal”), 0, 0);
c. }
d. void OnCollisionEnter() {
e. Destroy(gameObject);
f. }
4. Créez un objet Cube et lui ajouter le composant ‘Rigidbody’.
5. Ajouter ce cube comme Prefabs puis le supprimer de la scène.
6. Créez le script ‘cubes’ et l’associer à l’objet ‘Camera’ :
a. public float delay = 0.1f;
b. public GameObject cube;
c. void start() {
d. InvokeRepeating (“Spawn”, delay, delay);
e. void Spawn() {
f. Instantiate (cube, new Vector3(Random.Range(-6, 6), 10, 0),
Quaternion.identity);
g. }
7. Glissez l’objet cube du prefab vers l’attribut cube de l’objet Camera.
8. Lancez le jeu.
35
TP Cubes à Colorer et Redimensionner
Dans une scène nous disposons de 20 cubes (4 x 5). Nous créons ensuite un Gameobject vide.
Nous glissons les vingt cubes sur ce GameObject. Nous créons ensuite le script suivant :
Script “ColoriageAleatoire” :
public GameObject [] cubes;
Color[] couleurs = new Color[];
public int[] height;
void Start(){
couleurs = new Color[cubes.Length];
height=new int[cubes.Length];
for (int i=0; i<height.Length; i++){
height[i]=Random.Range(1, 10);
}
for (int i=0; i<couleurs.Length; i++){
couleurs[i]=new Color(Random.Range(0f, 1f),Random.Range(0f,
1f),Random.Range(0f, 1f));
}
for (int i=0; i<cubes.Length; i++){
cubes[i].transform.localScale=new Vector3(1,height[i],1);
cubes[i].GetComponent<Renderer>().material.color=couleurs[i];
}
}
36
Download